Me card contact is normally a OssoABookContact and not a EContact
[modest] / src / hildon2 / modest-country-picker.c
1 /* Copyright (c) 2008, 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-picker.h"
38 #include <hildon/hildon-touch-selector-entry.h>
39 #include <gtk/gtkliststore.h>
40 #include <gtk/gtkcelllayout.h>
41 #include <gtk/gtkcellrenderertext.h>
42
43 #include <stdlib.h>
44 #include <string.h> /* For memcpy() */
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 G_DEFINE_TYPE (ModestCountryPicker, modest_country_picker, HILDON_TYPE_PICKER_BUTTON);
54
55 typedef struct
56 {
57         gint locale_mcc;
58 /*      GtkTreeModel *model; */
59 } ModestCountryPickerPrivate;
60
61 #define MODEST_COUNTRY_PICKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
62                                                                            MODEST_TYPE_COUNTRY_PICKER, \
63                                                                            ModestCountryPickerPrivate))
64
65 static void
66 modest_country_picker_get_property (GObject *object, guint property_id,
67                                     GValue *value, GParamSpec *pspec)
68 {
69         switch (property_id) {
70         default:
71                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
72         }
73 }
74
75 static void
76 modest_country_picker_set_property (GObject *object, guint property_id,
77                                     const GValue *value, GParamSpec *pspec)
78 {
79         switch (property_id) {
80         default:
81                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
82         }
83 }
84
85 static void
86 modest_country_picker_dispose (GObject *object)
87 {
88         if (G_OBJECT_CLASS (modest_country_picker_parent_class)->dispose)
89                 G_OBJECT_CLASS (modest_country_picker_parent_class)->dispose (object);
90 }
91
92 enum MODEL_COLS {
93         MODEL_COL_NAME = 0, /* string */
94         MODEL_COL_MCC  = 1 /* the 'effective mcc' for this country */
95 };
96
97         
98 static void
99 modest_country_picker_finalize (GObject *object)
100 {
101         G_OBJECT_CLASS (modest_country_picker_parent_class)->finalize (object);
102 }
103
104 static void
105 modest_country_picker_class_init (ModestCountryPickerClass *klass)
106 {
107         GObjectClass *object_class = G_OBJECT_CLASS (klass);
108
109         g_type_class_add_private (klass, sizeof (ModestCountryPickerPrivate));
110
111         object_class->get_property = modest_country_picker_get_property;
112         object_class->set_property = modest_country_picker_set_property;
113         object_class->dispose = modest_country_picker_dispose;
114         object_class->finalize = modest_country_picker_finalize;
115 }
116
117
118
119
120
121 static void
122 modest_country_picker_init (ModestCountryPicker *self)
123 {
124         ModestCountryPickerPrivate *priv = MODEST_COUNTRY_PICKER_GET_PRIVATE (self);
125         priv->locale_mcc = 0;
126 }
127
128 static gchar *
129 country_picker_print_func (HildonTouchSelector *selector, gpointer userdata)
130 {
131         GtkTreeModel *model;
132         GtkTreeIter iter;
133         gchar *text = NULL;
134
135         /* Always pick the selected country from the tree view and
136            never from the entry */
137         model = hildon_touch_selector_get_model (selector, 0);
138         if (hildon_touch_selector_get_selected (selector, 0, &iter)) {
139                 gint column;
140                 GtkWidget *entry;
141                 const gchar *entry_text;
142
143                 column = hildon_touch_selector_entry_get_text_column (HILDON_TOUCH_SELECTOR_ENTRY (selector));
144                 gtk_tree_model_get (model, &iter, column, &text, -1);
145
146                 entry = GTK_WIDGET (hildon_touch_selector_entry_get_entry (HILDON_TOUCH_SELECTOR_ENTRY (selector)));
147                 entry_text = hildon_entry_get_text (HILDON_ENTRY (entry));
148                 if (entry_text != NULL && text != NULL && strcmp (entry_text, text)) {
149                         hildon_entry_set_text (HILDON_ENTRY (entry), text);
150                 }
151         }
152         return text;
153 }
154
155 void
156 modest_country_picker_load_data(ModestCountryPicker *self)
157 {
158         GtkCellRenderer *renderer;
159         GtkWidget *selector;
160         GtkTreeModel *model;
161         HildonTouchSelectorColumn *column;
162         ModestCountryPickerPrivate *priv;
163
164         priv = MODEST_COUNTRY_PICKER_GET_PRIVATE (self);
165
166         /* Create a tree model for the combo box,
167          * with a string for the name, and an int for the MCC ID.
168          * This must match our MODEL_COLS enum constants.
169          */
170         model = modest_utils_create_country_model ();
171
172         /* Country column:
173          * The ID model column in not shown in the view. */
174         renderer = gtk_cell_renderer_text_new ();
175         g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
176
177         selector = hildon_touch_selector_entry_new ();
178         hildon_touch_selector_set_print_func (HILDON_TOUCH_SELECTOR (selector), (HildonTouchSelectorPrintFunc) country_picker_print_func);
179
180         column = hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector), model,
181                                                       renderer, "text", MODEST_UTILS_COUNTRY_MODEL_COLUMN_NAME, NULL);
182         hildon_touch_selector_entry_set_text_column (HILDON_TOUCH_SELECTOR_ENTRY (selector),
183                                                      MODEST_UTILS_COUNTRY_MODEL_COLUMN_NAME);
184         modest_utils_fill_country_model (model, &(priv->locale_mcc));
185
186         /* Set this _after_ loading from file, it makes loading faster */
187         hildon_touch_selector_set_model (HILDON_TOUCH_SELECTOR (selector),
188                                          0, model);
189         hildon_touch_selector_entry_set_input_mode (HILDON_TOUCH_SELECTOR_ENTRY (selector),
190                                                     HILDON_GTK_INPUT_MODE_ALPHA |
191                                                     HILDON_GTK_INPUT_MODE_AUTOCAP);
192
193
194         hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (self), HILDON_TOUCH_SELECTOR (selector));
195
196         g_object_unref (model);
197 }
198
199 ModestCountryPicker*
200 modest_country_picker_new (HildonSizeType size,
201                            HildonButtonArrangement arrangement)
202 {
203         return g_object_new (MODEST_TYPE_COUNTRY_PICKER, 
204                              "arrangement", arrangement,
205                              "size", size,
206                              NULL);
207 }
208
209 /**
210  * Returns the MCC number of the selected country, or 0 if no country was selected. 
211  */
212 gint
213 modest_country_picker_get_active_country_mcc (ModestCountryPicker *self)
214 {
215         GtkTreeIter active;
216         gboolean found;
217
218         found = hildon_touch_selector_get_selected (hildon_picker_button_get_selector
219                                                     (HILDON_PICKER_BUTTON (self)), 0, &active);
220         if (found) {
221                 gint mcc = 0;
222                 gtk_tree_model_get (hildon_touch_selector_get_model (hildon_picker_button_get_selector
223                                                                      (HILDON_PICKER_BUTTON (self)), 
224                                                                      0), 
225                                     &active, MODEST_UTILS_COUNTRY_MODEL_COLUMN_MCC, &mcc, -1);
226                 return mcc;     
227         }
228         return 0; /* Failed. */
229 }
230
231
232 /**
233  * Selects the MCC number of the selected country.
234  * Specify 0 to select no country. 
235  */
236 gboolean
237 modest_country_picker_set_active_country_locale (ModestCountryPicker *self)
238 {
239         ModestCountryPickerPrivate *priv = MODEST_COUNTRY_PICKER_GET_PRIVATE (self);
240         GtkWidget *selector;
241         GtkTreeIter iter;
242         gint current_mcc;
243         GtkTreeModel *model;
244
245         selector = GTK_WIDGET (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (self)));
246         model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
247         if (!gtk_tree_model_get_iter_first (model, &iter))
248                 return FALSE;
249         do {
250                 gtk_tree_model_get (model, &iter, MODEST_UTILS_COUNTRY_MODEL_COLUMN_MCC, &current_mcc, -1);
251                 if (priv->locale_mcc == current_mcc) {
252                         hildon_touch_selector_select_iter (HILDON_TOUCH_SELECTOR (selector), 0, 
253                                                            &iter, TRUE);
254                         hildon_button_set_value (HILDON_BUTTON (self), 
255                                                  hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector)));
256                         return TRUE;
257                 }
258         } while (gtk_tree_model_iter_next (model, &iter));
259         
260         return FALSE; /* not found */
261 }
262