* Added new server security picker for hildon2, and replaced
[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 "modest-serversecurity-picker.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         ModestServersecurityPicker *picker;
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         picker = MODEST_SERVERSECURITY_PICKER (ppriv->security_view);
76         proto_type = modest_serversecurity_picker_get_active_serversecurity (picker);
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_picker_get_active_serversecurity_port (MODEST_SERVERSECURITY_PICKER (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 *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_picker_new ());
143         hildon_button_set_title (HILDON_BUTTON (ppriv->security_view), _("mcen_li_emailsetup_secure_connection"));
144
145         if (ppriv->full) {              
146                 ppriv->port_view = GTK_WIDGET (hildon_number_editor_new (PORT_MIN, PORT_MAX));
147                 entry_caption = hildon_caption_new (size_group, _("mcen_fi_emailsetup_port"), 
148                                                     ppriv->port_view, NULL, 
149                                                     HILDON_CAPTION_OPTIONAL);
150         }
151
152         ppriv->auth_view = gtk_check_button_new ();
153         check_caption = 
154                 hildon_caption_new (size_group, _("mcen_li_emailsetup_secure_authentication"),
155                                     ppriv->auth_view, NULL, HILDON_CAPTION_OPTIONAL);
156
157         /* Track changes in UI */       
158         g_signal_connect (G_OBJECT (ppriv->security_view), "value-changed",
159                           G_CALLBACK (on_security_changed), self);
160
161         /* Pack into container */
162         gtk_box_pack_start (GTK_BOX (self), ppriv->security_view,
163                             FALSE, FALSE, MODEST_MARGIN_HALF);
164         if (ppriv->full)
165                 gtk_box_pack_start (GTK_BOX (self), entry_caption, 
166                                     FALSE, FALSE, MODEST_MARGIN_HALF);
167         gtk_box_pack_start (GTK_BOX (self), check_caption,
168                             FALSE, FALSE, MODEST_MARGIN_HALF);
169
170         /* Show widgets */
171         if (ppriv->full) {
172                 gtk_widget_show (ppriv->port_view);
173                 gtk_widget_show (entry_caption);
174         }
175         gtk_widget_show (ppriv->security_view);
176         gtk_widget_show (ppriv->auth_view);
177         gtk_widget_show (check_caption);
178 }
179
180 static void
181 on_entry_max (ModestValidatingEntry *self, 
182               gpointer user_data)
183 {
184         modest_platform_information_banner (GTK_WIDGET (self), NULL, 
185                                             _CS("ckdg_ib_maximum_characters_reached"));
186 }
187
188 /*
189  * TODO: call this whenever the auth combo changes. If we set it
190  * explicitely at the beggining to a value then there is no need to
191  * call this handler directly at the beginning
192  */
193 static void
194 on_entry_changed (GtkEditable *editable, 
195                   gpointer user_data)
196 {
197         ModestSecurityOptionsView* self;
198         ModestSecurityOptionsViewPrivate *ppriv;
199         ModestProtocolType auth_proto;
200         ModestSecureauthComboBox *combo;
201         gboolean is_secure, missing;
202         ModestProtocolRegistry *protocol_registry;
203
204         self = MODEST_SECURITY_OPTIONS_VIEW (user_data);
205         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
206         protocol_registry = modest_runtime_get_protocol_registry ();
207
208         /* Outgoing username is mandatory if outgoing auth is secure */
209         combo = MODEST_SECUREAUTH_COMBO_BOX (ppriv->auth_view);
210         auth_proto = modest_secureauth_combo_box_get_active_secureauth (combo);
211         is_secure = modest_protocol_registry_protocol_type_is_secure (protocol_registry, 
212                                                                       auth_proto);
213
214         if (is_secure && 
215             !g_ascii_strcasecmp (gtk_entry_get_text (GTK_ENTRY (ppriv->user_entry)), "")) {
216                 missing = TRUE;
217         } else {
218                 missing = FALSE;
219         }
220         
221         /* Emit a signal to notify if mandatory data is missing */
222         g_signal_emit_by_name (G_OBJECT (self), "missing_mandatory_data", 
223                                missing, NULL);
224 }
225
226 static void
227 create_outgoing_security (ModestSecurityOptionsView* self,
228                           GtkSizeGroup *size_group)
229 {
230         ModestSecurityOptionsViewPrivate *ppriv;
231         GtkWidget *auth_caption, *user_caption = NULL;
232         GtkWidget *pwd_caption = NULL, *port_caption = NULL;
233
234         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
235         
236         /* The secure connection widgets */
237         ppriv->security_view = GTK_WIDGET (modest_serversecurity_picker_new ());
238         modest_serversecurity_picker_fill (MODEST_SERVERSECURITY_PICKER (ppriv->security_view), 
239                                               MODEST_PROTOCOLS_TRANSPORT_SMTP);
240         hildon_button_set_title (HILDON_BUTTON (ppriv->security_view), _("mcen_li_emailsetup_secure_connection"));
241         
242         /* The secure authentication widgets */
243         ppriv->auth_view = GTK_WIDGET (modest_secureauth_combo_box_new ());
244         auth_caption = hildon_caption_new (size_group, _("mcen_li_emailsetup_secure_authentication"),
245                                            ppriv->auth_view, NULL, HILDON_CAPTION_OPTIONAL);
246
247         if (ppriv->full) {
248                 gchar *user_label;
249
250                 /* Username widgets */
251                 ppriv->user_entry = GTK_WIDGET (modest_validating_entry_new ());
252
253                 /* Auto-capitalization is the default, so let's turn it off: */
254                 hildon_gtk_entry_set_input_mode (GTK_ENTRY (ppriv->user_entry), 
255                                                  HILDON_GTK_INPUT_MODE_FULL);
256
257                 user_label = g_strdup_printf("%s*", _("mail_fi_username"));
258                 user_caption = hildon_caption_new (size_group, user_label, 
259                                                    ppriv->user_entry, NULL, 
260                                                    HILDON_CAPTION_MANDATORY);
261                 g_free (user_label);
262         
263                 /* Prevent the use of some characters. Limit the max
264                    length as well */
265                 modest_validating_entry_set_unallowed_characters_whitespace (
266                      MODEST_VALIDATING_ENTRY (ppriv->user_entry));      
267                 gtk_entry_set_max_length (GTK_ENTRY (ppriv->user_entry), 64);
268                 modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (ppriv->user_entry),
269                                                       on_entry_max, self);
270                 
271                 /* Password widgets */
272                 ppriv->pwd_entry = gtk_entry_new ();
273
274                 /* Auto-capitalization is the default, so let's turn it off */
275                 hildon_gtk_entry_set_input_mode (GTK_ENTRY (ppriv->pwd_entry),
276                                                  HILDON_GTK_INPUT_MODE_FULL | 
277                                                  HILDON_GTK_INPUT_MODE_INVISIBLE);
278                 gtk_entry_set_visibility (GTK_ENTRY (ppriv->pwd_entry), FALSE);
279
280                 pwd_caption = hildon_caption_new (size_group, _("mail_fi_password"), 
281                                                   ppriv->pwd_entry, NULL, 
282                                                   HILDON_CAPTION_OPTIONAL);
283
284                 ppriv->port_view = GTK_WIDGET (hildon_number_editor_new (PORT_MIN, PORT_MAX));
285                 port_caption = hildon_caption_new (size_group, _("mcen_fi_emailsetup_port"), 
286                                                     ppriv->port_view, NULL, 
287                                                     HILDON_CAPTION_OPTIONAL);
288         }
289
290         /* Track changes in UI */       
291         g_signal_connect (G_OBJECT (ppriv->security_view), "value-changed",
292                           G_CALLBACK (on_security_changed), self);
293         if (ppriv->full) {
294                 g_signal_connect (G_OBJECT (ppriv->auth_view), "changed",
295                                   G_CALLBACK (on_auth_changed), self);
296                 g_signal_connect (G_OBJECT (ppriv->user_entry), "changed",
297                                   G_CALLBACK (on_entry_changed), self);
298         }
299
300         /* Initialize widgets */
301         modest_serversecurity_picker_set_active_serversecurity (
302                 MODEST_SERVERSECURITY_PICKER (ppriv->security_view), 
303                 MODEST_PROTOCOLS_CONNECTION_NONE);
304         modest_secureauth_combo_box_set_active_secureauth (
305            MODEST_SECUREAUTH_COMBO_BOX (ppriv->auth_view),
306            MODEST_PROTOCOLS_AUTH_NONE);
307
308         /* Pack into container */
309         if (ppriv->full) {
310                 gtk_box_pack_start (GTK_BOX (self), auth_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
311                 gtk_box_pack_start (GTK_BOX (self), user_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
312                 gtk_box_pack_start (GTK_BOX (self), pwd_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
313                 gtk_box_pack_start (GTK_BOX (self), ppriv->security_view, FALSE, FALSE, MODEST_MARGIN_HALF);
314                 gtk_box_pack_start (GTK_BOX (self), port_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
315         } else {
316                 /* The order is different */
317                 gtk_box_pack_start (GTK_BOX (self), ppriv->security_view, FALSE, FALSE, MODEST_MARGIN_HALF);
318                 gtk_box_pack_start (GTK_BOX (self), auth_caption, FALSE, FALSE, MODEST_MARGIN_HALF);
319         }
320
321         /* Show widgets */
322         if (ppriv->full) {
323                 gtk_widget_show (ppriv->pwd_entry);
324                 gtk_widget_show (ppriv->user_entry);
325                 gtk_widget_show (ppriv->port_view);
326                 gtk_widget_show (pwd_caption);
327                 gtk_widget_show (user_caption);
328                 gtk_widget_show (port_caption);
329         }
330         gtk_widget_show (ppriv->security_view);
331         gtk_widget_show (ppriv->auth_view);
332         gtk_widget_show (auth_caption);
333 }
334
335 GtkWidget *    
336 modest_maemo_security_options_view_new  (ModestSecurityOptionsType type,
337                                          gboolean full,
338                                          GtkSizeGroup *size_group)
339 {
340         ModestSecurityOptionsView* self;
341         ModestSecurityOptionsViewPrivate *ppriv;
342
343         self = (ModestSecurityOptionsView *)
344                 g_object_new (MODEST_TYPE_MAEMO_SECURITY_OPTIONS_VIEW, NULL);
345         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
346
347         ppriv->full = full;
348         self->type = type;
349         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
350                 create_incoming_security (self, size_group);
351         else
352                 create_outgoing_security (self, size_group);
353
354         return (GtkWidget *) self;
355 }
356
357 static void 
358 modest_maemo_security_options_view_load_settings (ModestSecurityOptionsView* self, 
359                                                   ModestAccountSettings *settings)
360 {
361         ModestSecurityOptionsViewPrivate *ppriv;
362         ModestServerAccountSettings *server_settings;
363         gint port_number;
364
365         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
366
367         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
368                 server_settings = modest_account_settings_get_store_settings (settings);
369         else
370                 server_settings = modest_account_settings_get_transport_settings (settings);
371         port_number = modest_server_account_settings_get_port (server_settings);
372
373         if (port_number == 0) {
374                 /* Show the appropriate port number */
375                 on_security_changed (ppriv->security_view, 
376                                      MODEST_MAEMO_SECURITY_OPTIONS_VIEW (self));
377         } else if (ppriv->full) {
378                 /* Keep the user-entered port-number, or the
379                  * already-appropriate automatic port number */
380                 hildon_number_editor_set_value (HILDON_NUMBER_EDITOR (ppriv->port_view), 
381                                                 port_number);
382         }
383         /* Frees */
384         g_object_unref (server_settings);
385 }
386
387 static void
388 modest_maemo_security_options_view_save_settings (ModestSecurityOptionsView* self, 
389                                                   ModestAccountSettings *settings)
390 {
391         ModestServerAccountSettings *server_settings;
392         ModestSecurityOptionsViewPrivate *ppriv;
393         gint server_port;
394
395         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
396
397         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
398                 server_settings = modest_account_settings_get_store_settings (settings);
399         else
400                 server_settings = modest_account_settings_get_transport_settings (settings);
401
402         if (ppriv->full) {
403                 server_port = hildon_number_editor_get_value (HILDON_NUMBER_EDITOR (ppriv->port_view));
404         } else {
405                 server_port = modest_serversecurity_picker_get_active_serversecurity_port (MODEST_SERVERSECURITY_PICKER (ppriv->security_view));
406         }
407
408         modest_server_account_settings_set_port (server_settings, server_port);
409
410         /* Frees */
411         g_object_unref (server_settings);
412 }
413
414 static gboolean 
415 modest_maemo_security_options_view_changed (ModestSecurityOptionsView* self,
416                                             ModestAccountSettings *settings)
417 {
418         ModestServerAccountSettings *server_settings;
419         ModestSecurityOptionsViewPrivate *ppriv;
420         gint server_port;
421
422         ppriv = MODEST_SECURITY_OPTIONS_VIEW_GET_PRIVATE (self);
423         
424         /* If we're not showing the port number then it never changes */
425         if (!ppriv->full)
426                 return FALSE;
427
428         if (self->type == MODEST_SECURITY_OPTIONS_INCOMING)
429                 server_settings = modest_account_settings_get_store_settings (settings);
430         else
431                 server_settings = modest_account_settings_get_transport_settings (settings);
432         
433         server_port = 
434                 hildon_number_editor_get_value (HILDON_NUMBER_EDITOR (ppriv->port_view));
435
436         /* Frees */
437         g_object_unref (server_settings);
438
439         if (server_port != ppriv->initial_state.port)
440                 return TRUE;
441         else
442                 return FALSE;
443 }
444
445 static void
446 modest_maemo_security_options_view_init (ModestMaemoSecurityOptionsView *obj)
447 {
448 }
449
450 static void
451 modest_maemo_security_options_view_finalize (GObject *obj)
452 {
453         G_OBJECT_CLASS (modest_maemo_security_options_view_parent_class)->finalize (obj);
454 }
455
456
457 static void     
458 modest_maemo_security_options_view_class_init (ModestMaemoSecurityOptionsViewClass *klass)
459 {
460         GObjectClass *gobject_class = (GObjectClass*) klass;
461
462         modest_maemo_security_options_view_parent_class = g_type_class_peek_parent (klass);
463
464         gobject_class->finalize = modest_maemo_security_options_view_finalize;
465
466         MODEST_SECURITY_OPTIONS_VIEW_CLASS (klass)->load_settings = 
467                 modest_maemo_security_options_view_load_settings;
468         MODEST_SECURITY_OPTIONS_VIEW_CLASS (klass)->save_settings = 
469                 modest_maemo_security_options_view_save_settings;
470         MODEST_SECURITY_OPTIONS_VIEW_CLASS (klass)->changed = 
471                 modest_maemo_security_options_view_changed;
472 }