2007-04-18 Murray Cumming <murrayc@murrayc.com>
[modest] / src / maemo / modest-account-settings-dialog.c
1 /* Copyright (c) 2007, Nokia Corporation
2  * All rights reserved.
3  *
4  */
5
6
7 #include "modest-account-settings-dialog.h"
8 #include <glib/gi18n.h>
9 #include <gtk/gtknotebook.h>
10 #include <gtk/gtkvbox.h>
11 #include <gtk/gtklabel.h>
12 #include <gtk/gtkcombobox.h>
13 #include <gtk/gtkentry.h>
14 #include <gtk/gtkbutton.h>
15 #include <gtk/gtkcheckbutton.h>
16 #include <gtk/gtkmessagedialog.h>
17 #include <gtk/gtkstock.h>
18 #include <hildon-widgets/hildon-caption.h>
19 #include "maemo/easysetup/modest-easysetup-country-combo-box.h"
20 #include "maemo/easysetup/modest-easysetup-provider-combo-box.h"
21 #include "maemo/easysetup/modest-easysetup-servertype-combo-box.h"
22 #include "maemo/easysetup/modest-easysetup-serversecurity-combo-box.h"
23 #include "maemo/easysetup/modest-easysetup-secureauth-combo-box.h"
24 #include "maemo/easysetup/modest-validating-entry.h"
25 #include "modest-text-utils.h"
26 #include "modest-account-mgr.h"
27 #include "modest-account-mgr-helpers.h" /* For modest_account_mgr_get_account_data(). */
28 #include "modest-runtime.h" /* For modest_runtime_get_account_mgr(). */
29 #include "maemo/modest-connection-specific-smtp-window.h"
30 #include <gconf/gconf-client.h>
31 #include <string.h> /* For strlen(). */
32
33 /* Include config.h so that _() works: */
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #define EXAMPLE_EMAIL_ADDRESS "first.last@provider.com"
39
40 G_DEFINE_TYPE (ModestAccountSettingsDialog, modest_account_settings_dialog, GTK_TYPE_DIALOG);
41
42 #define ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE(o) \
43         (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_ACCOUNT_SETTINGS_DIALOG, ModestAccountSettingsDialogPrivate))
44
45 typedef struct _ModestAccountSettingsDialogPrivate ModestAccountSettingsDialogPrivate;
46
47 struct _ModestAccountSettingsDialogPrivate
48 {
49 };
50
51 static void
52 enable_buttons (ModestAccountSettingsDialog *self);
53
54 static gboolean
55 save_configuration (ModestAccountSettingsDialog *dialog);
56
57 static void
58 modest_account_settings_dialog_get_property (GObject *object, guint property_id,
59                                                                                                                         GValue *value, GParamSpec *pspec)
60 {
61         switch (property_id) {
62         default:
63                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
64         }
65 }
66
67 static void
68 modest_account_settings_dialog_set_property (GObject *object, guint property_id,
69                                                                                                                         const GValue *value, GParamSpec *pspec)
70 {
71         switch (property_id) {
72         default:
73                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
74         }
75 }
76
77 static void
78 modest_account_settings_dialog_dispose (GObject *object)
79 {
80         if (G_OBJECT_CLASS (modest_account_settings_dialog_parent_class)->dispose)
81                 G_OBJECT_CLASS (modest_account_settings_dialog_parent_class)->dispose (object);
82 }
83
84 static void
85 modest_account_settings_dialog_finalize (GObject *object)
86 {
87         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (object);
88         
89         if (self->account_name)
90                 g_free (self->account_name);
91                 
92         if (self->original_account_title)
93                 g_free (self->original_account_title);
94                 
95         if (self->account_manager)
96                 g_object_unref (G_OBJECT (self->account_manager));
97         
98         G_OBJECT_CLASS (modest_account_settings_dialog_parent_class)->finalize (object);
99 }
100
101 static void
102 show_error (GtkWindow *parent_window, const gchar* text);
103
104 static void
105 show_ok (GtkWindow *parent_window, const gchar* text);
106
107 static void
108 on_combo_incoming_security_changed (GtkComboBox *widget, gpointer user_data);
109
110 static void
111 on_combo_outgoing_security_changed (GtkComboBox *widget, gpointer user_data);
112
113
114 static void
115 on_caption_entry_changed (GtkEditable *editable, gpointer user_data)
116 {
117         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
118         g_assert(self);
119         enable_buttons(self);
120 }
121
122 static void
123 on_caption_combobox_changed (GtkComboBox *widget, gpointer user_data)
124 {
125         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
126         g_assert(self);
127         enable_buttons(self);
128 }
129
130 /** This is a convenience function to create a caption containing a mandatory widget.
131  * When the widget is edited, the enable_buttons() vfunc will be called.
132  */
133 static GtkWidget* create_caption_new_with_asterix(ModestAccountSettingsDialog *self,
134         GtkSizeGroup *group,
135         const gchar *value,
136         GtkWidget *control,
137         GtkWidget *icon,
138         HildonCaptionStatus flag)
139 {
140   GtkWidget *caption = hildon_caption_new (group, value, control, icon, flag);
141   
142 /* The translated strings seem to already contain the *,
143  * but this code can be used if that is not true in future.
144  */
145 #if 0
146         /* Add a * character to indicate mandatory fields,
147          * as specified in our "Email UI Specification": */
148         if (flag == HILDON_CAPTION_MANDATORY) {
149                 gchar* title = g_strdup_printf("%s*", value);
150                 caption = hildon_caption_new (group, title, control, icon, flag);       
151                 g_free(title);
152         }       
153         else
154                 caption = hildon_caption_new (group, value, control, icon, flag);
155 #endif
156
157         /* Connect to the appropriate changed signal for the widget, 
158          * so we can ask for the prev/next buttons to be enabled/disabled appropriately:
159          */
160         if (GTK_IS_ENTRY (control)) {
161                 g_signal_connect (G_OBJECT (control), "changed",
162                 G_CALLBACK (on_caption_entry_changed), self);
163                 
164         }
165         else if (GTK_IS_COMBO_BOX (control)) {
166                 g_signal_connect (G_OBJECT (control), "changed",
167                 G_CALLBACK (on_caption_combobox_changed), self);
168         }
169          
170         return caption;
171 }
172
173 static GtkWidget*
174 create_page_account_details (ModestAccountSettingsDialog *self)
175 {
176         GtkWidget *box = gtk_vbox_new (FALSE, 2);
177         GtkWidget *label = gtk_label_new(_("mcen_ia_accountdetails"));
178         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 2);
179         gtk_widget_show (label);
180         
181         /* Create a size group to be used by all captions.
182          * Note that HildonCaption does not create a default size group if we do not specify one.
183          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
184         GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
185            
186         /* The description widgets: */  
187         self->entry_account_title = GTK_WIDGET (easysetup_validating_entry_new ());
188         GtkWidget *caption = create_caption_new_with_asterix (self, sizegroup, _("mcen_fi_account_title"), 
189                 self->entry_account_title, NULL, HILDON_CAPTION_MANDATORY);
190         gtk_widget_show (self->entry_account_title);
191         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
192         gtk_widget_show (caption);
193         
194         /* Prevent the use of some characters in the account title, 
195          * as required by our UI specification: */
196         GList *list_prevent = NULL;
197         list_prevent = g_list_append (list_prevent, "\\");
198         list_prevent = g_list_append (list_prevent, "/");
199         list_prevent = g_list_append (list_prevent, ":");
200         list_prevent = g_list_append (list_prevent, "*");
201         list_prevent = g_list_append (list_prevent, "?");
202         list_prevent = g_list_append (list_prevent, "\""); /* The UI spec mentions “, but maybe means ", maybe both. */
203         list_prevent = g_list_append (list_prevent, "“");
204         list_prevent = g_list_append (list_prevent, "<"); 
205         list_prevent = g_list_append (list_prevent, ">"); 
206         list_prevent = g_list_append (list_prevent, "|");
207         list_prevent = g_list_append (list_prevent, "^");       
208         easysetup_validating_entry_set_unallowed_characters (
209                 EASYSETUP_VALIDATING_ENTRY (self->entry_account_title), list_prevent);
210         g_list_free (list_prevent);
211         
212         /* Set max length as in the UI spec:
213          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
214         gtk_entry_set_max_length (GTK_ENTRY (self->entry_account_title), 64);
215         
216         /* TODO: The Retrieve and Limit Retrieve combo boxes. */
217         
218         /* The leave-messages widgets: */
219         if(!self->checkbox_leave_messages)
220                 self->checkbox_leave_messages = 
221                         gtk_check_button_new_with_label (_("mcen_fi_advsetup_leave_on_server"));
222         gtk_box_pack_start (GTK_BOX (box), self->checkbox_leave_messages, FALSE, FALSE, 2);
223         gtk_widget_show (self->checkbox_leave_messages);
224         
225         
226         gtk_widget_show (GTK_WIDGET (box));
227         
228         return GTK_WIDGET (box);
229 }
230
231 static void
232 on_button_signature (GtkButton *button, gpointer user_data)
233 {
234         
235 }
236
237 static GtkWidget*
238 create_page_user_details (ModestAccountSettingsDialog *self)
239 {
240         GtkWidget *box = gtk_vbox_new (FALSE, 2);
241         
242         /* Create a size group to be used by all captions.
243          * Note that HildonCaption does not create a default size group if we do not specify one.
244          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
245         GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
246          
247         /* The name widgets: */
248         self->entry_user_name = GTK_WIDGET (easysetup_validating_entry_new ());
249         /* Set max length as in the UI spec:
250          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
251         gtk_entry_set_max_length (GTK_ENTRY (self->entry_user_name), 64);
252         GtkWidget *caption = create_caption_new_with_asterix (self, sizegroup, 
253                 _("mcen_li_emailsetup_name"), self->entry_user_name, NULL, HILDON_CAPTION_OPTIONAL);
254         gtk_widget_show (self->entry_user_name);
255         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
256         gtk_widget_show (caption);
257         
258         /* Prevent the use of some characters in the name, 
259          * as required by our UI specification: */
260         GList *list_prevent = NULL;
261         list_prevent = g_list_append (list_prevent, "<");
262         list_prevent = g_list_append (list_prevent, ">");
263         easysetup_validating_entry_set_unallowed_characters (
264                 EASYSETUP_VALIDATING_ENTRY (self->entry_user_name), list_prevent);
265         g_list_free (list_prevent);
266         
267         /* The username widgets: */     
268         self->entry_user_username = GTK_WIDGET (easysetup_validating_entry_new ());
269         caption = create_caption_new_with_asterix (self, sizegroup, _("mail_fi_username"), 
270                 self->entry_user_username, NULL, HILDON_CAPTION_MANDATORY);
271         gtk_widget_show (self->entry_user_username);
272         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
273         gtk_widget_show (caption);
274         
275         /* Prevent the use of some characters in the username, 
276          * as required by our UI specification: */
277         easysetup_validating_entry_set_unallowed_characters_whitespace (
278                 EASYSETUP_VALIDATING_ENTRY (self->entry_user_username));
279         
280         /* Set max length as in the UI spec:
281          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
282         gtk_entry_set_max_length (GTK_ENTRY (self->entry_user_username), 64);
283         
284         /* The password widgets: */     
285         self->entry_user_password = gtk_entry_new ();
286         gtk_entry_set_visibility (GTK_ENTRY (self->entry_user_password), FALSE);
287         /* gtk_entry_set_invisible_char (GTK_ENTRY (self->entry_user_password), '*'); */
288         caption = create_caption_new_with_asterix (self, sizegroup, 
289                 _("mail_fi_password"), self->entry_user_password, NULL, HILDON_CAPTION_OPTIONAL);
290         gtk_widget_show (self->entry_user_password);
291         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
292         gtk_widget_show (caption);
293         
294         /* The email address widgets: */        
295         self->entry_user_email = GTK_WIDGET (easysetup_validating_entry_new ());
296         caption = create_caption_new_with_asterix (self, sizegroup, 
297                 _("mcen_li_emailsetup_email_address"), self->entry_user_email, NULL, HILDON_CAPTION_MANDATORY);
298         gtk_entry_set_text (GTK_ENTRY (self->entry_user_email), EXAMPLE_EMAIL_ADDRESS); /* Default text. */
299         gtk_widget_show (self->entry_user_email);
300         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
301         gtk_widget_show (caption);
302         
303         /* Set max length as in the UI spec:
304          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
305         gtk_entry_set_max_length (GTK_ENTRY (self->entry_user_email), 64);
306         
307         
308         /* Signature button: */
309         if (!self->button_signature)
310                 self->button_signature = gtk_button_new_with_label (_("mcen_bd_emailsetup_edit"));
311         caption = hildon_caption_new (sizegroup, _("mcen_fi_email_signature"), 
312                 self->button_signature, NULL, HILDON_CAPTION_OPTIONAL);
313         gtk_widget_show (self->button_signature);
314         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
315         gtk_widget_show (caption);
316                 
317         g_signal_connect (G_OBJECT (self->button_signature), "clicked",
318                 G_CALLBACK (on_button_signature), self);
319                 
320         gtk_widget_show (GTK_WIDGET (box));
321         
322         return GTK_WIDGET (box);
323 }
324
325 /** Change the caption title for the incoming server, 
326  * as specified in the UI spec:
327  */
328 static void update_incoming_server_title (ModestAccountSettingsDialog *self, ModestProtocol protocol)
329 {
330         const gchar* type = 
331                 (protocol == MODEST_PROTOCOL_STORE_POP ? 
332                         _("mail_fi_emailtype_pop3") : 
333                         _("mail_fi_emailtype_imap") );
334                         
335                 
336         /* Note that this produces a compiler warning, 
337          * because the compiler does not know that the translated string will have a %s in it.
338          * I do not see a way to avoid the warning while still using these Logical IDs. murrayc. */
339         gchar* incomingserver_title = g_strdup_printf(_("mcen_li_emailsetup_servertype"), type);
340         g_object_set (G_OBJECT (self->caption_incoming), "label", incomingserver_title, NULL);
341         g_free(incomingserver_title);
342 }
343
344 /** Change the caption title for the incoming server, 
345  * as specified in the UI spec:
346  */
347 static void update_incoming_server_security_choices (ModestAccountSettingsDialog *self, ModestProtocol protocol)
348 {
349         /* Fill the combo with appropriately titled choices for POP or IMAP. */
350         /* The choices are the same, but the titles are different, as in the UI spec. */
351         easysetup_serversecurity_combo_box_fill (
352                 EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_incoming_security), protocol);
353 }
354            
355 static GtkWidget* create_page_incoming (ModestAccountSettingsDialog *self)
356 {
357         GtkWidget *box = gtk_vbox_new (FALSE, 2);
358         
359         /* Create a size group to be used by all captions.
360          * Note that HildonCaption does not create a default size group if we do not specify one.
361          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
362         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
363          
364         /* The incoming server widgets: */
365         if(!self->entry_incomingserver)
366                 self->entry_incomingserver = gtk_entry_new ();
367
368         if (self->caption_incoming)
369           gtk_widget_destroy (self->caption_incoming);
370            
371         /* The caption title will be updated in update_incoming_server_title().
372          * so this default text will never be seen: */
373         /* (Note: Changing the title seems pointless. murrayc) */
374         self->caption_incoming = create_caption_new_with_asterix (self, sizegroup, 
375                 "Incoming Server", self->entry_incomingserver, NULL, HILDON_CAPTION_MANDATORY);
376         gtk_widget_show (self->entry_incomingserver);
377         gtk_box_pack_start (GTK_BOX (box), self->caption_incoming, FALSE, FALSE, 2);
378         gtk_widget_show (self->caption_incoming);
379         
380         /* The secure connection widgets: */
381         /* This will be filled by update_incoming_server_security_choices(). */
382         if (!self->combo_incoming_security)
383                 self->combo_incoming_security = GTK_WIDGET (easysetup_serversecurity_combo_box_new ());
384         GtkWidget *caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_connection"), 
385                 self->combo_incoming_security, NULL, HILDON_CAPTION_OPTIONAL);
386         gtk_widget_show (self->combo_incoming_security);
387         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
388         gtk_widget_show (caption);
389         
390         /* Show a default port number when the security method changes, as per the UI spec: */
391         g_signal_connect (G_OBJECT (self->combo_incoming_security), "changed", (GCallback)on_combo_incoming_security_changed, self);
392         
393         
394         /* The port widgets: */
395         /* TODO: There are various rules about this in the UI spec. */
396         if (!self->entry_incoming_port)
397                 self->entry_incoming_port = GTK_WIDGET (gtk_entry_new ());
398         caption = hildon_caption_new (sizegroup, _("mcen_fi_emailsetup_port"), 
399                 self->entry_incoming_port, NULL, HILDON_CAPTION_OPTIONAL);
400         gtk_widget_show (self->entry_incoming_port);
401         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
402         gtk_widget_show (caption);
403         
404         /* The secure authentication widgets: */
405         if(!self->checkbox_incoming_auth)
406                 self->checkbox_incoming_auth = 
407                         gtk_check_button_new_with_label (_("mcen_li_emailsetup_secure_authentication"));
408         gtk_box_pack_start (GTK_BOX (box), self->checkbox_incoming_auth, FALSE, FALSE, 2);
409         gtk_widget_show (self->checkbox_incoming_auth);
410         
411         gtk_widget_show (GTK_WIDGET (box));
412         
413         return GTK_WIDGET (box);
414 }
415
416 static void
417 on_toggle_button_changed (GtkToggleButton *togglebutton, gpointer user_data)
418 {
419         GtkWidget *widget = GTK_WIDGET (user_data);
420         
421         /* Enable the widget only if the toggle button is active: */
422         const gboolean enable = gtk_toggle_button_get_active (togglebutton);
423         gtk_widget_set_sensitive (widget, enable);
424 }
425
426 /* Make the sensitivity of a widget depend on a toggle button.
427  */
428 static void
429 enable_widget_for_togglebutton (GtkWidget *widget, GtkToggleButton* button)
430 {
431         g_signal_connect (G_OBJECT (button), "toggled",
432                 G_CALLBACK (on_toggle_button_changed), widget);
433         
434         /* Set the starting sensitivity: */
435         on_toggle_button_changed (button, widget);
436 }
437         
438 static void
439 on_smtp_servers_window_hide (GtkWindow *window, gpointer user_data)
440 {
441         /* Destroy the window when it is closed: */
442         gtk_widget_destroy (GTK_WIDGET (window));
443 }
444
445 static void
446 on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data)
447 {
448
449         ModestAccountSettingsDialog * self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
450         
451         /* Show the window: */
452         /* TODO: Retrieve the chosen settings,
453          * so we can supply them when creating the connection somehow.
454          */
455         GtkWidget *window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
456         gtk_window_set_transient_for (GTK_WINDOW (self), GTK_WINDOW (window));
457         g_signal_connect (G_OBJECT (window), "hide",
458                 G_CALLBACK (on_smtp_servers_window_hide), self);
459     gtk_widget_show (window);
460 }
461
462 static void
463 on_combo_outgoing_auth_changed (GtkComboBox *widget, gpointer user_data)
464 {
465         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
466         
467         ModestProtocol protocol_security = 
468                 easysetup_secureauth_combo_box_get_active_secureauth (
469                         EASYSETUP_SECUREAUTH_COMBO_BOX (self->combo_outgoing_auth));
470         const gboolean secureauth_used = protocol_security != MODEST_PROTOCOL_AUTH_NONE;
471         
472         gtk_widget_set_sensitive (self->caption_outgoing_username, secureauth_used);
473         gtk_widget_set_sensitive (self->caption_outgoing_password, secureauth_used);
474 }
475
476 static void
477 on_combo_outgoing_security_changed (GtkComboBox *widget, gpointer user_data)
478 {
479         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
480         
481         const gint port_number = 
482                 easysetup_serversecurity_combo_box_get_active_serversecurity_port (
483                         EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_outgoing_security));
484
485         if(port_number != 0) {
486                 gchar* str = g_strdup_printf ("%d", port_number);
487                 gtk_entry_set_text (GTK_ENTRY (self->entry_outgoing_port), str);
488                 g_free (str);   
489         }               
490 }
491
492 static void
493 on_combo_incoming_security_changed (GtkComboBox *widget, gpointer user_data)
494 {
495         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (user_data);
496         
497         const gint port_number = 
498                 easysetup_serversecurity_combo_box_get_active_serversecurity_port (
499                         EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_incoming_security));
500
501         if(port_number != 0) {
502                 gchar* str = g_strdup_printf ("%d", port_number);
503                 gtk_entry_set_text (GTK_ENTRY (self->entry_incoming_port), str);
504                 g_free (str);   
505         }               
506 }
507
508
509 static GtkWidget* create_page_outgoing (ModestAccountSettingsDialog *self)
510 {
511         GtkWidget *box = gtk_vbox_new (FALSE, 2);
512         
513         /* Create a size group to be used by all captions.
514          * Note that HildonCaption does not create a default size group if we do not specify one.
515          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
516         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
517          
518         /* The outgoing server widgets: */
519         if (!self->entry_outgoingserver)
520                 self->entry_outgoingserver = gtk_entry_new ();
521         GtkWidget *caption = create_caption_new_with_asterix (self, sizegroup, 
522                 _("mcen_li_emailsetup_smtp"), self->entry_outgoingserver, NULL, HILDON_CAPTION_OPTIONAL);
523         gtk_widget_show (self->entry_outgoingserver);
524         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
525         gtk_widget_show (caption);
526         
527         /* The secure authentication widgets: */
528         if (!self->combo_outgoing_auth)
529                 self->combo_outgoing_auth = GTK_WIDGET (easysetup_secureauth_combo_box_new ());
530         caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_authentication"), 
531                 self->combo_outgoing_auth, NULL, HILDON_CAPTION_OPTIONAL);
532         gtk_widget_show (self->combo_outgoing_auth);
533         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
534         gtk_widget_show (caption);
535         
536         /* Dim the outgoing username and password when no secure authentication is used, as per the UI spec: */
537         g_signal_connect (G_OBJECT (self->combo_outgoing_auth), "changed", (GCallback)on_combo_outgoing_auth_changed, self);
538         
539         /* The username widgets: */     
540         self->entry_outgoing_username = GTK_WIDGET (easysetup_validating_entry_new ());
541         self->caption_outgoing_username = create_caption_new_with_asterix (self, sizegroup, _("mail_fi_username"), 
542                 self->entry_outgoing_username, NULL, HILDON_CAPTION_MANDATORY);
543         gtk_widget_show (self->entry_outgoing_username);
544         gtk_box_pack_start (GTK_BOX (box), self->caption_outgoing_username, FALSE, FALSE, 2);
545         gtk_widget_show (self->caption_outgoing_username);
546         
547         /* Prevent the use of some characters in the username, 
548          * as required by our UI specification: */
549         easysetup_validating_entry_set_unallowed_characters_whitespace (
550                 EASYSETUP_VALIDATING_ENTRY (self->entry_outgoing_username));
551         
552         /* Set max length as in the UI spec:
553          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
554         gtk_entry_set_max_length (GTK_ENTRY (self->entry_outgoing_username), 64);
555         
556         /* The password widgets: */     
557         self->entry_outgoing_password = gtk_entry_new ();
558         gtk_entry_set_visibility (GTK_ENTRY (self->entry_outgoing_password), FALSE);
559         /* gtk_entry_set_invisible_char (GTK_ENTRY (self->entry_outgoing_password), '*'); */
560         self->caption_outgoing_password = create_caption_new_with_asterix (self, sizegroup, 
561                 _("mail_fi_password"), self->entry_outgoing_password, NULL, HILDON_CAPTION_OPTIONAL);
562         gtk_widget_show (self->entry_outgoing_password);
563         gtk_box_pack_start (GTK_BOX (box), self->caption_outgoing_password, FALSE, FALSE, 2);
564         gtk_widget_show (self->caption_outgoing_password);
565         
566         /* The secure connection widgets: */
567         /* This will be filled and set with easysetup_serversecurity_combo_box_fill() 
568          * and easysetup_serversecurity_combo_box_set_active_serversecurity().
569          */
570         if (!self->combo_outgoing_security)
571                 self->combo_outgoing_security = GTK_WIDGET (easysetup_serversecurity_combo_box_new ());
572         caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_connection"), 
573                 self->combo_outgoing_security, NULL, HILDON_CAPTION_OPTIONAL);
574         gtk_widget_show (self->combo_outgoing_security);
575         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
576         gtk_widget_show (caption);
577         
578         /* Show a default port number when the security method changes, as per the UI spec: */
579         g_signal_connect (G_OBJECT (self->combo_outgoing_security), "changed", (GCallback)on_combo_outgoing_security_changed, self);
580         
581         /* The port widgets: */
582         if (!self->entry_outgoing_port)
583                 self->entry_outgoing_port = GTK_WIDGET (gtk_entry_new ());
584         caption = hildon_caption_new (sizegroup, _("mcen_fi_emailsetup_port"), 
585                 self->entry_outgoing_port, NULL, HILDON_CAPTION_OPTIONAL);
586         gtk_widget_show (self->entry_outgoing_port);
587         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
588         gtk_widget_show (caption);
589         
590         /* connection-specific checkbox: */
591         if (!self->checkbox_outgoing_smtp_specific) {
592                 self->checkbox_outgoing_smtp_specific = gtk_check_button_new_with_label (_("mcen_fi_advsetup_connection_smtp"));
593                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->checkbox_outgoing_smtp_specific), 
594                         FALSE);
595         }
596         gtk_box_pack_start (GTK_BOX (box), self->checkbox_outgoing_smtp_specific, FALSE, FALSE, 2);
597         gtk_widget_show (self->checkbox_outgoing_smtp_specific);
598         
599         /* Connection-specific SMTP-Severs Edit button: */
600         if (!self->button_outgoing_smtp_servers)
601                 self->button_outgoing_smtp_servers = gtk_button_new_with_label (_("mcen_bd_emailsetup_edit"));
602         caption = hildon_caption_new (sizegroup, _("mcen_fi_advsetup_optional_smtp"), 
603                 self->button_outgoing_smtp_servers, NULL, HILDON_CAPTION_OPTIONAL);
604         gtk_widget_show (self->button_outgoing_smtp_servers);
605         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
606         gtk_widget_show (caption);
607         
608         /* Only enable the button when the checkbox is checked: */
609         enable_widget_for_togglebutton (self->button_outgoing_smtp_servers, 
610                 GTK_TOGGLE_BUTTON (self->checkbox_outgoing_smtp_specific));
611                 
612         g_signal_connect (G_OBJECT (self->button_outgoing_smtp_servers), "clicked",
613                 G_CALLBACK (on_button_outgoing_smtp_servers), self);
614         
615         
616         gtk_widget_show (GTK_WIDGET (box));
617         
618         return GTK_WIDGET (box);
619 }
620
621 static gboolean
622 check_data (ModestAccountSettingsDialog *self)
623 {
624         /* Check that the title is not already in use: */
625         const gchar* account_title = gtk_entry_get_text (GTK_ENTRY (self->entry_account_title));
626         if ((!account_title) || (strlen(account_title) == 0))
627                 return FALSE; /* Should be prevented already anyway. */
628                 
629         if (strcmp(account_title, self->original_account_title) != 0) {
630                 /* Check the changed title: */
631                 const gboolean name_in_use  = modest_account_mgr_account_with_display_name_exists (self->account_manager,
632                         account_title);
633         
634                 if (name_in_use) {
635                         /* Warn the user via a dialog: */
636                         show_error (GTK_WINDOW (self), _("mail_ib_account_name_already_existing"));
637                 
638                         return FALSE;
639                 }
640         }
641
642         /* Check that the email address is valud: */
643         const gchar* email_address = gtk_entry_get_text (GTK_ENTRY (self->entry_user_email));
644         if ((!email_address) || (strlen(email_address) == 0))
645                 return FALSE;
646                         
647         if (!modest_text_utils_validate_email_address (email_address)) {
648                 /* Warn the user via a dialog: */
649                 show_error (GTK_WINDOW (self), _("mcen_ib_invalid_email"));
650                                          
651         /* Return focus to the email address entry: */
652         gtk_widget_grab_focus (self->entry_user_email);
653         
654                 return FALSE;
655         }
656         
657         /* TODO: The UI Spec wants us to check that the servernames are valid, 
658          * but does not specify how.
659          */
660          
661         return TRUE;
662 }
663 /*
664  */
665 static void 
666 on_response (GtkDialog *wizard_dialog,
667         gint response_id,
668         gpointer user_data)
669 {
670         ModestAccountSettingsDialog *self = MODEST_ACCOUNT_SETTINGS_DIALOG (wizard_dialog);
671         enable_buttons (self);
672         
673         gboolean prevent_response = FALSE;
674         
675         /* Warn about unsaved changes: */
676         /* TODO: Actually detect whether changes were made. */
677         if (response_id == GTK_RESPONSE_CANCEL) {
678                 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (GTK_WINDOW (self),
679                 (GtkDialogFlags)0,
680                  GTK_MESSAGE_INFO,
681                  GTK_BUTTONS_OK_CANCEL, /* TODO: These button names are ambiguous, and not specified in the UI specification. */
682                  _("imum_nc_wizard_confirm_lose_changes") ));
683                  
684                  const gint dialog_response = gtk_dialog_run (dialog);
685                  gtk_widget_destroy (GTK_WIDGET (dialog));
686                  
687                 if (dialog_response != GTK_RESPONSE_OK)
688                         prevent_response = TRUE;
689         }
690         /* Check for invalid input: */
691         else if (!check_data (self)) {
692                 prevent_response = TRUE;
693         }
694                 
695         if (prevent_response) {
696                 /* This is a nasty hack. murrayc. */
697                 /* Don't let the dialog close */
698         g_signal_stop_emission_by_name (wizard_dialog, "response");
699                 return; 
700         }
701                 
702                 
703         if (response_id == GTK_RESPONSE_OK) {
704                 /* Try to save the changes: */  
705                 const gboolean saved = save_configuration (self);
706                 if (saved)
707                         show_ok (GTK_WINDOW (self), _("mcen_ib_advsetup_settings_saved"));
708                 else
709                         show_error (GTK_WINDOW (self), _("mail_ib_setting_failed"));
710         }
711 }
712
713 static void
714 modest_account_settings_dialog_init (ModestAccountSettingsDialog *self)
715 {
716         /* Create the notebook to be used by the GtkDialog base class:
717          * Each page of the notebook will be a page of the wizard: */
718         GtkNotebook *notebook = GTK_NOTEBOOK (gtk_notebook_new());
719
720     
721     gtk_window_set_title (GTK_WINDOW (self), _("mcen_ti_emailsetup"));
722         
723         /* Get the account manager object, 
724          * so we can check for existing accounts,
725          * and create new accounts: */
726         self->account_manager = modest_runtime_get_account_mgr ();
727         g_assert (self->account_manager);
728         g_object_ref (self->account_manager);
729         
730     /* Create the common pages, 
731      */
732         self->page_account_details = create_page_account_details (self);
733         self->page_user_details = create_page_user_details (self);
734         self->page_incoming = create_page_incoming (self);
735         self->page_outgoing = create_page_outgoing (self);
736         
737         /* Add the notebook pages: */
738         gtk_notebook_append_page (notebook, self->page_account_details, 
739                 gtk_label_new (_("mcen_ti_account_settings_account")));
740         gtk_notebook_append_page (notebook, self->page_user_details, 
741                 gtk_label_new (_("mcen_ti_account_settings_userinfo")));
742         gtk_notebook_append_page (notebook, self->page_incoming,
743                 gtk_label_new (_("mcen_ti_advsetup_retrieval")));
744         gtk_notebook_append_page (notebook, self->page_outgoing,
745                 gtk_label_new (_("mcen_ti_advsetup_sending")));
746                 
747         GtkDialog *dialog = GTK_DIALOG (self);
748         gtk_container_add (GTK_CONTAINER (dialog->vbox), GTK_WIDGET (notebook));
749         gtk_widget_show (GTK_WIDGET (notebook));
750         
751     /* Add the buttons: */
752     gtk_dialog_add_button (GTK_DIALOG(self), GTK_STOCK_OK, GTK_RESPONSE_OK);
753     gtk_dialog_add_button (GTK_DIALOG(self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
754     
755     /* Connect to the dialog's response signal: */
756     /* We use connect-before 
757      * so we can stop the signal emission, 
758      * to stop the default signal handler from closing the dialog.
759      */
760     g_signal_connect (G_OBJECT (self), "response",
761             G_CALLBACK (on_response), self);       
762 }
763
764 ModestAccountSettingsDialog*
765 modest_account_settings_dialog_new (void)
766 {
767         return g_object_new (MODEST_TYPE_ACCOUNT_SETTINGS_DIALOG, NULL);
768 }
769
770 /** Update the UI with the stored account details, so they can be edited.
771  * @account_name: Name of the account, which should contain incoming and outgoing server accounts.
772  */
773 void modest_account_settings_dialog_set_account_name (ModestAccountSettingsDialog *dialog, const gchar* account_name)
774 {
775         if (!account_name)
776                 return;
777                 
778         /* Save the account name so we can refer to it later: */
779         if (dialog->account_name)
780                 g_free (dialog->account_name);
781         dialog->account_name = g_strdup (account_name);
782         
783                 
784         /* Get the account data for this account name: */
785         ModestAccountData *account_data = modest_account_mgr_get_account_data (dialog->account_manager, 
786                 account_name);
787         if (!account_data) {
788                 g_printerr ("modest: failed to get account data for %s\n", account_name);
789                 return;
790         }
791         
792         /* Save the account title so we can refer to it if the user changes it: */
793         if (dialog->original_account_title)
794                 g_free (dialog->original_account_title);
795         dialog->original_account_title = g_strdup (account_data->display_name);
796         
797
798         if (!(account_data->store_account)) {
799                 g_printerr ("modest: account has no stores: %s\n", account_name);
800                 return;
801         }
802                 
803         /* Show the account data in the widgets: */
804         
805         /* Note that we never show the non-display name in the UI.
806          * (Though the display name defaults to the non-display name at the start.) */
807         gtk_entry_set_text( GTK_ENTRY (dialog->entry_account_title),
808                 account_data->display_name ? account_data->display_name : "");
809                 
810         gtk_entry_set_text( GTK_ENTRY (dialog->entry_user_name), 
811                 account_data->fullname ? account_data->fullname : "");
812         gtk_entry_set_text( GTK_ENTRY (dialog->entry_user_email), 
813                 account_data->email ? account_data->email : "");
814                 
815         const gboolean leave_on_server = modest_account_mgr_get_bool (dialog->account_manager, account_name,
816                 MODEST_ACCOUNT_LEAVE_ON_SERVER, FALSE /* not server account */);
817         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->checkbox_leave_messages), leave_on_server);    
818                 
819         ModestServerAccountData *incoming_account = account_data->store_account;
820         if (incoming_account) {
821                 gtk_entry_set_text( GTK_ENTRY (dialog->entry_user_username),
822                         incoming_account->username ? incoming_account->username : "");
823                 gtk_entry_set_text( GTK_ENTRY (dialog->entry_user_password), 
824                         incoming_account->password ? incoming_account->password : "");
825                         
826                 gtk_entry_set_text( GTK_ENTRY (dialog->entry_incomingserver), 
827                         incoming_account->hostname ? incoming_account->hostname : "");
828                         
829                 const ModestProtocol secure_auth = modest_server_account_data_get_option_secure_auth(incoming_account);
830                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (dialog->checkbox_incoming_auth), 
831                         secure_auth == MODEST_PROTOCOL_AUTH_PASSWORD);
832                         
833                 update_incoming_server_title (dialog, incoming_account->proto);
834                 update_incoming_server_security_choices (dialog, incoming_account->proto);
835                 
836                 const ModestProtocol security = modest_server_account_data_get_option_security (incoming_account);
837                 easysetup_serversecurity_combo_box_set_active_serversecurity (
838                         EASYSETUP_SERVERSECURITY_COMBO_BOX (dialog->combo_incoming_security), security);
839                 
840                 const gint port_num = modest_account_mgr_get_int (dialog->account_manager, incoming_account->account_name,
841                         MODEST_ACCOUNT_PORT, TRUE /* server account */);
842                 gchar *port_str = g_strdup_printf ("%d", port_num);
843                 gtk_entry_set_text (GTK_ENTRY (dialog->entry_incoming_port), port_str);
844                 g_free (port_str);
845         
846                 /* TODO:
847         gchar            *uri;
848         ModestProtocol    proto;
849         gchar            *password;
850         time_t            last_updated;
851         GSList           *options;
852         */
853         
854         }
855         
856         ModestServerAccountData *outgoing_account = account_data->transport_account;
857         if (outgoing_account) {
858                 gtk_entry_set_text( GTK_ENTRY (dialog->entry_outgoingserver), 
859                         outgoing_account->hostname ? outgoing_account->hostname : "");
860                 
861                 gtk_entry_set_text( GTK_ENTRY (dialog->entry_outgoing_username), 
862                         outgoing_account->username ? outgoing_account->username : "");
863                 gtk_entry_set_text( GTK_ENTRY (dialog->entry_outgoing_password), 
864                         outgoing_account->password ? outgoing_account->password : "");
865                 
866                 /* Get the secure-auth setting: */
867                 const ModestProtocol secure_auth = modest_server_account_data_get_option_secure_auth(outgoing_account);
868                 easysetup_secureauth_combo_box_set_active_secureauth (
869                         EASYSETUP_SECUREAUTH_COMBO_BOX (dialog->combo_outgoing_auth), secure_auth);
870                 on_combo_outgoing_auth_changed (GTK_COMBO_BOX (dialog->combo_outgoing_auth), dialog);
871                 
872                 easysetup_serversecurity_combo_box_fill (
873                         EASYSETUP_SERVERSECURITY_COMBO_BOX (dialog->combo_outgoing_security), outgoing_account->proto);
874                 
875                 /* Get the security setting: */
876                 const ModestProtocol security = modest_server_account_data_get_option_security (outgoing_account);
877                 easysetup_serversecurity_combo_box_set_active_serversecurity (
878                         EASYSETUP_SERVERSECURITY_COMBO_BOX (dialog->combo_outgoing_security), security);
879                 
880                 const gint port_num = modest_account_mgr_get_int (dialog->account_manager, outgoing_account->account_name,
881                         MODEST_ACCOUNT_PORT, TRUE /* server account */);
882                 gchar *port_str = g_strdup_printf ("%d", port_num);
883                 gtk_entry_set_text (GTK_ENTRY (dialog->entry_outgoing_port), port_str);
884                 g_free (port_str);
885         }
886         
887         /* account_data->is_enabled,  */
888         /*account_data->is_default,  */
889
890         /* account_data->store_account->proto */
891
892         modest_account_mgr_free_account_data (dialog->account_manager, account_data);
893 }
894
895 static gboolean
896 save_configuration (ModestAccountSettingsDialog *dialog)
897 {
898         g_assert (dialog->account_name);
899         
900         const gchar* account_name = dialog->account_name;
901                 
902         /* Set the account data from the widgets: */
903         const gchar* user_name = gtk_entry_get_text (GTK_ENTRY (dialog->entry_user_name));
904         gboolean test = modest_account_mgr_set_string (dialog->account_manager, account_name,
905                 MODEST_ACCOUNT_FULLNAME, user_name, FALSE /* not server account */);
906         if (!test)
907                 return FALSE;
908                 
909         const gchar* emailaddress = gtk_entry_get_text (GTK_ENTRY (dialog->entry_user_email));
910         test = modest_account_mgr_set_string (dialog->account_manager, account_name,
911                 MODEST_ACCOUNT_EMAIL, emailaddress, FALSE /* not server account */);
912         if (!test)
913                 return FALSE;
914         
915         const gboolean leave_on_server = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->checkbox_leave_messages));
916         test = modest_account_mgr_set_bool (dialog->account_manager, account_name,
917                 MODEST_ACCOUNT_LEAVE_ON_SERVER, leave_on_server, FALSE /* not server account */);
918         if (!test)
919                 return FALSE;
920                         
921         /* Incoming: */
922         gchar* incoming_account_name = modest_account_mgr_get_string (dialog->account_manager, account_name,
923                 MODEST_ACCOUNT_STORE_ACCOUNT, FALSE /* not server account */);
924         g_assert (incoming_account_name);
925         
926         const gchar* hostname = gtk_entry_get_text (GTK_ENTRY (dialog->entry_incomingserver));
927         test = modest_account_mgr_set_string (dialog->account_manager, incoming_account_name,
928                 MODEST_ACCOUNT_HOSTNAME, hostname, TRUE /* server account */);
929         if (!test)
930                 return FALSE;
931                                 
932         const gchar* username = gtk_entry_get_text (GTK_ENTRY (dialog->entry_user_username));
933         test = modest_account_mgr_set_string (dialog->account_manager, incoming_account_name,
934                 MODEST_ACCOUNT_USERNAME, username, TRUE /* server account */);
935         if (!test)
936                 return FALSE;
937                                 
938         const gchar* password = gtk_entry_get_text (GTK_ENTRY (dialog->entry_user_password));
939         test = modest_account_mgr_set_string (dialog->account_manager, incoming_account_name,
940                 MODEST_ACCOUNT_PASSWORD, password, TRUE /*  server account */);
941         if (!test)
942                 return FALSE;
943                         
944         const ModestProtocol protocol_authentication_incoming = gtk_toggle_button_get_active 
945                 (GTK_TOGGLE_BUTTON (dialog->checkbox_incoming_auth)) 
946                         ? MODEST_PROTOCOL_AUTH_PASSWORD
947                         : MODEST_PROTOCOL_AUTH_NONE;
948         modest_server_account_set_option_secure_auth (dialog->account_manager, incoming_account_name, protocol_authentication_incoming);
949                         
950         const ModestProtocol protocol_security_incoming = easysetup_serversecurity_combo_box_get_active_serversecurity (
951                 EASYSETUP_SERVERSECURITY_COMBO_BOX (dialog->combo_incoming_security));
952         modest_server_account_set_option_security (dialog->account_manager, incoming_account_name, protocol_security_incoming);
953         
954         /* port: */
955         const gchar* port_str = gtk_entry_get_text (GTK_ENTRY (dialog->entry_incoming_port));
956         gint port_num = 0;
957         if (port_str)
958                 port_num = atoi (port_str);
959         modest_account_mgr_set_int (dialog->account_manager, incoming_account_name,
960                         MODEST_ACCOUNT_PORT, port_num, TRUE /* server account */);
961                 
962         g_free (incoming_account_name);
963         
964         /* Outgoing: */
965         gchar* outgoing_account_name = modest_account_mgr_get_string (dialog->account_manager, account_name,
966                 MODEST_ACCOUNT_TRANSPORT_ACCOUNT, FALSE /* not server account */);
967         g_assert (outgoing_account_name);
968         
969         hostname = gtk_entry_get_text (GTK_ENTRY (dialog->entry_outgoingserver));
970         test = modest_account_mgr_set_string (dialog->account_manager, outgoing_account_name,
971                 MODEST_ACCOUNT_HOSTNAME, hostname, TRUE /* server account */);
972         if (!test)
973                 return FALSE;
974                 
975         username = gtk_entry_get_text (GTK_ENTRY (dialog->entry_outgoing_username));
976         test = modest_account_mgr_set_string (dialog->account_manager, outgoing_account_name,
977                 MODEST_ACCOUNT_USERNAME, username, TRUE /* server account */);
978         if (!test)
979                 return FALSE;
980                 
981         password = gtk_entry_get_text (GTK_ENTRY (dialog->entry_outgoing_password));
982         test = modest_account_mgr_set_string (dialog->account_manager, outgoing_account_name,
983                 MODEST_ACCOUNT_PASSWORD, password, TRUE /*  server account */);
984         if (!test)
985                 return FALSE;
986         
987         const ModestProtocol protocol_security_outgoing = easysetup_serversecurity_combo_box_get_active_serversecurity (
988                 EASYSETUP_SERVERSECURITY_COMBO_BOX (dialog->combo_outgoing_security));
989         modest_server_account_set_option_security (dialog->account_manager, outgoing_account_name, protocol_security_outgoing);
990         
991         const ModestProtocol protocol_authentication_outgoing = easysetup_secureauth_combo_box_get_active_secureauth (
992                 EASYSETUP_SECUREAUTH_COMBO_BOX (dialog->combo_outgoing_auth));
993         modest_server_account_set_option_secure_auth (dialog->account_manager, outgoing_account_name, protocol_authentication_outgoing);        
994                 
995         /* port: */
996         port_str = gtk_entry_get_text (GTK_ENTRY (dialog->entry_outgoing_port));
997         port_num = 0;
998         if (port_str)
999                 port_num = atoi (port_str);
1000         modest_account_mgr_set_int (dialog->account_manager, outgoing_account_name,
1001                         MODEST_ACCOUNT_PORT, port_num, TRUE /* server account */);
1002                         
1003         g_free (outgoing_account_name);
1004         
1005         
1006         /* Set the changed account title last, to simplify the previous code: */
1007         const gchar* account_title = gtk_entry_get_text (GTK_ENTRY (dialog->entry_account_title));
1008         if ((!account_title) || (strlen(account_title) == 0))
1009                 return FALSE; /* Should be prevented already anyway. */
1010                 
1011         if (strcmp(account_title, account_name) != 0) {
1012                 /* Change the title: */
1013                 gboolean test = modest_account_mgr_set_string (dialog->account_manager, account_name,
1014                 MODEST_ACCOUNT_DISPLAY_NAME, account_title, FALSE /* not server account */);
1015                 if (!test)
1016                         return FALSE;
1017         }
1018         
1019         return TRUE;
1020 }
1021
1022 static gboolean entry_is_empty (GtkWidget *entry)
1023 {
1024         if (!entry)
1025                 return FALSE;
1026                 
1027         const gchar* text = gtk_entry_get_text (GTK_ENTRY (entry));
1028         if ((!text) || (strlen(text) == 0))
1029                 return TRUE;
1030         else
1031                 return FALSE;
1032 }
1033
1034 static void
1035 enable_buttons (ModestAccountSettingsDialog *self)
1036 {
1037         gboolean enable_ok = TRUE;
1038         
1039         /* The account details title is mandatory: */
1040         if (entry_is_empty(self->entry_account_title))
1041                         enable_ok = FALSE;
1042
1043         /* The user details username is mandatory: */
1044         if (entry_is_empty(self->entry_user_username))
1045                 enable_ok = FALSE;
1046                 
1047         /* The user details email address is mandatory: */
1048         if (enable_ok && entry_is_empty (self->entry_user_email))
1049                 enable_ok = FALSE;
1050
1051         /* The custom incoming server is mandatory: */
1052         if (entry_is_empty(self->entry_incomingserver))
1053                 enable_ok = FALSE;
1054                         
1055         /* Enable the buttons, 
1056          * identifying them via their associated response codes:
1057          */
1058         GtkDialog *dialog_base = GTK_DIALOG (self);
1059     gtk_dialog_set_response_sensitive (dialog_base,
1060                                        GTK_RESPONSE_OK,
1061                                        enable_ok);
1062 }
1063
1064 static void
1065 modest_account_settings_dialog_class_init (ModestAccountSettingsDialogClass *klass)
1066 {
1067         GObjectClass *object_class = G_OBJECT_CLASS (klass);
1068         g_type_class_add_private (klass, sizeof (ModestAccountSettingsDialogPrivate));
1069
1070
1071         object_class->get_property = modest_account_settings_dialog_get_property;
1072         object_class->set_property = modest_account_settings_dialog_set_property;
1073         object_class->dispose = modest_account_settings_dialog_dispose;
1074         object_class->finalize = modest_account_settings_dialog_finalize;
1075 }
1076  
1077 static void
1078 show_error (GtkWindow *parent_window, const gchar* text)
1079 {
1080         GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
1081                 (GtkDialogFlags)0,
1082                  GTK_MESSAGE_ERROR,
1083                  GTK_BUTTONS_OK,
1084                  text ));
1085                  
1086                  gtk_dialog_run (dialog);
1087                  gtk_widget_destroy (GTK_WIDGET (dialog));
1088 }
1089
1090 static void
1091 show_ok (GtkWindow *parent_window, const gchar* text)
1092 {
1093         GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
1094                 (GtkDialogFlags)0,
1095                  GTK_MESSAGE_INFO,
1096                  GTK_BUTTONS_OK,
1097                  text ));
1098                  
1099                  gtk_dialog_run (dialog);
1100                  gtk_widget_destroy (GTK_WIDGET (dialog));
1101 }
1102
1103
1104