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