2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2006-2012 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/>.
22 #include "claws-features.h"
26 #include <glib/gi18n.h>
27 #include <gdk/gdkkeysyms.h>
33 typedef struct _combobox_sel_by_data_ctx {
34 GtkComboBox *combobox;
39 GtkWidget *combobox_text_new(const gboolean with_entry, const gchar *text, ...)
48 #if !GTK_CHECK_VERSION(2, 24, 0)
50 combo = gtk_combo_box_entry_new_text();
52 combo = gtk_combo_box_new_text();
55 combo = gtk_combo_box_text_new_with_entry();
57 combo = gtk_combo_box_text_new();
59 gtk_widget_show(combo);
61 #if !GTK_CHECK_VERSION(2, 24, 0)
62 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), text);
64 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), text);
67 while ((string = va_arg(args, gchar*)) != NULL)
68 #if !GTK_CHECK_VERSION(2, 24, 0)
69 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), string);
71 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), string);
75 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
80 static gboolean _select_by_data_func(GtkTreeModel *model, GtkTreePath *path,
81 GtkTreeIter *iter, ComboboxSelCtx *ctx)
83 GtkComboBox *combobox = ctx->combobox;
84 gint data = ctx->data;
87 gtk_tree_model_get(GTK_TREE_MODEL(model), iter, COMBOBOX_DATA, &curdata, -1);
88 if (data == curdata) {
89 gtk_combo_box_set_active_iter(combobox, iter);
96 void combobox_select_by_data(GtkComboBox *combobox, gint data)
99 ComboboxSelCtx *ctx = NULL;
101 cm_return_if_fail(combobox != NULL);
102 cm_return_if_fail(GTK_IS_COMBO_BOX (combobox));
104 model = gtk_combo_box_get_model(combobox);
106 ctx = g_new(ComboboxSelCtx,
107 sizeof(ComboboxSelCtx));
108 ctx->combobox = combobox;
111 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_data_func, ctx);
115 static gboolean _select_by_text_func(GtkTreeModel *model, GtkTreePath *path,
116 GtkTreeIter *iter, ComboboxSelCtx *ctx)
118 GtkComboBox *combobox = ctx->combobox;
119 const gchar *data = ctx->cdata;
122 cm_return_val_if_fail(combobox != NULL, FALSE);
123 cm_return_val_if_fail(GTK_IS_COMBO_BOX (combobox), FALSE);
125 gtk_tree_model_get (GTK_TREE_MODEL(model), iter, 0, &curdata, -1);
126 if (!g_utf8_collate(data, curdata)) {
127 gtk_combo_box_set_active_iter(combobox, iter);
137 void combobox_select_by_text(GtkComboBox *combobox, const gchar *data)
140 ComboboxSelCtx *ctx = NULL;
141 #if !GTK_CHECK_VERSION(2, 24, 0)
142 GtkComboBoxClass *class;
145 cm_return_if_fail(combobox != NULL);
146 #if !GTK_CHECK_VERSION(2, 24, 0)
147 class = GTK_COMBO_BOX_GET_CLASS (combobox);
149 /* we can do that only with gtk_combo_box_new_text() combo boxes */
150 cm_return_if_fail(class->get_active_text != NULL);
152 cm_return_if_fail(GTK_IS_COMBO_BOX (combobox));
155 model = gtk_combo_box_get_model(combobox);
157 ctx = g_new(ComboboxSelCtx,
158 sizeof(ComboboxSelCtx));
159 ctx->combobox = combobox;
162 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_text_func, ctx);
166 gint combobox_get_active_data(GtkComboBox *combobox)
172 cm_return_val_if_fail(combobox != NULL, -1);
173 cm_return_val_if_fail(GTK_IS_COMBO_BOX (combobox), -1);
174 cm_return_val_if_fail(gtk_combo_box_get_active_iter(combobox, &iter), -1);
176 model = gtk_combo_box_get_model(combobox);
178 gtk_tree_model_get(model, &iter, COMBOBOX_DATA, &data, -1);
183 #if !GTK_CHECK_VERSION(2, 24, 0)
184 void combobox_unset_popdown_strings(GtkComboBox *combobox)
186 void combobox_unset_popdown_strings(GtkComboBoxText *combobox)
192 cm_return_if_fail(combobox != NULL);
193 #if GTK_CHECK_VERSION(2, 24, 0)
194 cm_return_if_fail(GTK_IS_COMBO_BOX_TEXT (combobox));
197 model = gtk_combo_box_get_model(GTK_COMBO_BOX(combobox));
198 count = gtk_tree_model_iter_n_children(model, NULL);
199 for (i = 0; i < count; i++)
200 #if !GTK_CHECK_VERSION(2, 24, 0)
201 gtk_combo_box_remove_text(combobox, 0);
203 gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(combobox), 0);
207 #if !GTK_CHECK_VERSION(2, 24, 0)
208 void combobox_set_popdown_strings(GtkComboBox *combobox,
210 void combobox_set_popdown_strings(GtkComboBoxText *combobox,
216 cm_return_if_fail(combobox != NULL);
217 #if GTK_CHECK_VERSION(2, 24, 0)
218 cm_return_if_fail(GTK_IS_COMBO_BOX_TEXT (combobox));
221 for (cur = list; cur != NULL; cur = g_list_next(cur))
222 #if !GTK_CHECK_VERSION(2, 24, 0)
223 gtk_combo_box_append_text(combobox, (const gchar*) cur->data);
225 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox),
226 (const gchar*) cur->data);
230 gboolean combobox_set_value_from_arrow_key(GtkComboBox *combobox,
232 /* used from key_press events upon gtk_combo_box_entry with one text column
233 (gtk_combo_box_new_text() and with GtkComboBoxEntry's for instance),
234 make sure that up and down arrow keys behave the same as old with old
237 if the current text in entry widget is not found in combo list,
238 get last value from combo list
239 if the current text in entry widget exists in combo list,
240 get prev value from combo list
242 if the current text in entry widget is not found in combo list,
243 get first value from combo list
244 if the current text in entry widget exists in combo list,
245 get next value from combo list
248 gboolean valid = FALSE;
250 cm_return_val_if_fail(combobox != NULL, FALSE);
252 /* reproduce the behaviour of old gtk_combo_box */
253 GtkTreeModel *model = gtk_combo_box_get_model(combobox);
256 if (gtk_combo_box_get_active_iter(combobox, &iter)) {
257 /* if current text is in list, get prev or next one */
259 if (keyval == GDK_KEY_Up) {
260 #if !GTK_CHECK_VERSION(2, 24, 0)
261 gchar *text = gtk_combo_box_get_active_text(combobox);
263 text = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combobox))),0,-1);
266 gtk_tree_model_get(model, &iter, 0, &text, -1);
268 valid = gtkut_tree_model_text_iter_prev(model, &iter, text);
271 if (keyval == GDK_KEY_Down)
272 valid = gtk_tree_model_iter_next(model, &iter);
275 gtk_combo_box_set_active_iter(combobox, &iter);
278 /* current text is not in list, get first or next one */
280 if (keyval == GDK_KEY_Up)
281 valid = gtkut_tree_model_get_iter_last(model, &iter);
283 if (keyval == GDK_KEY_Down)
284 valid = gtk_tree_model_get_iter_first(model, &iter);
287 gtk_combo_box_set_active_iter(combobox, &iter);
290 /* return TRUE if value could be set */
294 static void store_set_sensitive(GtkTreeModel *model, GtkTreeIter *iter,
295 const gboolean sensitive)
297 if(GTK_IS_LIST_STORE(model)) {
298 gtk_list_store_set(GTK_LIST_STORE(model), iter,
299 COMBOBOX_SENS, sensitive,
302 gtk_tree_store_set(GTK_TREE_STORE(model), iter,
303 COMBOBOX_SENS, sensitive,
308 void combobox_set_sensitive(GtkComboBox *combobox, const guint index,
309 const gboolean sensitive)
312 GtkTreeIter iter, child;
315 if((model = gtk_combo_box_get_model(combobox)) == NULL)
318 gtk_tree_model_get_iter_first(model, &iter);
319 for(i=0; i<index; i++) {
320 if(gtk_tree_model_iter_next(model, &iter) == FALSE)
324 store_set_sensitive(model, &iter, sensitive);
326 if(gtk_tree_model_iter_children(model, &child, &iter) == FALSE)
330 store_set_sensitive(model, &child, sensitive);
331 } while (gtk_tree_model_iter_next(model, &child) == TRUE);