|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * gnc-gtk-utils.c -- utility functions based on glib functions * 00003 * Copyright (C) 2006 David Hampton <hampton@employees.org> * 00004 * * 00005 * This program is free software; you can redistribute it and/or * 00006 * modify it under the terms of the GNU General Public License as * 00007 * published by the Free Software Foundation; either version 2 of * 00008 * the License, or (at your option) any later version. * 00009 * * 00010 * This program is distributed in the hope that it will be useful, * 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00013 * GNU General Public License for more details. * 00014 * * 00015 * You should have received a copy of the GNU General Public License* 00016 * along with this program; if not, contact: * 00017 * * 00018 * Free Software Foundation Voice: +1-617-542-5942 * 00019 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00020 * Boston, MA 02110-1301, USA gnu@gnu.org * 00021 * * 00022 \********************************************************************/ 00023 00024 #include "config.h" 00025 00026 #include "gnc-gtk-utils.h" 00027 00028 #define LAST_INDEX "last_index" 00029 #define CHANGED_ID "changed_id" 00030 00031 00040 void 00041 gnc_cbe_set_by_string(GtkComboBoxEntry *cbe, 00042 const gchar *text) 00043 { 00044 GtkTreeModel *model; 00045 GtkTreeIter iter; 00046 gchar *tree_string; 00047 gint column, index, id; 00048 gboolean match; 00049 00050 model = gtk_combo_box_get_model(GTK_COMBO_BOX(cbe)); 00051 if (!gtk_tree_model_get_iter_first(model, &iter)) 00052 { 00053 /* empty tree */ 00054 gtk_combo_box_set_active(GTK_COMBO_BOX(cbe), -1); 00055 return; 00056 } 00057 00058 column = gtk_combo_box_entry_get_text_column(cbe); 00059 do 00060 { 00061 gtk_tree_model_get(model, &iter, column, &tree_string, -1); 00062 match = g_utf8_collate(text, tree_string) == 0; 00063 g_free(tree_string); 00064 if (!match) 00065 continue; 00066 00067 /* Found a matching string */ 00068 id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cbe), CHANGED_ID)); 00069 g_signal_handler_block(cbe, id); 00070 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cbe), &iter); 00071 g_signal_handler_unblock(cbe, id); 00072 00073 index = gtk_combo_box_get_active(GTK_COMBO_BOX(cbe)); 00074 g_object_set_data(G_OBJECT(cbe), LAST_INDEX, GINT_TO_POINTER(index)); 00075 return; 00076 } 00077 while (gtk_tree_model_iter_next(model, &iter)); 00078 } 00079 00080 00088 static void 00089 gnc_cbe_changed_cb (GtkComboBox *widget, 00090 GtkComboBoxEntry *cbe) 00091 { 00092 gint index; 00093 00094 index = gtk_combo_box_get_active(widget); 00095 if (index == -1) 00096 return; 00097 g_object_set_data(G_OBJECT(cbe), LAST_INDEX, GINT_TO_POINTER(index)); 00098 } 00099 00100 00117 static gboolean 00118 gnc_cbe_match_selected_cb (GtkEntryCompletion *completion, 00119 GtkTreeModel *comp_model, 00120 GtkTreeIter *comp_iter, 00121 GtkComboBoxEntry *cbe) 00122 { 00123 gint column; 00124 gchar *text; 00125 00126 column = gtk_combo_box_entry_get_text_column(cbe); 00127 gtk_tree_model_get(comp_model, comp_iter, column, &text, -1); 00128 gnc_cbe_set_by_string(cbe, text); 00129 g_free(text); 00130 return FALSE; 00131 } 00132 00133 00146 static gboolean 00147 gnc_cbe_focus_out_cb (GtkEntry *entry, 00148 GdkEventFocus *event, 00149 GtkComboBoxEntry *cbe) 00150 { 00151 const gchar *text; 00152 gint index; 00153 00154 /* Make a final attempt to match the current text. */ 00155 text = gtk_entry_get_text(entry); 00156 gnc_cbe_set_by_string(cbe, text); 00157 00158 /* Get the last known index (which may have just been set). */ 00159 index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cbe), LAST_INDEX)); 00160 gtk_combo_box_set_active(GTK_COMBO_BOX(cbe), index); 00161 return FALSE; 00162 } 00163 00164 void 00165 gnc_cbe_add_completion (GtkComboBoxEntry *cbe) 00166 { 00167 GtkEntry *entry; 00168 GtkEntryCompletion *completion; 00169 GtkTreeModel *model; 00170 00171 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(cbe))); 00172 completion = gtk_entry_get_completion(entry); 00173 if (completion) 00174 return; 00175 00176 /* No completion yet? Set one up. */ 00177 completion = gtk_entry_completion_new(); 00178 model = gtk_combo_box_get_model(GTK_COMBO_BOX(cbe)); 00179 gtk_entry_completion_set_model(completion, model); 00180 gtk_entry_completion_set_text_column(completion, 0); 00181 gtk_entry_completion_set_inline_completion(completion, TRUE); 00182 gtk_entry_set_completion(entry, completion); 00183 g_object_unref(completion); 00184 } 00185 00186 void 00187 gnc_cbe_require_list_item (GtkComboBoxEntry *cbe) 00188 { 00189 GtkEntry *entry; 00190 GtkEntryCompletion *completion; 00191 GtkTreeModel *model; 00192 GtkTreeIter iter; 00193 gint index, id; 00194 00195 /* Ensure completion is set up. */ 00196 gnc_cbe_add_completion(cbe); 00197 00198 /* If an item in the combo box isn't already selected, then force 00199 * select the first item. Take care, the combo box may not have been 00200 * filled yet. */ 00201 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(cbe))); 00202 completion = gtk_entry_get_completion(entry); 00203 index = gtk_combo_box_get_active(GTK_COMBO_BOX(cbe)); 00204 if (index == -1) 00205 { 00206 model = gtk_entry_completion_get_model(completion); 00207 if (gtk_tree_model_get_iter_first(model, &iter)) 00208 { 00209 gtk_combo_box_set_active(GTK_COMBO_BOX(cbe), 0); 00210 index = 0; 00211 } 00212 } 00213 g_object_set_data(G_OBJECT(cbe), LAST_INDEX, GINT_TO_POINTER(index)); 00214 00215 /* Now the signals to make sure the user can't leave the 00216 widget without a valid match. */ 00217 id = g_signal_connect(cbe, "changed", 00218 G_CALLBACK(gnc_cbe_changed_cb), cbe); 00219 g_signal_connect(completion, "match_selected", 00220 G_CALLBACK(gnc_cbe_match_selected_cb), cbe); 00221 g_signal_connect(entry, "focus-out-event", 00222 G_CALLBACK(gnc_cbe_focus_out_cb), cbe); 00223 00224 g_object_set_data(G_OBJECT(cbe), CHANGED_ID, GINT_TO_POINTER(id)); 00225 }
1.7.4