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_entry_new_text();
50 combo = gtk_combo_box_new_text();
51 gtk_widget_show(combo);
53 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), text);
55 while ((string = va_arg(args, gchar*)) != NULL)
56 gtk_combo_box_append_text(GTK_COMBO_BOX(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_remove_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_append_text(combobox, (const gchar*) cur->data);
177 gboolean combobox_set_value_from_arrow_key(GtkComboBox *combobox,
179 /* used from key_press events upon gtk_combo_box_entry with one text column
180 (gtk_combo_box_new_text() and with GtkComboBoxEntry's for instance),
181 make sure that up and down arrow keys behave the same as old with old
184 if the current text in entry widget is not found in combo list,
185 get last value from combo list
186 if the current text in entry widget exists in combo list,
187 get prev value from combo list
189 if the current text in entry widget is not found in combo list,
190 get first value from combo list
191 if the current text in entry widget exists in combo list,
192 get next value from combo list
195 gboolean valid = FALSE;
197 cm_return_val_if_fail(combobox != NULL, FALSE);
199 /* reproduce the behaviour of old gtk_combo_box */
200 GtkTreeModel *model = gtk_combo_box_get_model(combobox);
203 if (gtk_combo_box_get_active_iter(combobox, &iter)) {
204 /* if current text is in list, get prev or next one */
206 if (keyval == GDK_KEY_Up) {
207 gchar *text = gtk_combo_box_get_active_text(combobox);
209 text = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combobox))),0,-1);
210 valid = gtkut_tree_model_text_iter_prev(model, &iter, text);
213 if (keyval == GDK_KEY_Down)
214 valid = gtk_tree_model_iter_next(model, &iter);
217 gtk_combo_box_set_active_iter(combobox, &iter);
220 /* current text is not in list, get first or next one */
222 if (keyval == GDK_KEY_Up)
223 valid = gtkut_tree_model_get_iter_last(model, &iter);
225 if (keyval == GDK_KEY_Down)
226 valid = gtk_tree_model_get_iter_first(model, &iter);
229 gtk_combo_box_set_active_iter(combobox, &iter);
232 /* return TRUE if value could be set */
236 static void store_set_sensitive(GtkTreeModel *model, GtkTreeIter *iter,
237 const gboolean sensitive)
239 if(GTK_IS_LIST_STORE(model)) {
240 gtk_list_store_set(GTK_LIST_STORE(model), iter,
241 COMBOBOX_SENS, sensitive,
244 gtk_tree_store_set(GTK_TREE_STORE(model), iter,
245 COMBOBOX_SENS, sensitive,
250 void combobox_set_sensitive(GtkComboBox *combobox, const guint index,
251 const gboolean sensitive)
254 GtkTreeIter iter, child;
257 if((model = gtk_combo_box_get_model(combobox)) == NULL)
260 gtk_tree_model_get_iter_first(model, &iter);
261 for(i=0; i<index; i++) {
262 if(gtk_tree_model_iter_next(model, &iter) == FALSE)
266 store_set_sensitive(model, &iter, sensitive);
268 if(gtk_tree_model_iter_children(model, &child, &iter) == FALSE)
272 store_set_sensitive(model, &child, sensitive);
273 } while (gtk_tree_model_iter_next(model, &child) == TRUE);