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