* Fixes to touch selector usage of new pickers.
[modest] / src / hildon2 / modest-maemo-security-options-view.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 #include "modest-runtime.h"
31 #include "modest-security-options-view-priv.h"
32 #include "modest-maemo-security-options-view.h"
33 #include "modest-text-utils.h"
34 #include "modest-platform.h"
35 #include "modest-account-protocol.h"
36 #include "widgets/modest-ui-constants.h"
37 #include "widgets/modest-validating-entry.h"
38 #include "widgets/modest-serversecurity-combo-box.h"
39 #include "widgets/modest-secureauth-combo-box.h"
40 #ifdef MODEST_HAVE_HILDON0_WIDGETS
41 #include <hildon-widgets/hildon-caption.h>
42 #include <hildon-widgets/hildon-number-editor.h>
43 #else
44 #include <hildon/hildon-caption.h>
45 #include <hildon/hildon-number-editor.h>
46 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
47
48 #define PORT_MIN 1
49 #define PORT_MAX 65535
50
51 static void modest_maemo_security_options_view_init (ModestMaemoSecurityOptionsView *obj);
52 static void modest_maemo_security_options_view_finalize (GObject *obj);
53 static void modest_maemo_security_options_view_class_init (ModestMaemoSecurityOptionsViewClass *klass);
54
55 G_DEFINE_TYPE (ModestMaemoSecurityOptionsView, 
56                modest_maemo_security_options_view, 
57                MODEST_TYPE_SECURITY_OPTIONS_VIEW);
58
59 static void on_entry_changed (GtkEditable *editable, gpointer user_data);
60
61 /* Tracks changes in the incoming security combo box */
62 static void
63 on_security_changed (GtkWidget *widget, 
64                      ModestMaemoSecurityOptionsView *self)
65 {
66         ModestSecurityOptionsViewPrivate* ppriv;
67         ModestServersecurityComboBox *combo;
68         ModestProtocolType proto_type;
69         ModestProtocolRegistry *proto_registry;
70         gboolean is_secure;
71
72         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
73
74         proto_registry = modest_runtime_get_protocol_registry ();
75         combo = MODEST_SERVERSECURITY_COMBO_BOX (ppriv->security_view);
76         proto_type = modest_serversecurity_combo_box_get_active_serversecurity (combo);
77
78         is_secure = modest_protocol_registry_protocol_type_has_tag (proto_registry, proto_type, 
79                                                                     MODEST_PROTOCOL_REGISTRY_SECURE_PROTOCOLS);
80
81         if (MODEST_SECURITY_OPTIONS_VIEW (self)->type == MODEST_SECURITY_OPTIONS_INCOMING) {
82                 /* Activate and dim checkbutton if it's secure */
83                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ppriv->auth_view), 
84                                               is_secure);
85                 gtk_widget_set_sensitive (ppriv->auth_view, !is_secure);
86         } else {
87
88         }
89
90         if (ppriv->full) {
91                 gint port_number = 
92                         modest_serversecurity_combo_box_get_active_serversecurity_port (MODEST_SERVERSECURITY_COMBO_BOX (ppriv->security_view));
93                 
94                 if(port_number) {
95                         hildon_number_editor_set_value (HILDON_NUMBER_EDITOR (ppriv->port_view), 
96                                                         port_number);
97                 }
98         }
99 }
100
101 static void
102 on_auth_changed (GtkWidget *widget, 
103                  ModestMaemoSecurityOptionsView *self)
104 {
105         ModestSecurityOptionsViewPrivate* ppriv;
106         ModestSecureauthComboBox *combo;
107         ModestProtocolRegistry *protocol_registry;
108         ModestProtocolType auth_proto;
109         gboolean secureauth_used;
110         GtkWidget *user_caption, *pwd_caption;
111
112         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
113         protocol_registry = modest_runtime_get_protocol_registry ();
114         combo = MODEST_SECUREAUTH_COMBO_BOX (ppriv->auth_view);
115
116         auth_proto = modest_secureauth_combo_box_get_active_secureauth (combo);
117         secureauth_used = modest_protocol_registry_protocol_type_is_secure (protocol_registry, 
118                                                                             auth_proto);
119
120         /* Get captions, well dimm the whole widget */
121         user_caption = gtk_widget_get_parent (ppriv->user_entry);
122         pwd_caption = gtk_widget_get_parent (ppriv->pwd_entry);
123         
124         /* Enable / disable */
125         gtk_widget_set_sensitive (user_caption, secureauth_used);
126         gtk_widget_set_sensitive (pwd_caption, secureauth_used);
127
128         /* Check if mandatory data is missing */
129         on_entry_changed (GTK_EDITABLE (ppriv->user_entry), (gpointer) self);
130 }
131
132 static void
133 create_incoming_security (ModestSecurityOptionsView* self,
134                           GtkSizeGroup *size_group)
135 {
136         ModestSecurityOptionsViewPrivate *ppriv;
137         GtkWidget *combo_caption, *check_caption, *entry_caption = NULL;
138
139         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
140
141         /* Create widgets for incoming security */
142         ppriv->security_view = GTK_WIDGET (modest_serversecurity_combo_box_new ());
143         combo_caption = hildon_caption_new (size_group, _("mcen_li_emailsetup_secure_connection"),
144                                             ppriv->security_view, NULL, 
145                                             HILDON_CAPTION_OPTIONAL);
146
147         if (ppriv->full) {              
148                 ppriv->port_view = GTK_WIDGET (hildon_number_editor_new (PORT_MIN, PORT_MAX));
149                 entry_caption = hildon_caption_new (size_group, _("mcen_fi_emailsetup_port"), 
150                                                     ppriv->port_view, NULL, 
151                                                     HILDON_CAPTION_OPTIONAL);
152         }
153
154         ppriv->auth_view = gtk_check_button_new ();
155         check_caption = 
156                 hildon_caption_new (size_group, _("mcen_li_emailsetup_secure_authentication"),
157                                     ppriv->auth_view, NULL, HILDON_CAPTION_OPTIONAL);
158
159         /* Track changes in UI */       
160         g_signal_connect (G_OBJECT (ppriv->security_view), "changed",
161                           G_CALLBACK (on_security_changed), self);
162
163         /* Pack into container */
164         gtk_box_pack_start (GTK_BOX (self), combo_caption,
165                             FALSE, FALSE, MODEST_MARGIN_HALF);
166         if (ppriv->full)
167                 gtk_box_pack_start (GTK_BOX (self), entry_caption, 
168                                     FALSE, FALSE, MODEST_MARGIN_HALF);
169         gtk_box_pack_start (GTK_BOX (self), check_caption,
170                             FALSE, FALSE, MODEST_MARGIN_HALF);
171
172         /* Show widgets */
173         if (ppriv->full) {
174                 gtk_widget_show (ppriv->port_view);
175                 gtk_widget_show (entry_caption);
176         }
177         gtk_widget_show (ppriv->security_view);
178         gtk_widget_show (ppriv->auth_view);
179         gtk_widget_show (combo_caption);
180         gtk_widget_show (check_caption);
181 }
182
183 static void
184 on_entry_max (ModestValidatingEntry *self, 
185               gpointer user_data)
186 {
187         modest_platform_information_banner (GTK_WIDGET (self), NULL, 
188                                             _CS("ckdg_ib_maximum_characters_reached"));
189 }
190
191 /*
192  * TODO: call this whenever the auth combo changes. If we set it
193  * explicitely at the beggining to a value then there is no need to
194  * call this handler directly at the beginning
195  */
196 static void
197 on_entry_changed (GtkEditable *editable, 
198                   gpointer user_data)
199 {
200         ModestSecurityOptionsView* self;
201         ModestSecurityOptionsViewPrivate *ppriv;
202         ModestProtocolType auth_proto;
203         ModestSecureauthComboBox *combo;
204         gboolean is_secure, missing;
205         ModestProtocolRegistry *protocol_registry;
206
207         self = MODEST_SECURITY_OPTIONS_VIEW (user_data);
208         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
209         protocol_registry = modest_runtime_get_protocol_registry ();
210
211         /* Outgoing username is mandatory if outgoing auth is secure */
212         combo = MODEST_SECUREAUTH_COMBO_BOX (ppriv->auth_view);
213         auth_proto = modest_secureauth_combo_box_get_active_secureauth (combo);
214         is_secure = modest_protocol_registry_protocol_type_is_secure (protocol_registry, 
215                                                                       auth_proto);
216
217         if (is_secure && 
218             !g_ascii_strcasecmp (gtk_entry_get_text (GTK_ENTRY (ppriv->user_entry)), "")) {
219                 missing = TRUE;
220         } else {
221                 missing = FALSE;
222         }
223         
224         /* Emit a signal to notify if mandatory data is missing */
225         g_signal_emit_by_name (G_OBJECT (self), "missing_mandatory_data", 
226                                missing, NULL);
227 }
228
229 static void
230 create_outgoing_security (ModestSecurityOptionsView* self,
231                           GtkSizeGroup *size_group)
232 {
233         ModestSecurityOptionsViewPrivate *ppriv;
234         GtkWidget *sec_caption, *auth_caption, *user_caption = NULL;
235         GtkWidget *pwd_caption = NULL, *port_caption = NULL;
236
237         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
238         
239         /* The secure connection widgets */
240         ppriv->security_view = GTK_WIDGET (modest_serversecurity_combo_box_new ());
241         modest_serversecurity_combo_box_fill (MODEST_SERVERSECURITY_COMBO_BOX (ppriv->security_view), 
242                                               MODEST_PROTOCOLS_TRANSPORT_SMTP);
243         sec_caption = hildon_caption_new (size_group, _("mcen_li_emailsetup_secure_connection"),
244                                       ppriv->security_view, NULL, HILDON_CAPTION_OPTIONAL);
245         
246         /* The secure authentication widgets */
247         ppriv->auth_view = GTK_WIDGET (modest_secureauth_combo_box_new ());
248         auth_caption = hildon_caption_new (size_group, _("mcen_li_emailsetup_secure_authentication"),
249                                            ppriv->auth_view, NULL, HILDON_CAPTION_OPTIONAL);
250
251         if (ppriv->full) {
252                 gchar *user_label;
253
254                 /* Username widgets */
255                 ppriv->user_entry = GTK_WIDGET (modest_validating_entry_new ());
256
257                 /* Auto-capitalization is the default, so let's turn it off: */
258                 hildon_gtk_entry_set_input_mode (GTK_ENTRY (ppriv->user_entry), 
259                                                  HILDON_GTK_INPUT_MODE_FULL);
260
261                 user_label = g_strdup_printf("%s*", _("mail_fi_username"));
262                 user_caption = hildon_caption_new (size_group, user_label, 
263                                                    ppriv->user_entry, NULL, 
264                                                    HILDON_CAPTION_MANDATORY);
265                 g_free (user_label);
266         
267                 /* Prevent the use of some characters. Limit the max
268                    length as well */
269                 modest_validating_entry_set_unallowed_characters_whitespace (
270                      MODEST_VALIDATING_ENTRY (ppriv->user_entry));      
271                 gtk_entry_set_max_length (GTK_ENTRY (ppriv->user_entry), 64);
272                 modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (ppriv->user_entry),
273                                                       on_entry_max, self);
274                 
275                 /* Password widgets */
276                 ppriv->pwd_entry = gtk_entry_new ();
277
278                 /* Auto-capitalization is the default, so let's turn it off */
279                 hildon_gtk_entry_set_input_mode (GTK_ENTRY (ppriv->pwd_entry),
280                                                  HILDON_GTK_INPUT_MODE_FULL | 
281                                                  HILDON_GTK_INPUT_MODE_INVISIBLE);
282                 gtk_entry_set_visibility (GTK_ENTRY (ppriv->pwd_entry), FALSE);
283
284                 pwd_caption = hildon_caption_new (size_group, _("mail_fi_password"), 
285                                                   ppriv->pwd_entry, NULL, 
286                                                   HILDON_CAPTION_OPTIONAL);
287
288                 ppriv->port_view = GTK_WIDGET (hildon_number_editor_new (PORT_MIN, PORT_MAX));
289                 port_caption = hildon_caption_new (size_group, _("mcen_fi_emailsetup_port"), 
290                                                     ppriv->port_view, NULL, 
291                                                     HILDON_CAPTION_OPTIONAL);
292         }
293
294         /* Track changes in UI */       
295         g_signal_connect (G_OBJECT (ppriv->security_view), "changed",
296                           G_CALLBACK (on_security_changed), self);
297         if (ppriv->full) {
298                 g_signal_connect (G_OBJECT (ppriv->auth_view), "changed",
299                                   G_CALLBACK (on_auth_changed), self);
300                 g_signal_connect (G_OBJECT (ppriv->user_entry), "changed",
301                                   G_CALLBACK (on_entry_changed), self);
302         }
303
304         /* Initialize widgets */
305         modest_serversecurity_combo_box_set_active_serversecurity (
306                 MODEST_SERVERSECURITY_COMBO_BOX (ppriv->security_view), 
307                 MODEST_PROTOCOLS_CONNECTION_NONE);
308         modest_secureauth_combo_box_set_active_secureauth (
309            MODEST_SECUREAUTH_COMBO_BOX (ppriv->auth_view),
310            MODEST_PROTOCOLS_AUTH_NONE);
311
312         /* Pack into container */
313         if (ppriv->full) {
314                 gtk_box_pack_start (GTK_BOX (self), auth_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
315                 gtk_box_pack_start (GTK_BOX (self), user_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
316                 gtk_box_pack_start (GTK_BOX (self), pwd_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
317                 gtk_box_pack_start (GTK_BOX (self), sec_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
318                 gtk_box_pack_start (GTK_BOX (self), port_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
319         } else {
320                 /* The order is different */
321                 gtk_box_pack_start (GTK_BOX (self), sec_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
322                 gtk_box_pack_start (GTK_BOX (self), auth_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
323         }
324
325         /* Show widgets */
326         if (ppriv->full) {
327                 gtk_widget_show (ppriv->pwd_entry);
328                 gtk_widget_show (ppriv->user_entry);
329                 gtk_widget_show (ppriv->port_view);
330                 gtk_widget_show (pwd_caption);
331                 gtk_widget_show (user_caption);
332                 gtk_widget_show (port_caption);
333         }
334         gtk_widget_show (ppriv->security_view);
335         gtk_widget_show (ppriv->auth_view);
336         gtk_widget_show (sec_caption);
337         gtk_widget_show (auth_caption);
338 }
339
340 GtkWidget *    
341 modest_maemo_security_options_view_new  (ModestSecurityOptionsType type,
342                                          gboolean full,
343                                          GtkSizeGroup *size_group)
344 {
345         ModestSecurityOptionsView* self;
346         ModestSecurityOptionsViewPrivate *ppriv;
347
348         self = (ModestSecurityOptionsView *)
349                 g_object_new (MODEST_TYPE_MAEMO_SECURITY_OPTIONS_VIEW, NULL);
350         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
351
352         ppriv->full = full;
353         self->type = type;
354         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
355                 create_incoming_security (self, size_group);
356         else
357                 create_outgoing_security (self, size_group);
358
359         return (GtkWidget *) self;
360 }
361
362 static void 
363 modest_maemo_security_options_view_load_settings (ModestSecurityOptionsView* self, 
364                                                   ModestAccountSettings *settings)
365 {
366         ModestSecurityOptionsViewPrivate *ppriv;
367         ModestServerAccountSettings *server_settings;
368         gint port_number;
369
370         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
371
372         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
373                 server_settings = modest_account_settings_get_store_settings (settings);
374         else
375                 server_settings = modest_account_settings_get_transport_settings (settings);
376         port_number = modest_server_account_settings_get_port (server_settings);
377
378         if (port_number == 0) {
379                 /* Show the appropriate port number */
380                 on_security_changed (ppriv->security_view, 
381                                      MODEST_MAEMO_SECURITY_OPTIONS_VIEW (self));
382         } else if (ppriv->full) {
383                 /* Keep the user-entered port-number, or the
384                  * already-appropriate automatic port number */
385                 hildon_number_editor_set_value (HILDON_NUMBER_EDITOR (ppriv->port_view), 
386                                                 port_number);
387         }
388         /* Frees */
389         g_object_unref (server_settings);
390 }
391
392 static void
393 modest_maemo_security_options_view_save_settings (ModestSecurityOptionsView* self, 
394                                                   ModestAccountSettings *settings)
395 {
396         ModestServerAccountSettings *server_settings;
397         ModestSecurityOptionsViewPrivate *ppriv;
398         gint server_port;
399
400         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
401
402         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
403                 server_settings = modest_account_settings_get_store_settings (settings);
404         else
405                 server_settings = modest_account_settings_get_transport_settings (settings);
406
407         if (ppriv->full) {
408                 server_port = hildon_number_editor_get_value (HILDON_NUMBER_EDITOR (ppriv->port_view));
409         } else {
410                 server_port = modest_serversecurity_combo_box_get_active_serversecurity_port (MODEST_SERVERSECURITY_COMBO_BOX (ppriv->security_view));
411         }
412
413         modest_server_account_settings_set_port (server_settings, server_port);
414
415         /* Frees */
416         g_object_unref (server_settings);
417 }
418
419 static gboolean 
420 modest_maemo_security_options_view_changed (ModestSecurityOptionsView* self,
421                                             ModestAccountSettings *settings)
422 {
423         ModestServerAccountSettings *server_settings;
424         ModestSecurityOptionsViewPrivate *ppriv;
425         gint server_port;
426
427         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
428         
429         /* If we're not showing the port number then it never changes */
430         if (!ppriv->full)
431                 return FALSE;
432
433         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
434                 server_settings = modest_account_settings_get_store_settings (settings);
435         else
436                 server_settings = modest_account_settings_get_transport_settings (settings);
437         
438         server_port = 
439                 hildon_number_editor_get_value (HILDON_NUMBER_EDITOR (ppriv->port_view));
440
441         /* Frees */
442         g_object_unref (server_settings);
443
444         if (server_port != ppriv->initial_state.port)
445                 return TRUE;
446         else
447                 return FALSE;
448 }
449
450 static void
451 modest_maemo_security_options_view_init (ModestMaemoSecurityOptionsView *obj)
452 {
453 }
454
455 static void
456 modest_maemo_security_options_view_finalize (GObject *obj)
457 {
458         G_OBJECT_CLASS (modest_maemo_security_options_view_parent_class)->finalize (obj);
459 }
460
461
462 static void     
463 modest_maemo_security_options_view_class_init (ModestMaemoSecurityOptionsViewClass *klass)
464 {
465         GObjectClass *gobject_class = (GObjectClass*) klass;
466
467         modest_maemo_security_options_view_parent_class = g_type_class_peek_parent (klass);
468
469         gobject_class->finalize = modest_maemo_security_options_view_finalize;
470
471         MODEST_SECURITY_OPTIONS_VIEW_CLASS (klass)->load_settings = 
472                 modest_maemo_security_options_view_load_settings;
473         MODEST_SECURITY_OPTIONS_VIEW_CLASS (klass)->save_settings = 
474                 modest_maemo_security_options_view_save_settings;
475         MODEST_SECURITY_OPTIONS_VIEW_CLASS (klass)->changed = 
476                 modest_maemo_security_options_view_changed;
477 }