2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2006-2011 Andrej Kacian and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include <glib/gi18n.h>
26 #include <gdk/gdkkeysyms.h>
32 typedef struct _combobox_sel_by_data_ctx {
33 GtkComboBox *combobox;
38 GtkWidget *combobox_text_new(const gboolean with_entry, const gchar *text, ...)
48 combo = gtk_combo_box_new_with_entry();
50 combo = gtk_combo_box_text_new();
51 gtk_widget_show(combo);
53 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), text);
55 while ((string = va_arg(args, gchar*)) != NULL)
56 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), string);
59 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
64 static gboolean _select_by_data_func(GtkTreeModel *model, GtkTreePath *path,
65 GtkTreeIter *iter, ComboboxSelCtx *ctx)
67 GtkComboBox *combobox = ctx->combobox;
68 gint data = ctx->data;
71 gtk_tree_model_get(GTK_TREE_MODEL(model), iter, COMBOBOX_DATA, &curdata, -1);
72 if (data == curdata) {
73 gtk_combo_box_set_active_iter(combobox, iter);
80 void combobox_select_by_data(GtkComboBox *combobox, gint data)
83 ComboboxSelCtx *ctx = NULL;
84 cm_return_if_fail(combobox != NULL);
86 model = gtk_combo_box_get_model(combobox);
88 ctx = g_new(ComboboxSelCtx,
89 sizeof(ComboboxSelCtx));
90 ctx->combobox = combobox;
93 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_data_func, ctx);
97 static gboolean _select_by_text_func(GtkTreeModel *model, GtkTreePath *path,
98 GtkTreeIter *iter, ComboboxSelCtx *ctx)
100 GtkComboBox *combobox = ctx->combobox;
101 const gchar *data = ctx->cdata;
102 const gchar *curdata;
104 gtk_tree_model_get (GTK_TREE_MODEL(model), iter, 0, &curdata, -1);
105 if (!g_utf8_collate(data, curdata)) {
106 gtk_combo_box_set_active_iter(combobox, iter);
113 void combobox_select_by_text(GtkComboBox *combobox, const gchar *data)
116 ComboboxSelCtx *ctx = NULL;
117 GtkComboBoxClass *class;
119 cm_return_if_fail(combobox != NULL);
120 class = GTK_COMBO_BOX_GET_CLASS (combobox);
122 /* we can do that only with gtk_combo_box_new_text() combo boxes */
123 cm_return_if_fail(class->get_active_text != NULL);
125 model = gtk_combo_box_get_model(combobox);
127 ctx = g_new(ComboboxSelCtx,
128 sizeof(ComboboxSelCtx));
129 ctx->combobox = combobox;
132 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_text_func, ctx);
136 gint combobox_get_active_data(GtkComboBox *combobox)
142 cm_return_val_if_fail(combobox != NULL, -1);
144 cm_return_val_if_fail(gtk_combo_box_get_active_iter(combobox, &iter), -1);
146 model = gtk_combo_box_get_model(combobox);
148 gtk_tree_model_get(model, &iter, COMBOBOX_DATA, &data, -1);
153 void combobox_unset_popdown_strings(GtkComboBox *combobox)
158 cm_return_if_fail(combobox != NULL);
160 model = gtk_combo_box_get_model(combobox);
161 count = gtk_tree_model_iter_n_children(model, NULL);
162 for (i = 0; i < count; i++)
163 gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(combobox), 0);
166 void combobox_set_popdown_strings(GtkComboBox *combobox,
171 cm_return_if_fail(combobox != NULL);
173 for (cur = list; cur != NULL; cur = g_list_next(cur))
174 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox),
175 (const gchar*) cur->data);
178 gboolean combobox_set_value_from_arrow_key(GtkComboBox *combobox,
180 /* used from key_press events upon gtk_combo_box_entry with one text column
181 (gtk_combo_box_new_text() and with GtkComboBoxEntry's for instance),
182 make sure that up and down arrow keys behave the same as old with old
185 if the current text in entry widget is not found in combo list,
186 get last value from combo list
187 if the current text in entry widget exists in combo list,
188 get prev value from combo list
190 if the current text in entry widget is not found in combo list,
191 get first value from combo list
192 if the current text in entry widget exists in combo list,
193 get next value from combo list
196 gboolean valid = FALSE;
198 cm_return_val_if_fail(combobox != NULL, FALSE);
200 /* reproduce the behaviour of old gtk_combo_box */
201 GtkTreeModel *model = gtk_combo_box_get_model(combobox);
204 if (gtk_combo_box_get_active_iter(combobox, &iter)) {
205 /* if current text is in list, get prev or next one */
207 if (keyval == GDK_Up) {
208 gchar *text = gtk_combo_box_text_get_active_text(
209 GTK_COMBO_BOX_TEXT(combobox));
211 text = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combobox))),0,-1);
212 valid = gtkut_tree_model_text_iter_prev(model, &iter, text);
215 if (keyval == GDK_Down)
216 valid = gtk_tree_model_iter_next(model, &iter);
219 gtk_combo_box_set_active_iter(combobox, &iter);
222 /* current text is not in list, get first or next one */
224 if (keyval == GDK_Up)
225 valid = gtkut_tree_model_get_iter_last(model, &iter);
227 if (keyval == GDK_Down)
228 valid = gtk_tree_model_get_iter_first(model, &iter);
231 gtk_combo_box_set_active_iter(combobox, &iter);
234 /* return TRUE if value could be set */
238 static void store_set_sensitive(GtkTreeModel *model, GtkTreeIter *iter,
239 const gboolean sensitive)
241 if(GTK_IS_LIST_STORE(model)) {
242 gtk_list_store_set(GTK_LIST_STORE(model), iter,
243 COMBOBOX_SENS, sensitive,
246 gtk_tree_store_set(GTK_TREE_STORE(model), iter,
247 COMBOBOX_SENS, sensitive,
252 void combobox_set_sensitive(GtkComboBox *combobox, const guint index,
253 const gboolean sensitive)
256 GtkTreeIter iter, child;
259 if((model = gtk_combo_box_get_model(combobox)) == NULL)
262 gtk_tree_model_get_iter_first(model, &iter);
263 for(i=0; i<index; i++) {
264 if(gtk_tree_model_iter_next(model, &iter) == FALSE)
268 store_set_sensitive(model, &iter, sensitive);
270 if(gtk_tree_model_iter_children(model, &child, &iter) == FALSE)
274 store_set_sensitive(model, &child, sensitive);
275 } while (gtk_tree_model_iter_next(model, &child) == TRUE);