1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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.
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.
31 #define _GNU_SOURCE /* So we can use the getline() function, which is a convenient GNU extension. */
36 #include "../modest-maemo-utils.h"
37 #include "modest-easysetup-country-combo-box.h"
38 #include <gtk/gtkliststore.h>
39 #include <gtk/gtkcelllayout.h>
40 #include <gtk/gtkcellrenderertext.h>
43 #include <string.h> /* For memcpy() */
46 #include <libintl.h> /* For dgettext(). */
48 /* Include config.h so that _() works: */
53 #define MAX_LINE_LEN 128 /* max length of a line in MCC file */
55 #if MODEST_HILDON_API < 2
56 G_DEFINE_TYPE (EasysetupCountryComboBox, easysetup_country_combo_box, GTK_TYPE_COMBO_BOX);
58 G_DEFINE_TYPE (EasysetupCountryComboBox, easysetup_country_combo_box, HILDON_TYPE_PICKER_BUTTON);
64 /* GtkTreeModel *model; */
65 } ModestEasysetupCountryComboBoxPrivate;
67 #define MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
68 MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX, \
69 ModestEasysetupCountryComboBoxPrivate))
72 easysetup_country_combo_box_get_property (GObject *object, guint property_id,
73 GValue *value, GParamSpec *pspec)
75 switch (property_id) {
77 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
82 easysetup_country_combo_box_set_property (GObject *object, guint property_id,
83 const GValue *value, GParamSpec *pspec)
85 switch (property_id) {
87 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
92 easysetup_country_combo_box_dispose (GObject *object)
94 if (G_OBJECT_CLASS (easysetup_country_combo_box_parent_class)->dispose)
95 G_OBJECT_CLASS (easysetup_country_combo_box_parent_class)->dispose (object);
99 MODEL_COL_NAME = 0, /* string */
100 MODEL_COL_MCC = 1 /* the 'effective mcc' for this country */
105 easysetup_country_combo_box_finalize (GObject *object)
107 G_OBJECT_CLASS (easysetup_country_combo_box_parent_class)->finalize (object);
111 easysetup_country_combo_box_class_init (EasysetupCountryComboBoxClass *klass)
113 GObjectClass *object_class = G_OBJECT_CLASS (klass);
115 g_type_class_add_private (klass, sizeof (ModestEasysetupCountryComboBoxPrivate));
117 object_class->get_property = easysetup_country_combo_box_get_property;
118 object_class->set_property = easysetup_country_combo_box_set_property;
119 object_class->dispose = easysetup_country_combo_box_dispose;
120 object_class->finalize = easysetup_country_combo_box_finalize;
126 /* cluster mcc's, based on the list
127 * http://en.wikipedia.org/wiki/Mobile_country_code
130 effective_mcc (gint mcc)
133 case 405: return 404; /* india */
134 case 441: return 440; /* japan */
135 case 235: return 234; /* united kingdom */
141 case 316: return 310; /* united states */
147 /* each line is of the form:
150 NOTE: this function is NOT re-entrant, the out-param country
151 are static strings that should NOT be freed. and will change when
152 calling this function again
154 also note, this function will return the "effective mcc", which
155 is the normalized mcc for a country - ie. even if the there
156 are multiple entries for the United States with various mccs,
157 this function will always return 310, even if the real mcc parsed
158 would be 314. see the 'effective_mcc' function above.
161 parse_mcc_mapping_line (const char* line, char** country)
164 char mcc[4]; /* the mcc code, always 3 bytes*/
165 static char my_country[128];
172 for (i = 3, j = 0; i < 128; ++i) {
179 my_country [j++] = kar;
181 my_country[j] = '\0';
188 *country = my_country;
190 return effective_mcc ((int) strtol ((const char*)mcc, NULL, 10));
193 /** Note that the mcc_mapping file is installed
194 * by the operator-wizard-settings package.
197 load_from_file (EasysetupCountryComboBox *self, GtkListStore *liststore)
199 ModestEasysetupCountryComboBoxPrivate *priv = MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
201 char line[MAX_LINE_LEN];
202 guint previous_mcc = 0;
203 gchar *territory, *fallback = NULL;
204 gchar *current_locale;
206 /* Get the territory specified for the current locale */
207 territory = nl_langinfo (_NL_ADDRESS_COUNTRY_NAME);
209 /* Tricky stuff, the translations of the OSSO countries does
210 not always correspond to the country names in locale
211 databases. Add all these cases here. sergio */
212 if (!strcmp (territory, "United Kingdom"))
213 fallback = g_strdup ("UK");
215 current_locale = setlocale (LC_ALL ,NULL);
217 FILE *file = modest_maemo_open_mcc_mapping_file ();
219 g_warning("Could not open mcc_mapping file");
223 while (fgets (line, MAX_LINE_LEN, file) != NULL) {
226 char *country = NULL;
227 const gchar *name_translated, *english_translation;
229 mcc = parse_mcc_mapping_line (line, &country);
230 if (!country || mcc == 0) {
231 g_warning ("%s: error parsing line: '%s'", __FUNCTION__, line);
235 if (mcc == previous_mcc) {
236 /* g_warning ("already seen: %s", line); */
241 if (!priv->locale_mcc) {
242 english_translation = dgettext ("osso-countries", country);
243 if (!strcmp (english_translation, territory) ||
244 (fallback && !strcmp (english_translation, fallback)))
245 priv->locale_mcc = mcc;
247 name_translated = dgettext ("osso-countries", country);
249 /* Add the row to the model: */
251 gtk_list_store_append (liststore, &iter);
252 gtk_list_store_set(liststore, &iter, MODEL_COL_MCC, mcc, MODEL_COL_NAME, name_translated, -1);
256 /* Sort the items: */
257 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore),
258 MODEL_COL_NAME, GTK_SORT_ASCENDING);
264 easysetup_country_combo_box_init (EasysetupCountryComboBox *self)
266 ModestEasysetupCountryComboBoxPrivate *priv = MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
267 priv->locale_mcc = 0;
271 easysetup_country_combo_box_load_data(EasysetupCountryComboBox *self)
275 /* Create a tree model for the combo box,
276 * with a string for the name, and an int for the MCC ID.
277 * This must match our MODEL_COLS enum constants.
279 model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
282 * The ID model column in not shown in the view. */
283 GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
284 g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
286 #if MODEST_HILDON_API < 2
287 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (self), renderer, TRUE);
288 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer,
289 "text", MODEL_COL_NAME, NULL);
291 GtkWidget *selector = hildon_touch_selector_new ();
292 hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (self), HILDON_TOUCH_SELECTOR (selector));
293 hildon_touch_selector_append_column (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (self)),
294 GTK_TREE_MODEL (model),
295 renderer, "text", MODEL_COL_NAME, NULL);
298 /* Fill the model with rows: */
299 load_from_file (self, model);
301 /* Set this _after_ loading from file, it makes loading faster */
302 #if MODEST_HILDON_API < 2
303 gtk_combo_box_set_model (GTK_COMBO_BOX (self), GTK_TREE_MODEL (model));
305 hildon_touch_selector_set_model (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (self)),
306 0, GTK_TREE_MODEL (model));
310 EasysetupCountryComboBox*
311 easysetup_country_combo_box_new (void)
313 #if MODEST_HILDON_API >= 2
314 return g_object_new (MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX,
315 "arrangement", HILDON_BUTTON_ARRANGEMENT_VERTICAL,
316 "size", HILDON_SIZE_AUTO,
319 return g_object_new (MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX,
325 * Returns the MCC number of the selected country, or 0 if no country was selected.
328 easysetup_country_combo_box_get_active_country_mcc (EasysetupCountryComboBox *self)
333 #if MODEST_HILDON_API < 2
334 found = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self), &active);
336 found = hildon_touch_selector_get_selected (hildon_picker_button_get_selector
337 (HILDON_PICKER_BUTTON (self)), 0, &active);
341 #if MODEST_HILDON_API < 2
342 gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (self)),
343 &active, MODEL_COL_MCC, &mcc, -1);
345 gtk_tree_model_get (hildon_touch_selector_get_model (hildon_picker_button_get_selector
346 (HILDON_PICKER_BUTTON (self)),
348 &active, MODEL_COL_MCC, &mcc, -1);
352 return 0; /* Failed. */
357 * Selects the MCC number of the selected country.
358 * Specify 0 to select no country.
361 easysetup_country_combo_box_set_active_country_locale (EasysetupCountryComboBox *self)
363 ModestEasysetupCountryComboBoxPrivate *priv = MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
368 #if MODEST_HILDON_API < 2
369 model = gtk_combo_box_get_model (GTK_COMBO_BOX (self));
370 g_message ("HILDON < 2");
372 model = hildon_touch_selector_get_model (hildon_picker_button_get_selector
373 (HILDON_PICKER_BUTTON (self)), 0);
374 g_message ("HILDON >= 2");
376 if (!gtk_tree_model_get_iter_first (model, &iter))
379 gtk_tree_model_get (model, &iter, MODEL_COL_MCC, ¤t_mcc, -1);
380 if (priv->locale_mcc == current_mcc) {
381 #if MODEST_HILDON_API < 2
382 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self), &iter);
384 hildon_touch_selector_select_iter (hildon_picker_button_get_selector
385 (HILDON_PICKER_BUTTON (self)), 0,
390 } while (gtk_tree_model_iter_next (model, &iter));
392 return FALSE; /* not found */