fix bug 4773, 'remove obsolescent AC_C_CONST'
[claws.git] / src / gtk / combobox.c
blob4f97260291868e8e5121782e1020b81acb03996d
1 /*
2 * Claws Mail -- 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/>.
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #include "claws-features.h"
23 #endif
25 #include <glib.h>
26 #include <glib/gi18n.h>
27 #include <gdk/gdkkeysyms.h>
28 #include <gtk/gtk.h>
29 #include "gtkutils.h"
30 #include "combobox.h"
31 #include "utils.h"
33 typedef struct _combobox_sel_by_data_ctx {
34 GtkComboBox *combobox;
35 gint data;
36 const gchar *cdata;
37 } ComboboxSelCtx;
39 GtkWidget *combobox_text_new(const gboolean with_entry, const gchar *text, ...)
41 GtkWidget *combo;
42 va_list args;
43 gchar *string;
45 if(text == NULL)
46 return NULL;
48 if (with_entry)
49 combo = gtk_combo_box_text_new_with_entry();
50 else
51 combo = gtk_combo_box_text_new();
52 gtk_widget_show(combo);
54 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), text);
55 va_start(args, text);
56 while ((string = va_arg(args, gchar*)) != NULL)
57 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), string);
58 va_end(args);
60 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
62 return combo;
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;
70 gint curdata;
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);
75 return TRUE;
78 return FALSE;
81 void combobox_select_by_data(GtkComboBox *combobox, gint data)
83 GtkTreeModel *model;
84 ComboboxSelCtx *ctx = NULL;
86 cm_return_if_fail(combobox != NULL);
87 cm_return_if_fail(GTK_IS_COMBO_BOX (combobox));
89 model = gtk_combo_box_get_model(combobox);
91 ctx = g_new(ComboboxSelCtx,
92 sizeof(ComboboxSelCtx));
93 ctx->combobox = combobox;
94 ctx->data = data;
96 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_data_func, ctx);
97 g_free(ctx);
100 static gboolean _select_by_text_func(GtkTreeModel *model, GtkTreePath *path,
101 GtkTreeIter *iter, ComboboxSelCtx *ctx)
103 GtkComboBox *combobox = ctx->combobox;
104 const gchar *data = ctx->cdata;
105 gchar *curdata;
107 cm_return_val_if_fail(combobox != NULL, FALSE);
108 cm_return_val_if_fail(GTK_IS_COMBO_BOX (combobox), FALSE);
110 gtk_tree_model_get (GTK_TREE_MODEL(model), iter, 0, &curdata, -1);
111 if (!g_utf8_collate(data, curdata)) {
112 gtk_combo_box_set_active_iter(combobox, iter);
113 g_free(curdata);
114 return TRUE;
115 } else {
116 g_free(curdata);
119 return FALSE;
122 void combobox_select_by_text(GtkComboBox *combobox, const gchar *data)
124 GtkTreeModel *model;
125 ComboboxSelCtx *ctx = NULL;
127 cm_return_if_fail(combobox != NULL);
128 cm_return_if_fail(GTK_IS_COMBO_BOX (combobox));
130 model = gtk_combo_box_get_model(combobox);
132 ctx = g_new(ComboboxSelCtx,
133 sizeof(ComboboxSelCtx));
134 ctx->combobox = combobox;
135 ctx->cdata = data;
137 gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_text_func, ctx);
138 g_free(ctx);
141 gint combobox_get_active_data(GtkComboBox *combobox)
143 GtkTreeModel *model;
144 GtkTreeIter iter;
145 gint data;
147 cm_return_val_if_fail(combobox != NULL, -1);
148 cm_return_val_if_fail(GTK_IS_COMBO_BOX (combobox), -1);
149 cm_return_val_if_fail(gtk_combo_box_get_active_iter(combobox, &iter), -1);
151 model = gtk_combo_box_get_model(combobox);
153 gtk_tree_model_get(model, &iter, COMBOBOX_DATA, &data, -1);
155 return data;
158 void combobox_unset_popdown_strings(GtkComboBoxText *combobox)
160 GtkTreeModel *model;
161 gint count, i;
163 cm_return_if_fail(combobox != NULL);
164 cm_return_if_fail(GTK_IS_COMBO_BOX_TEXT (combobox));
166 model = gtk_combo_box_get_model(GTK_COMBO_BOX(combobox));
167 count = gtk_tree_model_iter_n_children(model, NULL);
168 for (i = 0; i < count; i++)
169 gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(combobox), 0);
172 void combobox_set_popdown_strings(GtkComboBoxText *combobox,
173 GList *list)
175 GList *cur;
177 cm_return_if_fail(combobox != NULL);
178 cm_return_if_fail(GTK_IS_COMBO_BOX_TEXT (combobox));
180 for (cur = list; cur != NULL; cur = g_list_next(cur))
181 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox),
182 (const gchar*) cur->data);
185 gboolean combobox_set_value_from_arrow_key(GtkComboBox *combobox,
186 guint keyval)
187 /* used from key_press events upon gtk_combo_box_entry with one text column
188 (gtk_combo_box_text_new() and with GtkComboBoxEntry's for instance),
189 make sure that up and down arrow keys behave the same as old with old
190 gtk_combo widgets:
191 when pressing Up:
192 if the current text in entry widget is not found in combo list,
193 get last value from combo list
194 if the current text in entry widget exists in combo list,
195 get prev value from combo list
196 when pressing Down:
197 if the current text in entry widget is not found in combo list,
198 get first value from combo list
199 if the current text in entry widget exists in combo list,
200 get next value from combo list
203 gboolean valid = FALSE;
205 cm_return_val_if_fail(combobox != NULL, FALSE);
207 /* reproduce the behaviour of old gtk_combo_box */
208 GtkTreeModel *model = gtk_combo_box_get_model(combobox);
209 GtkTreeIter iter;
211 if (gtk_combo_box_get_active_iter(combobox, &iter)) {
212 /* if current text is in list, get prev or next one */
214 if (keyval == GDK_KEY_Up) {
215 gchar *text = NULL;
216 gtk_tree_model_get(model, &iter, 0, &text, -1);
217 valid = gtkut_tree_model_text_iter_prev(model, &iter, text);
218 g_free(text);
219 } else
220 if (keyval == GDK_KEY_Down)
221 valid = gtk_tree_model_iter_next(model, &iter);
223 if (valid)
224 gtk_combo_box_set_active_iter(combobox, &iter);
226 } else {
227 /* current text is not in list, get first or next one */
229 if (keyval == GDK_KEY_Up)
230 valid = gtkut_tree_model_get_iter_last(model, &iter);
231 else
232 if (keyval == GDK_KEY_Down)
233 valid = gtk_tree_model_get_iter_first(model, &iter);
235 if (valid)
236 gtk_combo_box_set_active_iter(combobox, &iter);
239 /* return TRUE if value could be set */
240 return valid;
243 static void store_set_sensitive(GtkTreeModel *model, GtkTreeIter *iter,
244 const gboolean sensitive)
246 if(GTK_IS_LIST_STORE(model)) {
247 gtk_list_store_set(GTK_LIST_STORE(model), iter,
248 COMBOBOX_SENS, sensitive,
249 -1);
250 } else {
251 gtk_tree_store_set(GTK_TREE_STORE(model), iter,
252 COMBOBOX_SENS, sensitive,
253 -1);
257 void combobox_set_sensitive(GtkComboBox *combobox, const guint index,
258 const gboolean sensitive)
260 GtkTreeModel *model;
261 GtkTreeIter iter, child;
262 guint i;
264 if((model = gtk_combo_box_get_model(combobox)) == NULL)
265 return;
267 if(gtk_tree_model_get_iter_first(model, &iter) == FALSE)
268 return;
269 for(i=0; i<index; i++) {
270 if(gtk_tree_model_iter_next(model, &iter) == FALSE)
271 return;
274 store_set_sensitive(model, &iter, sensitive);
276 if(gtk_tree_model_iter_children(model, &child, &iter) == FALSE)
277 return;
279 do {
280 store_set_sensitive(model, &child, sensitive);
281 } while (gtk_tree_model_iter_next(model, &child) == TRUE);