2007-08-25 [paul] 2.10.0cvs172
[claws.git] / src / gtk / combobox.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2006-2007 Andrej Kacian and the Claws Mail team
4  *
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.
9  *
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.
14  *
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/>.
17  * 
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <glib.h>
25 #include <glib/gi18n.h>
26 #include <gdk/gdkkeysyms.h>
27 #include <gtk/gtk.h>
28 #include "gtkutils.h"
29 #include "combobox.h"
30
31 typedef struct _combobox_sel_by_data_ctx {
32         GtkComboBox *combobox;
33         gint data;
34 } ComboboxSelCtx;
35
36 static gboolean _select_by_data_func(GtkTreeModel *model,       GtkTreePath *path,
37                 GtkTreeIter *iter, ComboboxSelCtx *ctx)
38 {
39         GtkComboBox *combobox = ctx->combobox;
40         gint data = ctx->data;
41         gint curdata;
42
43         gtk_tree_model_get(GTK_TREE_MODEL(model), iter, COMBOBOX_DATA, &curdata, -1);
44         if (data == curdata) {
45                 gtk_combo_box_set_active_iter(combobox, iter);
46                 return TRUE;
47         }
48
49         return FALSE;
50 }
51
52 void combobox_select_by_data(GtkComboBox *combobox, gint data)
53 {
54         GtkTreeModel *model;
55         ComboboxSelCtx *ctx = NULL;
56         g_return_if_fail(combobox != NULL);
57
58         model = gtk_combo_box_get_model(combobox);
59
60         ctx = g_new(ComboboxSelCtx,
61                         sizeof(ComboboxSelCtx));
62         ctx->combobox = combobox;
63         ctx->data = data;
64
65         gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)_select_by_data_func, ctx);
66         g_free(ctx);
67 }
68
69 gint combobox_get_active_data(GtkComboBox *combobox)
70 {
71         GtkTreeModel *model;
72         GtkTreeIter iter;
73         gint data;
74
75         g_return_val_if_fail(combobox != NULL, -1);
76
77         g_return_val_if_fail(gtk_combo_box_get_active_iter(combobox, &iter), -1);
78
79         model = gtk_combo_box_get_model(combobox);
80
81         gtk_tree_model_get(model, &iter, COMBOBOX_DATA, &data, -1);
82
83         return data;
84 }
85
86 void combobox_unset_popdown_strings(GtkComboBox *combobox)
87 {
88         GtkTreeModel *model;
89         gint count, i;
90
91         g_return_if_fail(combobox != NULL);
92
93         model = gtk_combo_box_get_model(combobox);
94         count = gtk_tree_model_iter_n_children(model, NULL);
95         for (i = 0; i < count; i++)
96                 gtk_combo_box_remove_text(combobox, 0);
97 }
98
99 void combobox_set_popdown_strings(GtkComboBox *combobox,
100                                  GList       *list)
101 {
102         GList *cur;
103
104         g_return_if_fail(combobox != NULL);
105
106         for (cur = list; cur != NULL; cur = g_list_next(cur))
107                 gtk_combo_box_append_text(combobox, (const gchar*) cur->data);
108 }
109
110 gboolean combobox_set_value_from_arrow_key(GtkComboBox *combobox,
111                                  guint keyval)
112 /* used from key_press events upon gtk_combo_box_entry with one text column 
113    (gtk_combo_box_new_text() and with GtkComboBoxEntry's for instance),
114    make sure that up and down arrow keys behave the same as old with old
115    gtk_combo widgets:
116     when pressing Up:
117           if the current text in entry widget is not found in combo list,
118             get last value from combo list
119           if the current text in entry widget exists in combo list,
120             get prev value from combo list
121     when pressing Down:
122           if the current text in entry widget is not found in combo list,
123             get first value from combo list
124           if the current text in entry widget exists in combo list,
125             get next value from combo list
126 */
127 {
128         gboolean valid = FALSE;
129
130         g_return_val_if_fail(combobox != NULL, FALSE);
131
132         /* reproduce the behaviour of old gtk_combo_box */
133         GtkTreeModel *model = gtk_combo_box_get_model(combobox);
134         GtkTreeIter iter;
135
136         if (gtk_combo_box_get_active_iter(combobox, &iter)) {
137                 /* if current text is in list, get prev or next one */
138
139                 if (keyval == GDK_Up) {
140                         gchar *text = gtk_combo_box_get_active_text(combobox);
141                         if (!text)
142                                 text = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(combobox))),0,-1);
143                         valid = gtkut_tree_model_text_iter_prev(model, &iter, text);
144                         g_free(text);
145                 } else
146                 if (keyval == GDK_Down)
147                         valid = gtk_tree_model_iter_next(model, &iter);
148
149                 if (valid)
150                         gtk_combo_box_set_active_iter(combobox, &iter);
151
152         } else {
153                 /* current text is not in list, get first or next one */
154
155                 if (keyval == GDK_Up)
156                         valid = gtkut_tree_model_get_iter_last(model, &iter);
157                 else
158                 if (keyval == GDK_Down)
159                         valid = gtk_tree_model_get_iter_first(model, &iter);
160
161                 if (valid)
162                         gtk_combo_box_set_active_iter(combobox, &iter);
163         }
164
165         /* return TRUE if value could be set */
166         return valid;
167 }