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