2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2006-2009 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>
31 typedef struct _combobox_sel_by_data_ctx {
32 GtkComboBox *combobox;
37 GtkWidget *combobox_text_new(const gboolean with_entry, const gchar *text, ...)
47 combo = gtk_combo_box_entry_new_text();
49 combo = gtk_combo_box_new_text();
50 gtk_widget_show(combo);
52 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), text);
54 while ((string = va_arg(args, gchar*)) != NULL)
55 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), string);
58 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
63 static gboolean _select_by_data_func(GtkTreeModel *model, GtkTreePath *path,
64 GtkTreeIter *iter, ComboboxSelCtx *ctx)
66 GtkComboBox *combobox = ctx->combobox;
67 gint data = ctx->data;
70 gtk_tree_model_get(GTK_TREE_MODEL(model), iter, COMBOBOX_DATA, &curdata, -1);
71 if (data == curdata) {
72 gtk_combo_box_set_active_iter(combobox, iter);
79 void combobox_select_by_data(GtkComboBox *combobox, gint data)
82 ComboboxSelCtx *ctx = NULL;
83 g_return_if_fail(combobox != NULL);
85 model = gtk_combo_box_get_model(combobox);
87 ctx = g_new(ComboboxSelCtx,
88 sizeof(ComboboxSelCtx));
89 ctx->combobox = combobox;
92 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_data_func, ctx);
96 static gboolean _select_by_text_func(GtkTreeModel *model, GtkTreePath *path,
97 GtkTreeIter *iter, ComboboxSelCtx *ctx)
99 GtkComboBox *combobox = ctx->combobox;
100 const gchar *data = ctx->cdata;
101 const gchar *curdata;
103 gtk_tree_model_get (GTK_TREE_MODEL(model), iter, 0, &curdata, -1);
104 if (!g_utf8_collate(data, curdata)) {
105 gtk_combo_box_set_active_iter(combobox, iter);
112 void combobox_select_by_text(GtkComboBox *combobox, const gchar *data)
115 ComboboxSelCtx *ctx = NULL;
116 GtkComboBoxClass *class;
118 g_return_if_fail(combobox != NULL);
119 class = GTK_COMBO_BOX_GET_CLASS (combobox);
121 /* we can do that only with gtk_combo_box_new_text() combo boxes */
122 g_return_if_fail(class->get_active_text != NULL);
124 model = gtk_combo_box_get_model(combobox);
126 ctx = g_new(ComboboxSelCtx,
127 sizeof(ComboboxSelCtx));
128 ctx->combobox = combobox;
131 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_text_func, ctx);
135 gint combobox_get_active_data(GtkComboBox *combobox)
141 g_return_val_if_fail(combobox != NULL, -1);
143 g_return_val_if_fail(gtk_combo_box_get_active_iter(combobox, &iter), -1);
145 model = gtk_combo_box_get_model(combobox);
147 gtk_tree_model_get(model, &iter, COMBOBOX_DATA, &data, -1);
152 void combobox_unset_popdown_strings(GtkComboBox *combobox)
157 g_return_if_fail(combobox != NULL);
159 model = gtk_combo_box_get_model(combobox);
160 count = gtk_tree_model_iter_n_children(model, NULL);
161 for (i = 0; i < count; i++)
162 gtk_combo_box_remove_text(combobox, 0);
165 void combobox_set_popdown_strings(GtkComboBox *combobox,
170 g_return_if_fail(combobox != NULL);
172 for (cur = list; cur != NULL; cur = g_list_next(cur))
173 gtk_combo_box_append_text(combobox, (const gchar*) cur->data);
176 gboolean combobox_set_value_from_arrow_key(GtkComboBox *combobox,
178 /* used from key_press events upon gtk_combo_box_entry with one text column
179 (gtk_combo_box_new_text() and with GtkComboBoxEntry's for instance),
180 make sure that up and down arrow keys behave the same as old with old
183 if the current text in entry widget is not found in combo list,
184 get last value from combo list
185 if the current text in entry widget exists in combo list,
186 get prev value from combo list
188 if the current text in entry widget is not found in combo list,
189 get first value from combo list
190 if the current text in entry widget exists in combo list,
191 get next value from combo list
194 gboolean valid = FALSE;
196 g_return_val_if_fail(combobox != NULL, FALSE);
198 /* reproduce the behaviour of old gtk_combo_box */
199 GtkTreeModel *model = gtk_combo_box_get_model(combobox);
202 if (gtk_combo_box_get_active_iter(combobox, &iter)) {
203 /* if current text is in list, get prev or next one */
205 if (keyval == GDK_Up) {
206 gchar *text = gtk_combo_box_get_active_text(combobox);
208 text = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combobox))),0,-1);
209 valid = gtkut_tree_model_text_iter_prev(model, &iter, text);
212 if (keyval == GDK_Down)
213 valid = gtk_tree_model_iter_next(model, &iter);
216 gtk_combo_box_set_active_iter(combobox, &iter);
219 /* current text is not in list, get first or next one */
221 if (keyval == GDK_Up)
222 valid = gtkut_tree_model_get_iter_last(model, &iter);
224 if (keyval == GDK_Down)
225 valid = gtk_tree_model_get_iter_first(model, &iter);
228 gtk_combo_box_set_active_iter(combobox, &iter);
231 /* return TRUE if value could be set */
235 static void store_set_sensitive(GtkTreeModel *model, GtkTreeIter *iter,
236 const gboolean sensitive)
238 if(GTK_IS_LIST_STORE(model)) {
239 gtk_list_store_set(GTK_LIST_STORE(model), iter,
240 COMBOBOX_SENS, sensitive,
243 gtk_tree_store_set(GTK_TREE_STORE(model), iter,
244 COMBOBOX_SENS, sensitive,
249 void combobox_set_sensitive(GtkComboBox *combobox, const guint index,
250 const gboolean sensitive)
253 GtkTreeIter iter, child;
256 if((model = gtk_combo_box_get_model(combobox)) == NULL)
259 gtk_tree_model_get_iter_first(model, &iter);
260 for(i=0; i<index; i++) {
261 if(gtk_tree_model_iter_next(model, &iter) == FALSE)
265 store_set_sensitive(model, &iter, sensitive);
267 if(gtk_tree_model_iter_children(model, &child, &iter) == FALSE)
271 store_set_sensitive(model, &child, sensitive);
272 } while (gtk_tree_model_iter_next(model, &child) == TRUE);