/* search-panel.c generated by valac 0.12.0, the Vala compiler
 * generated from search-panel.vala, do not modify */

/* -*- mode: vala; indent-tabs-mode: nil -*-*/
/* Copyright (C) 2011  Daiki Ueno*/
/* Copyright (C) 2011  Red Hat, Inc.*/
/* This program is free software; you can redistribute it and/or*/
/* modify it under the terms of the GNU General Public License*/
/* as published by the Free Software Foundation; either version 2*/
/* of the License, or (at your option) any later version.*/
/* This program is distributed in the hope that it will be useful,*/
/* but WITHOUT ANY WARRANTY; without even the implied warranty of*/
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*/
/* GNU General Public License for more details.*/
/* You should have received a copy of the GNU General Public License*/
/* along with this program; if not, write to the Free Software*/
/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA*/
/* 02110-1301, USA.*/

#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <stdio.h>
#include <config.h>


#define IBUS_GUCHARMAP_TYPE_CHARACTER_RENDERER (ibus_gucharmap_character_renderer_get_type ())
#define IBUS_GUCHARMAP_CHARACTER_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_GUCHARMAP_TYPE_CHARACTER_RENDERER, IBusGucharmapCharacterRenderer))
#define IBUS_GUCHARMAP_CHARACTER_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_GUCHARMAP_TYPE_CHARACTER_RENDERER, IBusGucharmapCharacterRendererClass))
#define IBUS_GUCHARMAP_IS_CHARACTER_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_GUCHARMAP_TYPE_CHARACTER_RENDERER))
#define IBUS_GUCHARMAP_IS_CHARACTER_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_GUCHARMAP_TYPE_CHARACTER_RENDERER))
#define IBUS_GUCHARMAP_CHARACTER_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_GUCHARMAP_TYPE_CHARACTER_RENDERER, IBusGucharmapCharacterRendererClass))

typedef struct _IBusGucharmapCharacterRenderer IBusGucharmapCharacterRenderer;
typedef struct _IBusGucharmapCharacterRendererClass IBusGucharmapCharacterRendererClass;
typedef struct _IBusGucharmapCharacterRendererPrivate IBusGucharmapCharacterRendererPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))

#define IBUS_GUCHARMAP_TYPE_SEARCH_PANEL (ibus_gucharmap_search_panel_get_type ())
#define IBUS_GUCHARMAP_SEARCH_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_GUCHARMAP_TYPE_SEARCH_PANEL, IBusGucharmapSearchPanel))
#define IBUS_GUCHARMAP_SEARCH_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_GUCHARMAP_TYPE_SEARCH_PANEL, IBusGucharmapSearchPanelClass))
#define IBUS_GUCHARMAP_IS_SEARCH_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_GUCHARMAP_TYPE_SEARCH_PANEL))
#define IBUS_GUCHARMAP_IS_SEARCH_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_GUCHARMAP_TYPE_SEARCH_PANEL))
#define IBUS_GUCHARMAP_SEARCH_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_GUCHARMAP_TYPE_SEARCH_PANEL, IBusGucharmapSearchPanelClass))

typedef struct _IBusGucharmapSearchPanel IBusGucharmapSearchPanel;
typedef struct _IBusGucharmapSearchPanelClass IBusGucharmapSearchPanelClass;
typedef struct _IBusGucharmapSearchPanelPrivate IBusGucharmapSearchPanelPrivate;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
#define _gtk_tree_path_free0(var) ((var == NULL) ? NULL : (var = (gtk_tree_path_free (var), NULL)))
#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL)))
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))

#define IBUS_GUCHARMAP_TYPE_CONFIG_CACHE (ibus_gucharmap_config_cache_get_type ())
#define IBUS_GUCHARMAP_CONFIG_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_GUCHARMAP_TYPE_CONFIG_CACHE, IBusGucharmapConfigCache))
#define IBUS_GUCHARMAP_CONFIG_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_GUCHARMAP_TYPE_CONFIG_CACHE, IBusGucharmapConfigCacheClass))
#define IBUS_GUCHARMAP_IS_CONFIG_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_GUCHARMAP_TYPE_CONFIG_CACHE))
#define IBUS_GUCHARMAP_IS_CONFIG_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_GUCHARMAP_TYPE_CONFIG_CACHE))
#define IBUS_GUCHARMAP_CONFIG_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_GUCHARMAP_TYPE_CONFIG_CACHE, IBusGucharmapConfigCacheClass))

typedef struct _IBusGucharmapConfigCache IBusGucharmapConfigCache;
typedef struct _IBusGucharmapConfigCacheClass IBusGucharmapConfigCacheClass;
#define _sqlite3_close0(var) ((var == NULL) ? NULL : (var = (sqlite3_close (var), NULL)))

struct _IBusGucharmapCharacterRenderer {
	GtkCellRendererText parent_instance;
	IBusGucharmapCharacterRendererPrivate * priv;
};

