Modified webpage: now tinymail repository is in gitorious.
[modest] / src / widgets / modest-country-combo-box.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #ifndef _GNU_SOURCE
31 #define _GNU_SOURCE /* So we can use the getline() function, which is a convenient GNU extension. */
32 #endif
33
34 #include <stdio.h>
35
36 #include <modest-utils.h>
37 #include <modest-country-combo-box.h>
38 #include <gtk/gtkliststore.h>
39 #include <gtk/gtkcelllayout.h>
40 #include <gtk/gtkcellrenderertext.h>
41
42 #include <stdlib.h>
43 #include <string.h> /* For memcpy() */
44 #include <langinfo.h>
45 #include <locale.h>
46 #include <libintl.h> /* For dgettext(). */
47
48 /* Include config.h so that _() works: */
49 #ifdef HAVE_CONFIG_H
50 #include <config.h>
51 #endif
52
53 #define MAX_LINE_LEN 128 /* max length of a line in MCC file */
54
55 G_DEFINE_TYPE (ModestCountryComboBox, modest_country_combo_box, GTK_TYPE_COMBO_BOX);
56
57 typedef struct
58 {
59         gint locale_mcc;
60 } ModestCountryComboBoxPrivate;
61
62 #define MODEST_COUNTRY_COMBO_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
63                                                                               MODEST_TYPE_COUNTRY_COMBO_BOX, \
64                                                         ModestCountryComboBoxPrivate))
65
66 static void
67 modest_country_combo_box_get_property (GObject *object, guint property_id,
68                                        GValue *value, GParamSpec *pspec)
69 {
70         switch (property_id) {
71         default:
72                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
73         }
74 }
75
76 static void
77 modest_country_combo_box_set_property (GObject *object, guint property_id,
78                                                                                                                         const GValue *value, GParamSpec *pspec)
79 {
80         switch (property_id) {
81         default:
82                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
83         }
84 }
85
86 static void
87 modest_country_combo_box_dispose (GObject *object)
88 {
89         if (G_OBJECT_CLASS (modest_country_combo_box_parent_class)->dispose)
90                 G_OBJECT_CLASS (modest_country_combo_box_parent_class)->dispose (object);
91 }
92
93 enum MODEL_COLS {
94         MODEL_COL_NAME = 0, /* string */
95         MODEL_COL_MCC  = 1 /* the 'effective mcc' for this country */
96 };
97
98         
99 static void
100 modest_country_combo_box_finalize (GObject *object)
101 {
102         G_OBJECT_CLASS (modest_country_combo_box_parent_class)->finalize (object);
103 }
104
105 static void
106 modest_country_combo_box_class_init (ModestCountryComboBoxClass *klass)
107 {
108         GObjectClass *object_class = G_OBJECT_CLASS (klass);
109
110         g_type_class_add_private (klass, sizeof (ModestCountryComboBoxPrivate));
111
112         object_class->get_property = modest_country_combo_box_get_property;
113         object_class->set_property = modest_country_combo_box_set_property;
114         object_class->dispose = modest_country_combo_box_dispose;
115         object_class->finalize = modest_country_combo_box_finalize;
116 }
117
118
119 static void
120 modest_country_combo_box_init (ModestCountryComboBox *self)
121 {
122         ModestCountryComboBoxPrivate *priv = MODEST_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
123         priv->locale_mcc = 0;
124 }
125
126 void
127 modest_country_combo_box_load_data(ModestCountryComboBox *self)
128 {
129         ModestCountryComboBoxPrivate *priv;
130         GtkTreeModel *model;
131
132         priv = MODEST_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
133         /* Create a tree model for the combo box,
134          * with a string for the name, and an int for the MCC ID.
135          * This must match our MODEL_COLS enum constants.
136          */
137         model = modest_utils_create_country_model ();
138         
139         /* Country column:
140          * The ID model column in not shown in the view. */
141         GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
142         g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
143
144         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (self), renderer, TRUE);
145         gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer, 
146                                         "text", MODEST_UTILS_COUNTRY_MODEL_COLUMN_NAME, NULL);
147
148         modest_utils_fill_country_model (model, &(priv->locale_mcc));
149
150         /* Set this _after_ loading from file, it makes loading faster */
151         gtk_combo_box_set_model (GTK_COMBO_BOX (self), model);
152 }
153
154 GtkWidget*
155 modest_country_combo_box_new (void)
156 {
157         return g_object_new (MODEST_TYPE_COUNTRY_COMBO_BOX, 
158                              NULL);
159 }
160
161 /**
162  * Returns the MCC number of the selected country, or 0 if no country was selected. 
163  */
164 gint
165 modest_country_combo_box_get_active_country_mcc (ModestCountryComboBox *self)
166 {
167         GtkTreeIter active;
168         gboolean found;
169
170         found = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self), &active);
171         if (found) {
172                 gint mcc = 0;
173                 gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (self)), 
174                                     &active, MODEST_UTILS_COUNTRY_MODEL_COLUMN_MCC, &mcc, -1);
175                 return mcc;     
176         }
177         return 0; /* Failed. */
178 }
179
180
181 /**
182  * Selects the MCC number of the selected country.
183  * Specify 0 to select no country. 
184  */
185 gboolean
186 modest_country_combo_box_set_active_country_locale (ModestCountryComboBox *self)
187 {
188         ModestCountryComboBoxPrivate *priv = MODEST_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
189         GtkTreeIter iter;
190         gint current_mcc;
191         GtkTreeModel *model;
192
193         model = gtk_combo_box_get_model (GTK_COMBO_BOX (self));
194         if (!gtk_tree_model_get_iter_first (model, &iter))
195                 return FALSE;
196         do {
197                 gtk_tree_model_get (model, &iter, MODEST_UTILS_COUNTRY_MODEL_COLUMN_MCC, &current_mcc, -1);
198                 if (priv->locale_mcc == current_mcc) {
199                         gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self), &iter);
200                         return TRUE;
201                 }
202         } while (gtk_tree_model_iter_next (model, &iter));
203         
204         return FALSE; /* not found */
205 }
206