commit 8ca7e8bceae61cb29a5098170e6aaa1a6d5385c3 Author: Hodong Date: Sat Feb 5 01:18:29 2022 +0900 Search by entry text and preedit text Korean is different from Chinese and Japanese, so Korean users don't press a key such as Space to commit composing text explicitly. Current geany searches by entry text on the SearchEntry because the signal "changed" of the GtkEditable or gtk_entry_get_text() can't get preedit text. It is inconvenient for Korean users. So I suggest that geany should search by entry text and preedit text on the SearchEntry. diff --git a/src/Makefile.am b/src/Makefile.am index a4c78c5..0b51a16 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -74,7 +74,7 @@ libgeany_la_SOURCES = \ editor.c editor.h \ encodings.c encodings.h \ filetypes.c filetypes.h \ - geanyentryaction.c geanyentryaction.h \ + geanyentryaction.c geanyentryaction.h geanyentryactionprivate.h \ geanymenubuttonaction.c geanymenubuttonaction.h \ geanyobject.c geanyobject.h \ geanywraplabel.c geanywraplabel.h \ diff --git a/src/callbacks.c b/src/callbacks.c index 2e13d6d..57c2486 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -70,7 +70,7 @@ #include #include #include - +#include "geanyentryactionprivate.h" /* represents the state at switching a notebook page(in the left treeviews widget), to not emit * the selection-changed signal from tv.tree_openfiles */ @@ -417,7 +417,8 @@ void on_toolbar_search_entry_activate(GtkAction *action, const gchar *text, gpoi /* search text */ -void on_toolbutton_search_clicked(GtkAction *action, gpointer user_data) +void on_toolbutton_search_clicked(GtkAction *action, + GeanyEntryAction *entry_action) { GeanyDocument *doc = document_get_current(); gboolean result; @@ -426,9 +427,16 @@ void on_toolbutton_search_clicked(GtkAction *action, gpointer user_data) if (entry != NULL) { const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); + gchar *search_keyword; + + search_keyword = g_strconcat (gtk_entry_get_text(GTK_ENTRY(entry)), + entry_action->priv->preedit, NULL); + setup_find(search_keyword, FALSE); + + g_free(search_keyword); - setup_find(text, FALSE); result = document_search_bar_find(doc, search_data.text, FALSE, FALSE); + if (search_data.search_bar) ui_set_search_entry_background(entry, result); } diff --git a/src/callbacks.h b/src/callbacks.h index 4e9ac16..c68041c 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -22,6 +22,7 @@ #define GEANY_CALLBACKS_H 1 #include "gtkcompat.h" +#include "geanyentryaction.h" G_BEGIN_DECLS @@ -48,7 +49,7 @@ void on_close_all1_activate(GtkMenuItem *menuitem, gpointer user_data); void on_replace_tabs_activate(GtkMenuItem *menuitem, gpointer user_data); -void on_toolbutton_search_clicked(GtkAction *action, gpointer user_data); +void on_toolbutton_search_clicked(GtkAction *action, GeanyEntryAction *entry_action); gboolean toolbar_popup_menu(GtkWidget *widget, GdkEventButton *event, gpointer user_data); diff --git a/src/geanyentryaction.c b/src/geanyentryaction.c index e8f1a5e..1af6d4f 100644 --- a/src/geanyentryaction.c +++ b/src/geanyentryaction.c @@ -27,24 +27,11 @@ #endif #include "geanyentryaction.h" - +#include "geanyentryactionprivate.h" #include "ui_utils.h" #include - -typedef struct _GeanyEntryActionPrivate GeanyEntryActionPrivate; - -#define GEANY_ENTRY_ACTION_GET_PRIVATE(obj) (GEANY_ENTRY_ACTION(obj)->priv) - - -struct _GeanyEntryActionPrivate -{ - GtkWidget *entry; - gboolean numeric; - gboolean connected; -}; - enum { ENTRY_ACTIVATE, @@ -101,11 +88,26 @@ static void delegate_entry_activate_backward_cb(GtkEntry *entry, GeanyEntryActio static void delegate_entry_changed_cb(GtkEditable *editable, GeanyEntryAction *action) { GeanyEntryActionPrivate *priv = GEANY_ENTRY_ACTION_GET_PRIVATE(action); - const gchar *text = gtk_entry_get_text(GTK_ENTRY(priv->entry)); + gchar *new_search_keyword; + + new_search_keyword = g_strconcat(gtk_entry_get_text(GTK_ENTRY(priv->entry)), + priv->preedit, NULL); + g_signal_emit(action, signals[ENTRY_CHANGED], 0, new_search_keyword); - g_signal_emit(action, signals[ENTRY_CHANGED], 0, text); + g_free (new_search_keyword); } +static void +delegate_entry_preedit_changed_cb(GtkWidget *widget, + char *preedit, + GeanyEntryAction *action) +{ + GeanyEntryActionPrivate *priv = GEANY_ENTRY_ACTION_GET_PRIVATE(action); + + g_free(priv->preedit); + priv->preedit = g_strdup(preedit); + delegate_entry_changed_cb(GTK_EDITABLE (priv->entry), action); +} static void geany_entry_action_connect_proxy(GtkAction *action, GtkWidget *widget) { @@ -117,6 +119,7 @@ static void geany_entry_action_connect_proxy(GtkAction *action, GtkWidget *widge if (priv->numeric) g_signal_connect(priv->entry, "insert-text", G_CALLBACK(ui_editable_insert_text_callback), NULL); + g_signal_connect(priv->entry, "preedit-changed", G_CALLBACK(delegate_entry_preedit_changed_cb), action); g_signal_connect(priv->entry, "changed", G_CALLBACK(delegate_entry_changed_cb), action); g_signal_connect(priv->entry, "activate", G_CALLBACK(delegate_entry_activate_cb), action); g_signal_connect(priv->entry, "activate-backward", @@ -129,13 +132,23 @@ static void geany_entry_action_connect_proxy(GtkAction *action, GtkWidget *widge } +static void geany_entry_action_finalize (GObject *object) +{ + free (GEANY_ENTRY_ACTION (object)->priv->preedit); + + G_OBJECT_CLASS (geany_entry_action_parent_class)->finalize (object); +} + + static void geany_entry_action_class_init(GeanyEntryActionClass *klass) { GtkActionClass *action_class = GTK_ACTION_CLASS(klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); action_class->connect_proxy = geany_entry_action_connect_proxy; action_class->create_tool_item = geany_entry_action_create_tool_item; action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON; + object_class->finalize = geany_entry_action_finalize; g_type_class_add_private(klass, sizeof(GeanyEntryActionPrivate)); @@ -177,6 +190,7 @@ static void geany_entry_action_init(GeanyEntryAction *action) priv->entry = NULL; priv->numeric = FALSE; priv->connected = FALSE; + priv->preedit = g_strdup(""); } diff --git a/src/geanyentryaction.h b/src/geanyentryaction.h index 79ca2a7..3f5da3c 100644 --- a/src/geanyentryaction.h +++ b/src/geanyentryaction.h @@ -39,12 +39,12 @@ G_BEGIN_DECLS typedef struct _GeanyEntryAction GeanyEntryAction; typedef struct _GeanyEntryActionClass GeanyEntryActionClass; -struct _GeanyEntryActionPrivate; +typedef struct _GeanyEntryActionPrivate GeanyEntryActionPrivate; struct _GeanyEntryAction { GtkAction parent; - struct _GeanyEntryActionPrivate *priv; + GeanyEntryActionPrivate *priv; }; struct _GeanyEntryActionClass diff --git a/src/geanyentryactionprivate.h b/src/geanyentryactionprivate.h new file mode 100644 index 0000000..11578de --- /dev/null +++ b/src/geanyentryactionprivate.h @@ -0,0 +1,39 @@ +/* + * geanyentryactionprivate.h - this file is part of Geany, a fast and lightweight IDE + * + * Copyright 2008 The Geany contributors + * + * 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. + */ + + +#ifndef GEANY_ENTRY_ACTION_PRIVATE_H +#define GEANY_ENTRY_ACTION_PRIVATE_H 1 + +G_BEGIN_DECLS + +#define GEANY_ENTRY_ACTION_GET_PRIVATE(obj) (GEANY_ENTRY_ACTION(obj)->priv) + +struct _GeanyEntryActionPrivate +{ + GtkWidget *entry; + gboolean numeric; + gboolean connected; + gchar *preedit; +}; + +G_END_DECLS + +#endif /* GEANY_ENTRY_ACTION_PRIVATE_H */ diff --git a/src/toolbar.c b/src/toolbar.c index 7de7c52..4a04c31 100644 --- a/src/toolbar.c +++ b/src/toolbar.c @@ -53,7 +53,7 @@ static GSList *plugin_items = NULL; /* Available toolbar actions * Fields: name, stock_id, label, accelerator, tooltip, callback */ static const GtkActionEntry ui_entries[] = { - /* custom actions defined in toolbar_init(): "New", "Open", "SearchEntry", "GotoEntry", "Build" */ + /* custom actions defined in toolbar_init(): "New", "Open", "SearchEntry", "Search", "GotoEntry", "Build" */ { "Save", GTK_STOCK_SAVE, NULL, NULL, N_("Save the current file"), G_CALLBACK(on_save1_activate) }, { "SaveAs", GTK_STOCK_SAVE_AS, NULL, NULL, N_("Save as"), G_CALLBACK(on_save_as1_activate) }, { "SaveAll", GEANY_STOCK_SAVE_ALL, NULL, NULL, N_("Save all open files"), G_CALLBACK(on_save_all1_activate) }, @@ -75,7 +75,6 @@ static const GtkActionEntry ui_entries[] = { { "ZoomOut", GTK_STOCK_ZOOM_OUT, NULL, NULL, N_("Zoom out the text"), G_CALLBACK(on_zoom_out1_activate) }, { "UnIndent", GTK_STOCK_UNINDENT, NULL, NULL, N_("Decrease indentation"), G_CALLBACK(on_menu_decrease_indent1_activate) }, { "Indent", GTK_STOCK_INDENT, NULL, NULL, N_("Increase indentation"), G_CALLBACK(on_menu_increase_indent1_activate) }, - { "Search", GTK_STOCK_FIND, NULL, NULL, N_("Find the entered text in the current file"), G_CALLBACK(on_toolbutton_search_clicked) }, { "Goto", GTK_STOCK_JUMP_TO, NULL, NULL, N_("Jump to the entered line number"), G_CALLBACK(on_toolbutton_goto_clicked) }, { "Preferences", GTK_STOCK_PREFERENCES, NULL, NULL, N_("Show the preferences dialog"), G_CALLBACK(on_preferences1_activate) }, { "Quit", GTK_STOCK_QUIT, NULL, NULL, N_("Quit Geany"), G_CALLBACK(on_quit1_activate) }, @@ -344,6 +343,7 @@ GtkWidget *toolbar_init(void) GtkAction *action_open; GtkAction *action_build; GtkAction *action_searchentry; + GtkAction *action_search; GtkAction *action_gotoentry; GtkSettings *gtk_settings; @@ -389,6 +389,11 @@ GtkWidget *toolbar_init(void) G_CALLBACK(on_toolbar_search_entry_changed), NULL); gtk_action_group_add_action(group, action_searchentry); + action_search = gtk_action_new("Search", "Search", _("Find the entered text in the current file"), GTK_STOCK_FIND); + g_signal_connect(action_search, "activate", + G_CALLBACK(on_toolbutton_search_clicked), action_searchentry); + gtk_action_group_add_action(group, action_search); + action_gotoentry = geany_entry_action_new( "GotoEntry", _("Goto Field"), _("Jump to the entered line number"), TRUE); g_signal_connect(action_gotoentry, "entry-activate",