struct _IBusGucharmapCharacterRendererClass {
	GtkCellRendererTextClass parent_class;
};

struct _IBusGucharmapCharacterRendererPrivate {
	gunichar _codepoint;
};

struct _IBusGucharmapSearchPanel {
	GtkBox parent_instance;
	IBusGucharmapSearchPanelPrivate * priv;
};

struct _IBusGucharmapSearchPanelClass {
	GtkBoxClass parent_class;
};

struct _IBusGucharmapSearchPanelPrivate {
	GtkEntry* entry;
	GtkTreeView* matches;
	guint idle_search_id;
};


static gpointer ibus_gucharmap_character_renderer_parent_class = NULL;
static gpointer ibus_gucharmap_search_panel_parent_class = NULL;
static sqlite3* ibus_gucharmap_search_panel_database;
static sqlite3* ibus_gucharmap_search_panel_database = NULL;
extern IBusGucharmapConfigCache* ibus_gucharmap_config;

GType ibus_gucharmap_character_renderer_get_type (void) G_GNUC_CONST;
#define IBUS_GUCHARMAP_CHARACTER_RENDERER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_GUCHARMAP_TYPE_CHARACTER_RENDERER, IBusGucharmapCharacterRendererPrivate))
enum  {
	IBUS_GUCHARMAP_CHARACTER_RENDERER_DUMMY_PROPERTY,
	IBUS_GUCHARMAP_CHARACTER_RENDERER_CODEPOINT
};
IBusGucharmapCharacterRenderer* ibus_gucharmap_character_renderer_new (void);
IBusGucharmapCharacterRenderer* ibus_gucharmap_character_renderer_construct (GType object_type);
gunichar ibus_gucharmap_character_renderer_get_codepoint (IBusGucharmapCharacterRenderer* self);
void ibus_gucharmap_character_renderer_set_codepoint (IBusGucharmapCharacterRenderer* self, gunichar value);
static void ibus_gucharmap_character_renderer_finalize (GObject* obj);
static void _vala_ibus_gucharmap_character_renderer_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
static void _vala_ibus_gucharmap_character_renderer_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
GType ibus_gucharmap_search_panel_get_type (void) G_GNUC_CONST;
#define IBUS_GUCHARMAP_SEARCH_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_GUCHARMAP_TYPE_SEARCH_PANEL, IBusGucharmapSearchPanelPrivate))
enum  {
	IBUS_GUCHARMAP_SEARCH_PANEL_DUMMY_PROPERTY
};
void ibus_gucharmap_search_panel_append_c (IBusGucharmapSearchPanel* self, gchar c);
static void ibus_gucharmap_search_panel_update_matches (IBusGucharmapSearchPanel* self);
void ibus_gucharmap_search_panel_delete_c (IBusGucharmapSearchPanel* self);
void ibus_gucharmap_search_panel_erase (IBusGucharmapSearchPanel* self);
gchar* ibus_gucharmap_search_panel_get_text (IBusGucharmapSearchPanel* self);
void ibus_gucharmap_search_panel_activate_selected (IBusGucharmapSearchPanel* self);
void ibus_gucharmap_search_panel_move_cursor (IBusGucharmapSearchPanel* self, GtkMovementStep step, gint count);
static void ibus_gucharmap_search_panel_on_row_activated (IBusGucharmapSearchPanel* self, GtkTreePath* path, GtkTreeViewColumn* column);
static gboolean ibus_gucharmap_search_panel_idle_search (IBusGucharmapSearchPanel* self);
GType ibus_gucharmap_config_cache_get_type (void) G_GNUC_CONST;
gint ibus_gucharmap_config_cache_get_number_of_matches (IBusGucharmapConfigCache* self);
static gboolean _ibus_gucharmap_search_panel_idle_search_gsource_func (gpointer self);
IBusGucharmapSearchPanel* ibus_gucharmap_search_panel_new (void);
IBusGucharmapSearchPanel* ibus_gucharmap_search_panel_construct (GType object_type);
static void _ibus_gucharmap_search_panel_on_row_activated_gtk_tree_view_row_activated (GtkTreeView* _sender, GtkTreePath* path, GtkTreeViewColumn* column, gpointer self);
static void ibus_gucharmap_search_panel_finalize (GObject* obj);


IBusGucharmapCharacterRenderer* ibus_gucharmap_character_renderer_construct (GType object_type) {
	IBusGucharmapCharacterRenderer * self = NULL;
	self = (IBusGucharmapCharacterRenderer*) g_object_new (object_type, NULL);
	return self;
}


IBusGucharmapCharacterRenderer* ibus_gucharmap_character_renderer_new (void) {
	return ibus_gucharmap_character_renderer_construct (IBUS_GUCHARMAP_TYPE_CHARACTER_RENDERER);
}


gunichar ibus_gucharmap_character_renderer_get_codepoint (IBusGucharmapCharacterRenderer* self) {
	gunichar result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_codepoint;
	return result;
}


