2203f972a2e9be4c511e1cf856c096c997d25694
[modest] / src / gnome / modest-default-account-settings-dialog.c
1 /* Copyright (c) 2006, 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
31 #include "widgets/modest-account-settings-dialog.h"
32 #include <glib/gi18n.h>
33 #include <gtk/gtknotebook.h>
34 #include <gtk/gtkvbox.h>
35 #include <gtk/gtklabel.h>
36 #include <gtk/gtkcombobox.h>
37 #include <gtk/gtkentry.h>
38 #include <gtk/gtkbutton.h>
39 #include <gtk/gtkcheckbutton.h>
40 #include <gtk/gtkmessagedialog.h>
41 #include <gtk/gtkstock.h>
42
43 #include "widgets/modest-serversecurity-combo-box.h"
44 #include "widgets/modest-secureauth-combo-box.h"
45 #include "widgets/modest-validating-entry.h"
46 #include "widgets/modest-retrieve-combo-box.h"
47 #include "widgets/modest-limit-retrieve-combo-box.h"
48 #include "modest-defs.h"
49 #include "modest-text-utils.h"
50 #include "modest-account-mgr.h"
51 #include "modest-account-mgr-helpers.h" /* For modest_account_mgr_get_account_data(). */
52 #include "modest-runtime.h" /* For modest_runtime_get_account_mgr(). */
53 #include "modest-protocol-registry.h"
54 #include <modest-utils.h>
55 #include <modest-platform.h>
56 #include "widgets/modest-ui-constants.h"
57 #include "widgets/modest-default-account-settings-dialog.h"
58 #include <tny-account.h>
59 #include <tny-status.h>
60
61 #include <gconf/gconf-client.h>
62 #include <string.h> /* For strlen(). */
63
64 /* Include config.h so that _() works: */
65 #ifdef HAVE_CONFIG_H
66 #include <config.h>
67 #endif
68
69 #define PORT_MIN 1
70 #define PORT_MAX 65535
71
72 static void modest_account_settings_dialog_init (gpointer g, gpointer iface_data);
73
74 G_DEFINE_TYPE_EXTENDED (ModestDefaultAccountSettingsDialog, 
75                         modest_default_account_settings_dialog, 
76                         GTK_TYPE_DIALOG,
77                         0, 
78                         G_IMPLEMENT_INTERFACE (MODEST_TYPE_ACCOUNT_SETTINGS_DIALOG, 
79                                                modest_account_settings_dialog_init));
80
81 #define MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE(o) \
82         (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
83                                       MODEST_TYPE_DEFAULT_ACCOUNT_SETTINGS_DIALOG, \
84                                       ModestDefaultAccountSettingsDialogPrivate))
85
86 typedef struct _ModestDefaultAccountSettingsDialogPrivate ModestDefaultAccountSettingsDialogPrivate;
87
88 struct _ModestDefaultAccountSettingsDialogPrivate
89 {
90         /* Used by derived widgets to query existing accounts,
91          * and to create new accounts: */
92         ModestAccountMgr *account_manager;
93         ModestAccountSettings *settings;
94         
95         gboolean modified;
96         gchar * account_name; /* This may not change. It is not user visible. */
97         ModestProtocolType incoming_protocol; /* This may not change. */
98         ModestProtocolType outgoing_protocol; /* This may not change. */
99         gchar * original_account_title;
100
101         ModestProtocolType protocol_authentication_incoming;
102         
103         GtkNotebook *notebook;
104         
105         GtkWidget *page_account_details;
106         GtkWidget *entry_account_title;
107         GtkWidget *combo_retrieve;
108         GtkWidget *combo_limit_retrieve;
109         GtkWidget *caption_leave_messages;
110         GtkWidget *checkbox_leave_messages;
111         
112         GtkWidget *page_user_details;
113         GtkWidget *entry_user_name;
114         GtkWidget *entry_user_username;
115         GtkWidget *entry_user_password;
116         GtkWidget *entry_user_email;
117         GtkWidget *entry_incoming_port;
118         GtkWidget *button_signature;
119         
120         GtkWidget *page_complete_easysetup;
121         
122         GtkWidget *page_incoming;
123         GtkWidget *caption_incoming;
124         GtkWidget *entry_incomingserver;
125         GtkWidget *combo_incoming_security;
126         GtkWidget *checkbox_incoming_auth;
127
128         GtkWidget *page_outgoing;
129         GtkWidget *entry_outgoingserver;
130         GtkWidget *caption_outgoing_username;
131         GtkWidget *entry_outgoing_username;
132         GtkWidget *caption_outgoing_password;
133         GtkWidget *entry_outgoing_password;
134         GtkWidget *combo_outgoing_security;
135         GtkWidget *combo_outgoing_auth;
136         GtkWidget *entry_outgoing_port;
137         GtkWidget *checkbox_outgoing_smtp_specific;
138         GtkWidget *button_outgoing_smtp_servers;
139         
140         GtkWidget *signature_dialog;
141 };
142
143 static void enable_buttons (ModestAccountSettingsDialog *self);
144 static gboolean save_configuration (ModestAccountSettingsDialog *dialog);
145 static void modest_default_account_settings_dialog_load_settings (ModestAccountSettingsDialog *dialog, 
146                                                                   ModestAccountSettings *settings);
147
148 static const gchar *
149 null_means_empty (const gchar * str)
150 {
151         return str ? str : "";
152 }
153
154
155 static void
156 modest_account_settings_dialog_get_property (GObject *object, guint property_id,
157                                                                                                                         GValue *value, GParamSpec *pspec)
158 {
159         switch (property_id) {
160         default:
161                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
162         }
163 }
164
165 static void
166 modest_account_settings_dialog_set_property (GObject *object, guint property_id,
167                                                                                                                         const GValue *value, GParamSpec *pspec)
168 {
169         switch (property_id) {
170         default:
171                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
172         }
173 }
174
175 static void
176 modest_account_settings_dialog_dispose (GObject *object)
177 {
178         if (G_OBJECT_CLASS (modest_default_account_settings_dialog_parent_class)->dispose)
179                 G_OBJECT_CLASS (modest_default_account_settings_dialog_parent_class)->dispose (object);
180 }
181
182 static void
183 modest_account_settings_dialog_finalize (GObject *object)
184 {
185         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (object);
186         ModestDefaultAccountSettingsDialogPrivate *priv;
187
188         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
189         
190         if (priv->account_name)
191                 g_free (priv->account_name);
192                 
193         if (priv->original_account_title)
194                 g_free (priv->original_account_title);
195                 
196         if (priv->account_manager)
197                 g_object_unref (G_OBJECT (priv->account_manager));
198                 
199         if (priv->signature_dialog)
200                 gtk_widget_destroy (priv->signature_dialog);
201
202         if (priv->settings) {
203                 g_object_unref (priv->settings);
204                 priv->settings = NULL;
205         }
206         
207         G_OBJECT_CLASS (modest_default_account_settings_dialog_parent_class)->finalize (object);
208 }
209
210 static void
211 on_combo_incoming_security_changed (GtkComboBox *widget, gpointer user_data);
212
213 static void
214 on_combo_outgoing_security_changed (GtkComboBox *widget, gpointer user_data);
215
216 static void
217 on_modified_combobox_changed (GtkComboBox *widget, gpointer user_data)
218 {
219         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
220         ModestDefaultAccountSettingsDialogPrivate *priv;
221
222         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
223         priv->modified = TRUE;
224 }
225
226 static void
227 on_modified_entry_changed (GtkEditable *editable, gpointer user_data)
228 {
229         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
230         ModestDefaultAccountSettingsDialogPrivate *priv;
231
232         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
233         priv->modified = TRUE;
234 }
235
236 static void
237 on_modified_checkbox_toggled (GtkToggleButton *togglebutton, gpointer user_data)
238 {
239         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
240         ModestDefaultAccountSettingsDialogPrivate *priv;
241
242         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
243         priv->modified = TRUE;
244 }
245
246 static void
247 on_modified_spin_button_changed (GtkSpinButton *spin_button, gpointer user_data)
248 {
249         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
250         ModestDefaultAccountSettingsDialogPrivate *priv;
251
252         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
253         gint value = gtk_spin_button_get_value_as_int (spin_button);
254
255         gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK, value > 0);
256         priv->modified = TRUE;
257 }
258
259 /* Set a modified boolean whenever the widget is changed, 
260  * so we can check for it later.
261  */
262 static void
263 connect_for_modified (ModestDefaultAccountSettingsDialog *self, 
264                       GtkWidget *widget)
265 {
266         if (GTK_SPIN_BUTTON (widget)) {
267                 g_signal_connect (G_OBJECT (widget), "value_changed",
268                         G_CALLBACK (on_modified_spin_button_changed), self);
269         }
270         else if (GTK_IS_ENTRY (widget)) {
271                 g_signal_connect (G_OBJECT (widget), "changed",
272                         G_CALLBACK (on_modified_entry_changed), self);
273         } else if (GTK_IS_COMBO_BOX (widget)) {
274                 g_signal_connect (G_OBJECT (widget), "changed",
275                         G_CALLBACK (on_modified_combobox_changed), self);       
276         } else if (GTK_IS_TOGGLE_BUTTON (widget)) {
277                 g_signal_connect (G_OBJECT (widget), "toggled",
278                         G_CALLBACK (on_modified_checkbox_toggled), self);
279         }
280 }
281
282 static void
283 on_field_entry_changed (GtkEditable *editable, gpointer user_data)
284 {
285         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
286         g_assert(self);
287         enable_buttons(self);
288 }
289
290 static void
291 on_field_combobox_changed (GtkComboBox *widget, gpointer user_data)
292 {
293         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
294         g_assert(self);
295         enable_buttons(self);
296 }
297
298 /** This is a convenience function to create a field containing a mandatory widget.
299  * When the widget is edited, the enable_buttons() vfunc will be called.
300  */
301 static GtkWidget* 
302 create_field(ModestDefaultAccountSettingsDialog *self,
303              GtkSizeGroup *group,
304              const gchar *value,
305              GtkWidget *control,
306              GtkWidget *icon,
307              gboolean mandatory)
308 {
309         GtkWidget *hbox;
310         gchar *title;
311         GtkWidget *label;
312
313         hbox = gtk_hbox_new (FALSE, 12);
314         if (mandatory)
315                 title = g_strdup_printf("%s*:", value);
316         else
317                 title = g_strdup_printf ("%s:", value);
318         label = gtk_label_new (title);
319         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
320         g_free (title);
321
322         gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
323         gtk_box_pack_start (GTK_BOX (hbox), control, TRUE, TRUE, 0);
324         gtk_size_group_add_widget (group, label);
325   
326         /* Connect to the appropriate changed signal for the widget, 
327          * so we can ask for the prev/next buttons to be enabled/disabled appropriately:
328          */
329         if (GTK_IS_ENTRY (control)) {
330                 g_signal_connect (G_OBJECT (control), "changed",
331                 G_CALLBACK (on_field_entry_changed), self);
332                 
333         }
334         else if (GTK_IS_COMBO_BOX (control)) {
335                 g_signal_connect (G_OBJECT (control), "changed",
336                 G_CALLBACK (on_field_combobox_changed), self);
337         }
338         gtk_widget_show_all (hbox);
339          
340         return hbox;
341 }
342
343 static void
344 on_entry_invalid_account_title_character (ModestValidatingEntry *self, const gchar* character, gpointer user_data)
345 {
346         gchar *tmp, *msg;
347                         
348         tmp = g_strndup (account_title_forbidden_chars, ACCOUNT_TITLE_FORBIDDEN_CHARS_LENGTH);
349         msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
350
351         modest_platform_information_banner (GTK_WIDGET (self), NULL, msg);
352
353         g_free (msg);
354         g_free (tmp);
355 }
356
357 static void
358 on_entry_invalid_fullname_character (ModestValidatingEntry *self, const gchar* character, gpointer user_data)
359 {
360         gchar *tmp, *msg;
361                         
362         tmp = g_strndup (user_name_forbidden_chars, USER_NAME_FORBIDDEN_CHARS_LENGTH);
363         msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
364
365         modest_platform_information_banner(GTK_WIDGET (self), NULL, msg);
366
367         g_free (msg);
368         g_free (tmp);
369 }
370
371
372 static void
373 on_entry_max (ModestValidatingEntry *self, gpointer user_data)
374 {
375         modest_platform_information_banner(GTK_WIDGET (self), NULL, 
376                                          _CS("ckdg_ib_maximum_characters_reached"));
377 }
378
379 static GtkWidget*
380 create_page_account_details (ModestDefaultAccountSettingsDialog *self)
381 {
382         GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
383         GtkWidget *alignment;   
384         GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
385         ModestDefaultAccountSettingsDialogPrivate *priv;
386
387         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
388
389         /* The description widgets: */  
390         priv->entry_account_title = GTK_WIDGET (modest_validating_entry_new ());
391         GtkWidget *field = create_field (self, sizegroup, _("mcen_fi_account_title"), 
392                 priv->entry_account_title, NULL, TRUE);
393         gtk_widget_show (priv->entry_account_title);
394         connect_for_modified (self, priv->entry_account_title);
395         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
396         gtk_widget_show (field);
397         
398         /* Prevent the use of some characters in the account title, 
399          * as required by our UI specification: */
400         GList *list_prevent = NULL;
401         list_prevent = g_list_append (list_prevent, "\\");
402         list_prevent = g_list_append (list_prevent, "/");
403         list_prevent = g_list_append (list_prevent, ":");
404         list_prevent = g_list_append (list_prevent, "*");
405         list_prevent = g_list_append (list_prevent, "?");
406         list_prevent = g_list_append (list_prevent, "\"");
407         list_prevent = g_list_append (list_prevent, "<"); 
408         list_prevent = g_list_append (list_prevent, ">"); 
409         list_prevent = g_list_append (list_prevent, "|");
410         list_prevent = g_list_append (list_prevent, "^");       
411         modest_validating_entry_set_unallowed_characters (
412                 MODEST_VALIDATING_ENTRY (priv->entry_account_title), list_prevent);
413         g_list_free (list_prevent);
414         modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_account_title),
415                                          on_entry_invalid_account_title_character, self);
416         
417         /* Set max length as in the UI spec:
418          * The UI spec seems to want us to show a dialog if we hit the maximum. */
419         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_account_title), 64);
420         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_account_title), 
421                 on_entry_max, self);
422         
423         /* The retrieve combobox: */
424         priv->combo_retrieve = GTK_WIDGET (modest_retrieve_combo_box_new ());
425         field = create_field (self, sizegroup, _("mcen_fi_advsetup_retrievetype"), 
426                               priv->combo_retrieve, NULL, TRUE);
427         gtk_widget_show (priv->combo_retrieve);
428         connect_for_modified (self, priv->combo_retrieve);
429         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
430         gtk_widget_show (field);
431         
432         /* The limit-retrieve combobox: */
433         priv->combo_limit_retrieve = GTK_WIDGET (modest_limit_retrieve_combo_box_new ());
434         field = create_field (self, sizegroup, _("mcen_fi_advsetup_limit_retrieve"), 
435                               priv->combo_limit_retrieve, NULL, TRUE);
436         gtk_widget_show (priv->combo_limit_retrieve);
437         connect_for_modified (self, priv->combo_limit_retrieve);
438         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
439         gtk_widget_show (field);
440
441         /* The leave-messages widgets: */
442         if(!priv->checkbox_leave_messages)
443                 priv->checkbox_leave_messages = gtk_check_button_new ();
444         if (!priv->caption_leave_messages) {
445                 priv->caption_leave_messages = create_field (self, sizegroup, _("mcen_fi_advsetup_leave_on_server"), 
446                                                              priv->checkbox_leave_messages, NULL, TRUE);
447         }
448                         
449         gtk_widget_show (priv->checkbox_leave_messages);
450         connect_for_modified (self, priv->checkbox_leave_messages);
451         gtk_box_pack_start (GTK_BOX (box), priv->caption_leave_messages, FALSE, FALSE, MODEST_MARGIN_HALF);
452         gtk_widget_show (priv->caption_leave_messages);
453         
454         gtk_widget_show (GTK_WIDGET (box));
455
456         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
457         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12);
458         gtk_container_add (GTK_CONTAINER (alignment), box);
459         gtk_widget_show (alignment);
460         
461         return GTK_WIDGET (alignment);
462 }
463
464 static gchar*
465 get_entered_account_title (ModestAccountSettingsDialog *dialog)
466 {
467         ModestDefaultAccountSettingsDialogPrivate *priv;
468
469         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (dialog);
470
471         const gchar* account_title = 
472                 gtk_entry_get_text (GTK_ENTRY (priv->entry_account_title));
473         if (!account_title || (strlen (account_title) == 0))
474                 return NULL;
475         else {
476                 /* Strip it of whitespace at the start and end: */
477                 gchar *result = g_strdup (account_title);
478                 result = g_strstrip (result);
479                 
480                 if (!result)
481                         return NULL;
482                         
483                 if (strlen (result) == 0) {
484                         g_free (result);
485                         return NULL;    
486                 }
487                 
488                 return result;
489         }
490 }
491
492
493 static void
494 on_button_signature (GtkButton *button, gpointer user_data)
495 {
496 /*      ModestAccountSettingsDialog * self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data); */
497         
498 /*      /\* Create the window, if necessary: *\/ */
499 /*      if (!(priv->signature_dialog)) { */
500 /*              priv->signature_dialog = GTK_WIDGET (modest_signature_editor_dialog_new ()); */
501         
502 /*              gboolean use_signature = modest_account_settings_get_use_signature (priv->settings); */
503 /*              const gchar *signature = modest_account_settings_get_signature(priv->settings); */
504 /*              gchar* account_title = get_entered_account_title (self); */
505 /*              modest_signature_editor_dialog_set_settings ( */
506 /*                      MODEST_SIGNATURE_EDITOR_DIALOG (priv->signature_dialog),  */
507 /*                      use_signature, signature, account_title); */
508
509 /*              g_free (account_title); */
510 /*              account_title = NULL; */
511 /*              signature = NULL; */
512 /*      } */
513
514 /*      /\* Show the window: *\/         */
515 /*      gtk_window_set_transient_for (GTK_WINDOW (priv->signature_dialog), GTK_WINDOW (self)); */
516 /*      gtk_window_set_modal (GTK_WINDOW (priv->signature_dialog), TRUE); */
517 /*     const gint response = gtk_dialog_run (GTK_DIALOG (priv->signature_dialog)); */
518 /*     gtk_widget_hide (priv->signature_dialog); */
519 /*     if (response != GTK_RESPONSE_OK) { */
520 /*      /\* Destroy the widget now, and its data: *\/ */
521 /*      gtk_widget_destroy (priv->signature_dialog); */
522 /*      priv->signature_dialog = NULL; */
523 /*     } */
524 /*     else { */
525 /*      /\* Mark modified, so we use the dialog's data later: *\/ */
526 /*      priv->modified = TRUE;   */
527 /*     } */
528 }
529
530 static GtkWidget*
531 create_page_user_details (ModestDefaultAccountSettingsDialog *self)
532 {
533         GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
534         GtkWidget *alignment;   
535         GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
536         ModestDefaultAccountSettingsDialogPrivate *priv;
537
538         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
539          
540         /* The name widgets: */
541         priv->entry_user_name = GTK_WIDGET (modest_validating_entry_new ());
542
543         /* Set max length as in the UI spec:
544          * The UI spec seems to want us to show a dialog if we hit the maximum. */
545         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_name), 64);
546         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_name), 
547                 on_entry_max, self);
548         GtkWidget *field = create_field (self, sizegroup, 
549                                          _("mcen_li_emailsetup_name"), priv->entry_user_name, NULL, FALSE);
550         gtk_widget_show (priv->entry_user_name);
551         connect_for_modified (self, priv->entry_user_name);
552         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
553         gtk_widget_show (field);
554
555
556         /* Prevent the use of some characters in the name, 
557          * as required by our UI specification: */
558         GList *list_prevent = NULL;
559         list_prevent = g_list_append (list_prevent, "<");
560         list_prevent = g_list_append (list_prevent, ">");
561         modest_validating_entry_set_unallowed_characters (
562                 MODEST_VALIDATING_ENTRY (priv->entry_user_name), list_prevent);
563         g_list_free (list_prevent);
564         modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_user_name),
565                                          on_entry_invalid_fullname_character, self);
566         
567         /* The username widgets: */     
568         priv->entry_user_username = GTK_WIDGET (modest_validating_entry_new ());
569         field = create_field (self, sizegroup, _("mail_fi_username"), 
570                                 priv->entry_user_username, NULL, TRUE);
571         gtk_widget_show (priv->entry_user_username);
572         connect_for_modified (self, priv->entry_user_username);
573         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
574         gtk_widget_show (field);
575         
576         /* Prevent the use of some characters in the username, 
577          * as required by our UI specification: */
578         modest_validating_entry_set_unallowed_characters_whitespace (
579                 MODEST_VALIDATING_ENTRY (priv->entry_user_username));
580         
581         /* Set max length as in the UI spec:
582          * The UI spec seems to want us to show a dialog if we hit the maximum. */
583         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_username), 64);
584         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_username), 
585                 on_entry_max, self);
586         
587         /* The password widgets: */     
588         priv->entry_user_password = gtk_entry_new ();
589         gtk_entry_set_visibility (GTK_ENTRY (priv->entry_user_password), FALSE);
590         /* gtk_entry_set_invisible_char (GTK_ENTRY (priv->entry_user_password), '*'); */
591         field = create_field (self, sizegroup, 
592                               _("mail_fi_password"), priv->entry_user_password, NULL, FALSE);
593         gtk_widget_show (priv->entry_user_password);
594         connect_for_modified (self, priv->entry_user_password);
595         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
596         gtk_widget_show (field);
597         
598         /* The email address widgets: */        
599         priv->entry_user_email = GTK_WIDGET (modest_validating_entry_new ());
600         field = create_field (self, sizegroup, 
601                               _("mcen_li_emailsetup_email_address"), priv->entry_user_email, NULL, TRUE);
602         gtk_entry_set_text (GTK_ENTRY (priv->entry_user_email), MODEST_EXAMPLE_EMAIL_ADDRESS); /* Default text. */
603         gtk_widget_show (priv->entry_user_email);
604         connect_for_modified (self, priv->entry_user_email);
605         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
606         gtk_widget_show (field);
607         
608         /* Set max length as in the UI spec:
609          * The UI spec seems to want us to show a dialog if we hit the maximum. */
610         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_email), 64);
611         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_email), 
612                 on_entry_max, self);
613         
614         /* Signature button: */
615         if (!priv->button_signature)
616                 priv->button_signature = gtk_button_new_with_label (_("mcen_bd_edit"));
617         field = create_field (self, sizegroup, _("mcen_fi_email_signature"), 
618                 priv->button_signature, NULL, FALSE);
619         gtk_widget_show (priv->button_signature);
620         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
621         gtk_widget_show (field);
622                 
623         g_signal_connect (G_OBJECT (priv->button_signature), "clicked",
624                 G_CALLBACK (on_button_signature), self);
625                 
626         gtk_widget_show (GTK_WIDGET (box));
627
628         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
629         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12);
630         gtk_container_add (GTK_CONTAINER (alignment), box);
631         gtk_widget_show (alignment);
632         
633         return GTK_WIDGET (alignment);
634 }
635
636 /** Change the field title for the incoming server, 
637  * as specified in the UI spec:
638  */
639 static void 
640 update_incoming_server_title (ModestAccountSettingsDialog *self, 
641                               ModestProtocolType protocol)
642 {
643         ModestDefaultAccountSettingsDialogPrivate *priv;
644
645         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
646
647         const gchar* type = 
648                 (protocol == MODEST_PROTOCOLS_STORE_POP ? 
649                         _("mail_fi_emailtype_pop3") : 
650                         _("mail_fi_emailtype_imap") );
651                         
652                 
653         /* Note that this produces a compiler warning, 
654          * because the compiler does not know that the translated string will have a %s in it.
655          * I do not see a way to avoid the warning while still using these Logical IDs. murrayc. */
656         gchar* incomingserver_title = g_strdup_printf(_("mcen_li_emailsetup_servertype"), type);
657         
658         /* This is a mandatory field, so add a *. This is usually done by 
659          * create_field() but we can't use that here. */
660         gchar *with_asterisk = g_strconcat (incomingserver_title, "*", NULL);
661         g_free (incomingserver_title);
662         
663         g_object_set (G_OBJECT (priv->caption_incoming), "label", with_asterisk, NULL);
664         g_free(with_asterisk);
665 }
666
667 /** Change the field title for the incoming server, 
668  * as specified in the UI spec:
669  */
670 static void 
671 update_incoming_server_security_choices (ModestAccountSettingsDialog *self, 
672                                          ModestProtocolType protocol)
673 {
674         ModestDefaultAccountSettingsDialogPrivate *priv;
675
676         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
677
678         /* Fill the combo with appropriately titled choices for POP or IMAP. */
679         /* The choices are the same, but the titles are different, as in the UI spec. */
680         modest_serversecurity_combo_box_fill (
681                 MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_incoming_security), protocol);
682 }
683            
684 static GtkWidget* 
685 create_page_incoming (ModestDefaultAccountSettingsDialog *self)
686 {
687         GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
688         GtkWidget *alignment;
689         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
690         ModestDefaultAccountSettingsDialogPrivate *priv;
691
692         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
693          
694         /* The incoming server widgets: */
695         if(!priv->entry_incomingserver)
696                 priv->entry_incomingserver = gtk_entry_new ();
697
698         if (priv->caption_incoming)
699           gtk_widget_destroy (priv->caption_incoming);
700            
701         /* The field title will be updated in update_incoming_server_title().
702          * so this default text will never be seen: */
703         /* (Note: Changing the title seems pointless. murrayc) */
704         priv->caption_incoming = create_field (self, sizegroup, 
705                                              "Incoming Server", priv->entry_incomingserver, NULL, TRUE);
706         gtk_widget_show (priv->entry_incomingserver);
707         connect_for_modified (self, priv->entry_incomingserver);
708         gtk_box_pack_start (GTK_BOX (box), priv->caption_incoming, FALSE, FALSE, MODEST_MARGIN_HALF);
709         gtk_widget_show (priv->caption_incoming);
710         
711         /* The secure connection widgets: */
712         /* This will be filled by update_incoming_server_security_choices(). */
713         if (!priv->combo_incoming_security)
714                 priv->combo_incoming_security = GTK_WIDGET (modest_serversecurity_combo_box_new ());
715         GtkWidget *field = create_field (self, sizegroup, _("mcen_li_emailsetup_secure_connection"), 
716                                          priv->combo_incoming_security, NULL, FALSE);
717         gtk_widget_show (priv->combo_incoming_security);
718         connect_for_modified (self, priv->combo_incoming_security);
719         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
720         gtk_widget_show (field);
721         
722         /* Show a default port number when the security method changes, as per the UI spec: */
723         g_signal_connect (G_OBJECT (priv->combo_incoming_security), "changed", (GCallback)on_combo_incoming_security_changed, self);
724         
725         
726         /* The port widgets: */
727         if (!priv->entry_incoming_port)
728                 priv->entry_incoming_port = GTK_WIDGET (gtk_spin_button_new_with_range ((gdouble) PORT_MIN, (gdouble) PORT_MAX, 1.0));
729         field = create_field (self, sizegroup, _("mcen_fi_emailsetup_port"), 
730                 priv->entry_incoming_port, NULL, FALSE);
731         gtk_widget_show (priv->entry_incoming_port);
732         connect_for_modified (self, priv->entry_incoming_port);
733         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
734         gtk_widget_show (field);
735         
736         /* The secure authentication widgets: */
737         if(!priv->checkbox_incoming_auth)
738                 priv->checkbox_incoming_auth = gtk_check_button_new ();
739         field = create_field (self, sizegroup, _("mcen_li_emailsetup_secure_authentication"), 
740                               priv->checkbox_incoming_auth, NULL, FALSE);
741         gtk_widget_show (priv->checkbox_incoming_auth);
742         connect_for_modified (self, priv->checkbox_incoming_auth);
743         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
744         gtk_widget_show (field);
745         
746         gtk_widget_show (GTK_WIDGET (box));
747         
748         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
749         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12);
750         gtk_container_add (GTK_CONTAINER (alignment), box);
751         gtk_widget_show (alignment);
752         
753         return GTK_WIDGET (alignment);
754 }
755
756 static void
757 on_toggle_button_changed (GtkToggleButton *togglebutton, gpointer user_data)
758 {
759         GtkWidget *widget = GTK_WIDGET (user_data);
760         
761         /* Enable the widget only if the toggle button is active: */
762         const gboolean enable = gtk_toggle_button_get_active (togglebutton);
763         gtk_widget_set_sensitive (widget, enable);
764 }
765
766 /* Make the sensitivity of a widget depend on a toggle button.
767  */
768 static void
769 enable_widget_for_togglebutton (GtkWidget *widget, GtkToggleButton* button)
770 {
771         g_signal_connect (G_OBJECT (button), "toggled",
772                 G_CALLBACK (on_toggle_button_changed), widget);
773         
774         /* Set the starting sensitivity: */
775         on_toggle_button_changed (button, widget);
776 }
777
778 static void
779 on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data)
780 {
781 /*      ModestAccountSettingsDialog * self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data); */
782         
783 /*      /\* Create the window if necessary: *\/ */
784 /*      if (!(priv->specific_window)) { */
785 /*              priv->specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ()); */
786 /*              modest_connection_specific_smtp_window_fill_with_connections ( */
787 /*                      MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (priv->specific_window), priv->account_manager); */
788 /*      } */
789
790 /*      /\* Show the window: *\/         */
791 /*      gtk_window_set_transient_for (GTK_WINDOW (priv->specific_window), GTK_WINDOW (self)); */
792 /*      gtk_window_set_modal (GTK_WINDOW (priv->specific_window), TRUE); */
793 /*      gtk_widget_show (priv->specific_window); */
794 /*      priv->modified = TRUE; */
795 }
796
797 static void
798 on_combo_outgoing_auth_changed (GtkComboBox *widget, gpointer user_data)
799 {
800         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
801         ModestDefaultAccountSettingsDialogPrivate *priv;
802
803         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
804         
805         ModestProtocolType protocol_security = 
806                 modest_secureauth_combo_box_get_active_secureauth (
807                         MODEST_SECUREAUTH_COMBO_BOX (priv->combo_outgoing_auth));
808         const gboolean secureauth_used = protocol_security != MODEST_PROTOCOLS_AUTH_NONE;
809         
810         gtk_widget_set_sensitive (priv->caption_outgoing_username, secureauth_used);
811         gtk_widget_set_sensitive (priv->caption_outgoing_password, secureauth_used);
812 }
813
814 static void
815 on_combo_outgoing_security_changed (GtkComboBox *widget, gpointer user_data)
816 {
817         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
818         ModestDefaultAccountSettingsDialogPrivate *priv;
819
820         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
821         
822         const gint port_number = 
823                 modest_serversecurity_combo_box_get_active_serversecurity_port (
824                         MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security));
825
826         if(port_number != 0) {
827                 gtk_spin_button_set_value (
828                         GTK_SPIN_BUTTON (priv->entry_outgoing_port), (gdouble) port_number);
829         }               
830 }
831
832 static void
833 on_combo_incoming_security_changed (GtkComboBox *widget, gpointer user_data)
834 {
835         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
836         ModestDefaultAccountSettingsDialogPrivate *priv;
837
838         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
839
840         const gint port_number = 
841                 modest_serversecurity_combo_box_get_active_serversecurity_port (
842                         MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_incoming_security));
843
844         if(port_number != 0) {
845                 gtk_spin_button_set_value (
846                         GTK_SPIN_BUTTON (priv->entry_incoming_port), (gdouble) port_number);
847         }               
848 }
849
850
851 static GtkWidget* 
852 create_page_outgoing (ModestDefaultAccountSettingsDialog *self)
853 {
854         GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
855         GtkWidget *alignment;
856         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
857
858         ModestDefaultAccountSettingsDialogPrivate *priv;
859
860         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
861          
862         /* The outgoing server widgets: */
863         if (!priv->entry_outgoingserver)
864                 priv->entry_outgoingserver = gtk_entry_new ();
865         GtkWidget *field = create_field (self, sizegroup, 
866                                          _("mcen_li_emailsetup_smtp"), priv->entry_outgoingserver, NULL, FALSE);
867         gtk_widget_show (priv->entry_outgoingserver);
868         connect_for_modified (self, priv->entry_outgoingserver);
869         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
870         gtk_widget_show (field);
871         
872         /* The secure authentication widgets: */
873         if (!priv->combo_outgoing_auth)
874                 priv->combo_outgoing_auth = GTK_WIDGET (modest_secureauth_combo_box_new ());
875         field = create_field (self, sizegroup, _("mcen_li_emailsetup_secure_authentication"), 
876                 priv->combo_outgoing_auth, NULL, FALSE);
877         gtk_widget_show (priv->combo_outgoing_auth);
878         connect_for_modified (self, priv->combo_outgoing_auth);
879         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
880         gtk_widget_show (field);
881         
882         /* Dim the outgoing username and password when no secure authentication is used, as per the UI spec: */
883         g_signal_connect (G_OBJECT (priv->combo_outgoing_auth), "changed", (GCallback)on_combo_outgoing_auth_changed, self);
884         
885         /* The username widgets: */     
886         priv->entry_outgoing_username = GTK_WIDGET (modest_validating_entry_new ());
887         priv->caption_outgoing_username = create_field (self, sizegroup, _("mail_fi_username"), 
888                                                       priv->entry_outgoing_username, NULL, TRUE);
889         gtk_widget_show (priv->entry_outgoing_username);
890         connect_for_modified (self, priv->entry_outgoing_username);
891         gtk_box_pack_start (GTK_BOX (box), priv->caption_outgoing_username, FALSE, FALSE, MODEST_MARGIN_HALF);
892         gtk_widget_show (priv->caption_outgoing_username);
893         
894         /* Prevent the use of some characters in the username, 
895          * as required by our UI specification: */
896         modest_validating_entry_set_unallowed_characters_whitespace (
897                 MODEST_VALIDATING_ENTRY (priv->entry_outgoing_username));
898         
899         /* Set max length as in the UI spec:
900          * The UI spec seems to want us to show a dialog if we hit the maximum. */
901         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_outgoing_username), 64);
902         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_outgoing_username), 
903                 on_entry_max, self);
904                 
905         /* The password widgets: */     
906         priv->entry_outgoing_password = gtk_entry_new ();
907         gtk_entry_set_visibility (GTK_ENTRY (priv->entry_outgoing_password), FALSE);
908         /* gtk_entry_set_invisible_char (GTK_ENTRY (priv->entry_outgoing_password), '*'); */
909         priv->caption_outgoing_password = create_field (self, sizegroup, 
910                                                       _("mail_fi_password"), priv->entry_outgoing_password, NULL, FALSE);
911         gtk_widget_show (priv->entry_outgoing_password);
912         connect_for_modified (self, priv->entry_outgoing_password);
913         gtk_box_pack_start (GTK_BOX (box), priv->caption_outgoing_password, FALSE, FALSE, MODEST_MARGIN_HALF);
914         gtk_widget_show (priv->caption_outgoing_password);
915         
916         /* The secure connection widgets: */
917         /* This will be filled and set with modest_serversecurity_combo_box_fill() 
918          * and modest_serversecurity_combo_box_set_active_serversecurity().
919          */
920         if (!priv->combo_outgoing_security)
921                 
922                 priv->combo_outgoing_security = GTK_WIDGET (modest_serversecurity_combo_box_new ());
923         field = create_field (self, sizegroup, _("mcen_li_emailsetup_secure_connection"), 
924                               priv->combo_outgoing_security, NULL, FALSE);
925         gtk_widget_show (priv->combo_outgoing_security);
926         connect_for_modified (self, priv->combo_outgoing_security);
927         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
928         gtk_widget_show (field);
929         
930         /* Show a default port number when the security method changes, as per the UI spec: */
931         g_signal_connect (G_OBJECT (priv->combo_outgoing_security), "changed", (GCallback)on_combo_outgoing_security_changed, self);
932         
933         /* The port widgets: */
934         if (!priv->entry_outgoing_port)
935                 priv->entry_outgoing_port = GTK_WIDGET (gtk_spin_button_new_with_range ((gdouble)PORT_MIN, (gdouble) PORT_MAX, 1.0));
936         field = create_field (self, sizegroup, _("mcen_fi_emailsetup_port"), 
937                               priv->entry_outgoing_port, NULL, FALSE);
938         gtk_widget_show (priv->entry_outgoing_port);
939         connect_for_modified (self, priv->entry_outgoing_port);
940         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
941         gtk_widget_show (field);
942         
943         GtkWidget *separator = gtk_hseparator_new ();
944         gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, MODEST_MARGIN_HALF);
945         gtk_widget_show (separator);
946         
947         /* connection-specific checkbox: */
948         if (!priv->checkbox_outgoing_smtp_specific) {
949                 priv->checkbox_outgoing_smtp_specific = gtk_check_button_new ();
950                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox_outgoing_smtp_specific), 
951                         FALSE);
952         }
953         field = create_field (self, sizegroup, _("mcen_fi_advsetup_connection_smtp"), 
954                               priv->checkbox_outgoing_smtp_specific, NULL, FALSE);
955         gtk_widget_show (priv->checkbox_outgoing_smtp_specific);
956         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
957         gtk_widget_show (field);
958         connect_for_modified (self, priv->checkbox_outgoing_smtp_specific);
959         
960         /* Connection-specific SMTP-Severs Edit button: */
961         if (!priv->button_outgoing_smtp_servers)
962                 priv->button_outgoing_smtp_servers = gtk_button_new_with_label (_("mcen_bd_edit"));
963         field = create_field (self, sizegroup, _("mcen_fi_advsetup_optional_smtp"), 
964                               priv->button_outgoing_smtp_servers, NULL, FALSE);
965         gtk_widget_show (priv->button_outgoing_smtp_servers);
966         gtk_box_pack_start (GTK_BOX (box), field, FALSE, FALSE, MODEST_MARGIN_HALF);
967         gtk_widget_show (field);
968         
969         /* Only enable the button when the checkbox is checked: */
970         enable_widget_for_togglebutton (priv->button_outgoing_smtp_servers, 
971                 GTK_TOGGLE_BUTTON (priv->checkbox_outgoing_smtp_specific));
972                 
973         g_signal_connect (G_OBJECT (priv->button_outgoing_smtp_servers), "clicked",
974                 G_CALLBACK (on_button_outgoing_smtp_servers), self);
975                 
976         gtk_widget_show (GTK_WIDGET (box));
977         
978         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
979         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12);
980         gtk_container_add (GTK_CONTAINER (alignment), box);
981         gtk_widget_show (alignment);
982         
983         return GTK_WIDGET (alignment);
984 }
985         
986 static gboolean
987 check_data (ModestAccountSettingsDialog *self)
988 {
989         ModestDefaultAccountSettingsDialogPrivate *priv;
990
991         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
992
993         /* Check that the title is not already in use: */
994         gchar* account_title = get_entered_account_title (self);
995         if (!account_title)
996                 return FALSE; /* Should be prevented already anyway. */
997                 
998         if (strcmp(account_title, priv->original_account_title) != 0) {
999                 /* Check the changed title: */
1000                 const gboolean name_in_use  = modest_account_mgr_account_with_display_name_exists (priv->account_manager,
1001                         account_title);
1002         
1003                 if (name_in_use) {
1004                         /* Warn the user via a dialog: */
1005                         modest_platform_information_banner(NULL, NULL, _("mail_ib_account_name_already_existing"));
1006                 
1007                 g_free (account_title);
1008                         return FALSE;
1009                 }
1010         }
1011         
1012         g_free (account_title);
1013         account_title  = NULL;
1014
1015         /* Check that the email address is valid: */
1016         const gchar* email_address = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_email));
1017         if ((!email_address) || (strlen(email_address) == 0)) {
1018                 return FALSE;
1019         }
1020                         
1021         if (!modest_text_utils_validate_email_address (email_address, NULL)) {
1022                 /* Warn the user via a dialog: */
1023                 modest_platform_information_banner (NULL, NULL, _("mcen_ib_invalid_email"));
1024                                          
1025                 /* Return focus to the email address entry: */
1026                 gtk_widget_grab_focus (priv->entry_user_email);
1027                 gtk_editable_select_region (GTK_EDITABLE (priv->entry_user_email), 0, -1);
1028                 return FALSE;
1029         }
1030
1031         /* make sure the domain name for the incoming server is valid */
1032         const gchar* hostname = gtk_entry_get_text (GTK_ENTRY (priv->entry_incomingserver));
1033         if ((!hostname) || (strlen(hostname) == 0)) {
1034                 return FALSE;
1035         }
1036         
1037         if (!modest_text_utils_validate_domain_name (hostname)) {
1038                 /* Warn the user via a dialog: */
1039                 modest_platform_information_banner (NULL, NULL, _("mcen_ib_invalid_servername"));
1040                                          
1041                 /* Return focus to the email address entry: */
1042                 gtk_widget_grab_focus (priv->entry_incomingserver);
1043                 gtk_editable_select_region (GTK_EDITABLE (priv->entry_incomingserver), 0, -1);
1044                 return FALSE;
1045         }
1046
1047         /* make sure the domain name for the outgoing server is valid */
1048         const gchar* hostname2 = gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoingserver));
1049         if ((!hostname2) || (strlen(hostname2) == 0)) {
1050                 return FALSE;
1051         }
1052         
1053         if (!modest_text_utils_validate_domain_name (hostname2)) {
1054                 /* Warn the user via a dialog: */
1055                 modest_platform_information_banner (priv->entry_outgoingserver, NULL, _("mcen_ib_invalid_servername"));
1056
1057                 /* Return focus to the email address entry: */
1058                 gtk_widget_grab_focus (priv->entry_outgoingserver);
1059                 gtk_editable_select_region (GTK_EDITABLE (priv->entry_outgoingserver), 0, -1);
1060                 return FALSE;
1061         }
1062         
1063         /* Find a suitable authentication method when secure authentication is desired */
1064
1065         const gint port_num = gtk_spin_button_get_value_as_int (
1066                         GTK_SPIN_BUTTON (priv->entry_incoming_port));
1067         const gchar* username = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_username));
1068
1069         /*
1070         const ModestProtocolType protocol_security_incoming = modest_serversecurity_combo_box_get_active_serversecurity (
1071                 MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_incoming_security));
1072         */
1073         /* If we use an encrypted protocol then there is no need to encrypt the password */
1074         /* I don't think this is a good assumption. It overrides the user's request. murrayc: 
1075          *  if (!modest_protocol_info_is_secure(protocol_security_incoming)) */
1076         if (TRUE)
1077         {
1078                 if (gtk_toggle_button_get_active (
1079                                 GTK_TOGGLE_BUTTON (priv->checkbox_incoming_auth))) {
1080                         GError *error = NULL;
1081
1082                         GList *list_auth_methods = 
1083                                 modest_utils_get_supported_secure_authentication_methods (priv->incoming_protocol, 
1084                                         hostname, port_num, username, GTK_WINDOW (self), &error);
1085                         if (list_auth_methods) {
1086                                 /* Use the first supported method.
1087                                  * TODO: Should we prioritize them, to prefer a particular one? */
1088                                 GList* method;
1089                                 for (method = list_auth_methods; method != NULL; method = g_list_next(method))
1090                                 {
1091                                         ModestProtocolType proto = (ModestProtocolType)(GPOINTER_TO_INT(method->data));
1092                                         // Allow secure methods, e.g MD5 only
1093                                         if (modest_protocol_registry_protocol_type_is_secure (modest_runtime_get_protocol_registry (), proto))
1094                                         {
1095                                                 priv->protocol_authentication_incoming = proto;
1096                                                 break;
1097                                         }
1098                                 }
1099                                 g_list_free (list_auth_methods);
1100                         }
1101
1102                         if (list_auth_methods == NULL || 
1103                             !modest_protocol_registry_protocol_type_is_secure (modest_runtime_get_protocol_registry (),
1104                                                                                priv->protocol_authentication_incoming)) {
1105                                 if(error == NULL || error->domain != modest_utils_get_supported_secure_authentication_error_quark() ||
1106                                                 error->code != MODEST_UTILS_GET_SUPPORTED_SECURE_AUTHENTICATION_ERROR_CANCELED)
1107                                         modest_platform_information_banner(GTK_WIDGET (self), NULL, 
1108                                                                          _("Could not discover supported secure authentication methods."));
1109
1110                                 if(error != NULL)
1111                                         g_error_free(error);
1112                                         
1113                                 /* This is a nasty hack. jschmid. */
1114                                 /* Don't let the dialog close */
1115                                 /*g_signal_stop_emission_by_name (dialog, "response");*/
1116                                 return FALSE;
1117                         }
1118                 }
1119         }
1120         
1121         return TRUE;
1122 }
1123 /*
1124  */
1125 static void 
1126 on_response (GtkDialog *wizard_dialog,
1127         gint response_id,
1128         gpointer user_data)
1129 {
1130         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (wizard_dialog);
1131         ModestDefaultAccountSettingsDialogPrivate *priv;
1132
1133         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
1134
1135         enable_buttons (self);
1136         
1137         gboolean prevent_response = FALSE;
1138
1139         /* Warn about unsaved changes: */
1140         if (response_id == GTK_RESPONSE_CANCEL && priv->modified) {
1141                 GtkDialog *dialog = GTK_DIALOG (modest_platform_run_confirmation_dialog (GTK_WINDOW (self), 
1142                                                                                          _("imum_nc_wizard_confirm_lose_changes")));
1143                 /* TODO: These button names will be ambiguous, and not specified in the UI specification. */
1144                 
1145                 const gint dialog_response = gtk_dialog_run (dialog);
1146                 gtk_widget_destroy (GTK_WIDGET (dialog));
1147                 
1148                 if (dialog_response != GTK_RESPONSE_OK)
1149                         prevent_response = TRUE;
1150         }
1151         /* Check for invalid input: */
1152         else if (response_id != GTK_RESPONSE_CANCEL && !check_data (self)) {
1153                 prevent_response = TRUE;
1154         }
1155                 
1156         if (prevent_response) {
1157                 /* This is a nasty hack. murrayc. */
1158                 /* Don't let the dialog close */
1159                 g_signal_stop_emission_by_name (wizard_dialog, "response");
1160                 return; 
1161         }
1162                 
1163         if (response_id == GTK_RESPONSE_OK) {
1164                 /* Try to save the changes if modified (NB #59251): */
1165                 if (priv->modified)
1166                 {
1167                         const gboolean saved = save_configuration (self);
1168                         if (saved) {
1169                                 /* Do not show the account-saved dialog if we are just saving this 
1170                                  * temporarily, because from the user's point of view it will not 
1171                                  * really be saved (saved + enabled) until later
1172                                  */
1173                                 if (modest_account_settings_get_account_name (priv->settings) != NULL) {
1174                                         ModestServerAccountSettings *store_settings;
1175                                         ModestServerAccountSettings *transport_settings;
1176                                         const gchar *store_account_name;
1177                                         const gchar *transport_account_name;
1178
1179
1180                                         store_settings = modest_account_settings_get_store_settings (priv->settings);
1181                                         transport_settings = modest_account_settings_get_transport_settings (priv->settings);
1182                                         store_account_name = modest_server_account_settings_get_account_name (store_settings);
1183                                         transport_account_name = modest_server_account_settings_get_account_name (transport_settings);
1184                                         
1185                                         if (store_account_name) {
1186                                                 modest_account_mgr_notify_account_update (priv->account_manager, 
1187                                                                                           store_account_name);
1188                                         }
1189                                         if (transport_account_name) {
1190                                                 modest_account_mgr_notify_account_update (priv->account_manager, 
1191                                                                                           transport_account_name);
1192                                         }
1193                                         g_object_unref (store_settings);
1194                                         g_object_unref (transport_settings);
1195
1196                                         modest_platform_information_banner(NULL, NULL, _("mcen_ib_advsetup_settings_saved"));
1197                                 }
1198                         } else {
1199                                 modest_platform_information_banner (NULL, NULL, _("mail_ib_setting_failed"));
1200                         }
1201                 }
1202         }
1203 }
1204
1205 static void 
1206 modest_account_settings_dialog_init (gpointer g, gpointer iface_data)
1207 {
1208         ModestAccountSettingsDialogClass *iface = (ModestAccountSettingsDialogClass *) g;
1209
1210         iface->load_settings = modest_default_account_settings_dialog_load_settings;
1211 }
1212
1213 static void
1214 modest_default_account_settings_dialog_init (ModestDefaultAccountSettingsDialog *self)
1215 {
1216         ModestDefaultAccountSettingsDialogPrivate *priv;
1217
1218         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
1219
1220         /* Create the notebook to be used by the GtkDialog base class:
1221          * Each page of the notebook will be a page of the wizard: */
1222         priv->notebook = GTK_NOTEBOOK (gtk_notebook_new());
1223         priv->settings = modest_account_settings_new ();
1224
1225         /* Get the account manager object, 
1226          * so we can check for existing accounts,
1227          * and create new accounts: */
1228         priv->account_manager = modest_runtime_get_account_mgr ();
1229         g_assert (priv->account_manager);
1230         g_object_ref (priv->account_manager);
1231         
1232         priv->protocol_authentication_incoming = MODEST_PROTOCOLS_AUTH_PASSWORD;
1233
1234     /* Create the common pages, 
1235      */
1236         priv->page_account_details = create_page_account_details (self);
1237         priv->page_user_details = create_page_user_details (self);
1238         priv->page_incoming = create_page_incoming (self);
1239         priv->page_outgoing = create_page_outgoing (self);
1240         
1241         /* Add the notebook pages: */
1242         gtk_notebook_append_page (priv->notebook, priv->page_account_details, 
1243                 gtk_label_new (_("mcen_ti_account_settings_account")));
1244         gtk_notebook_append_page (priv->notebook, priv->page_user_details, 
1245                 gtk_label_new (_("mcen_ti_account_settings_userinfo")));
1246         gtk_notebook_append_page (priv->notebook, priv->page_incoming,
1247                 gtk_label_new (_("mcen_ti_advsetup_retrieval")));
1248         gtk_notebook_append_page (priv->notebook, priv->page_outgoing,
1249                 gtk_label_new (_("mcen_ti_advsetup_sending")));
1250                 
1251         GtkDialog *dialog = GTK_DIALOG (self);
1252         gtk_container_add (GTK_CONTAINER (dialog->vbox), GTK_WIDGET (priv->notebook));
1253         gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), MODEST_MARGIN_HALF);
1254         gtk_widget_show (GTK_WIDGET (priv->notebook));
1255         
1256     /* Add the buttons: */
1257         gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
1258         gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_SAVE, GTK_RESPONSE_OK);
1259     
1260     /* Connect to the dialog's response signal: */
1261     /* We use connect-before 
1262      * so we can stop the signal emission, 
1263      * to stop the default signal handler from closing the dialog.
1264      */
1265     g_signal_connect (G_OBJECT (self), "response",
1266             G_CALLBACK (on_response), self); 
1267             
1268     priv->modified = FALSE;
1269
1270     /* When this window is shown, hibernation should not be possible, 
1271          * because there is no sensible way to save the state: */
1272     modest_window_mgr_prevent_hibernation_while_window_is_shown (
1273         modest_runtime_get_window_mgr (), GTK_WINDOW (self)); 
1274
1275     gtk_window_set_default_size (GTK_WINDOW (self), 600, 400);
1276
1277 /*     hildon_help_dialog_help_enable (GTK_DIALOG(self), "applications_email_accountsettings", */
1278 /*                                  modest_maemo_utils_get_osso_context()); */
1279 }
1280
1281 ModestAccountSettingsDialog*
1282 modest_account_settings_dialog_new (void)
1283 {
1284         return g_object_new (MODEST_TYPE_ACCOUNT_SETTINGS_DIALOG, NULL);
1285 }
1286
1287 /** Update the UI with the stored account details, so they can be edited.
1288  * @account_name: Name of the account, which should contain incoming and outgoing server accounts.
1289  */
1290 static void 
1291 modest_default_account_settings_dialog_load_settings (ModestAccountSettingsDialog *dialog, 
1292                                                       ModestAccountSettings *settings)
1293 {
1294         ModestServerAccountSettings *incoming_account;
1295         ModestServerAccountSettings *outgoing_account;
1296         const gchar *account_name;
1297
1298         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
1299         ModestDefaultAccountSettingsDialogPrivate *priv;
1300
1301         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (dialog);
1302
1303         incoming_account = modest_account_settings_get_store_settings (settings);
1304         outgoing_account = modest_account_settings_get_transport_settings (settings);
1305
1306         account_name = modest_account_settings_get_account_name (settings);
1307                 
1308         /* Save the account name so we can refer to it later: */
1309         if (priv->account_name)
1310                 g_free (priv->account_name);
1311         priv->account_name = g_strdup (account_name);
1312
1313         if (priv->settings)
1314                 g_object_unref (priv->settings);
1315         priv->settings = g_object_ref (settings);
1316         
1317         /* Save the account title so we can refer to it if the user changes it: */
1318         if (priv->original_account_title)
1319                 g_free (priv->original_account_title);
1320         priv->original_account_title = g_strdup (modest_account_settings_get_display_name (settings));
1321         
1322         /* Show the account data in the widgets: */
1323         
1324         /* Note that we never show the non-display name in the UI.
1325          * (Though the display name defaults to the non-display name at the start.) */
1326         gtk_entry_set_text( GTK_ENTRY (priv->entry_account_title),
1327                             null_means_empty (modest_account_settings_get_display_name (settings)));
1328         gtk_entry_set_text( GTK_ENTRY (priv->entry_user_name), 
1329                             null_means_empty (modest_account_settings_get_fullname (settings)));
1330         gtk_entry_set_text( GTK_ENTRY (priv->entry_user_email), 
1331                             null_means_empty (modest_account_settings_get_email_address (settings)));
1332         modest_retrieve_combo_box_fill (MODEST_RETRIEVE_COMBO_BOX (priv->combo_retrieve), 
1333                                         modest_server_account_settings_get_protocol (incoming_account));
1334         modest_retrieve_combo_box_set_active_retrieve_conf (MODEST_RETRIEVE_COMBO_BOX (priv->combo_retrieve), 
1335                                                             modest_account_settings_get_retrieve_type (settings));
1336         modest_limit_retrieve_combo_box_set_active_limit_retrieve (
1337                 MODEST_LIMIT_RETRIEVE_COMBO_BOX (priv->combo_limit_retrieve), 
1338                 modest_account_settings_get_retrieve_limit (settings));
1339         
1340         
1341         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox_leave_messages), 
1342                                       modest_account_settings_get_leave_messages_on_server (settings));
1343         
1344         /* Only show the leave-on-server checkbox for POP, 
1345          * as per the UI spec: */
1346         if (modest_server_account_settings_get_protocol (incoming_account) != MODEST_PROTOCOLS_STORE_POP) {
1347                 gtk_widget_hide (priv->caption_leave_messages);
1348         } else {
1349                 gtk_widget_show (priv->caption_leave_messages);
1350         }
1351         
1352         update_incoming_server_security_choices (dialog, modest_server_account_settings_get_protocol (incoming_account));
1353         if (incoming_account) {
1354                 const gchar *username;
1355                 const gchar *password;
1356                 const gchar *hostname;
1357                 /* Remember this for later: */
1358                 priv->incoming_protocol = modest_server_account_settings_get_protocol (incoming_account);;
1359                 
1360                 hostname = modest_server_account_settings_get_hostname (incoming_account);
1361                 username = modest_server_account_settings_get_username (incoming_account);
1362                 password = modest_server_account_settings_get_password (incoming_account);
1363                 gtk_entry_set_text( GTK_ENTRY (priv->entry_user_username),
1364                                     null_means_empty (username));
1365                 gtk_entry_set_text( GTK_ENTRY (priv->entry_user_password), 
1366                                     null_means_empty (password));
1367                         
1368                 gtk_entry_set_text( GTK_ENTRY (priv->entry_incomingserver), 
1369                                     null_means_empty (hostname));
1370                         
1371                 /* The UI spec says:
1372                  * If secure authentication is unchecked, allow sending username and password also as plain text.
1373          * If secure authentication is checked, require one of the secure methods during connection: SSL, TLS, CRAM-MD5 etc. 
1374                  * TODO: Do we need to discover which of these (SSL, TLS, CRAM-MD5) is supported?
1375          */                                                                                                              
1376                 modest_serversecurity_combo_box_set_active_serversecurity (
1377                         MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_incoming_security), 
1378                         modest_server_account_settings_get_security_protocol (incoming_account));
1379                 
1380                 /* Check if we have
1381                  - a secure protocol
1382                  OR
1383                  - use encrypted passwords
1384                 */
1385                 const ModestProtocolType secure_auth = modest_server_account_settings_get_auth_protocol (incoming_account);
1386                 priv->protocol_authentication_incoming = (secure_auth != MODEST_PROTOCOLS_AUTH_NONE)?
1387                         secure_auth:MODEST_PROTOCOLS_AUTH_PASSWORD;
1388                 if (modest_protocol_registry_protocol_type_is_secure(modest_runtime_get_protocol_registry (),
1389                                                                      secure_auth))
1390                 {
1391                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (priv->checkbox_incoming_auth), 
1392                                                      TRUE);
1393                 }
1394                 else
1395                 {
1396                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (priv->checkbox_incoming_auth), 
1397                                                      FALSE);
1398                 };
1399                                         
1400                 update_incoming_server_title (dialog, priv->incoming_protocol);
1401                 
1402                 const gint port_num = modest_server_account_settings_get_port (incoming_account);
1403                 if (port_num == 0) {
1404                         /* Show the appropriate port number: */
1405                         on_combo_incoming_security_changed (
1406                                 GTK_COMBO_BOX (priv->combo_incoming_security), dialog);
1407                 } else {
1408                         /* Keep the user-entered port-number,
1409                          * or the already-appropriate automatic port number: */
1410                         gtk_spin_button_set_value (
1411                                 GTK_SPIN_BUTTON (priv->entry_incoming_port), (gdouble) port_num);
1412                 }
1413                 g_object_unref (incoming_account);
1414         }
1415         
1416         outgoing_account = modest_account_settings_get_transport_settings (settings);
1417         if (outgoing_account) {
1418                 const gchar *hostname;
1419                 const gchar *username;
1420                 const gchar *password;
1421
1422                 /* Remember this for later: */
1423                 priv->outgoing_protocol = 
1424                         modest_server_account_settings_get_protocol (outgoing_account);
1425
1426                 hostname = modest_server_account_settings_get_hostname (outgoing_account);
1427                 username = modest_server_account_settings_get_username (outgoing_account);
1428                 password = modest_server_account_settings_get_password (outgoing_account);
1429                 gtk_entry_set_text( GTK_ENTRY (priv->entry_outgoingserver), 
1430                                     null_means_empty (hostname));
1431                 
1432                 gtk_entry_set_text( GTK_ENTRY (priv->entry_outgoing_username), 
1433                                     null_means_empty (username));
1434                 gtk_entry_set_text( GTK_ENTRY (priv->entry_outgoing_password), 
1435                                     null_means_empty (password));
1436                 
1437                 /* Get the secure-auth setting: */
1438                 const ModestProtocolType secure_auth = modest_server_account_settings_get_auth_protocol (outgoing_account);
1439                 modest_secureauth_combo_box_set_active_secureauth (
1440                         MODEST_SECUREAUTH_COMBO_BOX (priv->combo_outgoing_auth), secure_auth);
1441                 on_combo_outgoing_auth_changed (GTK_COMBO_BOX (priv->combo_outgoing_auth), dialog);
1442                 
1443                 modest_serversecurity_combo_box_fill (
1444                         MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security), 
1445                         priv->outgoing_protocol);
1446                 
1447                 /* Get the security setting: */
1448                 const ModestProtocolType security = 
1449                         modest_server_account_settings_get_security_protocol (outgoing_account);
1450                 modest_serversecurity_combo_box_set_active_serversecurity (
1451                         MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security), security);
1452                 
1453                 const gint port_num = modest_server_account_settings_get_port (outgoing_account);
1454                 if (port_num == 0) {
1455                         /* Show the appropriate port number: */
1456                         on_combo_outgoing_security_changed (
1457                                 GTK_COMBO_BOX (priv->combo_outgoing_security), dialog);
1458                 }
1459                 else {
1460                         /* Keep the user-entered port-number,
1461                          * or the already-appropriate automatic port number: */
1462                         gtk_spin_button_set_value (
1463                                 GTK_SPIN_BUTTON (priv->entry_outgoing_port), (gdouble) port_num);
1464                 }
1465                 
1466                 const gboolean has_specific = 
1467                         modest_account_settings_get_use_connection_specific_smtp (settings);
1468                 gtk_toggle_button_set_active (
1469                         GTK_TOGGLE_BUTTON (priv->checkbox_outgoing_smtp_specific), 
1470                         has_specific);
1471                 g_object_unref (outgoing_account);
1472         }
1473
1474         /* Set window title according to account: */
1475         /* TODO: Is this the correct way to find a human-readable name for
1476          * the protocol used? */
1477         ModestProtocol *proto = 
1478                 modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), 
1479                                                                priv->incoming_protocol);
1480
1481         const gchar* proto_str = modest_protocol_get_display_name (proto);
1482         gchar *proto_name = g_utf8_strup(proto_str, -1);
1483         const gchar *account_title = modest_account_settings_get_display_name(settings);
1484
1485         gchar *title = g_strdup_printf(_("mcen_ti_account_settings"), proto_name, account_title);
1486         g_free (proto_name);
1487
1488         gtk_window_set_title (GTK_WINDOW (dialog), title);
1489         g_free (title);
1490
1491         /* account_data->is_enabled,  */
1492         /*account_data->is_default,  */
1493
1494         /* Unset the modified flag so we can detect changes later: */
1495         priv->modified = FALSE;
1496 }
1497
1498 /** Show the User Info tab.
1499  */
1500 void 
1501 modest_account_settings_dialog_switch_to_user_info (ModestAccountSettingsDialog *dialog)
1502 {
1503         ModestDefaultAccountSettingsDialogPrivate *priv;
1504
1505         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (dialog);
1506
1507         const gint page_num = gtk_notebook_page_num (priv->notebook, priv->page_user_details);
1508         if (page_num == -1) {
1509                 g_warning ("%s: notebook page not found.\n", __FUNCTION__);     
1510         }
1511                 
1512         /* Ensure that the widget is visible so that gtk_notebook_set_current_page() works: */
1513         /* TODO: even this hack (recommened by the GTK+ documentation) doesn't seem to work. */
1514         
1515         gtk_widget_show (priv->page_user_details);
1516         gtk_widget_show (GTK_WIDGET (priv->notebook));
1517         gtk_widget_show (GTK_WIDGET (dialog));
1518         gtk_notebook_set_current_page (priv->notebook, page_num);
1519 }
1520
1521 static gboolean
1522 save_configuration (ModestAccountSettingsDialog *dialog)
1523 {
1524         ModestServerAccountSettings *store_settings;
1525         ModestServerAccountSettings *transport_settings;
1526         ModestDefaultAccountSettingsDialogPrivate *priv;
1527
1528         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (dialog);
1529                 
1530         /* Set the account data from the widgets: */
1531         const gchar* account_name = priv->account_name;
1532         const gchar* user_fullname = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_name));
1533         modest_account_settings_set_fullname (priv->settings, user_fullname);
1534         
1535         const gchar* emailaddress = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_email));
1536         modest_account_settings_set_email_address (priv->settings, emailaddress);
1537                 
1538 /*      /\* Signature: *\/ */
1539 /*      if (priv->signature_dialog) { */
1540 /*              gboolean use_signature = FALSE; */
1541 /*              gchar *signature =  */
1542 /*                      modest_signature_editor_dialog_get_settings (MODEST_SIGNATURE_EDITOR_DIALOG (priv->signature_dialog), */
1543 /*                                                                   &use_signature); */
1544         
1545 /*              modest_account_settings_set_use_signature (priv->settings, use_signature); */
1546 /*              modest_account_settings_set_signature (priv->settings, signature); */
1547 /*      } */
1548         
1549         ModestAccountRetrieveType retrieve_type = modest_retrieve_combo_box_get_active_retrieve_conf (
1550                 MODEST_RETRIEVE_COMBO_BOX (priv->combo_retrieve));
1551         modest_account_settings_set_retrieve_type (priv->settings, retrieve_type);
1552         
1553         gint retrieve_limit = modest_limit_retrieve_combo_box_get_active_limit_retrieve (
1554                 MODEST_LIMIT_RETRIEVE_COMBO_BOX (priv->combo_limit_retrieve));
1555         modest_account_settings_set_retrieve_limit (priv->settings, retrieve_limit);
1556         
1557         const gboolean leave_on_server = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbox_leave_messages));
1558         modest_account_settings_set_leave_messages_on_server (priv->settings, leave_on_server); 
1559
1560         store_settings = modest_account_settings_get_store_settings (priv->settings);
1561                         
1562         const gchar* hostname = gtk_entry_get_text (GTK_ENTRY (priv->entry_incomingserver));
1563         modest_server_account_settings_set_hostname (store_settings, hostname);
1564                                 
1565         const gchar* username = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_username));
1566         modest_server_account_settings_set_username (store_settings, username);
1567         
1568         const gchar* password = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_password));
1569         modest_server_account_settings_set_password (store_settings, password);
1570                         
1571         /* port: */
1572         gint port_num = gtk_spin_button_get_value_as_int (
1573                         GTK_SPIN_BUTTON (priv->entry_incoming_port));
1574         modest_server_account_settings_set_port (store_settings, port_num);
1575                         
1576         /* The UI spec says:
1577          * If secure authentication is unchecked, allow sending username and password also as plain text.
1578          * If secure authentication is checked, require one of the secure 
1579          * methods during connection: SSL, TLS, CRAM-MD5 etc. 
1580          */
1581         
1582         const ModestProtocolType protocol_security_incoming = modest_serversecurity_combo_box_get_active_serversecurity (
1583                 MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_incoming_security));
1584         modest_server_account_settings_set_security_protocol (store_settings, 
1585                                                               protocol_security_incoming);      
1586         modest_server_account_settings_set_auth_protocol (store_settings, 
1587                                                           priv->protocol_authentication_incoming);
1588
1589         g_object_unref (store_settings);
1590         
1591         /* Outgoing: */
1592         transport_settings = modest_account_settings_get_transport_settings (priv->settings);
1593         
1594         hostname = gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoingserver));
1595         modest_server_account_settings_set_hostname (transport_settings, hostname);
1596                 
1597         username = gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoing_username));
1598         modest_server_account_settings_set_username (transport_settings, username);
1599                 
1600         password = gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoing_password));
1601         modest_server_account_settings_set_password (transport_settings, password);
1602         
1603         const ModestProtocolType protocol_security_outgoing = modest_serversecurity_combo_box_get_active_serversecurity (
1604                 MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security));
1605         modest_server_account_settings_set_security_protocol (transport_settings, 
1606                                                               protocol_security_outgoing);
1607         
1608         const ModestProtocolType protocol_authentication_outgoing = modest_secureauth_combo_box_get_active_secureauth (
1609                 MODEST_SECUREAUTH_COMBO_BOX (priv->combo_outgoing_auth));
1610         modest_server_account_settings_set_auth_protocol (transport_settings, protocol_authentication_outgoing);        
1611         
1612         /* port: */
1613         port_num = gtk_spin_button_get_value_as_int (
1614                         GTK_SPIN_BUTTON (priv->entry_outgoing_port));
1615         modest_server_account_settings_set_port (transport_settings, port_num);
1616         g_object_unref (transport_settings);
1617         
1618         
1619         /* Set the changed account title last, to simplify the previous code: */
1620         gchar* account_title = get_entered_account_title (dialog);
1621         if (!account_title)
1622                 return FALSE; /* Should be prevented already anyway. */
1623                 
1624 /*      if (strcmp (account_title, account_name) != 0) { */
1625         modest_account_settings_set_display_name (priv->settings, account_title);
1626 /*      } */
1627         g_free (account_title);
1628         account_title = NULL;
1629         
1630         /* Save connection-specific SMTP server accounts: */
1631         modest_account_settings_set_use_connection_specific_smtp 
1632                 (priv->settings, 
1633                  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbox_outgoing_smtp_specific)));
1634
1635         /* this configuration is not persistent, we should not save */
1636         if (account_name != NULL)
1637                 modest_account_mgr_save_account_settings (priv->account_manager, priv->settings);
1638
1639 /*      if (priv->specific_window) { */
1640 /*              return modest_connection_specific_smtp_window_save_server_accounts ( */
1641 /*                      MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (priv->specific_window)); */
1642 /*      } else { */
1643                 return TRUE;
1644 /*      } */
1645
1646 }
1647
1648 static gboolean entry_is_empty (GtkWidget *entry)
1649 {
1650         if (!entry)
1651                 return FALSE;
1652                 
1653         const gchar* text = gtk_entry_get_text (GTK_ENTRY (entry));
1654         if ((!text) || (strlen(text) == 0))
1655                 return TRUE;
1656         else {
1657                 /* Strip it of whitespace at the start and end: */
1658                 gchar *stripped = g_strdup (text);
1659                 stripped = g_strstrip (stripped);
1660                 
1661                 if (!stripped)
1662                         return TRUE;
1663                         
1664                 const gboolean result = (strlen (stripped) == 0);
1665                 
1666                 g_free (stripped);
1667                 return result;
1668         }
1669 }
1670
1671 static void
1672 enable_buttons (ModestAccountSettingsDialog *self)
1673 {
1674         gboolean enable_ok = TRUE;
1675         ModestProtocolType outgoing_auth_protocol;
1676         ModestDefaultAccountSettingsDialogPrivate *priv;
1677
1678         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);;
1679         
1680         /* The account details title is mandatory: */
1681         if (entry_is_empty(priv->entry_account_title))
1682                 enable_ok = FALSE;
1683
1684         /* The user details username is mandatory: */
1685         if (enable_ok && entry_is_empty(priv->entry_user_username))
1686                 enable_ok = FALSE;
1687                 
1688         /* The user details email address is mandatory: */
1689         if (enable_ok && entry_is_empty (priv->entry_user_email))
1690                 enable_ok = FALSE;
1691
1692         /* The custom incoming server is mandatory: */
1693         if (enable_ok && entry_is_empty(priv->entry_incomingserver))
1694                 enable_ok = FALSE;
1695
1696         /* The custom incoming server is mandatory: */
1697         if (enable_ok && entry_is_empty(priv->entry_outgoingserver))
1698                 enable_ok = FALSE;
1699
1700         /* Outgoing username is mandatory if outgoing auth is secure */
1701         if (priv->combo_outgoing_auth) {
1702                 outgoing_auth_protocol = modest_secureauth_combo_box_get_active_secureauth (
1703                         MODEST_SECUREAUTH_COMBO_BOX (priv->combo_outgoing_auth));
1704                 if (enable_ok && 
1705                     outgoing_auth_protocol != MODEST_PROTOCOLS_AUTH_NONE &&
1706                     entry_is_empty (priv->entry_outgoing_username))
1707                         enable_ok = FALSE;
1708         }
1709                         
1710         /* Enable the buttons, 
1711          * identifying them via their associated response codes:
1712          */
1713         GtkDialog *dialog_base = GTK_DIALOG (self);
1714         gtk_dialog_set_response_sensitive (dialog_base,
1715                                            GTK_RESPONSE_OK,
1716                                            enable_ok);
1717 }
1718
1719 void
1720 modest_account_settings_dialog_check_allow_changes (ModestAccountSettingsDialog *self)
1721 {
1722         ModestServerAccountSettings *incoming_settings;
1723         const gchar *server_account_name;
1724         gboolean username_known;
1725         ModestDefaultAccountSettingsDialogPrivate *priv;
1726
1727         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);;
1728
1729         if (!G_IS_OBJECT (priv->settings))
1730                 return;
1731
1732         incoming_settings = modest_account_settings_get_store_settings (priv->settings);
1733         server_account_name = modest_server_account_settings_get_account_name (incoming_settings);
1734
1735         username_known = modest_account_mgr_get_server_account_username_has_succeeded (priv->account_manager, 
1736                                                                                        server_account_name);
1737
1738         /* Enable or disable widgets */
1739         gtk_widget_set_sensitive (priv->entry_user_username, !username_known);
1740         gtk_widget_set_sensitive (priv->entry_incomingserver, !username_known);
1741         gtk_widget_set_sensitive (priv->entry_incoming_port, !username_known);
1742         gtk_widget_set_sensitive (priv->combo_incoming_security, !username_known);
1743 }
1744
1745 void
1746 modest_account_settings_dialog_save_password (ModestAccountSettingsDialog *dialog)
1747 {
1748         ModestDefaultAccountSettingsDialogPrivate *priv;
1749
1750         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS_DIALOG (dialog));
1751
1752         priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (dialog);
1753         priv->modified = TRUE;
1754 }
1755
1756 static void
1757 modest_account_settings_dialog_class_init (ModestAccountSettingsDialogClass *klass)
1758 {
1759         GObjectClass *object_class = G_OBJECT_CLASS (klass);
1760         g_type_class_add_private (klass, sizeof (ModestDefaultAccountSettingsDialogPrivate));
1761
1762         object_class->get_property = modest_account_settings_dialog_get_property;
1763         object_class->set_property = modest_account_settings_dialog_set_property;
1764         object_class->dispose = modest_account_settings_dialog_dispose;
1765         object_class->finalize = modest_account_settings_dialog_finalize;
1766 }