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, ...)
49 combo = gtk_combo_box_entry_new_text();
51 combo = gtk_combo_box_new_text();
52 gtk_widget_show(combo);
54 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), text);
56 while ((string = va_arg(args, gchar*)) != NULL)
57 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), string);
60 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
65 static gboolean _select_by_data_func(GtkTreeModel *model, GtkTreePath *path,
66 GtkTreeIter *iter, ComboboxSelCtx *ctx)
68 GtkComboBox *combobox = ctx->combobox;
69 gint data = ctx->data;
72 gtk_tree_model_get(GTK_TREE_MODEL(model), iter, COMBOBOX_DATA, &curdata, -1);
73 if (data == curdata) {
74 gtk_combo_box_set_active_iter(combobox, iter);
81 void combobox_select_by_data(GtkComboBox *combobox, gint data)
84 ComboboxSelCtx *ctx = NULL;
85 cm_return_if_fail(combobox != NULL);
87 model = gtk_combo_box_get_model(combobox);
89 ctx = g_new(ComboboxSelCtx,
90 sizeof(ComboboxSelCtx));
91 ctx->combobox = combobox;
94 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_data_func, ctx);
98 static gboolean _select_by_text_func(GtkTreeModel *model, GtkTreePath *path,
99 GtkTreeIter *iter, ComboboxSelCtx *ctx)
101 GtkComboBox *combobox = ctx->combobox;
102 const gchar *data = ctx->cdata;
103 const gchar *curdata;
105 gtk_tree_model_get (GTK_TREE_MODEL(model), iter, 0, &curdata, -1);
106 if (!g_utf8_collate(data, curdata)) {
107 gtk_combo_box_set_active_iter(combobox, iter);
114 void combobox_select_by_text(GtkComboBox *combobox, const gchar *data)
117 ComboboxSelCtx *ctx = NULL;
118 GtkComboBoxClass *class;
120 cm_return_if_fail(combobox != NULL);
121 class = GTK_COMBO_BOX_GET_CLASS (combobox);
123 /* we can do that only with gtk_combo_box_new_text() combo boxes */
124 cm_return_if_fail(class->get_active_text != NULL);
126 model = gtk_combo_box_get_model(combobox);
128 ctx = g_new(ComboboxSelCtx,
129 sizeof(ComboboxSelCtx));
130 ctx->combobox = combobox;
133 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_text_func, ctx);
137 gint combobox_get_active_data(GtkComboBox *combobox)
143 cm_return_val_if_fail(combobox != NULL, -1);
145 cm_return_val_if_fail(gtk_combo_box_get_active_iter(combobox, &iter), -1);
147 model = gtk_combo_box_get_model(combobox);
149 gtk_tree_model_get(model, &iter, COMBOBOX_DATA, &data, -1);
154 void combobox_unset_popdown_strings(GtkComboBox *combobox)
159 cm_return_if_fail(combobox != NULL);
161 model = gtk_combo_box_get_model(combobox);
162 count = gtk_tree_model_iter_n_children(model, NULL);
163 for (i = 0; i < count; i++)
164 gtk_combo_box_remove_text(combobox, 0);
167 void combobox_set_popdown_strings(GtkComboBox *combobox,
172 cm_return_if_fail(combobox != NULL);
174 for (cur = list; cur != NULL; cur = g_list_next(cur))
175 gtk_combo_box_append_text(combobox, (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_KEY_Up) {
208 gchar *text = gtk_combo_box_get_active_text(combobox);
210 text = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combobox))),0,-1);
211 valid = gtkut_tree_model_text_iter_prev(model, &iter, text);
214 if (keyval == GDK_KEY_Down)
215 valid = gtk_tree_model_iter_next(model, &iter);
218 gtk_combo_box_set_active_iter(combobox, &iter);
221 /* current text is not in list, get first or next one */
223 if (keyval == GDK_KEY_Up)
224 valid = gtkut_tree_model_get_iter_last(model, &iter);
226 if (keyval == GDK_KEY_Down)
227 valid = gtk_tree_model_get_iter_first(model, &iter);
230 gtk_combo_box_set_active_iter(combobox, &iter);
233 /* return TRUE if value could be set */
237 static void store_set_sensitive(GtkTreeModel *model, GtkTreeIter *iter,
238 const gboolean sensitive)
240 if(GTK_IS_LIST_STORE(model)) {
241 gtk_list_store_set(GTK_LIST_STORE(model), iter,
242 COMBOBOX_SENS, sensitive,
245 gtk_tree_store_set(GTK_TREE_STORE(model), iter,
246 COMBOBOX_SENS, sensitive,
251 void combobox_set_sensitive(GtkComboBox *combobox, const guint index,
252 const gboolean sensitive)
255 GtkTreeIter iter, child;
258 if((model = gtk_combo_box_get_model(combobox)) == NULL)
261 gtk_tree_model_get_iter_first(model, &iter);
262 for(i=0; i<index; i++) {
263 if(gtk_tree_model_iter_next(model, &iter) == FALSE)
267 store_set_sensitive(model, &iter, sensitive);
269 if(gtk_tree_model_iter_children(model, &child, &iter) == FALSE)
273 store_set_sensitive(model, &child, sensitive);
274 } while (gtk_tree_model_iter_next(model, &child) == TRUE);