static gchar* g_unichar_to_string (gunichar self) {
	gchar* result = NULL;
	gchar* _tmp0_ = NULL;
	gchar* str;
	_tmp0_ = g_new0 (gchar, 7);
	str = (gchar*) _tmp0_;
	g_unichar_to_utf8 (self, str);
	result = str;
	return result;
}


void ibus_gucharmap_character_renderer_set_codepoint (IBusGucharmapCharacterRenderer* self, gunichar value) {
	gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	self->priv->_codepoint = value;
	_tmp0_ = g_unichar_to_string (self->priv->_codepoint);
	_tmp1_ = _tmp0_;
	g_object_set ((GtkCellRendererText*) self, "text", _tmp1_, NULL);
	_g_free0 (_tmp1_);
	g_object_notify ((GObject *) self, "codepoint");
}


static void ibus_gucharmap_character_renderer_class_init (IBusGucharmapCharacterRendererClass * klass) {
	ibus_gucharmap_character_renderer_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (IBusGucharmapCharacterRendererPrivate));
	G_OBJECT_CLASS (klass)->get_property = _vala_ibus_gucharmap_character_renderer_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ibus_gucharmap_character_renderer_set_property;
	G_OBJECT_CLASS (klass)->finalize = ibus_gucharmap_character_renderer_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), IBUS_GUCHARMAP_CHARACTER_RENDERER_CODEPOINT, g_param_spec_uint ("codepoint", "codepoint", "codepoint", 0, G_MAXUINT, 0U, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
}


static void ibus_gucharmap_character_renderer_instance_init (IBusGucharmapCharacterRenderer * self) {
	self->priv = IBUS_GUCHARMAP_CHARACTER_RENDERER_GET_PRIVATE (self);
}


static void ibus_gucharmap_character_renderer_finalize (GObject* obj) {
	IBusGucharmapCharacterRenderer * self;
	self = IBUS_GUCHARMAP_CHARACTER_RENDERER (obj);
	G_OBJECT_CLASS (ibus_gucharmap_character_renderer_parent_class)->finalize (obj);
}


GType ibus_gucharmap_character_renderer_get_type (void) {
	static volatile gsize ibus_gucharmap_character_renderer_type_id__volatile = 0;
	if (g_once_init_enter (&ibus_gucharmap_character_renderer_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (IBusGucharmapCharacterRendererClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ibus_gucharmap_character_renderer_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (IBusGucharmapCharacterRenderer), 0, (GInstanceInitFunc) ibus_gucharmap_character_renderer_instance_init, NULL };
		GType ibus_gucharmap_character_renderer_type_id;
		ibus_gucharmap_character_renderer_type_id = g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT, "IBusGucharmapCharacterRenderer", &g_define_type_info, 0);
		g_once_init_leave (&ibus_gucharmap_character_renderer_type_id__volatile, ibus_gucharmap_character_renderer_type_id);
	}
	return ibus_gucharmap_character_renderer_type_id__volatile;
}


