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;
120 const gchar *curdata;
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);
134 void combobox_select_by_text(GtkComboBox *combobox, const gchar *data)
137 ComboboxSelCtx *ctx = NULL;
138 #if !GTK_CHECK_VERSION(2, 24, 0)
139 GtkComboBoxClass *class;
142 cm_return_if_fail(combobox != NULL);
143 #if !GTK_CHECK_VERSION(2, 24, 0)
144 class = GTK_COMBO_BOX_GET_CLASS (combobox);
146 /* we can do that only with gtk_combo_box_new_text() combo boxes */
147 cm_return_if_fail(class->get_active_text != NULL);
149 cm_return_if_fail(GTK_IS_COMBO_BOX (combobox));
152 model = gtk_combo_box_get_model(combobox);
154 ctx = g_new(ComboboxSelCtx,
155 sizeof(ComboboxSelCtx));
156 ctx->combobox = combobox;
159 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_text_func, ctx);
163 gint combobox_get_active_data(GtkComboBox *combobox)
169 cm_return_val_if_fail(combobox != NULL, -1);
170 cm_return_val_if_fail(GTK_IS_COMBO_BOX (combobox), -1);
171 cm_return_val_if_fail(gtk_combo_box_get_active_iter(combobox, &iter), -1);
173 model = gtk_combo_box_get_model(combobox);
175 gtk_tree_model_get(model, &iter, COMBOBOX_DATA, &data, -1);
180 #if !GTK_CHECK_VERSION(2, 24, 0)
181 void combobox_unset_popdown_strings(GtkComboBox *combobox)
183 void combobox_unset_popdown_strings(GtkComboBoxText *combobox)
189 cm_return_if_fail(combobox != NULL);
190 #if GTK_CHECK_VERSION(2, 24, 0)
191 cm_return_if_fail(GTK_IS_COMBO_BOX_TEXT (combobox));
194 model = gtk_combo_box_get_model(GTK_COMBO_BOX(combobox));
195 count = gtk_tree_model_iter_n_children(model, NULL);
196 for (i = 0; i < count; i++)
197 #if !GTK_CHECK_VERSION(2, 24, 0)
198 gtk_combo_box_remove_text(combobox, 0);
200 gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(combobox), 0);
204 #if !GTK_CHECK_VERSION(2, 24, 0)
205 void combobox_set_popdown_strings(GtkComboBox *combobox,
207 void combobox_set_popdown_strings(GtkComboBoxText *combobox,
213 cm_return_if_fail(combobox != NULL);
214 #if GTK_CHECK_VERSION(2, 24, 0)
215 cm_return_if_fail(GTK_IS_COMBO_BOX_TEXT (combobox));
218 for (cur = list; cur != NULL; cur = g_list_next(cur))
219 #if !GTK_CHECK_VERSION(2, 24, 0)
220 gtk_combo_box_append_text(combobox, (const gchar*) cur->data);
222 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox),
223 (const gchar*) cur->data);
227 gboolean combobox_set_value_from_arrow_key(GtkComboBox *combobox,
229 /* used from key_press events upon gtk_combo_box_entry with one text column
230 (gtk_combo_box_new_text() and with GtkComboBoxEntry's for instance),
231 make sure that up and down arrow keys behave the same as old with old
234 if the current text in entry widget is not found in combo list,
235 get last value from combo list
236 if the current text in entry widget exists in combo list,
237 get prev value from combo list
239 if the current text in entry widget is not found in combo list,
240 get first value from combo list
241 if the current text in entry widget exists in combo list,
242 get next value from combo list
245 gboolean valid = FALSE;
247 cm_return_val_if_fail(combobox != NULL, FALSE);
249 /* reproduce the behaviour of old gtk_combo_box */
250 GtkTreeModel *model = gtk_combo_box_get_model(combobox);
253 if (gtk_combo_box_get_active_iter(combobox, &iter)) {
254 /* if current text is in list, get prev or next one */
256 if (keyval == GDK_KEY_Up) {
257 #if !GTK_CHECK_VERSION(2, 24, 0)
258 gchar *text = gtk_combo_box_get_active_text(combobox);
260 text = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combobox))),0,-1);
263 gtk_tree_model_get(model, &iter, 0, &text, -1);
265 valid = gtkut_tree_model_text_iter_prev(model, &iter, text);
268 if (keyval == GDK_KEY_Down)
269 valid = gtk_tree_model_iter_next(model, &iter);
272 gtk_combo_box_set_active_iter(combobox, &iter);
275 /* current text is not in list, get first or next one */
277 if (keyval == GDK_KEY_Up)
278 valid = gtkut_tree_model_get_iter_last(model, &iter);
280 if (keyval == GDK_KEY_Down)
281 valid = gtk_tree_model_get_iter_first(model, &iter);
284 gtk_combo_box_set_active_iter(combobox, &iter);
287 /* return TRUE if value could be set */
291 static void store_set_sensitive(GtkTreeModel *model, GtkTreeIter *iter,
292 const gboolean sensitive)
294 if(GTK_IS_LIST_STORE(model)) {
295 gtk_list_store_set(GTK_LIST_STORE(model), iter,
296 COMBOBOX_SENS, sensitive,
299 gtk_tree_store_set(GTK_TREE_STORE(model), iter,
300 COMBOBOX_SENS, sensitive,
305 void combobox_set_sensitive(GtkComboBox *combobox, const guint index,
306 const gboolean sensitive)
309 GtkTreeIter iter, child;
312 if((model = gtk_combo_box_get_model(combobox)) == NULL)
315 gtk_tree_model_get_iter_first(model, &iter);
316 for(i=0; i<index; i++) {
317 if(gtk_tree_model_iter_next(model, &iter) == FALSE)
321 store_set_sensitive(model, &iter, sensitive);
323 if(gtk_tree_model_iter_children(model, &child, &iter) == FALSE)
327 store_set_sensitive(model, &child, sensitive);
328 } while (gtk_tree_model_iter_next(model, &child) == TRUE);