2007-04-04 Murray Cumming <murrayc@murrayc.com>
[modest] / src / maemo / easysetup / modest-easysetup-wizard.c
1 /* Copyright (c) 2007, Nokia Corporation
2  * All rights reserved.
3  *
4  */
5
6
7 #include "modest-easysetup-wizard.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 <hildon-widgets/hildon-caption.h>
18 #include "modest-easysetup-country-combo-box.h"
19 #include "modest-easysetup-provider-combo-box.h"
20 #include "modest-easysetup-servertype-combo-box.h"
21 #include "modest-easysetup-serversecurity-combo-box.h"
22 #include "modest-easysetup-secureauth-combo-box.h"
23 #include "modest-validating-entry.h"
24 #include "modest-text-utils.h"
25 #include "modest-account-mgr.h"
26 #include "modest-runtime.h" /* For modest_runtime_get_account_mgr(). */
27 #include <gconf/gconf-client.h>
28 #include <string.h> /* For strlen(). */
29
30 /* Include config.h so that _() works: */
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #define EXAMPLE_EMAIL_ADDRESS "first.last@provider.com"
36
37 G_DEFINE_TYPE (ModestEasysetupWizardDialog, modest_easysetup_wizard_dialog, MODEST_TYPE_WIZARD_DIALOG);
38
39 #define WIZARD_DIALOG_GET_PRIVATE(o) \
40         (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_EASYSETUP_WIZARD_DIALOG, ModestEasysetupWizardDialogPrivate))
41
42 typedef struct _ModestEasysetupWizardDialogPrivate ModestEasysetupWizardDialogPrivate;
43
44 struct _ModestEasysetupWizardDialogPrivate
45 {
46         ModestPresets *presets;
47 };
48
49 static void
50 modest_easysetup_wizard_dialog_get_property (GObject *object, guint property_id,
51                                                                                                                         GValue *value, GParamSpec *pspec)
52 {
53         switch (property_id) {
54         default:
55                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
56         }
57 }
58
59 static void
60 modest_easysetup_wizard_dialog_set_property (GObject *object, guint property_id,
61                                                                                                                         const GValue *value, GParamSpec *pspec)
62 {
63         switch (property_id) {
64         default:
65                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
66         }
67 }
68
69 static void
70 modest_easysetup_wizard_dialog_dispose (GObject *object)
71 {
72         if (G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->dispose)
73                 G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->dispose (object);
74 }
75
76 static void
77 modest_easysetup_wizard_dialog_finalize (GObject *object)
78 {
79         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (object);
80         ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE (self);
81         
82         if (self->account_manager)
83                 g_object_unref (G_OBJECT (self->account_manager));
84                 
85         if (priv->presets)
86                 modest_presets_destroy (priv->presets);
87         
88         G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->finalize (object);
89 }
90
91 static void
92 show_error (GtkWindow *parent_window, const gchar* text);
93
94 static gboolean
95 create_account (ModestEasysetupWizardDialog *self);
96
97 static void
98 create_subsequent_easysetup_pages (ModestEasysetupWizardDialog *self);
99
100 static void
101 set_default_custom_servernames(ModestEasysetupWizardDialog *dialog);
102
103 static void
104 invoke_enable_buttons_vfunc (ModestEasysetupWizardDialog *wizard_dialog)
105 {
106         ModestWizardDialogClass *klass = MODEST_WIZARD_DIALOG_GET_CLASS (wizard_dialog);
107         
108         /* Call the vfunc, which may be overridden by derived classes: */
109         if (klass->enable_buttons) {
110                 GtkNotebook *notebook = NULL;
111                 g_object_get (wizard_dialog, "wizard-notebook", &notebook, NULL);
112                 
113                 const gint current_page_num = gtk_notebook_get_current_page (notebook);
114                 if (current_page_num == -1)
115                         return;
116                         
117                 GtkWidget* current_page_widget = gtk_notebook_get_nth_page (notebook, current_page_num);
118                 (*(klass->enable_buttons))(MODEST_WIZARD_DIALOG (wizard_dialog), current_page_widget);
119         }
120 }
121
122 static void
123 on_caption_entry_changed (GtkEditable *editable, gpointer user_data)
124 {
125         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
126         g_assert(self);
127         invoke_enable_buttons_vfunc(self);
128 }
129
130 static void
131 on_caption_combobox_changed (GtkComboBox *widget, gpointer user_data)
132 {
133         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
134         g_assert(self);
135         invoke_enable_buttons_vfunc(self);
136 }
137
138 /** This is a convenience function to create a caption containing a mandatory widget.
139  * When the widget is edited, the enable_buttons() vfunc will be called.
140  */
141 static GtkWidget* create_caption_new_with_asterix(ModestEasysetupWizardDialog *self,
142         GtkSizeGroup *group,
143         const gchar *value,
144         GtkWidget *control,
145         GtkWidget *icon,
146         HildonCaptionStatus flag)
147 {
148   GtkWidget *caption = hildon_caption_new (group, value, control, icon, flag);
149   
150 /* The translated strings seem to already contain the *,
151  * but this code can be used if that is not true in future.
152  */
153 #if 0
154         /* Add a * character to indicate mandatory fields,
155          * as specified in our "Email UI Specification": */
156         if (flag == HILDON_CAPTION_MANDATORY) {
157                 gchar* title = g_strdup_printf("%s*", value);
158                 caption = hildon_caption_new (group, title, control, icon, flag);       
159                 g_free(title);
160         }       
161         else
162                 caption = hildon_caption_new (group, value, control, icon, flag);
163 #endif
164
165         /* Connect to the appropriate changed signal for the widget, 
166          * so we can ask for the prev/next buttons to be enabled/disabled appropriately:
167          */
168         if (GTK_IS_ENTRY (control)) {
169                 g_signal_connect (G_OBJECT (control), "changed",
170                 G_CALLBACK (on_caption_entry_changed), self);
171                 
172         }
173         else if (GTK_IS_COMBO_BOX (control)) {
174                 g_signal_connect (G_OBJECT (control), "changed",
175                 G_CALLBACK (on_caption_combobox_changed), self);
176         }
177          
178         return caption;
179 }
180            
181 static GtkWidget*
182 create_page_welcome (ModestEasysetupWizardDialog *self)
183 {
184         GtkWidget *box = gtk_vbox_new (FALSE, 2);
185         GtkWidget *label = gtk_label_new(_("mcen_ia_emailsetup_intro"));
186         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
187         gtk_widget_show (label);
188         gtk_widget_show (GTK_WIDGET (box));
189         return GTK_WIDGET (box);
190 }
191
192 static void
193 on_combo_account_country (GtkComboBox *widget, gpointer user_data)
194 {
195         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
196         g_assert(self);
197         ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE (self);
198         
199         /* Fill the providers combo, based on the selected country: */
200         gint mcc_id = easysetup_country_combo_box_get_active_country_id (
201                 EASYSETUP_COUNTRY_COMBO_BOX (self->combo_account_country));
202         easysetup_provider_combo_box_fill (
203                 EASYSETUP_PROVIDER_COMBO_BOX (self->combo_account_serviceprovider), priv->presets, mcc_id);
204 }
205
206 static void
207 on_combo_account_serviceprovider (GtkComboBox *widget, gpointer user_data)
208 {
209         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
210         g_assert(self);
211         ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE (self);
212         
213         /* Fill the providers combo, based on the selected country: */
214         gchar* provider_id = easysetup_provider_combo_box_get_active_provider_id (
215                 EASYSETUP_PROVIDER_COMBO_BOX (self->combo_account_serviceprovider));
216         
217         gchar* domain_name = NULL;
218         if(provider_id)
219           domain_name = modest_presets_get_domain (priv->presets, provider_id);
220         
221         if(!domain_name)
222                 domain_name = g_strdup (EXAMPLE_EMAIL_ADDRESS);
223                 
224         if (self->entry_user_email)
225                 gtk_entry_set_text (GTK_ENTRY (self->entry_user_email), domain_name);
226                 
227     g_free (domain_name);
228         
229         g_free (provider_id);
230 }
231
232
233 static GtkWidget*
234 create_page_account_details (ModestEasysetupWizardDialog *self)
235 {
236         GtkWidget *box = gtk_vbox_new (FALSE, 2);
237         GtkWidget *label = gtk_label_new(_("mcen_ia_accountdetails"));
238         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 2);
239         gtk_widget_show (label);
240         
241         /* Create a size group to be used by all captions.
242          * Note that HildonCaption does not create a default size group if we do not specify one.
243          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
244         GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
245
246         /* The country widgets: */
247         self->combo_account_country = GTK_WIDGET (easysetup_country_combo_box_new ());
248         GtkWidget *caption = create_caption_new_with_asterix (self, sizegroup, _("mcen_fi_country"), 
249                 self->combo_account_country, NULL, HILDON_CAPTION_OPTIONAL);
250         gtk_widget_show (self->combo_account_country);
251         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
252         gtk_widget_show (caption);
253         
254         /* connect to country combo's changed signal, so we can fill the provider combo: */
255     g_signal_connect (G_OBJECT (self->combo_account_country), "changed",
256             G_CALLBACK (on_combo_account_country), self);
257             
258         
259         /* The service provider widgets: */     
260         self->combo_account_serviceprovider = GTK_WIDGET (easysetup_provider_combo_box_new ());
261         
262         caption = create_caption_new_with_asterix (self, sizegroup, _("mcen_fi_serviceprovider"), 
263                 self->combo_account_serviceprovider, NULL, HILDON_CAPTION_OPTIONAL);
264         gtk_widget_show (self->combo_account_serviceprovider);
265         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
266         gtk_widget_show (caption);
267         
268         /* connect to providers combo's changed signal, so we can fill the email address: */
269     g_signal_connect (G_OBJECT (self->combo_account_serviceprovider), "changed",
270             G_CALLBACK (on_combo_account_serviceprovider), self);
271         
272         /* TODO: Default to the current country somehow.
273          * But I don't know how to get the information that is specified in the 
274          * "Language and region" control panel. It does not seem be anywhere in gconf. murrayc.
275          *
276          * This is probably not the best choice of gconf key:
277          * This is the  "mcc used in the last pairing", ie. the last connection you made.
278      * set by the osso-operator-wizard package, suggested by Dirk-Jan Binnema.
279      *
280          */
281         GConfClient *client = gconf_client_get_default ();
282         GError *error = NULL;
283         const gchar* key = "/apps/osso/operator-wizard/last_mcc";
284         gint mcc_id = gconf_client_get_int(client, key, &error);
285         
286         if(mcc_id < 0)
287         mcc_id = 0;
288      
289     if (error) {
290         g_warning ("Error getting gconf key %s:\n%s", key, error->message);
291         g_error_free (error);
292         error = NULL;
293         
294         mcc_id = 0;
295     }
296     
297     /* Note that gconf_client_get_int() seems to return 0 without an error if the key is not there
298      * This might just be a Maemo bug.
299      */
300     if (mcc_id == 0) 
301     {
302         /* For now, we default to Finland when there is nothing better: */
303         mcc_id = 244;
304     }
305    
306         easysetup_country_combo_box_set_active_country_id (
307                 EASYSETUP_COUNTRY_COMBO_BOX (self->combo_account_country), mcc_id);
308                 
309         
310         /* The description widgets: */  
311         self->entry_account_title = GTK_WIDGET (easysetup_validating_entry_new ());
312         gtk_entry_set_text( GTK_ENTRY (self->entry_account_title), 
313                 _("mcen_ia_emailsetup_defaultname")); /* default description. */
314         /* TODO: Check if an account with this default name exists, and increment if necessary. */
315                 
316         caption = create_caption_new_with_asterix (self, sizegroup, _("mcen_fi_account_title"), 
317                 self->entry_account_title, NULL, HILDON_CAPTION_MANDATORY);
318         gtk_widget_show (self->entry_account_title);
319         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
320         gtk_widget_show (caption);
321         
322         /* Prevent the use of some characters in the account title, 
323          * as required by our UI specification: */
324         GList *list_prevent = NULL;
325         list_prevent = g_list_append (list_prevent, "\\");
326         list_prevent = g_list_append (list_prevent, "/");
327         list_prevent = g_list_append (list_prevent, ":");
328         list_prevent = g_list_append (list_prevent, "*");
329         list_prevent = g_list_append (list_prevent, "?");
330         list_prevent = g_list_append (list_prevent, "\""); /* The UI spec mentions â€œ, but maybe means ", maybe both. */
331         list_prevent = g_list_append (list_prevent, "“");
332         list_prevent = g_list_append (list_prevent, "<"); 
333         list_prevent = g_list_append (list_prevent, ">"); 
334         list_prevent = g_list_append (list_prevent, "|");
335         list_prevent = g_list_append (list_prevent, "^");       
336         easysetup_validating_entry_set_unallowed_characters (
337                 EASYSETUP_VALIDATING_ENTRY (self->entry_account_title), list_prevent);
338         g_list_free (list_prevent);
339         
340         /* Set max length as in the UI spec:
341          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
342         gtk_entry_set_max_length (GTK_ENTRY (self->entry_account_title), 64);
343         
344         gtk_widget_show (GTK_WIDGET (box));
345         
346         return GTK_WIDGET (box);
347 }
348
349 static GtkWidget*
350 create_page_user_details (ModestEasysetupWizardDialog *self)
351 {
352         GtkWidget *box = gtk_vbox_new (FALSE, 2);
353         
354         /* Create a size group to be used by all captions.
355          * Note that HildonCaption does not create a default size group if we do not specify one.
356          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
357         GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
358          
359         /* The name widgets: */
360         self->entry_user_name = GTK_WIDGET (easysetup_validating_entry_new ());
361         /* Set max length as in the UI spec:
362          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
363         gtk_entry_set_max_length (GTK_ENTRY (self->entry_user_name), 64);
364         GtkWidget *caption = create_caption_new_with_asterix (self, sizegroup, 
365                 _("mcen_li_emailsetup_name"), self->entry_user_name, NULL, HILDON_CAPTION_OPTIONAL);
366         gtk_widget_show (self->entry_user_name);
367         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
368         gtk_widget_show (caption);
369         
370         /* Prevent the use of some characters in the name, 
371          * as required by our UI specification: */
372         GList *list_prevent = NULL;
373         list_prevent = g_list_append (list_prevent, "<");
374         list_prevent = g_list_append (list_prevent, ">");
375         easysetup_validating_entry_set_unallowed_characters (
376                 EASYSETUP_VALIDATING_ENTRY (self->entry_user_name), list_prevent);
377         g_list_free (list_prevent);
378         
379         /* The username widgets: */     
380         self->entry_user_username = GTK_WIDGET (easysetup_validating_entry_new ());
381         caption = create_caption_new_with_asterix (self, sizegroup, _("mail_fi_username"), 
382                 self->entry_user_username, NULL, HILDON_CAPTION_MANDATORY);
383         gtk_widget_show (self->entry_user_username);
384         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
385         gtk_widget_show (caption);
386         
387         /* Prevent the use of some characters in the username, 
388          * as required by our UI specification: */
389         easysetup_validating_entry_set_unallowed_characters_whitespace (
390                 EASYSETUP_VALIDATING_ENTRY (self->entry_user_username));
391         
392         /* Set max length as in the UI spec:
393          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
394         gtk_entry_set_max_length (GTK_ENTRY (self->entry_user_username), 64);
395         
396         /* The password widgets: */     
397         self->entry_user_password = gtk_entry_new ();
398         gtk_entry_set_visibility (GTK_ENTRY (self->entry_user_password), FALSE);
399         /* gtk_entry_set_invisible_char (GTK_ENTRY (self->entry_user_password), '*'); */
400         caption = create_caption_new_with_asterix (self, sizegroup, 
401                 _("mail_fi_password"), self->entry_user_password, NULL, HILDON_CAPTION_OPTIONAL);
402         gtk_widget_show (self->entry_user_password);
403         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
404         gtk_widget_show (caption);
405         
406         /* The email address widgets: */        
407         self->entry_user_email = GTK_WIDGET (easysetup_validating_entry_new ());
408         caption = create_caption_new_with_asterix (self, sizegroup, 
409                 _("mcen_li_emailsetup_email_address"), self->entry_user_email, NULL, HILDON_CAPTION_MANDATORY);
410         gtk_entry_set_text (GTK_ENTRY (self->entry_user_email), EXAMPLE_EMAIL_ADDRESS); /* Default text. */
411         gtk_widget_show (self->entry_user_email);
412         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
413         gtk_widget_show (caption);
414         
415         /* Set max length as in the UI spec:
416          * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
417         gtk_entry_set_max_length (GTK_ENTRY (self->entry_user_email), 64);
418         
419         
420         gtk_widget_show (GTK_WIDGET (box));
421         
422         return GTK_WIDGET (box);
423 }
424
425 static GtkWidget* create_page_complete_easysetup (ModestEasysetupWizardDialog *self)
426 {
427         GtkWidget *box = gtk_vbox_new (FALSE, 2);
428         GtkWidget *label = gtk_label_new(_("mcen_ia_emailsetup_setup_complete"));
429         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
430         gtk_widget_show (label);
431         gtk_widget_show (GTK_WIDGET (box));
432         return GTK_WIDGET (box);
433 }
434
435 /** Change the caption title for the incoming server, 
436  * as specified in the UI spec:
437  */
438 static void update_incoming_server_title (ModestEasysetupWizardDialog *self)
439 {
440         ModestProtocol protocol = easysetup_servertype_combo_box_get_active_servertype (
441                 EASYSETUP_SERVERTYPE_COMBO_BOX (self->combo_incoming_servertype));
442         const gchar* type = 
443                 (protocol == MODEST_PROTOCOL_STORE_POP ? 
444                         _("mail_fi_emailtype_pop3") : 
445                         _("mail_fi_emailtype_imap") );
446                         
447                 
448         /* Note that this produces a compiler warning, 
449          * because the compiler does not know that the translated string will have a %s in it.
450          * I do not see a way to avoid the warning while still using these Logical IDs. murrayc. */
451         gchar* incomingserver_title = g_strdup_printf(_("mcen_li_emailsetup_servertype"), type);
452         g_object_set (G_OBJECT (self->caption_incoming), "label", incomingserver_title, NULL);
453         g_free(incomingserver_title);
454 }
455
456 /** Change the caption title for the incoming server, 
457  * as specified in the UI spec:
458  */
459 static void update_incoming_server_security_choices (ModestEasysetupWizardDialog *self)
460 {
461         ModestProtocol protocol = easysetup_servertype_combo_box_get_active_servertype (
462                 EASYSETUP_SERVERTYPE_COMBO_BOX (self->combo_incoming_servertype));
463         
464         /* Fill the combo with appropriately titled choices for POP or IMAP. */
465         /* The choices are the same, but the titles are different, as in the UI spec. */
466         easysetup_serversecurity_combo_box_fill (
467                 EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_incoming_security), protocol);
468 }
469
470 void on_combo_servertype_changed(GtkComboBox *combobox, gpointer user_data)
471 {
472         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
473         update_incoming_server_title (self);
474         update_incoming_server_security_choices (self);
475 }
476            
477 static GtkWidget* create_page_custom_incoming (ModestEasysetupWizardDialog *self)
478 {
479         GtkWidget *box = gtk_vbox_new (FALSE, 2);
480         
481         /* Create a size group to be used by all captions.
482          * Note that HildonCaption does not create a default size group if we do not specify one.
483          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
484         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
485          
486         /* The incoming server widgets: */
487         if (!self->combo_incoming_servertype)
488                 self->combo_incoming_servertype = GTK_WIDGET (easysetup_servertype_combo_box_new ());
489         easysetup_servertype_combo_box_set_active_servertype (
490                 EASYSETUP_SERVERTYPE_COMBO_BOX (self->combo_incoming_servertype), MODEST_PROTOCOL_STORE_POP);
491         GtkWidget *caption = create_caption_new_with_asterix (self, sizegroup, 
492                 _("mcen_li_emailsetup_type"), self->combo_incoming_servertype, NULL, HILDON_CAPTION_MANDATORY);
493         gtk_widget_show (self->combo_incoming_servertype);
494         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
495         gtk_widget_show (caption);
496         
497         if(!self->entry_incomingserver)
498                 self->entry_incomingserver = gtk_entry_new ();
499         set_default_custom_servernames (self);
500
501         if (self->caption_incoming)
502           gtk_widget_destroy (self->caption_incoming);
503            
504         /* The caption title will be updated in update_incoming_server_title().
505          * so this default text will never be seen: */
506         /* (Note: Changing the title seems pointless. murrayc) */
507         self->caption_incoming = create_caption_new_with_asterix (self, sizegroup, 
508                 "Incoming Server", self->entry_incomingserver, NULL, HILDON_CAPTION_MANDATORY);
509         update_incoming_server_title (self);
510         gtk_widget_show (self->entry_incomingserver);
511         gtk_box_pack_start (GTK_BOX (box), self->caption_incoming, FALSE, FALSE, 2);
512         gtk_widget_show (self->caption_incoming);
513         
514         /* Change the caption title when the servertype changes, 
515          * as in the UI spec: */
516          g_signal_connect (G_OBJECT (self->combo_incoming_servertype), "changed",
517                 G_CALLBACK (on_combo_servertype_changed), self);
518         
519         /* The secure connection widgets: */    
520         if (!self->combo_incoming_security)
521                 self->combo_incoming_security = GTK_WIDGET (easysetup_serversecurity_combo_box_new ());
522         update_incoming_server_security_choices (self);
523         easysetup_serversecurity_combo_box_set_active_serversecurity (
524                 EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_incoming_security), MODEST_PROTOCOL_SECURITY_NONE);
525         caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_connection"), 
526                 self->combo_incoming_security, NULL, HILDON_CAPTION_OPTIONAL);
527         gtk_widget_show (self->combo_incoming_security);
528         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
529         gtk_widget_show (caption);
530         
531         if(!self->checkbox_incoming_auth)
532                 self->checkbox_incoming_auth = 
533                         gtk_check_button_new_with_label (_("mcen_li_emailsetup_secure_authentication"));
534         gtk_box_pack_start (GTK_BOX (box), self->checkbox_incoming_auth, FALSE, FALSE, 2);
535         gtk_widget_show (self->checkbox_incoming_auth);
536         
537         gtk_widget_show (GTK_WIDGET (box));
538         
539         return GTK_WIDGET (box);
540 }
541
542 static void
543 on_toggle_button_changed (GtkToggleButton *togglebutton, gpointer user_data)
544 {
545         GtkWidget *widget = GTK_WIDGET (user_data);
546         
547         /* Enable the widget only if the toggle button is active: */
548         const gboolean enable = gtk_toggle_button_get_active (togglebutton);
549         gtk_widget_set_sensitive (widget, enable);
550 }
551
552 /* Make the sensitivity of a widget depend on a toggle button.
553  */
554 static void
555 enable_widget_for_togglebutton (GtkWidget *widget, GtkToggleButton* button)
556 {
557         g_signal_connect (G_OBJECT (button), "toggled",
558                 G_CALLBACK (on_toggle_button_changed), widget);
559         
560         /* Set the starting sensitivity: */
561         on_toggle_button_changed (button, widget);
562 }
563         
564 static GtkWidget* create_page_custom_outgoing (ModestEasysetupWizardDialog *self)
565 {
566         GtkWidget *box = gtk_vbox_new (FALSE, 2);
567         
568         /* Create a size group to be used by all captions.
569          * Note that HildonCaption does not create a default size group if we do not specify one.
570          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
571         GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
572          
573         /* The outgoing server widgets: */
574         if (!self->entry_outgoingserver)
575                 self->entry_outgoingserver = gtk_entry_new ();
576         GtkWidget *caption = create_caption_new_with_asterix (self, sizegroup, 
577                 _("mcen_li_emailsetup_smtp"), self->entry_outgoingserver, NULL, HILDON_CAPTION_OPTIONAL);
578         gtk_widget_show (self->entry_outgoingserver);
579         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
580         gtk_widget_show (caption);
581         set_default_custom_servernames (self);
582         
583         /* The secure connection widgets: */    
584         if (!self->combo_outgoing_security)
585                 self->combo_outgoing_security = GTK_WIDGET (easysetup_serversecurity_combo_box_new ());
586         easysetup_serversecurity_combo_box_fill (
587                 EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_outgoing_security), MODEST_PROTOCOL_TRANSPORT_SMTP);
588         easysetup_serversecurity_combo_box_set_active_serversecurity (
589                 EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_outgoing_security), MODEST_PROTOCOL_SECURITY_NONE);
590         caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_connection"), 
591                 self->combo_outgoing_security, NULL, HILDON_CAPTION_OPTIONAL);
592         gtk_widget_show (self->combo_outgoing_security);
593         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
594         gtk_widget_show (caption);
595         
596         /* The secure authentication widgets: */
597         if (!self->combo_outgoing_auth)
598                 self->combo_outgoing_auth = GTK_WIDGET (easysetup_secureauth_combo_box_new ());
599         caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_authentication"), 
600                 self->combo_outgoing_auth, NULL, HILDON_CAPTION_OPTIONAL);
601         gtk_widget_show (self->combo_outgoing_auth);
602         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
603         gtk_widget_show (caption);
604         
605         /* connection-specific checkbox: */
606         if (!self->checkbox_outgoing_smtp_specific) {
607                 self->checkbox_outgoing_smtp_specific = gtk_check_button_new_with_label (_("mcen_fi_advsetup_connection_smtp"));
608                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->checkbox_outgoing_smtp_specific), 
609                         FALSE);
610         }
611         gtk_box_pack_start (GTK_BOX (box), self->checkbox_outgoing_smtp_specific, FALSE, FALSE, 2);
612         gtk_widget_show (self->checkbox_outgoing_smtp_specific);
613         
614         /* Connection-specific SMTP-Severs Edit button: */
615         if (!self->button_outgoing_smtp_servers)
616                 self->button_outgoing_smtp_servers = gtk_button_new_with_label (_("mcen_bd_emailsetup_edit"));
617         caption = hildon_caption_new (sizegroup, _("mcen_fi_advsetup_optional_smtp"), 
618                 self->button_outgoing_smtp_servers, NULL, HILDON_CAPTION_OPTIONAL);
619         gtk_widget_show (self->button_outgoing_smtp_servers);
620         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
621         gtk_widget_show (caption);
622         
623         /* Only enable the button when the checkbox is checked: */
624         enable_widget_for_togglebutton (self->button_outgoing_smtp_servers, 
625                 GTK_TOGGLE_BUTTON (self->checkbox_outgoing_smtp_specific));
626         
627         
628         gtk_widget_show (GTK_WIDGET (box));
629         
630         return GTK_WIDGET (box);
631 }
632
633 static GtkWidget* create_page_complete_custom (ModestEasysetupWizardDialog *self)
634 {
635         GtkWidget *box = gtk_vbox_new (FALSE, 2);
636         GtkWidget *label = gtk_label_new(_("mcen_ia_emailsetup_setup_complete"));
637         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
638         gtk_widget_show (label);
639         
640         if (!self->button_edit)
641                 self->button_edit = gtk_button_new_with_label (_("mcen_bd_emailsetup_edit"));
642         GtkWidget *caption = hildon_caption_new (NULL, _("mcen_fi_advanced_settings"), 
643                 self->button_edit, NULL, HILDON_CAPTION_OPTIONAL);
644         gtk_widget_show (self->button_edit);
645         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 2);
646         gtk_widget_show (caption);
647         
648         gtk_widget_show (GTK_WIDGET (box));
649         return GTK_WIDGET (box);
650 }
651
652
653 /*
654  */
655 static void 
656 on_response (ModestWizardDialog *wizard_dialog,
657         gint response_id,
658         gpointer user_data)
659 {
660         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (wizard_dialog);
661         invoke_enable_buttons_vfunc (self);
662 }
663
664 static void
665 modest_easysetup_wizard_dialog_init (ModestEasysetupWizardDialog *self)
666 {
667         /* Create the notebook to be used by the ModestWizardDialog base class:
668          * Each page of the notebook will be a page of the wizard: */
669         GtkNotebook *notebook = GTK_NOTEBOOK (gtk_notebook_new());
670         
671     /* Set the notebook used by the ModestWizardDialog base class: */
672     g_object_set (G_OBJECT(self), "wizard-notebook", notebook, NULL);
673     
674     /* Set the wizard title:
675      * The actual window title will be a combination of this and the page's tab label title. */
676     g_object_set (G_OBJECT(self), "wizard-name", _("mcen_ti_emailsetup"), NULL);
677
678         /* Read in the information about known service providers: */
679         ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE (self);
680         
681         const gchar* filepath = "/usr/share/operator-wizard/provider-data.keyfile";
682         priv->presets = modest_presets_new (filepath); /* TODO: the actual filepath. */
683         if (!(priv->presets))
684         {
685                 const gchar* filepath_hack = "./src/maemo/easysetup/provider-data-test.keyfile";
686                 g_warning ("Could not locate the official provider data keyfile from %s, "
687                         "so attempting to load it instead from %s", filepath, filepath_hack);
688                 priv->presets = modest_presets_new (filepath_hack); /* TODO: the actual filepath. */
689         }
690         
691         g_assert(priv->presets);
692         
693         
694         /* Get the account manager object, 
695          * so we can check for existing accounts,
696          * and create new accounts: */
697         self->account_manager = modest_runtime_get_account_mgr ();
698         g_assert (self->account_manager);
699         
700     /* Create the common pages, 
701      */
702     self->page_welcome = create_page_welcome (self);
703         self->page_account_details = create_page_account_details (self);
704         self->page_user_details = create_page_user_details (self);
705         
706         /* Add the common pages: */
707         gtk_notebook_append_page (notebook, self->page_welcome, 
708                 gtk_label_new (_("mcen_ti_emailsetup_welcome")));
709         gtk_notebook_append_page (notebook, self->page_account_details, 
710                 gtk_label_new (_("mcen_ti_accountdetails")));
711         gtk_notebook_append_page (notebook, self->page_user_details, 
712                 gtk_label_new (_("mcen_ti_emailsetup_userdetails")));
713                 
714         /* Create and add the easysetup-specific pages,
715          * because we need _some_ final page to enable the Next and Finish buttons: */
716         create_subsequent_easysetup_pages (self);
717
718             
719     /* Connect to the dialog's response signal so we can enable/disable buttons 
720      * for the newly-selected page, because the prev/next buttons cause response to be emitted.
721      * Note that we use g_signal_connect_after() instead of g_signal_connect()
722      * so that we can be enable/disable after ModestWizardDialog has done its own 
723      * enabling/disabling of buttons.
724      * 
725      * HOWEVER, this doesn't work because ModestWizardDialog's response signal handler 
726      * does g_signal_stop_emission_by_name(), stopping our signal handler from running.
727      * 
728      * It's not enough to connect to the notebook's switch-page signal, because 
729      * ModestWizardDialog's "response" signal handler enables the buttons itself, 
730      * _after_ switching the page (understandably).
731      * (Note that if we had, if we used g_signal_connect() instead of g_signal_connect_after()
732      * then gtk_notebook_get_current_page() would return an incorrect value.)
733      */
734     g_signal_connect_after (G_OBJECT (self), "response",
735             G_CALLBACK (on_response), self);       
736 }
737
738 ModestEasysetupWizardDialog*
739 modest_easysetup_wizard_dialog_new (void)
740 {
741         return g_object_new (MODEST_TYPE_EASYSETUP_WIZARD_DIALOG, NULL);
742 }
743
744 static void create_subsequent_customsetup_pages (ModestEasysetupWizardDialog *self)
745 {
746         GtkNotebook *notebook = NULL;
747         g_object_get (self, "wizard-notebook", &notebook, NULL);
748         g_assert(notebook);
749         
750         /* Create the custom pages: */
751         if(!(self->page_custom_incoming)) {
752                 self->page_custom_incoming = create_page_custom_incoming (self);
753         }
754                 
755         if(!(self->page_custom_outgoing)) {
756                 self->page_custom_outgoing = create_page_custom_outgoing (self);
757         }
758         
759         if(!(self->page_complete_customsetup)) {
760                 self->page_complete_customsetup = create_page_complete_custom (self);
761         }
762         
763         if (!gtk_widget_get_parent (GTK_WIDGET (self->page_custom_incoming)))
764                 gtk_notebook_append_page (notebook, self->page_custom_incoming,
765                         gtk_label_new (_("mcen_ti_emailsetup_incomingdetails")));
766         
767         if (!gtk_widget_get_parent (GTK_WIDGET (self->page_custom_outgoing)))           
768                 gtk_notebook_append_page (notebook, self->page_custom_outgoing,
769                         gtk_label_new (_("mcen_ti_emailsetup_outgoingdetails")));
770                 
771         if (!gtk_widget_get_parent (GTK_WIDGET (self->page_complete_customsetup)))
772                 gtk_notebook_append_page (notebook, self->page_complete_customsetup,
773                         gtk_label_new (_("mcen_ti_emailsetup_complete")));
774 }
775         
776 static void create_subsequent_easysetup_pages (ModestEasysetupWizardDialog *self)
777 {
778         GtkNotebook *notebook = NULL;
779         g_object_get (self, "wizard-notebook", &notebook, NULL);
780         g_assert(notebook);
781         
782         /* Create the easysetup-specific pages: */
783         if(!self->page_complete_easysetup)
784                 self->page_complete_easysetup = create_page_complete_easysetup (self);
785
786         if (!gtk_widget_get_parent (GTK_WIDGET (self->page_complete_easysetup)))
787                 gtk_notebook_append_page (notebook, self->page_complete_easysetup, 
788                         gtk_label_new (_("mcen_ti_emailsetup_complete")));
789                         
790 }
791 /* After the user details page,
792  * the following pages depend on whether "Other" was chosen 
793  * in the provider combobox on the account page
794  */
795 static void create_subsequent_pages (ModestEasysetupWizardDialog *self)
796 {
797         if (easysetup_provider_combo_box_get_active_provider_id (
798                 EASYSETUP_PROVIDER_COMBO_BOX (self->combo_account_serviceprovider)) == 0) {
799                 /* "Other..." was selected: */
800                 
801                 /* Make sure that the easysetup pages do not exist: */
802                 if(self->page_complete_easysetup) {
803                         gtk_widget_destroy (self->page_complete_easysetup);
804                         self->page_complete_easysetup = NULL;
805                 }
806                 
807                 create_subsequent_customsetup_pages (self);
808         }       
809         else {
810                 /* A specific provider was selected: */
811                 {
812                         /* Make sure that the custom pages do not exist:
813                          * Because they will be used if they exist, when creating the account. */
814                         if(self->page_custom_incoming) {
815                                 gtk_widget_destroy (self->page_custom_incoming);
816                                 self->page_custom_incoming = NULL;
817                         }
818                         
819                         if(self->page_custom_outgoing) {
820                                 gtk_widget_destroy (self->page_custom_outgoing);
821                                 self->page_custom_outgoing = NULL;
822                         }
823                         
824                         if(self->page_complete_customsetup) {
825                                 gtk_widget_destroy (self->page_complete_customsetup);
826                                 self->page_complete_customsetup = NULL;
827                         }
828                 }
829                 
830                 /* Create the easysetup pages: */
831                 create_subsequent_easysetup_pages (self);
832         }
833 }
834
835 gchar*
836 util_get_default_servername_from_email_address (const gchar* email_address, ModestProtocol servertype)
837 {
838         if (!email_address)
839                 return NULL;
840         
841         gchar* at = g_utf8_strchr (email_address, -1, '@');
842         if (!at || (g_utf8_strlen (at, -1) < 2))
843                 return NULL;
844                 
845         gchar* domain = g_utf8_next_char (at);
846         if(!domain)
847                 return NULL;
848                 
849         const gchar* hostname = NULL;
850         if (servertype == MODEST_PROTOCOL_STORE_POP)
851                 hostname = "pop";
852         else if (servertype == MODEST_PROTOCOL_STORE_IMAP)
853                 hostname = "imap";
854         else if (servertype == MODEST_PROTOCOL_TRANSPORT_SMTP)
855                 hostname = "smtp";
856         
857         if (!hostname)
858                 return NULL;
859                 
860         return g_strdup_printf ("%s.%s", hostname, domain);
861 }
862
863 static void set_default_custom_servernames (ModestEasysetupWizardDialog *account_wizard)
864 {
865         /* Set a default domain for the server, based on the email address,
866          * if no server name was already specified.
867          */
868         const gchar* incoming_existing = gtk_entry_get_text (GTK_ENTRY (account_wizard->entry_incomingserver));
869         if ((!incoming_existing || (strlen(incoming_existing) == 0)) 
870                 && account_wizard->entry_user_email) {
871                 const ModestProtocol protocol = easysetup_servertype_combo_box_get_active_servertype (
872                         EASYSETUP_SERVERTYPE_COMBO_BOX (account_wizard->combo_incoming_servertype));
873                 const gchar* email_address = gtk_entry_get_text (GTK_ENTRY(account_wizard->entry_user_email));
874                 gtk_entry_set_text (GTK_ENTRY (account_wizard->entry_incomingserver), util_get_default_servername_from_email_address (email_address, protocol));
875         }
876         
877         /* Set a default domain for the server, based on the email address,
878          * if no server name was already specified.
879          */
880         const gchar* outgoing_existing = gtk_entry_get_text (GTK_ENTRY (account_wizard->entry_outgoingserver));
881         if ((!outgoing_existing || (strlen(outgoing_existing) == 0)) 
882                 && account_wizard->entry_user_email) {
883                 const gchar* email_address = gtk_entry_get_text (GTK_ENTRY(account_wizard->entry_user_email));
884                 gtk_entry_set_text (GTK_ENTRY (account_wizard->entry_outgoingserver), util_get_default_servername_from_email_address (email_address, MODEST_PROTOCOL_TRANSPORT_SMTP));
885         }
886 }
887
888 static gboolean
889 on_before_next (ModestWizardDialog *dialog, GtkWidget *current_page, GtkWidget *next_page)
890 {
891         ModestEasysetupWizardDialog *account_wizard = MODEST_EASYSETUP_WIZARD_DIALOG (dialog);
892         
893         /* Do extra validation that couldn't be done for every key press,
894          * either because it was too slow,
895          * or because it requires interaction:
896          */
897         if (current_page == account_wizard->page_account_details) {     
898                 /* Check that the title is not already in use: */
899                 const gchar* account_name = gtk_entry_get_text (GTK_ENTRY (account_wizard->entry_account_title));
900                 if ((!account_name) || (strlen(account_name) == 0))
901                         return FALSE;
902                         
903                 gboolean name_in_use = FALSE;
904                 name_in_use = modest_account_mgr_account_exists (account_wizard->account_manager,
905                         account_name, TRUE /*  server_account */);
906                 
907                 if (name_in_use) {
908                         /* Warn the user via a dialog: */
909                         /* TODO: The UI spec says we should increment the title,
910                          * as well as warning. This seems contradictory.
911                          */
912                         show_error (GTK_WINDOW (account_wizard), _("mail_ib_account_name_already_existing."));
913             
914                         return FALSE;
915                 }
916         }
917         else if (current_page == account_wizard->page_user_details) {
918                 /* Check that the email address is valud: */
919                 const gchar* email_address = gtk_entry_get_text (GTK_ENTRY (account_wizard->entry_user_email));
920                 if ((!email_address) || (strlen(email_address) == 0))
921                         return FALSE;
922                         
923                 if (!modest_text_utils_validate_email_address (email_address)) {
924                         /* Warn the user via a dialog: */
925                         show_error (GTK_WINDOW (account_wizard), _("mcen_ib_invalid_email"));
926                                              
927             /* Return focus to the email address entry: */
928             gtk_widget_grab_focus (account_wizard->entry_user_email);
929             
930                         return FALSE;
931                 }
932                 
933                 /* Make sure that the subsequent pages are appropriate for the provider choice. */
934                 create_subsequent_pages (account_wizard);
935         }
936         
937         /* TODO: The UI Spec wants us to check that the servernames are valid, 
938          * but does not specify how.
939          */
940           
941         if(next_page == account_wizard->page_custom_incoming) {
942                 set_default_custom_servernames (account_wizard);
943         }
944         else if (next_page == account_wizard->page_custom_outgoing) {
945                 set_default_custom_servernames (account_wizard);
946         }
947         
948         /* If this is the last page, and this is a click on Finish, 
949          * then attempt to create the dialog.
950          */
951         if(!next_page) /* This is NULL when this is a click on Finish. */
952         {
953                 create_account (account_wizard);
954         }
955         
956         
957         return TRUE;
958 }
959
960 static gboolean entry_is_empty (GtkWidget *entry)
961 {
962         if (!entry)
963                 return FALSE;
964                 
965         const gchar* text = gtk_entry_get_text (GTK_ENTRY (entry));
966         if ((!text) || (strlen(text) == 0))
967                 return TRUE;
968         else
969                 return FALSE;
970 }
971
972 static void
973 on_enable_buttons (ModestWizardDialog *dialog, GtkWidget *current_page)
974 {
975         ModestEasysetupWizardDialog *account_wizard = MODEST_EASYSETUP_WIZARD_DIALOG (dialog);
976         
977         gboolean enable_next = TRUE;
978         if (current_page == account_wizard->page_welcome) {
979                 enable_next = TRUE;
980         }
981         else if (current_page == account_wizard->page_account_details) {
982                 /* The account details title is mandatory: */
983                 if (entry_is_empty(account_wizard->entry_account_title))
984                         enable_next = FALSE;
985         }
986         else if (current_page == account_wizard->page_user_details) {   
987                 /* The user details username is mandatory: */
988                 if (entry_is_empty(account_wizard->entry_user_username))
989                         enable_next = FALSE;
990                         
991                 /* The user details email address is mandatory: */
992                 if (enable_next && entry_is_empty (account_wizard->entry_user_email))
993                         enable_next = FALSE;
994         }
995         else if (current_page == account_wizard->page_custom_incoming) {
996                 /* The custom incoming server is mandatory: */
997                 if (entry_is_empty(account_wizard->entry_incomingserver))
998                         enable_next = FALSE;
999         }
1000                         
1001         /* Enable the buttons, 
1002          * identifying them via their associated response codes:
1003          */
1004         GtkDialog *dialog_base = GTK_DIALOG (dialog);
1005     gtk_dialog_set_response_sensitive (dialog_base,
1006                                        MODEST_WIZARD_DIALOG_NEXT,
1007                                        enable_next);
1008                                        
1009     /* Disable the Finish button until we are on the last page,
1010      * because HildonWizardDialog enables this for all but the first page: */
1011     GtkNotebook *notebook = NULL;
1012         g_object_get (dialog_base, "wizard-notebook", &notebook, NULL);
1013         
1014     gint current = gtk_notebook_get_current_page (notebook);
1015     gint last = gtk_notebook_get_n_pages (notebook) - 1;
1016     gboolean is_last = (current == last);
1017     
1018     if(!is_last) {
1019         gtk_dialog_set_response_sensitive (dialog_base,
1020                                        MODEST_WIZARD_DIALOG_FINISH,
1021                                        FALSE);
1022     }
1023 }
1024
1025 static void
1026 modest_easysetup_wizard_dialog_class_init (ModestEasysetupWizardDialogClass *klass)
1027 {
1028         GObjectClass *object_class = G_OBJECT_CLASS (klass);
1029         g_type_class_add_private (klass, sizeof (ModestEasysetupWizardDialogPrivate));
1030
1031
1032         object_class->get_property = modest_easysetup_wizard_dialog_get_property;
1033         object_class->set_property = modest_easysetup_wizard_dialog_set_property;
1034         object_class->dispose = modest_easysetup_wizard_dialog_dispose;
1035         object_class->finalize = modest_easysetup_wizard_dialog_finalize;
1036         
1037         /* Provide a vfunc implementation so we can decide 
1038          * when to enable/disable the prev/next buttons.
1039          */
1040         ModestWizardDialogClass *base_klass = (ModestWizardDialogClass*)(klass);
1041         base_klass->before_next = on_before_next;
1042         base_klass->enable_buttons = on_enable_buttons;
1043 }
1044  
1045 static void
1046 show_error (GtkWindow *parent_window, const gchar* text)
1047 {
1048         GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
1049                 (GtkDialogFlags)0,
1050                  GTK_MESSAGE_ERROR,
1051                  GTK_BUTTONS_OK,
1052                  text ));
1053                  
1054                  gtk_dialog_run (dialog);
1055                  gtk_widget_destroy (GTK_WIDGET (dialog));
1056 }
1057
1058 /** Attempt to create the account from the information that the user has entered.
1059  * @result: TRUE if the account was successfully created.
1060  */
1061 gboolean
1062 create_account (ModestEasysetupWizardDialog *self)
1063 {
1064         ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE (self);
1065         
1066         const gchar* account_name = gtk_entry_get_text (GTK_ENTRY (self->entry_account_title));
1067
1068         /* Some checks: */
1069         if (!account_name)
1070                 return FALSE;
1071                 
1072         /* We should have checked for this already, 
1073          * and changed that name accordingly, 
1074          * but let's check again just in case:
1075          */
1076         if (modest_account_mgr_account_exists (self->account_manager, account_name, FALSE)) 
1077                 return FALSE;
1078                 
1079         /* username and password (for both incoming and outgoing): */
1080         const gchar* username = gtk_entry_get_text (GTK_ENTRY (self->entry_user_username));
1081         const gchar* password = gtk_entry_get_text (GTK_ENTRY (self->entry_user_password));
1082         
1083         /* Incoming server: */
1084         /* Note: We need something as default for the ModestProtocol values, 
1085          * or modest_account_mgr_add_server_account will fail. */
1086         gchar* servername_incoming = NULL;
1087         ModestProtocol protocol_incoming = MODEST_PROTOCOL_STORE_POP;
1088         ModestProtocol protocol_security_incoming = MODEST_PROTOCOL_SECURITY_NONE;
1089         ModestProtocol protocol_authentication_incoming = MODEST_PROTOCOL_AUTH_NONE;
1090         
1091         /* Get details from the specified presets: */
1092         gchar* provider_id = easysetup_provider_combo_box_get_active_provider_id (
1093                 EASYSETUP_PROVIDER_COMBO_BOX (self->combo_account_serviceprovider));
1094         if(provider_id) {
1095                 /* Use presets: */
1096                 
1097                 servername_incoming = modest_presets_get_server (priv->presets, provider_id, 
1098                         TRUE /* incoming */);
1099                 
1100                 ModestPresetsServerType servertype_incoming = modest_presets_get_info_server_type (priv->presets, provider_id, 
1101                         TRUE /* incoming */);
1102                 
1103         
1104                 /* We don't check for SMTP here as that is impossible for an incoming server. */
1105                 if (servertype_incoming == MODEST_PRESETS_SERVER_TYPE_IMAP)
1106                         protocol_incoming = MODEST_PROTOCOL_STORE_IMAP;
1107                 else if (servertype_incoming == MODEST_PRESETS_SERVER_TYPE_POP)
1108                         protocol_incoming = MODEST_PROTOCOL_STORE_POP;
1109                                 
1110                 ModestPresetsSecurity security_incoming = modest_presets_get_info_server_security (priv->presets, provider_id, 
1111                         TRUE /* incoming */);
1112                         
1113                 
1114                 if (security_incoming & MODEST_PRESETS_SECURITY_SECURE_INCOMING)
1115                         protocol_security_incoming = MODEST_PROTOCOL_SECURITY_SSL; /* TODO: Is this what we want? */
1116                 
1117                 if (security_incoming & MODEST_PRESETS_SECURITY_APOP)
1118                         protocol_authentication_incoming = MODEST_PROTOCOL_AUTH_PASSWORD; /* TODO: Is this what we want? */
1119         }
1120         else {
1121                 /* Use custom pages because no preset was specified: */
1122                 servername_incoming = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->entry_incomingserver) ));
1123                 
1124                 protocol_incoming = easysetup_servertype_combo_box_get_active_servertype (
1125                 EASYSETUP_SERVERTYPE_COMBO_BOX (self->combo_incoming_servertype));
1126                 
1127                 protocol_security_incoming = easysetup_serversecurity_combo_box_get_active_serversecurity (
1128                 EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_incoming_security));
1129                 
1130                 protocol_authentication_incoming = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->checkbox_incoming_auth)) 
1131                         ? MODEST_PROTOCOL_AUTH_PASSWORD
1132                         : MODEST_PROTOCOL_AUTH_NONE;
1133                 
1134         }
1135         
1136         gboolean created = modest_account_mgr_add_server_account (self->account_manager,
1137                 account_name,
1138                 servername_incoming,
1139                 username, password,
1140                 protocol_incoming,
1141                 protocol_security_incoming,
1142                 protocol_authentication_incoming);              
1143                 
1144         g_free (servername_incoming);
1145         
1146         if (!created) {
1147                 /* TODO: Provide a Logical ID for the text: */
1148                 show_error (GTK_WINDOW (self), _("An error occurred while creating the incoming account."));
1149                 return FALSE;   
1150         }
1151         
1152         /* Outgoing server: */
1153         gchar* servername_outgoing = NULL;
1154         ModestProtocol protocol_outgoing = MODEST_PROTOCOL_STORE_POP;
1155         ModestProtocol protocol_security_outgoing = MODEST_PROTOCOL_SECURITY_NONE;
1156         ModestProtocol protocol_authentication_outgoing = MODEST_PROTOCOL_AUTH_NONE;
1157         
1158         if(provider_id) {
1159                 /* Use presets: */
1160                 servername_outgoing = modest_presets_get_server (priv->presets, provider_id, 
1161                         FALSE /* incoming */);
1162                         
1163                 ModestPresetsServerType servertype_outgoing = modest_presets_get_info_server_type (priv->presets, provider_id, 
1164                         FALSE /* incoming */);
1165                 
1166                 /* Note: We need something as default, or modest_account_mgr_add_server_account will fail. */
1167                 protocol_outgoing = MODEST_PROTOCOL_TRANSPORT_SENDMAIL; 
1168                 if (servertype_outgoing == MODEST_PRESETS_SERVER_TYPE_SMTP)
1169                         protocol_outgoing = MODEST_PROTOCOL_TRANSPORT_SMTP; /* TODO: Is this what we want? */
1170                 
1171                 ModestPresetsSecurity security_outgoing = 
1172                         modest_presets_get_info_server_security (priv->presets, provider_id, 
1173                                 FALSE /* incoming */);
1174                         
1175                 protocol_security_outgoing = MODEST_PROTOCOL_SECURITY_NONE;
1176                 if (security_outgoing & MODEST_PRESETS_SECURITY_SECURE_SMTP)
1177                         protocol_security_outgoing = MODEST_PROTOCOL_SECURITY_SSL; /* TODO: Is this what we want? */
1178                 
1179                 protocol_authentication_outgoing = MODEST_PROTOCOL_AUTH_NONE;
1180                 /* TODO: There is no SMTP authentication enum for presets. */
1181         }
1182         else {
1183                 /* Use custom pages because no preset was specified: */
1184                 servername_outgoing = g_strdup (gtk_entry_get_text (GTK_ENTRY (self->entry_outgoingserver) ));
1185                 
1186                 protocol_outgoing = MODEST_PROTOCOL_TRANSPORT_SMTP; /* It's always SMTP for outgoing. */
1187
1188                 protocol_security_outgoing = easysetup_serversecurity_combo_box_get_active_serversecurity (
1189                         EASYSETUP_SERVERSECURITY_COMBO_BOX (self->combo_outgoing_security));
1190                 
1191                 protocol_authentication_outgoing = easysetup_secureauth_combo_box_get_active_secureauth (
1192                         EASYSETUP_SECUREAUTH_COMBO_BOX (self->combo_outgoing_auth));
1193                 
1194                 gboolean specific = gtk_toggle_button_get_active (
1195                         GTK_TOGGLE_BUTTON (self->checkbox_outgoing_smtp_specific));
1196                 
1197         }
1198             
1199         created = modest_account_mgr_add_server_account (self->account_manager,
1200                 account_name,
1201                 servername_outgoing,
1202                 username, password,
1203                 protocol_outgoing,
1204                 protocol_security_outgoing,
1205                 protocol_authentication_outgoing);
1206                 
1207         g_free (servername_outgoing);
1208                 
1209         if (!created) {
1210                 /* TODO: Provide a Logical ID for the text: */
1211                 show_error (GTK_WINDOW (self), _("An error occurred while creating the outgoing account."));
1212                 return FALSE;   
1213         }            
1214         
1215         return FALSE;
1216 }
1217
1218