static void _vala_ibus_gucharmap_character_renderer_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	IBusGucharmapCharacterRenderer * self;
	self = IBUS_GUCHARMAP_CHARACTER_RENDERER (object);
	switch (property_id) {
		case IBUS_GUCHARMAP_CHARACTER_RENDERER_CODEPOINT:
		g_value_set_uint (value, ibus_gucharmap_character_renderer_get_codepoint (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void _vala_ibus_gucharmap_character_renderer_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
	IBusGucharmapCharacterRenderer * self;
	self = IBUS_GUCHARMAP_CHARACTER_RENDERER (object);
	switch (property_id) {
		case IBUS_GUCHARMAP_CHARACTER_RENDERER_CODEPOINT:
		ibus_gucharmap_character_renderer_set_codepoint (self, g_value_get_uint (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


void ibus_gucharmap_search_panel_append_c (IBusGucharmapSearchPanel* self, gchar c) {
	const gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	gchar* text;
	GString* _tmp2_ = NULL;
	GString* builder;
	g_return_if_fail (self != NULL);
	_tmp0_ = gtk_entry_get_text (self->priv->entry);
	_tmp1_ = g_strdup (_tmp0_);
	text = _tmp1_;
	_tmp2_ = g_string_new (text);
	builder = _tmp2_;
	g_string_append_c (builder, c);
	gtk_entry_set_text (self->priv->entry, builder->str);
	ibus_gucharmap_search_panel_update_matches (self);
	_g_string_free0 (builder);
	_g_free0 (text);
}


void ibus_gucharmap_search_panel_delete_c (IBusGucharmapSearchPanel* self) {
	const gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	gchar* text;
	GString* _tmp2_ = NULL;
	GString* builder;
	g_return_if_fail (self != NULL);
	_tmp0_ = gtk_entry_get_text (self->priv->entry);
	_tmp1_ = g_strdup (_tmp0_);
	text = _tmp1_;
	_tmp2_ = g_string_new (text);
	builder = _tmp2_;
	g_string_truncate (builder, (gsize) (builder->len - 1));
	gtk_entry_set_text (self->priv->entry, builder->str);
	ibus_gucharmap_search_panel_update_matches (self);
	_g_string_free0 (builder);
	_g_free0 (text);
}


void ibus_gucharmap_search_panel_erase (IBusGucharmapSearchPanel* self) {
	g_return_if_fail (self != NULL);
	gtk_entry_set_text (self->priv->entry, "");
	ibus_gucharmap_search_panel_update_matches (self);
}


gchar* ibus_gucharmap_search_panel_get_text (IBusGucharmapSearchPanel* self) {
	gchar* result = NULL;
	const gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gtk_entry_get_text (self->priv->entry);
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}


void ibus_gucharmap_search_panel_activate_selected (IBusGucharmapSearchPanel* self) {
	GtkTreePath* path = NULL;
	GtkTreePath* _tmp0_ = NULL;
	GtkTreeViewColumn* _tmp1_ = NULL;
	g_return_if_fail (self != NULL);
	gtk_tree_view_get_cursor (self->priv->matches, &_tmp0_, NULL);
	_gtk_tree_path_free0 (path);
	path = _tmp0_;
	_tmp1_ = gtk_tree_view_get_column (self->priv->matches, 0);
	gtk_tree_view_row_activated (self->priv->matches, path, _tmp1_);
	_gtk_tree_path_free0 (path);
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


void ibus_gucharmap_search_panel_move_cursor (IBusGucharmapSearchPanel* self, GtkMovementStep step, gint count) {
	g_return_if_fail (self != NULL);
	if (step == GTK_MOVEMENT_DISPLAY_LINES) {
		GtkTreePath* path = NULL;
		GtkTreePath* _tmp0_ = NULL;
		GtkTreeModel* _tmp1_ = NULL;
		GtkTreeModel* _tmp2_;
		GtkTreeModel* store;
		GtkTreeIter iter = {0};
		GtkTreeIter _tmp3_ = {0};
		gboolean _tmp4_;
		gtk_widget_grab_focus ((GtkWidget*) self->priv->matches);
		gtk_tree_view_get_cursor (self->priv->matches, &_tmp0_, NULL);
		_gtk_tree_path_free0 (path);
		path = _tmp0_;
		while (TRUE) {
			if (!(count < 0)) {
				break;
			}
			gtk_tree_path_prev (path);
			count++;
		}
		while (TRUE) {
			if (!(count > 0)) {
				break;
			}
			gtk_tree_path_next (path);
			count--;
		}
		_tmp1_ = gtk_tree_view_get_model (self->priv->matches);
		_tmp2_ = _g_object_ref0 (_tmp1_);
		store = _tmp2_;
		_tmp4_ = gtk_tree_model_get_iter (store, &_tmp3_, path);
		iter = _tmp3_;
		if (_tmp4_) {
			gtk_tree_view_set_cursor (self->priv->matches, path, NULL, FALSE);
		}
		_g_object_unref0 (store);
		_gtk_tree_path_free0 (path);
	}
}


static void ibus_gucharmap_search_panel_on_row_activated (IBusGucharmapSearchPanel* self, GtkTreePath* path, GtkTreeViewColumn* column) {
	GtkTreeModel* _tmp0_ = NULL;
	GtkTreeModel* _tmp1_;
	GtkTreeModel* store;
	GtkTreeIter iter = {0};
	GtkTreeIter _tmp2_ = {0};
	gunichar uc = 0U;
	g_return_if_fail (self != NULL);
	g_return_if_fail (path != NULL);
	g_return_if_fail (column != NULL);
	_tmp0_ = gtk_tree_view_get_model (self->priv->matches);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	store = _tmp1_;
	gtk_tree_model_get_iter (store, &_tmp2_, path);
	iter = _tmp2_;
	gtk_tree_model_get (store, &iter, 0, &uc, -1);
	g_signal_emit_by_name (self, "activate-character", uc);
	_g_object_unref0 (store);
}


static gchar* string_replace (const gchar* self, const gchar* old, const gchar* replacement) {
	gchar* result = NULL;
	gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	GRegex* _tmp2_ = NULL;
	GRegex* _tmp3_;
	GRegex* regex;
	gchar* _tmp4_ = NULL;
	gchar* _tmp5_;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	_tmp0_ = g_regex_escape_string (old, -1);
	_tmp1_ = _tmp0_;
	_tmp2_ = g_regex_new (_tmp1_, 0, 0, &_inner_error_);
	_tmp3_ = _tmp2_;
	_g_free0 (_tmp1_);
	regex = _tmp3_;
	if (_inner_error_ != NULL) {
		if (_inner_error_->domain == G_REGEX_ERROR) {
			goto __catch0_g_regex_error;
		}
		g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return NULL;
	}
	_tmp4_ = g_regex_replace_literal (regex, self, (gssize) (-1), 0, replacement, 0, &_inner_error_);
	_tmp5_ = _tmp4_;
	if (_inner_error_ != NULL) {
		_g_regex_unref0 (regex);
		if (_inner_error_->domain == G_REGEX_ERROR) {
			goto __catch0_g_regex_error;
		}
		_g_regex_unref0 (regex);
		g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return NULL;
	}
	result = _tmp5_;
	_g_regex_unref0 (regex);
	return result;
	_g_regex_unref0 (regex);
	goto __finally0;
	__catch0_g_regex_error:
	{
		GError * e;
		e = _inner_error_;
		_inner_error_ = NULL;
		g_assert_not_reached ();
		_g_error_free0 (e);
	}
	__finally0:
	if (_inner_error_ != NULL) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return NULL;
	}
}


static gint string_index_of (const gchar* self, const gchar* needle, gint start_index) {
	gint result = 0;
	gchar* _tmp0_ = NULL;
	gchar* _result_;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (needle != NULL, 0);
	_tmp0_ = strstr (((gchar*) self) + start_index, (gchar*) needle);
	_result_ = _tmp0_;
	if (_result_ != NULL) {
		result = (gint) (_result_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}


static glong string_strnlen (gchar* str, glong maxlen) {
	glong result = 0L;
	gchar* _tmp0_ = NULL;
	gchar* end;
	_tmp0_ = memchr (str, 0, (gsize) maxlen);
	end = _tmp0_;
	if (end == NULL) {
		result = maxlen;
		return result;
	} else {
		result = (glong) (end - str);
		return result;
	}
}


static gchar* string_substring (const gchar* self, glong offset, glong len) {
	gchar* result = NULL;
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	gchar* _tmp3_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	if (offset >= 0) {
		_tmp0_ = len >= 0;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		glong _tmp1_;
		_tmp1_ = string_strnlen ((gchar*) self, offset + len);
		string_length = _tmp1_;
	} else {
		gint _tmp2_;
		_tmp2_ = strlen (self);
		string_length = (glong) _tmp2_;
	}
	if (offset < 0) {
		offset = string_length + offset;
		g_return_val_if_fail (offset >= 0, NULL);
	} else {
		g_return_val_if_fail (offset <= string_length, NULL);
	}
	if (len < 0) {
		len = string_length - offset;
	}
	g_return_val_if_fail ((offset + len) <= string_length, NULL);
	_tmp3_ = g_strndup (((gchar*) self) + offset, (gsize) len);
	result = _tmp3_;
	return result;
}


static gboolean ibus_gucharmap_search_panel_idle_search (IBusGucharmapSearchPanel* self) {
	gboolean result = FALSE;
	const gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	gchar* text;
	GtkTreeModel* _tmp2_ = NULL;
	GtkListStore* _tmp3_;
	GtkListStore* store;
	sqlite3_stmt* stmt = NULL;
	gchar* _tmp4_;
	gchar* sql;
	gint rc = 0;
	gint _tmp5_;
	sqlite3_stmt* _tmp6_ = NULL;
	gint _tmp7_;
	gchar* _tmp9_ = NULL;
	gchar* _tmp10_;
	gchar* _tmp11_;
	gchar* _tmp12_;
	gchar* _tmp13_;
	gint _tmp14_;
	gint _tmp16_;
	gint _tmp17_;
	GtkTreeIter iter = {0};
	GtkTreeIter _tmp19_ = {0};
	gboolean _tmp20_;
	gboolean valid;
	gint n_matches;
	GtkTreeIter _tmp46_ = {0};
	gboolean _tmp47_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = gtk_entry_get_text (self->priv->entry);
	_tmp1_ = g_strdup (_tmp0_);
	text = _tmp1_;
	_tmp2_ = gtk_tree_view_get_model (self->priv->matches);
	_tmp3_ = _g_object_ref0 (GTK_LIST_STORE (_tmp2_));
	store = _tmp3_;
	_tmp4_ = g_strdup ("\n" \
"SELECT codepoint, name FROM unicode_names WHERE name LIKE ? LIMIT ?;\n");
	sql = _tmp4_;
	_tmp5_ = strlen (sql);
	_tmp7_ = sqlite3_prepare (ibus_gucharmap_search_panel_database, sql, _tmp5_, &_tmp6_, NULL);
	_sqlite3_finalize0 (stmt);
	stmt = _tmp6_;
	rc = _tmp7_;
	if (rc != SQLITE_OK) {
		const gchar* _tmp8_ = NULL;
		_tmp8_ = sqlite3_errmsg (ibus_gucharmap_search_panel_database);
		fprintf (stderr, "can't prepare statement: %s\n", _tmp8_);
		result = FALSE;
		_g_free0 (sql);
		_sqlite3_finalize0 (stmt);
		_g_object_unref0 (store);
		_g_free0 (text);
		return result;
	}
	_tmp9_ = string_replace (text, "%", "%%");
	_tmp10_ = _tmp9_;
	_tmp11_ = g_strconcat ("%", _tmp10_, NULL);
	_tmp12_ = _tmp11_;
	_tmp13_ = g_strconcat (_tmp12_, "%", NULL);
	_tmp14_ = sqlite3_bind_text (stmt, 1, _tmp13_, -1, g_free);
	rc = _tmp14_;
	_g_free0 (_tmp12_);
	_g_free0 (_tmp10_);
	if (rc != SQLITE_OK) {
		const gchar* _tmp15_ = NULL;
		_tmp15_ = sqlite3_errmsg (ibus_gucharmap_search_panel_database);
		fprintf (stderr, "can't bind values: %s\n", _tmp15_);
		result = FALSE;
		_g_free0 (sql);
		_sqlite3_finalize0 (stmt);
		_g_object_unref0 (store);
		_g_free0 (text);
		return result;
	}
	_tmp16_ = ibus_gucharmap_config_cache_get_number_of_matches (ibus_gucharmap_config);
	_tmp17_ = sqlite3_bind_int64 (stmt, 2, (gint64) ((gint) _tmp16_));
	rc = _tmp17_;
	if (rc != SQLITE_OK) {
		const gchar* _tmp18_ = NULL;
		_tmp18_ = sqlite3_errmsg (ibus_gucharmap_search_panel_database);
		fprintf (stderr, "can't bind values: %s\n", _tmp18_);
		result = FALSE;
		_g_free0 (sql);
		_sqlite3_finalize0 (stmt);
		_g_object_unref0 (store);
		_g_free0 (text);
		return result;
	}
	_tmp20_ = gtk_tree_model_get_iter_first ((GtkTreeModel*) store, &_tmp19_);
	iter = _tmp19_;
	valid = _tmp20_;
	n_matches = 0;
	while (TRUE) {
		gint _tmp21_;
		_tmp21_ = sqlite3_step (stmt);
		rc = _tmp21_;
		if (rc == SQLITE_ROW) {
			const gchar* _tmp24_ = NULL;
			gchar* _tmp25_;
			gchar* name;
			gchar* _tmp26_ = NULL;
			gchar* _tmp27_;
			gchar* _tmp28_ = NULL;
			gchar* _tmp29_;
			gint _tmp30_;
			gint _tmp31_;
			gint index;
			gchar* _tmp32_ = NULL;
			gchar* _tmp33_;
			gint _tmp34_;
			gchar* _tmp35_ = NULL;
			gchar* _tmp36_;
			gint _tmp37_;
			gchar* _tmp38_ = NULL;
			gchar* _tmp39_;
			gchar* _tmp40_ = NULL;
			gchar* _tmp41_;
			gchar* markup;
			gint64 _tmp42_;
			gboolean _tmp43_;
			if (!valid) {
				gint _tmp22_;
				GtkTreeIter _tmp23_ = {0};
				_tmp22_ = n_matches;
				n_matches = _tmp22_ + 1;
				gtk_list_store_insert (store, &_tmp23_, _tmp22_);
				iter = _tmp23_;
			}
			_tmp24_ = sqlite3_column_text (stmt, 1);
			_tmp25_ = g_strdup (_tmp24_);
			name = _tmp25_;
			_tmp26_ = g_utf8_casefold (name, (gssize) (-1));
			_tmp27_ = _tmp26_;
			_tmp28_ = g_utf8_casefold (text, (gssize) (-1));
			_tmp29_ = _tmp28_;
			_tmp30_ = string_index_of (_tmp27_, _tmp29_, 0);
			_tmp31_ = _tmp30_;
			_g_free0 (_tmp29_);
			_g_free0 (_tmp27_);
			index = _tmp31_;
			_tmp32_ = string_substring (name, (glong) 0, (glong) index);
			_tmp33_ = _tmp32_;
			_tmp34_ = strlen (text);
			_tmp35_ = string_substring (name, (glong) index, (glong) _tmp34_);
			_tmp36_ = _tmp35_;
			_tmp37_ = strlen (text);
			_tmp38_ = string_substring (name, (glong) (index + _tmp37_), (glong) (-1));
			_tmp39_ = _tmp38_;
			_tmp40_ = g_markup_printf_escaped ("%s<b>%s</b>%s", _tmp33_, _tmp36_, _tmp39_);
			_tmp41_ = _tmp40_;
			_g_free0 (_tmp39_);
			_g_free0 (_tmp36_);
			_g_free0 (_tmp33_);
			markup = _tmp41_;
			_tmp42_ = sqlite3_column_int64 (stmt, 0);
			gtk_list_store_set (store, &iter, 0, (guint) _tmp42_, 1, markup, -1);
			_tmp43_ = gtk_tree_model_iter_next ((GtkTreeModel*) store, &iter);
			valid = _tmp43_;
			_g_free0 (markup);
			_g_free0 (name);
		} else {
			if (rc == SQLITE_DONE) {
				break;
			} else {
				const gchar* _tmp44_ = NULL;
				_tmp44_ = sqlite3_errmsg (ibus_gucharmap_search_panel_database);
				fprintf (stderr, "can't step: %s\n", _tmp44_);
				break;
			}
		}
	}
	while (TRUE) {
		gboolean _tmp45_;
		if (!valid) {
			break;
		}
		_tmp45_ = gtk_list_store_remove (store, &iter);
		valid = _tmp45_;
	}
	_tmp47_ = gtk_tree_model_get_iter_first ((GtkTreeModel*) store, &_tmp46_);
	iter = _tmp46_;
	if (_tmp47_) {
		GtkTreePath* _tmp48_ = NULL;
		GtkTreePath* _tmp49_;
		_tmp48_ = gtk_tree_model_get_path ((GtkTreeModel*) store, &iter);
		_tmp49_ = _tmp48_;
		gtk_tree_view_set_cursor (self->priv->matches, _tmp49_, NULL, FALSE);
		_gtk_tree_path_free0 (_tmp49_);
	}
	result = FALSE;
	_g_free0 (sql);
	_sqlite3_finalize0 (stmt);
	_g_object_unref0 (store);
	_g_free0 (text);
	return result;
}


static gboolean _ibus_gucharmap_search_panel_idle_search_gsource_func (gpointer self) {
	gboolean result;
	result = ibus_gucharmap_search_panel_idle_search (self);
	return result;
}


static void ibus_gucharmap_search_panel_update_matches (IBusGucharmapSearchPanel* self) {
	const gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	gchar* text;
	GtkTreeModel* _tmp2_ = NULL;
	GtkListStore* _tmp3_;
	GtkListStore* store;
	gint _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp0_ = gtk_entry_get_text (self->priv->entry);
	_tmp1_ = g_strdup (_tmp0_);
	text = _tmp1_;
	_tmp2_ = gtk_tree_view_get_model (self->priv->matches);
	_tmp3_ = _g_object_ref0 (GTK_LIST_STORE (_tmp2_));
	store = _tmp3_;
	if (self->priv->idle_search_id > 0) {
		g_source_remove (self->priv->idle_search_id);
	}
	_tmp4_ = strlen (text);
	if (_tmp4_ == 0) {
		gtk_list_store_clear (store);
	} else {
		guint _tmp5_;
		_tmp5_ = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, _ibus_gucharmap_search_panel_idle_search_gsource_func, g_object_ref (self), g_object_unref);
		self->priv->idle_search_id = _tmp5_;
	}
	_g_object_unref0 (store);
	_g_free0 (text);
}


static void _ibus_gucharmap_search_panel_on_row_activated_gtk_tree_view_row_activated (GtkTreeView* _sender, GtkTreePath* path, GtkTreeViewColumn* column, gpointer self) {
	ibus_gucharmap_search_panel_on_row_activated (self, path, column);
}


IBusGucharmapSearchPanel* ibus_gucharmap_search_panel_construct (GType object_type) {
	IBusGucharmapSearchPanel * self = NULL;
	GtkVBox* _tmp0_ = NULL;
	GtkVBox* paned;
	GtkEntry* _tmp1_ = NULL;
	GtkScrolledWindow* _tmp2_ = NULL;
	GtkScrolledWindow* scrolled_window;
	GtkListStore* _tmp3_ = NULL;
	GtkListStore* model;
	GtkTreeView* _tmp4_ = NULL;
	IBusGucharmapCharacterRenderer* _tmp5_ = NULL;
	GtkCellRenderer* renderer;
	GtkCellRendererText* _tmp6_ = NULL;
	GtkTreeViewColumn* _tmp7_ = NULL;
	GtkTreeViewColumn* _tmp8_;
	GtkTreeViewColumn* column;
	self = (IBusGucharmapSearchPanel*) g_object_new (object_type, NULL);
	_tmp0_ = (GtkVBox*) gtk_vbox_new (FALSE, 0);
	paned = g_object_ref_sink (_tmp0_);
	_tmp1_ = (GtkEntry*) gtk_entry_new ();
	_g_object_unref0 (self->priv->entry);
	self->priv->entry = g_object_ref_sink (_tmp1_);
	gtk_editable_set_editable ((GtkEditable*) self->priv->entry, FALSE);
	gtk_box_pack_start ((GtkBox*) paned, (GtkWidget*) self->priv->entry, FALSE, FALSE, (guint) 0);
	_tmp2_ = (GtkScrolledWindow*) gtk_scrolled_window_new (NULL, NULL);
	scrolled_window = g_object_ref_sink (_tmp2_);
	gtk_scrolled_window_set_policy (scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type (scrolled_window, GTK_SHADOW_ETCHED_IN);
	_tmp3_ = gtk_list_store_new (2, G_TYPE_UINT, G_TYPE_STRING);
	model = _tmp3_;
	_tmp4_ = (GtkTreeView*) gtk_tree_view_new_with_model ((GtkTreeModel*) model);
	_g_object_unref0 (self->priv->matches);
	self->priv->matches = g_object_ref_sink (_tmp4_);
	_tmp5_ = ibus_gucharmap_character_renderer_new ();
	renderer = (GtkCellRenderer*) g_object_ref_sink (_tmp5_);
	gtk_tree_view_insert_column_with_attributes (self->priv->matches, -1, "codepoint", renderer, "codepoint", 0, NULL);
	_tmp6_ = (GtkCellRendererText*) gtk_cell_renderer_text_new ();
	_g_object_unref0 (renderer);
	renderer = (GtkCellRenderer*) g_object_ref_sink (_tmp6_);
	gtk_tree_view_insert_column_with_attributes (self->priv->matches, -1, "name", renderer, "markup", 1, NULL);
	gtk_tree_view_set_headers_visible (self->priv->matches, FALSE);
	g_signal_connect_object (self->priv->matches, "row-activated", (GCallback) _ibus_gucharmap_search_panel_on_row_activated_gtk_tree_view_row_activated, self, 0);
	_tmp7_ = gtk_tree_view_get_column (self->priv->matches, 1);
	_tmp8_ = _g_object_ref0 (_tmp7_);
	column = _tmp8_;
	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_container_add ((GtkContainer*) scrolled_window, (GtkWidget*) self->priv->matches);
	gtk_box_pack_end ((GtkBox*) paned, (GtkWidget*) scrolled_window, TRUE, TRUE, (guint) 0);
	gtk_widget_show_all ((GtkWidget*) paned);
	gtk_box_pack_start ((GtkBox*) self, (GtkWidget*) paned, TRUE, TRUE, (guint) 0);
	_g_object_unref0 (column);
	_g_object_unref0 (renderer);
	_g_object_unref0 (model);
	_g_object_unref0 (scrolled_window);
	_g_object_unref0 (paned);
	return self;
}


IBusGucharmapSearchPanel* ibus_gucharmap_search_panel_new (void) {
	return ibus_gucharmap_search_panel_construct (IBUS_GUCHARMAP_TYPE_SEARCH_PANEL);
}


static void ibus_gucharmap_search_panel_class_init (IBusGucharmapSearchPanelClass * klass) {
	gchar* _tmp0_ = NULL;
	gchar* filename;
	gint rc = 0;
	sqlite3* _tmp1_ = NULL;
	gint _tmp2_;
	ibus_gucharmap_search_panel_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (IBusGucharmapSearchPanelPrivate));
	G_OBJECT_CLASS (klass)->finalize = ibus_gucharmap_search_panel_finalize;
	g_signal_new ("activate_character", IBUS_GUCHARMAP_TYPE_SEARCH_PANEL, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
	_tmp0_ = g_build_filename (PACKAGE_DATADIR, UNICODENAMESFILE, NULL);
	filename = _tmp0_;
	_tmp2_ = sqlite3_open_v2 (filename, &_tmp1_, SQLITE_OPEN_READONLY, NULL);
	_sqlite3_close0 (ibus_gucharmap_search_panel_database);
	ibus_gucharmap_search_panel_database = _tmp1_;
	rc = _tmp2_;
	if (rc != SQLITE_OK) {
		fprintf (stderr, "can't open database\n");
		g_assert_not_reached ();
	}
	_g_free0 (filename);
}


static void ibus_gucharmap_search_panel_instance_init (IBusGucharmapSearchPanel * self) {
	self->priv = IBUS_GUCHARMAP_SEARCH_PANEL_GET_PRIVATE (self);
	self->priv->idle_search_id = (guint) 0;
}


static void ibus_gucharmap_search_panel_finalize (GObject* obj) {
	IBusGucharmapSearchPanel * self;
	self = IBUS_GUCHARMAP_SEARCH_PANEL (obj);
	_g_object_unref0 (self->priv->entry);
	_g_object_unref0 (self->priv->matches);
	G_OBJECT_CLASS (ibus_gucharmap_search_panel_parent_class)->finalize (obj);
}


GType ibus_gucharmap_search_panel_get_type (void) {
	static volatile gsize ibus_gucharmap_search_panel_type_id__volatile = 0;
	if (g_once_init_enter (&ibus_gucharmap_search_panel_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (IBusGucharmapSearchPanelClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ibus_gucharmap_search_panel_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (IBusGucharmapSearchPanel), 0, (GInstanceInitFunc) ibus_gucharmap_search_panel_instance_init, NULL };
		GType ibus_gucharmap_search_panel_type_id;
		ibus_gucharmap_search_panel_type_id = g_type_register_static (GTK_TYPE_BOX, "IBusGucharmapSearchPanel", &g_define_type_info, 0);
		g_once_init_leave (&ibus_gucharmap_search_panel_type_id__volatile, ibus_gucharmap_search_panel_type_id);
	}
	return ibus_gucharmap_search_panel_type_id__volatile;
}



