Added some extra debugging to track problems with
[modest] / src / hildon2 / modest-easysetup-wizard-dialog.c
1
2 /* Copyright (c) 2006, Nokia Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  *   notice, this list of conditions and the following disclaimer in the
13  *   documentation and/or other materials provided with the distribution.
14  * * Neither the name of the Nokia Corporation nor the names of its
15  *   contributors may be used to endorse or promote products derived from
16  *   this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <config.h>
32 #include "modest-easysetup-wizard-dialog.h"
33 #include <glib/gi18n.h>
34 #include <gtk/gtknotebook.h>
35 #include <gtk/gtkvbox.h>
36 #include <gtk/gtklabel.h>
37 #include <gtk/gtkentry.h>
38 #include <gtk/gtkbutton.h>
39 #include <gtk/gtkcheckbutton.h>
40 #include <gtk/gtkmessagedialog.h>
41 #include <gtk/gtkseparator.h>
42 #include "modest-country-picker.h"
43 #include "modest-provider-picker.h"
44 #include "modest-servertype-picker.h"
45 #include "widgets/modest-validating-entry.h"
46 #include "modest-text-utils.h"
47 #include "modest-conf.h"
48 #include "modest-defs.h"
49 #include "modest-account-mgr.h"
50 #include "modest-signal-mgr.h"
51 #include "modest-account-mgr-helpers.h"
52 #include "modest-runtime.h" /* For modest_runtime_get_account_mgr(). */
53 #include "modest-connection-specific-smtp-window.h"
54 #include "widgets/modest-ui-constants.h"
55 #include "widgets/modest-default-account-settings-dialog.h"
56 #include "widgets/modest-easysetup-wizard-page.h"
57 #include "modest-maemo-utils.h"
58 #include "modest-utils.h"
59 #include "modest-hildon-includes.h"
60 #include "modest-maemo-security-options-view.h"
61 #include "modest-account-protocol.h"
62 #include "modest-address-book.h"
63 #include <modest-scrollable.h>
64 #include <modest-toolkit-factory.h>
65
66 /* Include config.h so that _() works: */
67 #ifdef HAVE_CONFIG_H
68 #include <config.h>
69 #endif
70
71 G_DEFINE_TYPE (ModestEasysetupWizardDialog, modest_easysetup_wizard_dialog, MODEST_TYPE_WIZARD_DIALOG);
72
73 #define MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
74                                                     MODEST_TYPE_EASYSETUP_WIZARD_DIALOG, \
75                                                     ModestEasysetupWizardDialogPrivate))
76
77 #define LABELS_WIDTH 520
78 #define DIALOG_WIDTH LABELS_WIDTH + MODEST_MARGIN_DOUBLE
79
80 typedef struct _ModestEasysetupWizardDialogPrivate ModestEasysetupWizardDialogPrivate;
81
82
83 typedef enum {
84         MODEST_EASYSETUP_WIZARD_DIALOG_INCOMING_CHANGED = 0x01,
85         MODEST_EASYSETUP_WIZARD_DIALOG_OUTGOING_CHANGED = 0x02
86 } ModestEasysetupWizardDialogServerChanges;
87
88 struct _ModestEasysetupWizardDialogPrivate
89 {
90         ModestPresets *presets;
91
92         /* Remember what fields the user edited manually to not prefill them
93          * again. */
94         ModestEasysetupWizardDialogServerChanges server_changes;
95
96         /* Check if the user changes a field to show a confirmation dialog */
97         gboolean dirty;
98
99         /* If we have a pending load of settings or not. */
100         gboolean pending_load_settings;
101
102         /* Used by derived widgets to query existing accounts,
103          * and to create new accounts: */
104         ModestAccountMgr *account_manager;
105         ModestAccountSettings *settings;
106
107         /* notebook pages: */
108         GtkWidget *page_welcome;
109         gboolean  check_support_done;
110         guint check_support_show_progress_id;
111         guint check_support_progress_pulse_id;
112         GtkWidget *check_support_cancel_note;
113         GtkWidget *check_support_progress;
114         gint pending_check_support;
115         gboolean destroyed;
116
117         GtkWidget *page_account_details;
118         GtkWidget *account_country_picker;
119         GtkWidget *account_serviceprovider_picker;
120         GtkWidget *entry_account_title;
121         GtkWidget *caption_account_title;
122
123         GtkWidget *page_user_details;
124         GtkWidget *entry_user_name;
125         GtkWidget *entry_user_username;
126         GtkWidget *entry_user_password;
127         GtkWidget *entry_user_email;
128
129         GtkWidget *page_complete_easysetup;
130
131         GtkWidget *page_custom_incoming;
132         GtkWidget *incoming_servertype_picker;
133         GtkWidget *caption_incoming;
134         GtkWidget *entry_incomingserver;
135
136         /* Security widgets */
137         GtkWidget *incoming_security;
138         GtkWidget *outgoing_security;
139
140         GtkWidget *page_custom_outgoing;
141         GtkWidget *entry_outgoingserver;
142         GtkWidget *checkbox_outgoing_smtp_specific;
143         GtkWidget *button_outgoing_smtp_servers;
144
145         GtkWidget *page_complete_customsetup;
146
147         ModestProtocolType last_plugin_protocol_selected;
148         GSList *missing_data_signals;
149 };
150
151 static void save_to_settings (ModestEasysetupWizardDialog *self);
152 static void real_enable_buttons (ModestWizardDialog *dialog, gboolean enable_next);
153 static void on_update_model (ModestWizardDialog *dialog);
154 static gboolean on_save (ModestWizardDialog *dialog);
155 static GList* check_for_supported_auth_methods (ModestEasysetupWizardDialog* self);
156 static gboolean check_has_supported_auth_methods(ModestEasysetupWizardDialog* self);
157 static void check_support_callback (ModestAccountProtocol *protocol,
158                                     gboolean supported,
159                                     gpointer userdata);
160 static void check_support_of_protocols (ModestEasysetupWizardDialog *self);
161 static gboolean check_support_show_progress (gpointer userdata);
162 static gboolean check_support_progress_pulse (gpointer userdata);
163
164 static gboolean
165 on_delete_event (GtkWidget *widget,
166                  GdkEvent *event,
167                  ModestEasysetupWizardDialog *wizard)
168 {
169         gtk_dialog_response (GTK_DIALOG (wizard), GTK_RESPONSE_CANCEL);
170         return TRUE;
171 }
172
173 static void
174 on_easysetup_changed(GtkWidget* widget, ModestEasysetupWizardDialog* wizard)
175 {
176         ModestEasysetupWizardDialogPrivate* priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(wizard);
177         g_return_if_fail (priv != NULL);
178         priv->dirty = TRUE;
179 }
180
181 static void
182 modest_easysetup_wizard_dialog_dispose (GObject *object)
183 {
184         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (object);
185         priv->destroyed = TRUE;
186
187         if (priv->check_support_show_progress_id > 0) {
188                 g_source_remove (priv->check_support_show_progress_id);
189                 priv->check_support_show_progress_id = 0;
190         }
191
192         if (priv->check_support_progress_pulse_id > 0) {
193                 g_source_remove (priv->check_support_progress_pulse_id);
194                 priv->check_support_progress_pulse_id = 0;
195         }
196
197         if (G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->dispose)
198                 G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->dispose (object);
199 }
200
201 static void
202 modest_easysetup_wizard_dialog_finalize (GObject *object)
203 {
204         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (object);
205         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
206         ModestProtocolRegistry *registry;
207         GSList *provider_protos, *node;
208
209         registry = modest_runtime_get_protocol_registry ();
210         provider_protos = modest_protocol_registry_get_by_tag (registry,
211                                                                MODEST_PROTOCOL_REGISTRY_PROVIDER_PROTOCOLS);
212
213         for (node = provider_protos; node != NULL; node = g_slist_next (node)) {
214                 ModestProtocol *proto = MODEST_PROTOCOL (node->data);
215
216                 if (!modest_protocol_registry_protocol_type_has_tag (registry,
217                                                                      modest_protocol_get_type_id (proto),
218                                                                      MODEST_PROTOCOL_REGISTRY_STORE_PROTOCOLS))
219                         continue;
220
221                 if (MODEST_ACCOUNT_PROTOCOL (proto)) {
222                         modest_account_protocol_wizard_finished (MODEST_ACCOUNT_PROTOCOL (proto));
223                 }
224         }
225         g_slist_free (provider_protos);
226
227         if (priv->account_manager)
228                 g_object_unref (G_OBJECT (priv->account_manager));
229
230         if (priv->presets)
231                 modest_presets_destroy (priv->presets);
232
233         if (priv->settings)
234                 g_object_unref (priv->settings);
235
236         if (priv->missing_data_signals) {
237                 modest_signal_mgr_disconnect_all_and_destroy (priv->missing_data_signals);
238                 priv->missing_data_signals = NULL;
239         }
240
241         G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->finalize (object);
242 }
243
244 static void
245 create_subsequent_easysetup_pages (ModestEasysetupWizardDialog *self);
246
247 static void
248 set_default_custom_servernames(ModestEasysetupWizardDialog *dialog);
249
250 static void on_servertype_selector_changed(HildonTouchSelector *selector, gint column, gpointer user_data);
251
252 static gint
253 get_port_from_protocol (ModestProtocolType server_type,
254                         gboolean alternate_port)
255 {
256         int server_port = 0;
257         ModestProtocol *protocol;
258         ModestProtocolRegistry *protocol_registry;
259
260         protocol_registry = modest_runtime_get_protocol_registry ();
261         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, server_type);
262
263         if (alternate_port) {
264                 server_port = modest_account_protocol_get_alternate_port (MODEST_ACCOUNT_PROTOCOL (protocol));
265         } else {
266                 server_port = modest_account_protocol_get_port (MODEST_ACCOUNT_PROTOCOL (protocol));
267         }
268         return server_port;
269 }
270
271 static void
272 invoke_enable_buttons_vfunc (ModestEasysetupWizardDialog *wizard_dialog)
273 {
274         ModestWizardDialogClass *klass = MODEST_WIZARD_DIALOG_GET_CLASS (wizard_dialog);
275
276         /* Call the vfunc, which may be overridden by derived classes: */
277         if (klass->enable_buttons) {
278                 GtkNotebook *notebook = NULL;
279                 g_object_get (wizard_dialog, "wizard-notebook", &notebook, NULL);
280
281                 const gint current_page_num = gtk_notebook_get_current_page (notebook);
282                 if (current_page_num == -1)
283                         return;
284
285                 GtkWidget* current_page_widget = gtk_notebook_get_nth_page (notebook, current_page_num);
286                 (*(klass->enable_buttons))(MODEST_WIZARD_DIALOG (wizard_dialog), current_page_widget);
287         }
288 }
289
290 static void
291 on_caption_entry_changed (GtkEditable *editable, gpointer user_data)
292 {
293         ModestEasysetupWizardDialog *self;
294
295         g_return_if_fail (user_data);
296
297         self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
298
299         invoke_enable_buttons_vfunc(self);
300 }
301
302 static void
303 on_caption_combobox_changed (GtkComboBox *widget, gpointer user_data)
304 {
305         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
306         g_assert(self);
307         invoke_enable_buttons_vfunc(self);
308 }
309
310 static void
311 on_picker_button_value_changed (HildonPickerButton *widget, gpointer user_data)
312 {
313         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
314         g_assert(self);
315         invoke_enable_buttons_vfunc(self);
316 }
317
318 static void
319 on_serviceprovider_picker_button_value_changed (HildonPickerButton *widget, gpointer user_data)
320 {
321         gchar* default_account_name_start;
322         gchar* default_account_name;
323         ModestEasysetupWizardDialog *self;
324         ModestEasysetupWizardDialogPrivate *priv;
325         ModestProviderPickerIdType provider_id_type;
326         ModestProtocol *protocol;
327         gchar *proto_name;
328         ModestProtocolType proto_type;
329         gboolean hide_account_title;
330
331         self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
332         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
333
334         on_picker_button_value_changed (widget, user_data);
335
336         provider_id_type = modest_provider_picker_get_active_id_type (
337                 MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker));
338         if (provider_id_type == MODEST_PROVIDER_PICKER_ID_OTHER) {
339                 default_account_name_start = g_strdup (_("mcen_ia_emailsetup_defaultname"));
340         } else {
341                 GtkWidget *selector;
342
343                 selector = GTK_WIDGET (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (widget)));
344                 default_account_name_start =
345                         g_strdup (hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector)));
346
347         }
348         default_account_name = modest_account_mgr_get_unused_account_display_name (
349                 priv->account_manager, default_account_name_start);
350         g_free (default_account_name_start);
351         default_account_name_start = NULL;
352
353         hide_account_title = FALSE;
354         proto_name = modest_provider_picker_get_active_provider_id (MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker));
355         if (proto_name != NULL) {
356                 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
357                                                                           MODEST_PROTOCOL_REGISTRY_PROVIDER_PROTOCOLS,
358                                                                           proto_name);
359                 if (protocol != NULL) {
360                         proto_type = modest_protocol_get_type_id (protocol);
361
362                         hide_account_title = (modest_protocol_registry_protocol_type_has_tag
363                                               (modest_runtime_get_protocol_registry (),
364                                                proto_type,
365                                                MODEST_PROTOCOL_REGISTRY_SINGLETON_PROVIDER_PROTOCOLS) ||
366                                               modest_protocol_registry_protocol_type_has_tag
367                                               (modest_runtime_get_protocol_registry (),
368                                                proto_type,
369                                                MODEST_PROTOCOL_REGISTRY_MULTI_MAILBOX_PROVIDER_PROTOCOLS));
370                 }
371         }
372
373         if (hide_account_title)
374                 gtk_widget_hide (priv->caption_account_title);
375         else
376                 gtk_widget_show (priv->caption_account_title);
377
378         hildon_entry_set_text (HILDON_ENTRY (priv->entry_account_title), default_account_name);
379         g_free (default_account_name);
380 }
381
382 /** This is a convenience function to create a caption containing a mandatory widget.
383  * When the widget is edited, the enable_buttons() vfunc will be called.
384  */
385 static GtkWidget*
386 create_captioned (ModestEasysetupWizardDialog *self,
387                   GtkSizeGroup *title_size_group,
388                   GtkSizeGroup *value_size_group,
389                   const gchar *value,
390                   gboolean use_markup,
391                   GtkWidget *control)
392 {
393
394         GtkWidget *result;
395         result = modest_maemo_utils_create_captioned_with_size_type (title_size_group, value_size_group,
396                                                                      value, use_markup, control,
397                                                                      MODEST_EDITABLE_SIZE);
398
399         /* Connect to the appropriate changed signal for the widget,
400          * so we can ask for the prev/next buttons to be enabled/disabled appropriately:
401          */
402         if (GTK_IS_ENTRY (control)) {
403                 g_signal_connect (G_OBJECT (control), "changed",
404                                   G_CALLBACK (on_caption_entry_changed), self);
405
406         }
407         else if (GTK_IS_COMBO_BOX (control)) {
408                 g_signal_connect (G_OBJECT (control), "changed",
409                                   G_CALLBACK (on_caption_combobox_changed), self);
410         }
411
412         return result;
413 }
414
415 static GtkWidget*
416 create_page_welcome (ModestEasysetupWizardDialog *self)
417 {
418         GtkWidget *box;
419         GtkWidget *align;
420         GtkWidget *label;
421         GtkWidget *privacy_note;
422         GtkWidget *scrollable;
423         ModestEasysetupWizardDialogPrivate *priv;
424
425         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
426         box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
427         scrollable = modest_toolkit_factory_create_scrollable (modest_runtime_get_toolkit_factory ());
428         label = gtk_label_new(_("mcen_ia_emailsetup_intro"));
429         privacy_note = gtk_label_new (_("mcen_ia_privacy_notice"));
430         align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
431         gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, MODEST_MARGIN_DOUBLE, 0);
432         gtk_widget_set_size_request (label, LABELS_WIDTH, -1);
433         gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
434         gtk_widget_set_size_request (privacy_note, LABELS_WIDTH, -1);
435         gtk_label_set_line_wrap (GTK_LABEL (privacy_note), TRUE);
436         hildon_helper_set_logical_font (privacy_note, "SmallSystemFont");
437         /* So that it is not truncated: */
438         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
439         gtk_misc_set_padding (GTK_MISC (label), MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE);
440         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
441         gtk_box_pack_start (GTK_BOX (box), privacy_note, FALSE, FALSE, 0);
442         gtk_container_add (GTK_CONTAINER (align), box);
443         gtk_widget_show (label);
444         gtk_widget_show (privacy_note);
445
446         modest_scrollable_add_with_viewport (MODEST_SCROLLABLE (scrollable), align);
447         gtk_widget_show (GTK_WIDGET (box));
448         gtk_widget_show (GTK_WIDGET (align));
449         gtk_widget_show (scrollable);
450
451         return GTK_WIDGET (scrollable);
452 }
453
454 static void
455 on_account_country_selector_changed (HildonTouchSelector *widget, gpointer user_data)
456 {
457         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
458         g_assert(self);
459         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
460
461         priv->dirty = TRUE;
462
463         /* Fill the providers picker, based on the selected country: */
464         if (priv->presets != NULL) {
465                 gint mcc = modest_country_picker_get_active_country_mcc (
466                         MODEST_COUNTRY_PICKER (priv->account_country_picker));
467                 modest_provider_picker_fill (
468                         MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker), priv->presets, mcc);
469         }
470 }
471
472 static void
473 update_user_email_from_provider (ModestEasysetupWizardDialog *self)
474 {
475         ModestEasysetupWizardDialogPrivate *priv;
476         gchar* provider_id = NULL, *with_at = NULL;
477
478         g_assert(self);
479         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
480
481         /* Fill the providers combo, based on the selected country: */
482         provider_id = modest_provider_picker_get_active_provider_id (
483                 MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker));
484
485         if (provider_id) {
486                 gchar *domain_name = modest_presets_get_domain (priv->presets, provider_id);
487                 with_at = g_strdup_printf ("%c%s", '@', domain_name);
488                 g_free (domain_name);
489         }
490
491         /* The sample address already contains the '@' */
492         if (!with_at)
493                 with_at = g_strdup (MODEST_EXAMPLE_EMAIL_ADDRESS);
494
495         if (priv->entry_user_email)
496                 hildon_entry_set_text (HILDON_ENTRY (priv->entry_user_email), with_at);
497
498         g_free (with_at);
499         g_free (provider_id);
500 }
501
502 static void
503 on_account_serviceprovider_selector_changed (HildonTouchSelector *widget, gint column, gpointer user_data)
504 {
505         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
506         g_assert(self);
507         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
508
509         priv->dirty = TRUE;
510
511         update_user_email_from_provider (self);
512 }
513
514 static void
515 on_entry_max (ModestValidatingEntry *self, gpointer user_data)
516 {
517         modest_platform_information_banner (GTK_WIDGET (self), NULL,
518                                             _CS("ckdg_ib_maximum_characters_reached"));
519 }
520
521 static GtkWidget*
522 create_page_account_details (ModestEasysetupWizardDialog *self)
523 {
524         GtkWidget *align;
525         GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
526         GtkWidget *label = gtk_label_new(_("mcen_ia_accountdetails"));
527         ModestEasysetupWizardDialogPrivate* priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
528
529         gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
530         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
531         gtk_misc_set_padding (GTK_MISC (label), MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE);
532         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
533         gtk_widget_show (label);
534
535         /* Create a size group to be used by all captions.
536          * Note that HildonCaption does not create a default size group if we do not specify one.
537          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
538         GtkSizeGroup* title_sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
539         GtkSizeGroup* value_sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
540
541         /* The country widgets: */
542         priv->account_country_picker = GTK_WIDGET (modest_country_picker_new (MODEST_EDITABLE_SIZE,
543                                                                               HILDON_BUTTON_ARRANGEMENT_HORIZONTAL));
544         modest_maemo_utils_set_hbutton_layout (title_sizegroup, value_sizegroup,
545                                                _("mcen_fi_country"), priv->account_country_picker);
546         g_signal_connect (G_OBJECT (priv->account_country_picker), "value-changed",
547                           G_CALLBACK (on_picker_button_value_changed), self);
548         gtk_box_pack_start (GTK_BOX (box), priv->account_country_picker, FALSE, FALSE, MODEST_MARGIN_HALF);
549         gtk_widget_show (priv->account_country_picker);
550
551         /* The service provider widgets: */
552         priv->account_serviceprovider_picker = GTK_WIDGET (modest_provider_picker_new (MODEST_EDITABLE_SIZE,
553                                                                                        HILDON_BUTTON_ARRANGEMENT_HORIZONTAL));
554         modest_maemo_utils_set_hbutton_layout (title_sizegroup, value_sizegroup,
555                                                _("mcen_fi_serviceprovider"),
556                                                priv->account_serviceprovider_picker);
557         g_signal_connect (G_OBJECT (priv->account_serviceprovider_picker), "value-changed",
558                           G_CALLBACK (on_serviceprovider_picker_button_value_changed), self);
559         gtk_box_pack_start (GTK_BOX (box), priv->account_serviceprovider_picker, FALSE, FALSE, 0);
560         gtk_widget_show (priv->account_serviceprovider_picker);
561
562         /* The description widgets: */
563         priv->entry_account_title = GTK_WIDGET (modest_validating_entry_new ());
564
565         /* Do use auto-capitalization: */
566         hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_account_title),
567                                          HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
568
569         /* Set a default account title, choosing one that does not already exist: */
570         /* Note that this is irrelevant to the non-user visible name, which we will create later. */
571         gchar* default_account_name_start = g_strdup (_("mcen_ia_emailsetup_defaultname"));
572         gchar* default_account_name = modest_account_mgr_get_unused_account_display_name (
573                 priv->account_manager, default_account_name_start);
574         g_free (default_account_name_start);
575         default_account_name_start = NULL;
576
577         hildon_entry_set_text (HILDON_ENTRY (priv->entry_account_title), default_account_name);
578         g_free (default_account_name);
579         default_account_name = NULL;
580
581         /* Connect signal after changing the text in the entry */
582         g_signal_connect(G_OBJECT(priv->entry_account_title), "changed",
583                          G_CALLBACK(on_easysetup_changed), self);
584
585         priv->caption_account_title = create_captioned (self, title_sizegroup, value_sizegroup,
586                                                         _("mcen_fi_account_title"), FALSE,
587                                                         priv->entry_account_title);
588         gtk_widget_show (priv->entry_account_title);
589         gtk_box_pack_start (GTK_BOX (box), priv->caption_account_title, FALSE, FALSE, 0);
590         gtk_widget_show (priv->caption_account_title);
591         gtk_widget_set_no_show_all (priv->caption_account_title, TRUE);
592
593         /* Prevent the use of some characters in the account title,
594          * as required by our UI specification: */
595         GList *list_prevent = NULL;
596         list_prevent = g_list_append (list_prevent, "\\");
597         list_prevent = g_list_append (list_prevent, "/");
598         list_prevent = g_list_append (list_prevent, ":");
599         list_prevent = g_list_append (list_prevent, "*");
600         list_prevent = g_list_append (list_prevent, "?");
601         list_prevent = g_list_append (list_prevent, "\""); /* The UI spec mentions â€œ, but maybe means ", maybe both. */
602         list_prevent = g_list_append (list_prevent, "“");
603         list_prevent = g_list_append (list_prevent, "<");
604         list_prevent = g_list_append (list_prevent, ">");
605         list_prevent = g_list_append (list_prevent, "|");
606         list_prevent = g_list_append (list_prevent, "^");
607         modest_validating_entry_set_unallowed_characters (
608                 MODEST_VALIDATING_ENTRY (priv->entry_account_title), list_prevent);
609         g_list_free (list_prevent);
610         list_prevent = NULL;
611         modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_account_title),
612                                                                                                                                          modest_utils_on_entry_invalid_character, self);
613
614         /* Set max length as in the UI spec:
615          * The UI spec seems to want us to show a dialog if we hit the maximum. */
616         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_account_title), 64);
617         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_account_title),
618                                               on_entry_max, self);
619
620         gtk_widget_show (GTK_WIDGET (box));
621
622         g_object_unref (title_sizegroup);
623         g_object_unref (value_sizegroup);
624
625         align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
626         gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
627         gtk_widget_show (align);
628         gtk_container_add (GTK_CONTAINER (align), box);
629
630         return GTK_WIDGET (align);
631 }
632
633 static void
634 on_user_username_changed(GtkWidget* widget, ModestEasysetupWizardDialog *self)
635 {
636         ModestEasysetupWizardDialogPrivate* priv;
637         gchar* provider_id = NULL;
638
639         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
640
641         /* Work out the user email address */
642         provider_id = modest_provider_picker_get_active_provider_id (
643                 MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker));
644
645         if (provider_id) {
646                 const gchar *current_username;
647                 gchar *email_address;
648                 gchar *domain_name = modest_presets_get_domain (priv->presets, provider_id);
649
650                 current_username = hildon_entry_get_text (HILDON_ENTRY (priv->entry_user_username));
651
652                 if (current_username && strstr (current_username, "@")) {
653                         email_address = g_strdup (current_username);
654                 } else {
655                         email_address = g_strdup_printf ("%s@%s",
656                                                          current_username,
657                                                          domain_name);
658                 }
659
660                 /* Update the email address */
661                 hildon_entry_set_text (HILDON_ENTRY (priv->entry_user_email), email_address);
662
663                 g_free (email_address);
664                 g_free (domain_name);
665                 g_free (provider_id);
666         }
667
668         /* Update state */
669         on_easysetup_changed(widget, self);
670 }
671
672
673 static GtkWidget*
674 create_page_user_details (ModestEasysetupWizardDialog *self)
675 {
676         GtkSizeGroup* title_sizegroup;
677         GtkSizeGroup* value_sizegroup;
678         GtkWidget *box;
679         ModestEasysetupWizardDialogPrivate *priv;
680         GtkWidget *align;
681         const gchar *my_name;
682
683         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
684
685         /* Create a size group to be used by all captions.
686          * Note that HildonCaption does not create a default size group if we do not specify one.
687          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
688         box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
689         title_sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
690         value_sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
691
692         /* The name widgets: (use auto cap) */
693         priv->entry_user_name = GTK_WIDGET (modest_validating_entry_new ());
694         hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_name),
695                                          HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
696
697         /* Set max length as in the UI spec:
698          * The UI spec seems to want us to show a dialog if we hit the maximum. */
699         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_name), 64);
700         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_name),
701                                               on_entry_max, self);
702         GtkWidget *caption = create_captioned (self, title_sizegroup, value_sizegroup,
703                                                _("mcen_li_emailsetup_name"), FALSE, priv->entry_user_name);
704
705         /* Try to initialize the user name with my own contact */
706         my_name = modest_address_book_get_my_name ();
707         if (my_name)
708                 gtk_entry_set_text (GTK_ENTRY (priv->entry_user_name), my_name);
709
710         g_signal_connect(G_OBJECT(priv->entry_user_name), "changed",
711                          G_CALLBACK(on_easysetup_changed), self);
712         gtk_widget_show (priv->entry_user_name);
713         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 0);
714         gtk_widget_show (caption);
715
716         /* Prevent the use of some characters in the name,
717          * as required by our UI specification: */
718         GList *list_prevent = NULL;
719         list_prevent = g_list_append (list_prevent, "<");
720         list_prevent = g_list_append (list_prevent, ">");
721         modest_validating_entry_set_unallowed_characters (
722                 MODEST_VALIDATING_ENTRY (priv->entry_user_name), list_prevent);
723         modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_user_name),
724                 modest_utils_on_entry_invalid_character, self);
725         g_list_free (list_prevent);
726
727         /* The username widgets: */
728         priv->entry_user_username = GTK_WIDGET (modest_validating_entry_new ());
729         /* Auto-capitalization is the default, so let's turn it off: */
730         hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_username),
731                                          HILDON_GTK_INPUT_MODE_FULL);
732         caption = create_captioned (self, title_sizegroup, value_sizegroup, _("mail_fi_username"), FALSE,
733                                     priv->entry_user_username);
734         gtk_widget_show (priv->entry_user_username);
735         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 0);
736         g_signal_connect(G_OBJECT(priv->entry_user_username), "changed",
737                          G_CALLBACK(on_user_username_changed), self);
738         gtk_widget_show (caption);
739
740         /* Prevent the use of some characters in the username,
741          * as required by our UI specification: */
742         modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_user_username),
743                 modest_utils_on_entry_invalid_character, self);
744
745         /* Set max length as in the UI spec:
746          * The UI spec seems to want us to show a dialog if we hit the maximum. */
747         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_username), 64);
748         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_username),
749                                               on_entry_max, self);
750
751         /* The password widgets: */
752         priv->entry_user_password = hildon_entry_new (MODEST_EDITABLE_SIZE);
753         /* Auto-capitalization is the default, so let's turn it off: */
754         hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_password),
755                                          HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
756         gtk_entry_set_visibility (GTK_ENTRY (priv->entry_user_password), FALSE);
757         /* gtk_entry_set_invisible_char (GTK_ENTRY (priv->entry_user_password), '*'); */
758         caption = create_captioned (self, title_sizegroup, value_sizegroup,
759                                     _("mail_fi_password"), FALSE, priv->entry_user_password);
760         g_signal_connect(G_OBJECT(priv->entry_user_password), "changed",
761                          G_CALLBACK(on_easysetup_changed), self);
762         gtk_widget_show (priv->entry_user_password);
763         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 0);
764         gtk_widget_show (caption);
765
766         /* The email address widgets: */
767         priv->entry_user_email = GTK_WIDGET (modest_validating_entry_new ());
768         /* Auto-capitalization is the default, so let's turn it off: */
769         hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_email), HILDON_GTK_INPUT_MODE_FULL);
770         caption = create_captioned (self, title_sizegroup, value_sizegroup,
771                                     _("mcen_li_emailsetup_email_address"), FALSE, priv->entry_user_email);
772         update_user_email_from_provider (self);
773         gtk_widget_show (priv->entry_user_email);
774         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 0);
775         g_signal_connect(G_OBJECT(priv->entry_user_email), "changed",
776                          G_CALLBACK(on_easysetup_changed), self);
777         gtk_widget_show (caption);
778
779         /* Set max length as in the UI spec:
780          * The UI spec seems to want us to show a dialog if we hit the maximum. */
781         gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_email), 64);
782         modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_email),
783                                               on_entry_max, self);
784
785
786         gtk_widget_show (GTK_WIDGET (box));
787         g_object_unref (title_sizegroup);
788         g_object_unref (value_sizegroup);
789
790         align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
791         gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
792         gtk_widget_show (align);
793         gtk_container_add (GTK_CONTAINER (align), box);
794
795         return GTK_WIDGET (align);
796 }
797
798 static GtkWidget*
799 create_page_complete_easysetup (ModestEasysetupWizardDialog *self)
800 {
801         GtkWidget *align;
802         GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
803
804         GtkWidget *label = gtk_label_new(_("mcen_ia_emailsetup_setup_complete"));
805         gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
806         gtk_widget_set_size_request (label, LABELS_WIDTH, -1);
807         gtk_misc_set_padding (GTK_MISC (label), MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE);
808         gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
809
810         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
811         gtk_widget_show (label);
812
813         label = gtk_label_new (_("mcen_ia_easysetup_complete"));
814         gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
815         gtk_widget_set_size_request (label, LABELS_WIDTH, -1);
816
817         gtk_misc_set_padding (GTK_MISC (label), MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE);
818         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 1.0);
819         gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
820         gtk_widget_show (label);
821
822         gtk_widget_show (GTK_WIDGET (box));
823
824         align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
825         gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
826         gtk_widget_show (align);
827         gtk_container_add (GTK_CONTAINER (align), box);
828
829         return GTK_WIDGET (align);
830 }
831
832 /** Change the caption title for the incoming server,
833  * as specified in the UI spec:
834  */
835 static void
836 update_incoming_server_title (ModestEasysetupWizardDialog *self)
837 {
838         ModestEasysetupWizardDialogPrivate* priv;
839         ModestProtocolType protocol_type;
840         ModestProtocolRegistry *protocol_registry;
841
842         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
843         protocol_registry = modest_runtime_get_protocol_registry ();
844
845         protocol_type = modest_servertype_picker_get_active_servertype (
846                 MODEST_SERVERTYPE_PICKER (priv->incoming_servertype_picker));
847
848         /* This could happen when the combo box has still no active iter */
849         if (protocol_type != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
850                 gchar* incomingserver_title;
851                 const gchar *protocol_display_name;
852                 ModestProtocol *protocol;
853
854                 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry,
855                                                                           protocol_type);
856                 protocol_display_name = modest_protocol_get_display_name (protocol);
857
858                 incomingserver_title = g_strconcat (_("mcen_li_emailsetup_servertype"), "\n<small>(",
859                                                     protocol_display_name, ")</small>", NULL);
860
861                 modest_maemo_utils_captioned_set_label (priv->caption_incoming, incomingserver_title, TRUE);
862
863                 g_free(incomingserver_title);
864         }
865 }
866
867 /** Change the caption title for the incoming server,
868  * as specified in the UI spec:
869  */
870 static void
871 update_incoming_server_security_choices (ModestEasysetupWizardDialog *self)
872 {
873         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
874         ModestServertypePicker *server_type_picker;
875         ModestProtocolType protocol_type;
876         ModestSecurityOptionsView *view;
877
878         server_type_picker =
879                 MODEST_SERVERTYPE_PICKER (priv->incoming_servertype_picker);
880         protocol_type =
881                 modest_servertype_picker_get_active_servertype (server_type_picker);
882
883         /* Fill the combo with appropriately titled choices for all
884            those protocols */
885         view = MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security);
886         modest_security_options_view_set_server_type (view, protocol_type);
887 }
888
889 static void
890 on_servertype_selector_changed(HildonTouchSelector *selector, gint column, gpointer user_data)
891 {
892         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
893         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
894
895         priv->dirty = TRUE;
896
897         /* Update title */
898         update_incoming_server_title (self);
899
900         /* Update security options if needed */
901         update_incoming_server_security_choices (self);
902         gtk_widget_show (priv->incoming_security);
903
904         set_default_custom_servernames (self);
905 }
906
907 static void
908 on_entry_incoming_servername_changed(GtkEntry *entry, gpointer user_data)
909 {
910         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
911         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
912         priv->dirty = TRUE;
913         priv->server_changes |= MODEST_EASYSETUP_WIZARD_DIALOG_INCOMING_CHANGED;
914 }
915
916 static GtkWidget*
917 create_page_custom_incoming (ModestEasysetupWizardDialog *self)
918 {
919         ModestProtocolRegistry *protocol_registry;
920         ModestEasysetupWizardDialogPrivate* priv;
921         GtkWidget *box;
922         GtkWidget *align;
923         GtkWidget *scrollable;
924         GtkWidget *label;
925         GtkSizeGroup *title_sizegroup;
926         GtkSizeGroup *value_sizegroup;
927
928         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
929         protocol_registry = modest_runtime_get_protocol_registry ();
930
931         box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
932         scrollable = modest_toolkit_factory_create_scrollable (modest_runtime_get_toolkit_factory ());
933
934         /* Show note that account type cannot be changed in future: */
935         label = gtk_label_new (_("mcen_ia_emailsetup_account_type"));
936         gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
937         gtk_misc_set_padding (GTK_MISC (label), MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE);
938         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
939         gtk_widget_set_size_request (label, LABELS_WIDTH, -1);
940         gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
941         gtk_widget_show (label);
942
943         /* Create a size group to be used by all captions.
944          * Note that HildonCaption does not create a default size group if we do not specify one.
945          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
946         title_sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
947         value_sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
948
949         /* The incoming server widgets: */
950         priv->incoming_servertype_picker = GTK_WIDGET (modest_servertype_picker_new (MODEST_EDITABLE_SIZE,
951                                                                                      HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
952                                                                                      TRUE));
953         modest_maemo_utils_set_hbutton_layout (title_sizegroup, value_sizegroup,
954                                                _("mcen_li_emailsetup_type"),
955                                                priv->incoming_servertype_picker);
956         g_signal_connect (G_OBJECT (priv->incoming_servertype_picker), "value-changed",
957                           G_CALLBACK (on_picker_button_value_changed), self);
958         gtk_box_pack_start (GTK_BOX (box), priv->incoming_servertype_picker, FALSE, FALSE, 0);
959         gtk_widget_show (priv->incoming_servertype_picker);
960
961         priv->entry_incomingserver = hildon_entry_new (MODEST_EDITABLE_SIZE);
962
963         /* Auto-capitalization is the default, so let's turn it off: */
964         hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_incomingserver), HILDON_GTK_INPUT_MODE_FULL);
965         set_default_custom_servernames (self);
966
967         /* The caption title will be updated in update_incoming_server_title().
968          * so this default text will never be seen: */
969         priv->caption_incoming = create_captioned (self, title_sizegroup, value_sizegroup,
970                                                    "This will be removed",
971                                                    FALSE, priv->entry_incomingserver);
972         update_incoming_server_title (self);
973         gtk_widget_show (priv->entry_incomingserver);
974         gtk_box_pack_start (GTK_BOX (box), priv->caption_incoming, FALSE, FALSE, 0);
975         gtk_widget_show (priv->caption_incoming);
976
977         /* Remember when the servername was changed manually: */
978         g_signal_connect (G_OBJECT (priv->entry_incomingserver), "changed",
979                           G_CALLBACK (on_entry_incoming_servername_changed), self);
980
981         /* The secure connection widgets. These are only valid for
982            protocols with security */
983         priv->incoming_security =
984                 modest_maemo_security_options_view_new (MODEST_SECURITY_OPTIONS_INCOMING,
985                                                         FALSE, title_sizegroup, value_sizegroup);
986         gtk_box_pack_start (GTK_BOX (box), priv->incoming_security,
987                             FALSE, FALSE, 0);
988         gtk_widget_show (priv->incoming_security);
989
990         /* Set default selection */
991         modest_servertype_picker_set_active_servertype (
992                 MODEST_SERVERTYPE_PICKER (priv->incoming_servertype_picker),
993                 MODEST_PROTOCOLS_STORE_POP);
994         update_incoming_server_title (self);
995         update_incoming_server_security_choices (self);
996         set_default_custom_servernames (self);
997
998         /* Change the caption title when the servertype changes,
999          * as in the UI spec: */
1000         g_signal_connect (G_OBJECT (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->incoming_servertype_picker))),
1001                           "changed",
1002                           G_CALLBACK (on_servertype_selector_changed), self);
1003
1004         align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
1005         gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, MODEST_MARGIN_DOUBLE, 0);
1006         gtk_widget_show (align);
1007         gtk_container_add (GTK_CONTAINER (align), box);
1008
1009         modest_scrollable_add_with_viewport (MODEST_SCROLLABLE (scrollable), align);
1010         gtk_widget_show (GTK_WIDGET (box));
1011         gtk_widget_show (scrollable);
1012
1013         g_object_unref (title_sizegroup);
1014         g_object_unref (value_sizegroup);
1015
1016         /* Connect changed signals. We do it here after initializing everything */
1017         g_signal_connect (G_OBJECT(priv->entry_incomingserver), "changed",
1018                           G_CALLBACK(on_easysetup_changed), self);
1019
1020
1021         return GTK_WIDGET (scrollable);
1022 }
1023
1024 static void
1025 on_check_button_changed (HildonCheckButton *button, gpointer user_data)
1026 {
1027         GtkWidget *widget = GTK_WIDGET (user_data);
1028
1029         /* Enable the widget only if the check button is active: */
1030         const gboolean enable = hildon_check_button_get_active (button);
1031         gtk_widget_set_sensitive (widget, enable);
1032 }
1033
1034 /* Make the sensitivity of a widget depend on a check button.
1035  */
1036 static void
1037 enable_widget_for_checkbutton (GtkWidget *widget, HildonCheckButton* button)
1038 {
1039         g_signal_connect (G_OBJECT (button), "toggled",
1040                           G_CALLBACK (on_check_button_changed), widget);
1041
1042         /* Set the starting sensitivity: */
1043         on_check_button_changed (button, widget);
1044 }
1045
1046 static void
1047 on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data)
1048 {
1049         ModestEasysetupWizardDialog * self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
1050         ModestEasysetupWizardDialogPrivate* priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
1051         GtkWidget *specific_window;
1052
1053         /* We set dirty here because setting it depending on the connection specific dialog
1054         seems overkill */
1055         priv->dirty = TRUE;
1056
1057         /* Create the window, if necessary: */
1058         specific_window = (GtkWidget *) modest_connection_specific_smtp_window_new ();
1059         modest_connection_specific_smtp_window_fill_with_connections (MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), priv->account_manager);
1060
1061         /* Show the window */
1062         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (specific_window), GTK_WINDOW (self));
1063         gtk_widget_show (specific_window);
1064 }
1065
1066 static void
1067 on_entry_outgoing_servername_changed (GtkEntry *entry, gpointer user_data)
1068 {
1069         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
1070         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1071         priv->server_changes |= MODEST_EASYSETUP_WIZARD_DIALOG_OUTGOING_CHANGED;
1072 }
1073
1074 static GtkWidget*
1075 create_page_custom_outgoing (ModestEasysetupWizardDialog *self)
1076 {
1077         ModestEasysetupWizardDialogPrivate *priv;
1078         gchar *smtp_caption_label;
1079         GtkWidget *scrollable;
1080         GtkWidget *align;
1081         GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
1082
1083         scrollable = modest_toolkit_factory_create_scrollable (modest_runtime_get_toolkit_factory ());
1084
1085         /* Create a size group to be used by all captions.
1086          * Note that HildonCaption does not create a default size group if we do not specify one.
1087          * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1088         GtkSizeGroup *title_sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1089         GtkSizeGroup *value_sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1090
1091         /* The outgoing server widgets: */
1092         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1093         priv->entry_outgoingserver = hildon_entry_new (MODEST_EDITABLE_SIZE);
1094
1095         /* Auto-capitalization is the default, so let's turn it off: */
1096         hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_outgoingserver), HILDON_GTK_INPUT_MODE_FULL);
1097         smtp_caption_label = g_strconcat (_("mcen_li_emailsetup_smtp"), "\n<small>(SMTP)</small>", NULL);
1098         GtkWidget *caption = create_captioned (self, title_sizegroup, value_sizegroup,
1099                                                smtp_caption_label, TRUE, priv->entry_outgoingserver);
1100         g_free (smtp_caption_label);
1101         gtk_widget_show (priv->entry_outgoingserver);
1102         gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, 0);
1103         gtk_widget_show (caption);
1104         set_default_custom_servernames (self);
1105
1106         /* The secure connection widgets. These are only valid for
1107            protocols with security */
1108         priv->outgoing_security =
1109                 modest_maemo_security_options_view_new (MODEST_SECURITY_OPTIONS_OUTGOING,
1110                                                         FALSE, title_sizegroup, value_sizegroup);
1111         gtk_box_pack_start (GTK_BOX (box), priv->outgoing_security,
1112                             FALSE, FALSE, 0);
1113         gtk_widget_show (priv->outgoing_security);
1114
1115         GtkWidget *separator = gtk_hseparator_new ();
1116         gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, 0);
1117         gtk_widget_show (separator);
1118
1119         /* connection-specific checkbox: */
1120         priv->checkbox_outgoing_smtp_specific = hildon_check_button_new (HILDON_SIZE_FINGER_HEIGHT);
1121         hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->checkbox_outgoing_smtp_specific),
1122                                         FALSE);
1123         gtk_button_set_label (GTK_BUTTON (priv->checkbox_outgoing_smtp_specific),
1124                               _("mcen_fi_advsetup_connection_smtp"));
1125         gtk_button_set_alignment (GTK_BUTTON (priv->checkbox_outgoing_smtp_specific),
1126                                   0.0, 0.5);
1127
1128         gtk_widget_show (priv->checkbox_outgoing_smtp_specific);
1129         gtk_box_pack_start (GTK_BOX (box), priv->checkbox_outgoing_smtp_specific,
1130                             FALSE, FALSE, 0);
1131
1132         /* Connection-specific SMTP-Severs Edit button: */
1133         priv->button_outgoing_smtp_servers = gtk_button_new_with_label (_("mcen_bd_advsetup_optional_smtp"));
1134         hildon_gtk_widget_set_theme_size (priv->button_outgoing_smtp_servers,
1135                                           HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
1136         gtk_widget_show (priv->button_outgoing_smtp_servers);
1137         gtk_box_pack_start (GTK_BOX (box), priv->button_outgoing_smtp_servers,
1138                             FALSE, FALSE, 0);
1139
1140         /* Only enable the button when the checkbox is checked: */
1141         enable_widget_for_checkbutton (priv->button_outgoing_smtp_servers,
1142                                        HILDON_CHECK_BUTTON (priv->checkbox_outgoing_smtp_specific));
1143
1144         g_signal_connect (G_OBJECT (priv->button_outgoing_smtp_servers), "clicked",
1145                           G_CALLBACK (on_button_outgoing_smtp_servers), self);
1146
1147         g_signal_connect (G_OBJECT (priv->entry_outgoingserver), "changed",
1148                           G_CALLBACK (on_entry_outgoing_servername_changed), self);
1149
1150
1151         align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
1152         gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, MODEST_MARGIN_DOUBLE, 0);
1153         gtk_widget_show (align);
1154         gtk_container_add (GTK_CONTAINER (align), box);
1155
1156         modest_scrollable_add_with_viewport (MODEST_SCROLLABLE (scrollable), align);
1157         gtk_widget_show (GTK_WIDGET (box));
1158         gtk_widget_show (scrollable);
1159
1160         g_object_unref (title_sizegroup);
1161         g_object_unref (value_sizegroup);
1162
1163         /* Connect changed signals. We do it here after initializing everything */
1164         g_signal_connect (G_OBJECT (priv->entry_outgoingserver), "changed",
1165                           G_CALLBACK (on_easysetup_changed), self);
1166         g_signal_connect (G_OBJECT (priv->checkbox_outgoing_smtp_specific), "toggled",
1167                           G_CALLBACK (on_easysetup_changed), self);
1168
1169         return GTK_WIDGET (scrollable);
1170 }
1171
1172 static gboolean
1173 show_advanced_edit(gpointer user_data)
1174 {
1175         ModestEasysetupWizardDialog * self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
1176         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1177         gint response;
1178
1179         /* Show the Account Settings window: */
1180         ModestAccountSettingsDialog *dialog = modest_default_account_settings_dialog_new ();
1181         if (priv->pending_load_settings) {
1182                 save_to_settings (self);
1183                 priv->pending_load_settings = FALSE;
1184         }
1185         modest_account_settings_dialog_load_settings (dialog, priv->settings);
1186
1187         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (self));
1188
1189         response = gtk_dialog_run (GTK_DIALOG (dialog));
1190
1191         gtk_widget_destroy (GTK_WIDGET (dialog));
1192
1193         return FALSE; /* Do not call this timeout callback again. */
1194 }
1195
1196 static void
1197 on_button_edit_advanced_settings (GtkButton *button, gpointer user_data)
1198 {
1199         ModestEasysetupWizardDialog * self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
1200
1201         /* Show the Account Settings window: */
1202         show_advanced_edit(self);
1203 }
1204 static GtkWidget*
1205 create_page_complete_custom (ModestEasysetupWizardDialog *self)
1206 {
1207         gchar *complete_string;
1208         GtkWidget *align;
1209         GtkWidget *box;
1210         GtkWidget *label;
1211         GtkWidget *button_edit;
1212
1213         box = gtk_vbox_new (FALSE, MODEST_MARGIN_DEFAULT);
1214         complete_string = g_strconcat (_("mcen_ia_emailsetup_setup_complete"), " ",
1215                                        _("mcen_ia_customsetup_complete"), NULL);
1216         label = gtk_label_new(complete_string);
1217         g_free (complete_string);
1218         gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1219         gtk_widget_set_size_request (label, LABELS_WIDTH, -1);
1220         gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1221         gtk_misc_set_padding (GTK_MISC (label), MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE);
1222         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
1223         gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
1224         gtk_widget_show (label);
1225
1226         button_edit = gtk_button_new_with_label (_("mcen_fi_advanced_settings"));
1227         hildon_gtk_widget_set_theme_size (button_edit, HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
1228         gtk_widget_show (button_edit);
1229         gtk_box_pack_start (GTK_BOX (box), button_edit, FALSE, FALSE, 0);
1230
1231         g_signal_connect (G_OBJECT (button_edit), "clicked",
1232                           G_CALLBACK (on_button_edit_advanced_settings), self);
1233
1234         gtk_widget_show (GTK_WIDGET (box));
1235
1236         align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
1237         gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
1238         gtk_widget_show (align);
1239         gtk_container_add (GTK_CONTAINER (align), box);
1240
1241         return GTK_WIDGET (align);
1242 }
1243
1244
1245 /*
1246  */
1247 static void
1248 on_response (ModestWizardDialog *wizard_dialog,
1249              gint response_id,
1250              gpointer user_data)
1251 {
1252         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (wizard_dialog);
1253
1254         invoke_enable_buttons_vfunc (self);
1255 }
1256
1257 static void
1258 on_response_before (ModestWizardDialog *wizard_dialog,
1259                     gint response_id,
1260                     gpointer user_data)
1261 {
1262         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (wizard_dialog);
1263         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(wizard_dialog);
1264         if (response_id == GTK_RESPONSE_CANCEL) {
1265                 /* This is mostly copied from
1266                  * src/maemo/modest-account-settings-dialog.c */
1267                 if (priv->dirty) {
1268                         gint dialog_response;
1269                         GtkWidget *dialog;
1270
1271                         dialog = hildon_note_new_confirmation ((GtkWindow *) self,
1272                                                                _("imum_nc_wizard_confirm_lose_changes"));
1273
1274                         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
1275                                                      (GtkWindow *) dialog,
1276                                                      (GtkWindow *) wizard_dialog);
1277
1278                         dialog_response = gtk_dialog_run ((GtkDialog *) dialog);
1279                         gtk_widget_destroy (GTK_WIDGET (dialog));
1280
1281                         if (dialog_response != GTK_RESPONSE_OK) {
1282                                 /* Don't let the dialog close */
1283                                 g_signal_stop_emission_by_name (wizard_dialog, "response");
1284                         }
1285                 }
1286         }
1287 }
1288
1289 static void
1290 fill_providers (ModestEasysetupWizardDialog *self)
1291 {
1292         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1293
1294         if (MODEST_IS_COUNTRY_PICKER (priv->account_country_picker)) {
1295 /*              gint mcc = get_default_country_code(); */
1296                 gint mcc;
1297                 /* Fill the combo in an idle call, as it takes a lot of time */
1298                 modest_country_picker_load_data(
1299                         MODEST_COUNTRY_PICKER (priv->account_country_picker));
1300                 /* connect to country picker's changed signal, so we can fill the provider picker: */
1301                 g_signal_connect ((GObject *) priv->account_country_picker,
1302                                   "value-changed",
1303                                   G_CALLBACK (on_account_country_selector_changed), self);
1304
1305                 modest_country_picker_set_active_country_locale (
1306                         MODEST_COUNTRY_PICKER (priv->account_country_picker));
1307                 mcc = modest_country_picker_get_active_country_mcc (
1308                         MODEST_COUNTRY_PICKER (priv->account_country_picker));
1309                 modest_provider_picker_fill (
1310                         MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker),
1311                         priv->presets, mcc);
1312                 /* connect to providers picker's changed signal, so we can fill the email address: */
1313                 g_signal_connect (G_OBJECT (hildon_picker_button_get_selector
1314                                             (HILDON_PICKER_BUTTON (priv->account_serviceprovider_picker))),
1315                                   "changed",
1316                                   G_CALLBACK (on_account_serviceprovider_selector_changed), self);
1317
1318                 modest_provider_picker_set_others_provider (MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker));
1319         }
1320
1321         priv->dirty = FALSE;
1322
1323 }
1324
1325 typedef struct IdleData {
1326         ModestEasysetupWizardDialog *dialog;
1327         ModestPresets *presets;
1328 } IdleData;
1329
1330 static gboolean
1331 presets_idle (gpointer userdata)
1332 {
1333         IdleData *idle_data = (IdleData *) userdata;
1334         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (idle_data->dialog);
1335         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1336
1337         g_assert (idle_data->presets);
1338
1339         gdk_threads_enter ();
1340
1341         priv->presets = idle_data->presets;
1342
1343         if (priv->check_support_done)
1344                 fill_providers (self);
1345
1346         g_object_unref (idle_data->dialog);
1347         g_free (idle_data);
1348
1349         gdk_threads_leave ();
1350
1351         return FALSE;
1352 }
1353
1354 static gpointer
1355 presets_loader (gpointer userdata)
1356 {
1357         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (userdata);
1358         ModestPresets *presets = NULL;
1359         IdleData *idle_data;
1360
1361         const gchar* path  = NULL;
1362         const gchar* path1 = MODEST_PROVIDER_DATA_FILE;
1363         const gchar* path2 = MODEST_FALLBACK_PROVIDER_DATA_FILE;
1364
1365         if (access(path1, R_OK) == 0)
1366                 path = path1;
1367         else if (access(path2, R_OK) == 0)
1368                 path = path2;
1369         else {
1370                 g_warning ("%s: neither '%s' nor '%s' is a readable provider data file",
1371                            __FUNCTION__, path1, path2);
1372                 return NULL;
1373         }
1374
1375         presets = modest_presets_new (path);
1376         if (!presets) {
1377                 g_warning ("%s: failed to parse '%s'", __FUNCTION__, path);
1378                 return NULL;
1379         }
1380
1381         idle_data = g_new0 (IdleData, 1);
1382         idle_data->dialog = self;
1383         idle_data->presets = presets;
1384
1385         g_idle_add (presets_idle, idle_data);
1386
1387         return NULL;
1388 }
1389
1390 static void
1391 modest_easysetup_wizard_dialog_append_page (GtkNotebook *notebook,
1392                                             GtkWidget *page,
1393                                             const gchar *label)
1394 {
1395         gint index;
1396
1397         /* Append page and set attributes */
1398         index = gtk_notebook_append_page (notebook, page, gtk_label_new (label));
1399         gtk_container_child_set (GTK_CONTAINER (notebook), page,
1400                                  "tab-expand", TRUE, "tab-fill", TRUE,
1401                                  NULL);
1402
1403         /* Give focus to page and show it */
1404         gtk_container_set_focus_child (GTK_CONTAINER (notebook), page);
1405         gtk_widget_show (page);
1406 }
1407
1408 static void
1409 init_user_page (ModestEasysetupWizardDialogPrivate *priv)
1410 {
1411         priv->page_user_details = NULL;
1412         priv->entry_user_name = NULL;
1413         priv->entry_user_username = NULL;
1414         priv->entry_user_password = NULL;
1415         priv->entry_user_email = NULL;
1416 }
1417
1418 static void
1419 init_incoming_page (ModestEasysetupWizardDialogPrivate *priv)
1420 {
1421         priv->page_custom_incoming = NULL;
1422         priv->incoming_servertype_picker = NULL;
1423         priv->caption_incoming = NULL;
1424         priv->entry_incomingserver = NULL;
1425         priv->entry_user_email = NULL;
1426         priv->incoming_security = NULL;
1427 }
1428
1429 static void
1430 init_outgoing_page (ModestEasysetupWizardDialogPrivate *priv)
1431 {
1432         priv->page_custom_outgoing = NULL;
1433         priv->entry_outgoingserver = NULL;
1434         priv->checkbox_outgoing_smtp_specific = NULL;
1435         priv->button_outgoing_smtp_servers = NULL;
1436         priv->outgoing_security = NULL;
1437 }
1438
1439 static void
1440 modest_easysetup_wizard_dialog_init (ModestEasysetupWizardDialog *self)
1441 {
1442         gtk_container_set_border_width (GTK_CONTAINER (self), MODEST_MARGIN_HALF);
1443
1444         /* Create the notebook to be used by the ModestWizardDialog base class:
1445          * Each page of the notebook will be a page of the wizard: */
1446         GtkNotebook *notebook = GTK_NOTEBOOK (gtk_notebook_new());
1447         gtk_widget_set_size_request (GTK_WIDGET (notebook), -1, MODEST_DIALOG_WINDOW_MAX_HEIGHT);
1448
1449         /* Set the notebook used by the ModestWizardDialog base class: */
1450         g_object_set (G_OBJECT(self), "wizard-notebook", notebook, NULL);
1451
1452         /* Set the wizard title:
1453          * The actual window title will be a combination of this and the page's tab label title. */
1454         g_object_set (G_OBJECT(self), "wizard-name", _("mcen_ti_emailsetup"), NULL);
1455
1456         /* Read in the information about known service providers: */
1457         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1458
1459         /* The server fields did not have been manually changed yet */
1460         priv->server_changes = 0;
1461         priv->pending_load_settings = TRUE;
1462
1463         /* Get the account manager object,
1464          * so we can check for existing accounts,
1465          * and create new accounts: */
1466         priv->account_manager = modest_runtime_get_account_mgr ();
1467         g_object_ref (priv->account_manager);
1468
1469         /* Initialize fields */
1470         priv->check_support_done = FALSE;
1471         priv->check_support_show_progress_id = 0;
1472         priv->check_support_progress_pulse_id = 0;
1473         priv->check_support_cancel_note = NULL;
1474         priv->check_support_progress = NULL;
1475         priv->pending_check_support = 0;
1476         priv->destroyed = FALSE;
1477         priv->page_welcome = create_page_welcome (self);
1478         gtk_widget_show (priv->page_welcome);
1479         priv->page_account_details = create_page_account_details (self);
1480
1481         init_user_page (priv);
1482         init_incoming_page (priv);
1483         init_outgoing_page (priv);
1484
1485         priv->page_complete_easysetup = NULL;
1486         priv->page_complete_customsetup = NULL;
1487         priv->last_plugin_protocol_selected = MODEST_PROTOCOL_REGISTRY_TYPE_INVALID;
1488         priv->missing_data_signals = NULL;
1489
1490         /* Add the common pages */
1491         modest_easysetup_wizard_dialog_append_page (notebook, priv->page_welcome,
1492                                                     _("mcen_ti_emailsetup_welcome"));
1493         modest_easysetup_wizard_dialog_append_page (notebook, priv->page_account_details,
1494                                                     _("mcen_ti_accountdetails"));
1495
1496         /* Connect to the dialog's response signal so we can enable/disable buttons
1497          * for the newly-selected page, because the prev/next buttons cause response to be emitted.
1498          * Note that we use g_signal_connect_after() instead of g_signal_connect()
1499          * so that we can be enable/disable after ModestWizardDialog has done its own
1500          * enabling/disabling of buttons.
1501          *
1502          * HOWEVER, this doesn't work because ModestWizardDialog's response signal handler
1503          * does g_signal_stop_emission_by_name(), stopping our signal handler from running.
1504          *
1505          * It's not enough to connect to the notebook's switch-page signal, because
1506          * ModestWizardDialog's "response" signal handler enables the buttons itself,
1507          * _after_ switching the page (understandably).
1508          * (Note that if we had, if we used g_signal_connect() instead of g_signal_connect_after()
1509          * then gtk_notebook_get_current_page() would return an incorrect value.)
1510          */
1511         g_signal_connect_after (G_OBJECT (self), "response",
1512                                 G_CALLBACK (on_response), self);
1513
1514         /* This is to show a confirmation dialog when the user hits cancel */
1515         g_signal_connect (G_OBJECT (self), "response",
1516                           G_CALLBACK (on_response_before), self);
1517
1518         g_signal_connect (G_OBJECT (self), "delete-event",
1519                           G_CALLBACK (on_delete_event), self);
1520
1521         /* Reset dirty, because there was no user input until now */
1522         priv->dirty = FALSE;
1523
1524         /* When this window is shown, hibernation should not be possible,
1525          * because there is no sensible way to save the state: */
1526         modest_window_mgr_prevent_hibernation_while_window_is_shown (
1527                 modest_runtime_get_window_mgr (), GTK_WINDOW (self));
1528
1529         /* Load provider presets */
1530         g_object_ref (self);
1531         g_thread_create (presets_loader, self, FALSE, NULL);
1532
1533         priv->settings = modest_account_settings_new ();
1534
1535 }
1536
1537 ModestEasysetupWizardDialog*
1538 modest_easysetup_wizard_dialog_new (void)
1539 {
1540
1541         return g_object_new (MODEST_TYPE_EASYSETUP_WIZARD_DIALOG, NULL);
1542 }
1543
1544 static void
1545 create_subsequent_customsetup_pages (ModestEasysetupWizardDialog *self)
1546 {
1547         ModestEasysetupWizardDialogPrivate *priv;
1548         GtkNotebook *notebook = NULL;
1549
1550         g_object_get (self, "wizard-notebook", &notebook, NULL);
1551         g_assert(notebook);
1552
1553         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1554
1555         if (!priv->page_user_details) {
1556                 priv->page_user_details = create_page_user_details (self);
1557         }
1558
1559         /* Create the custom pages: */
1560         if(!(priv->page_custom_incoming)) {
1561                 priv->page_custom_incoming = create_page_custom_incoming (self);
1562         }
1563
1564         /* TODO: only if needed */
1565         if(!(priv->page_custom_outgoing)) {
1566                 priv->page_custom_outgoing = create_page_custom_outgoing (self);
1567         }
1568
1569         if(!(priv->page_complete_customsetup)) {
1570                 priv->page_complete_customsetup = create_page_complete_custom (self);
1571         }
1572
1573         if (!gtk_widget_get_parent (GTK_WIDGET (priv->page_user_details)))
1574                 modest_easysetup_wizard_dialog_append_page (notebook, priv->page_user_details,
1575                                                             _("mcen_ti_emailsetup_userdetails"));
1576
1577         if (!gtk_widget_get_parent (GTK_WIDGET (priv->page_custom_incoming)))
1578                 modest_easysetup_wizard_dialog_append_page (notebook, priv->page_custom_incoming,
1579                                                             _("mcen_ti_emailsetup_incomingdetails"));
1580
1581         if (!gtk_widget_get_parent (GTK_WIDGET (priv->page_custom_outgoing)))
1582                 modest_easysetup_wizard_dialog_append_page (notebook, priv->page_custom_outgoing,
1583                                                             _("mcen_ti_emailsetup_outgoingdetails"));
1584
1585         if (!gtk_widget_get_parent (GTK_WIDGET (priv->page_complete_customsetup)))
1586                 modest_easysetup_wizard_dialog_append_page (notebook, priv->page_complete_customsetup,
1587                                                             _("mcen_ti_emailsetup_complete"));
1588
1589         /* This is unnecessary with GTK+ 2.10: */
1590         modest_wizard_dialog_force_title_update (MODEST_WIZARD_DIALOG(self));
1591 }
1592
1593 static void
1594 create_subsequent_easysetup_pages (ModestEasysetupWizardDialog *self)
1595 {
1596         ModestEasysetupWizardDialogPrivate *priv;
1597         GtkNotebook *notebook = NULL;
1598
1599         g_object_get (self, "wizard-notebook", &notebook, NULL);
1600         g_assert(notebook);
1601
1602         /* Create the easysetup-specific pages: */
1603         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1604         if(!priv->page_complete_easysetup)
1605                 priv->page_complete_easysetup = create_page_complete_easysetup (self);
1606
1607         if (!gtk_widget_get_parent (GTK_WIDGET (priv->page_complete_easysetup)))
1608                 modest_easysetup_wizard_dialog_append_page (notebook, priv->page_complete_easysetup,
1609                                                             _("mcen_ti_emailsetup_complete"));
1610
1611         /* This is unnecessary with GTK+ 2.10: */
1612         modest_wizard_dialog_force_title_update (MODEST_WIZARD_DIALOG(self));
1613 }
1614
1615 /* */
1616 static void
1617 remove_non_common_tabs (ModestEasysetupWizardDialog *self,
1618                         gboolean remove_user_details)
1619 {
1620         gint starting_tab;
1621         GtkNotebook *notebook;
1622         ModestEasysetupWizardDialogPrivate *priv;
1623
1624         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1625         g_object_get (self, "wizard-notebook", &notebook, NULL);
1626
1627         /* The first 2 tabs are the common ones (welcome tab and the
1628            providers tab), so we always remove starting from the
1629            end */
1630         starting_tab = (remove_user_details) ? 2 : 3;
1631         while (gtk_notebook_get_n_pages (notebook) > starting_tab) {
1632                 /* Disconnect signal */
1633                 GtkWidget *page = gtk_notebook_get_nth_page (notebook, -1);
1634                 if (modest_signal_mgr_is_connected (priv->missing_data_signals, (GObject *) page, "missing-mandatory-data")) {
1635                         priv->missing_data_signals = modest_signal_mgr_disconnect (priv->missing_data_signals,
1636                                                                                    (GObject *) page,
1637                                                                                    "missing-mandatory-data");
1638                 }
1639                 /* Remove page from notebook */
1640                 gtk_notebook_remove_page (notebook, -1);
1641         }
1642 }
1643
1644 static void
1645 on_missing_mandatory_data (ModestAccountProtocol *protocol,
1646                            gboolean missing,
1647                            gpointer user_data)
1648 {
1649         real_enable_buttons (MODEST_WIZARD_DIALOG (user_data), !missing);
1650 }
1651
1652 /* After the user details page,
1653  * the following pages depend on whether "Other" was chosen
1654  * in the provider combobox on the account page
1655  */
1656 static void
1657 create_subsequent_pages (ModestEasysetupWizardDialog *self)
1658 {
1659         ModestEasysetupWizardDialogPrivate *priv;
1660         ModestProviderPicker *picker;
1661         ModestProviderPickerIdType id_type;
1662         GtkNotebook *notebook;
1663
1664         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1665         picker = MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker);
1666         id_type = modest_provider_picker_get_active_id_type (picker);
1667         g_object_get (self, "wizard-notebook", &notebook, NULL);
1668
1669         /* Remove the response override handler for non-plugin
1670            protocols. For plugins it'll be overriden later */
1671         if (id_type != MODEST_PROVIDER_PICKER_ID_PLUGIN_PROTOCOL)
1672                 modest_wizard_dialog_set_response_override_handler (MODEST_WIZARD_DIALOG (self),
1673                                                                     NULL);
1674
1675
1676         if (id_type == MODEST_PROVIDER_PICKER_ID_OTHER) {
1677                 /* "Other..." was selected: */
1678
1679                 /* If we come from a rollbacked easysetup */
1680                 if (priv->page_complete_easysetup) {
1681                         remove_non_common_tabs (self, FALSE);
1682                         priv->page_complete_easysetup = NULL;
1683                 }
1684
1685                 /* If we come from a rollbacked plugin protocol setup */
1686                 if (priv->last_plugin_protocol_selected != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1687                         remove_non_common_tabs (self, TRUE);
1688                         priv->last_plugin_protocol_selected = MODEST_PROTOCOL_REGISTRY_TYPE_INVALID;
1689                         modest_signal_mgr_disconnect_all_and_destroy (priv->missing_data_signals);
1690                         priv->missing_data_signals = NULL;
1691                 }
1692
1693                 create_subsequent_customsetup_pages (self);
1694         } else {
1695                 /* If we come from a rollbacked custom setup */
1696                 if (priv->page_custom_incoming) {
1697                         remove_non_common_tabs (self, TRUE);
1698                         init_user_page (priv);
1699                         init_incoming_page (priv);
1700                         init_outgoing_page (priv);
1701                         init_user_page (priv);
1702                         priv->page_complete_customsetup = NULL;
1703                 }
1704
1705                 /* It's a pluggable protocol and not a provider with presets */
1706                 if (id_type == MODEST_PROVIDER_PICKER_ID_PLUGIN_PROTOCOL) {
1707                         ModestProtocol *protocol;
1708                         gchar *proto_name;
1709                         ModestProtocolType proto_type;
1710                         ModestWizardDialogResponseOverrideFunc response_override;
1711
1712                         /* Get protocol data */
1713                         proto_name = modest_provider_picker_get_active_provider_id (picker);
1714                         protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
1715                                                                                   MODEST_PROTOCOL_REGISTRY_PROVIDER_PROTOCOLS,
1716                                                                                   proto_name);
1717                         proto_type = modest_protocol_get_type_id (protocol);
1718
1719
1720                         /* If we come from a rollbacked easy setup */
1721                         if (priv->last_plugin_protocol_selected != proto_type &&
1722                             priv->page_complete_easysetup) {
1723                                 remove_non_common_tabs (self, TRUE);
1724                                 init_user_page (priv);
1725                                 priv->page_complete_easysetup = NULL;
1726                         }
1727
1728                         /* Ensure that the response override handler
1729                            is set. It might happen that plugins clear
1730                            them incorrectly */
1731                         response_override = modest_account_protocol_get_wizard_response_override
1732                                 (MODEST_ACCOUNT_PROTOCOL (protocol));
1733                         modest_wizard_dialog_set_response_override_handler (MODEST_WIZARD_DIALOG (self),
1734                                                                             response_override);
1735
1736                         if (protocol && MODEST_IS_ACCOUNT_PROTOCOL (protocol) &&
1737                             proto_type != priv->last_plugin_protocol_selected) {
1738                                 ModestPairList *tabs;
1739                                 GSList *tmp;
1740                                 gboolean first_page = TRUE;
1741
1742                                 /* Remember the last selected plugin protocol */
1743                                 priv->last_plugin_protocol_selected = proto_type;
1744
1745                                 /* Get tabs */
1746                                 tabs = modest_account_protocol_get_easysetupwizard_tabs (MODEST_ACCOUNT_PROTOCOL (protocol));
1747                                 tmp = (GSList *) tabs;
1748                                 while (tmp) {
1749                                         ModestPair *pair = (ModestPair *) tmp->data;
1750                                         modest_easysetup_wizard_dialog_append_page (notebook,
1751                                                                                     GTK_WIDGET (pair->second),
1752                                                                                     (const gchar *) pair->first);
1753                                         if (first_page) {
1754                                                 gtk_container_set_focus_child (GTK_CONTAINER (notebook),
1755                                                                                GTK_WIDGET (pair->second));
1756                                                 first_page = FALSE;
1757                                         }
1758
1759                                         /* Connect signals */
1760                                         if (MODEST_IS_EASYSETUP_WIZARD_PAGE (pair->second)) {
1761                                                 priv->missing_data_signals =
1762                                                         modest_signal_mgr_connect (priv->missing_data_signals,
1763                                                                                    G_OBJECT (pair->second),
1764                                                                                    "missing-mandatory-data",
1765                                                                                    G_CALLBACK (on_missing_mandatory_data),
1766                                                                                    self);
1767                                         }
1768
1769                                         g_free (pair->first);
1770                                         tmp = g_slist_next (tmp);
1771                                         /* Critical: if you don't show the page then the dialog will ignore it */
1772 /*                                      gtk_widget_show (GTK_WIDGET (pair->second)); */
1773                                 }
1774                                 modest_pair_list_free (tabs);
1775                         }
1776                         g_free (proto_name);
1777                 } else {
1778                         if (priv->last_plugin_protocol_selected !=
1779                             MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1780                                 remove_non_common_tabs (self, TRUE);
1781                                 init_user_page (priv);
1782                                 priv->page_complete_easysetup = NULL;
1783                                 priv->last_plugin_protocol_selected = MODEST_PROTOCOL_REGISTRY_TYPE_INVALID;
1784                                 modest_signal_mgr_disconnect_all_and_destroy (priv->missing_data_signals);
1785                                 priv->missing_data_signals = NULL;
1786                         }
1787                         if (!priv->page_user_details) {
1788                                 priv->page_user_details = create_page_user_details (self);
1789                                 modest_easysetup_wizard_dialog_append_page (notebook,
1790                                                                             priv->page_user_details,
1791                                                                             _("mcen_ti_emailsetup_userdetails"));
1792                         }
1793                 }
1794
1795                 /* Create the easysetup pages: */
1796                 create_subsequent_easysetup_pages (self);
1797         }
1798 }
1799
1800
1801 static gchar*
1802 util_get_default_servername_from_email_address (const gchar* email_address, ModestProtocolType protocol_type)
1803 {
1804         const gchar* hostname = NULL;
1805         gchar* at;
1806         gchar* domain;
1807         ModestProtocolRegistry *protocol_registry;
1808         ModestProtocol *protocol;
1809
1810         if (!email_address)
1811                 return NULL;
1812
1813         at = g_utf8_strchr (email_address, -1, '@');
1814         if (!at || (g_utf8_strlen (at, -1) < 2))
1815                 return NULL;
1816
1817         domain = g_utf8_next_char (at);
1818         if(!domain)
1819                 return NULL;
1820
1821         protocol_registry = modest_runtime_get_protocol_registry ();
1822         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, protocol_type);
1823
1824         if (modest_protocol_registry_protocol_type_has_tag (protocol_registry, protocol_type, MODEST_PROTOCOL_REGISTRY_REMOTE_STORE_PROTOCOLS) ||
1825             modest_protocol_registry_protocol_type_has_tag (protocol_registry, protocol_type, MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS)) {
1826                 hostname = modest_protocol_get_name (protocol);
1827         }
1828
1829         if (!hostname)
1830                 return NULL;
1831
1832         return g_strdup_printf ("%s.%s", hostname, domain);
1833 }
1834
1835 static void
1836 set_default_custom_servernames (ModestEasysetupWizardDialog *self)
1837 {
1838         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
1839
1840         if (!priv->entry_incomingserver)
1841                 return;
1842
1843         /* Set a default domain for the server, based on the email address,
1844          * if no server name was already specified.
1845          */
1846         if (priv->entry_user_email
1847             && ((priv->server_changes & MODEST_EASYSETUP_WIZARD_DIALOG_INCOMING_CHANGED) == 0)) {
1848                 const ModestProtocolType protocol_type = modest_servertype_picker_get_active_servertype (
1849                         MODEST_SERVERTYPE_PICKER (priv->incoming_servertype_picker));
1850
1851                 /* This could happen when the combo box has still no active iter */
1852                 if (protocol_type != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1853                         const gchar* email_address = hildon_entry_get_text (HILDON_ENTRY(priv->entry_user_email));
1854                         gchar* servername = util_get_default_servername_from_email_address (email_address,
1855                                                                                             protocol_type);
1856
1857                         /* Do not set the INCOMING_CHANGED flag because of this edit */
1858                         g_signal_handlers_block_by_func (G_OBJECT (priv->entry_incomingserver), G_CALLBACK (on_entry_incoming_servername_changed), self);
1859                         hildon_entry_set_text (HILDON_ENTRY (priv->entry_incomingserver), servername);
1860                         g_signal_handlers_unblock_by_func (G_OBJECT (priv->entry_incomingserver), G_CALLBACK (on_entry_incoming_servername_changed), self);
1861
1862                         g_free (servername);
1863                 }
1864         }
1865
1866         /* Set a default domain for the server, based on the email address,
1867          * if no server name was already specified.
1868          */
1869         if (!priv->entry_outgoingserver)
1870                 return;
1871
1872         if (priv->entry_user_email
1873             && ((priv->server_changes & MODEST_EASYSETUP_WIZARD_DIALOG_OUTGOING_CHANGED) == 0)) {
1874                 const gchar* email_address = hildon_entry_get_text (HILDON_ENTRY(priv->entry_user_email));
1875
1876                 gchar* servername = util_get_default_servername_from_email_address (email_address, MODEST_PROTOCOLS_TRANSPORT_SMTP);
1877
1878                 /* Do not set the OUTGOING_CHANGED flag because of this edit */
1879                 g_signal_handlers_block_by_func (G_OBJECT (priv->entry_outgoingserver), G_CALLBACK (on_entry_outgoing_servername_changed), self);
1880                 hildon_entry_set_text (HILDON_ENTRY (priv->entry_outgoingserver), servername);
1881                 g_signal_handlers_unblock_by_func (G_OBJECT (priv->entry_outgoingserver), G_CALLBACK (on_entry_outgoing_servername_changed), self);
1882
1883                 g_free (servername);
1884         }
1885 }
1886
1887 static gchar*
1888 get_entered_account_title (ModestEasysetupWizardDialog *self)
1889 {
1890         ModestEasysetupWizardDialogPrivate *priv;
1891         const gchar* account_title;
1892
1893         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
1894         account_title = hildon_entry_get_text (HILDON_ENTRY (priv->entry_account_title));
1895
1896         if (!account_title || (g_utf8_strlen (account_title, -1) == 0)) {
1897                 return NULL;
1898         } else {
1899                 /* Strip it of whitespace at the start and end: */
1900                 gchar *result = g_strdup (account_title);
1901                 result = g_strstrip (result);
1902
1903                 if (!result)
1904                         return NULL;
1905
1906                 if (g_utf8_strlen (result, -1) == 0) {
1907                         g_free (result);
1908                         return NULL;
1909                 }
1910
1911                 return result;
1912         }
1913 }
1914
1915 static gboolean
1916 on_before_next (ModestWizardDialog *dialog, GtkWidget *current_page, GtkWidget *next_page)
1917 {
1918         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (dialog);
1919         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
1920         ModestProtocolRegistry *protocol_registry;
1921
1922         protocol_registry = modest_runtime_get_protocol_registry ();
1923
1924         /* if are browsing pages previous to the last one, then we have pending settings in
1925          * this wizard */
1926         if (next_page != NULL)
1927                 priv->pending_load_settings = TRUE;
1928
1929         /* Do extra validation that couldn't be done for every key press,
1930          * either because it was too slow,
1931          * or because it requires interaction:
1932          */
1933         if (current_page == priv->page_welcome) {
1934                 if (!priv->check_support_done) {
1935                         check_support_of_protocols (self);
1936                         return priv->check_support_done;
1937                 }
1938         } else if (current_page == priv->page_account_details) {
1939                 /* Check that the title is not already in use: */
1940                 gchar* account_title = get_entered_account_title (self);
1941                 if (!account_title)
1942                         return FALSE;
1943
1944                 /* Aavoid a clash with an existing display name: */
1945                 const gboolean name_in_use = modest_account_mgr_account_with_display_name_exists (
1946                         priv->account_manager, account_title);
1947                 g_free (account_title);
1948
1949                 if (name_in_use) {
1950                         /* Warn the user via a dialog: */
1951                         modest_platform_system_banner(NULL, NULL, _("mail_ib_account_name_already_existing"));
1952
1953                         return FALSE;
1954                 }
1955
1956                 /* Make sure that the subsequent pages are appropriate for the provider choice. */
1957                 create_subsequent_pages (self);
1958
1959         } else if (current_page == priv->page_user_details) {
1960                 /* Check that the email address is valud: */
1961                 const gchar* email_address = hildon_entry_get_text (HILDON_ENTRY (priv->entry_user_email));
1962                 if ((!email_address) || (g_utf8_strlen (email_address, -1) == 0))
1963                         return FALSE;
1964
1965                 if (!modest_text_utils_validate_email_address (email_address, NULL)) {
1966                         /* Warn the user via a dialog: */
1967                         modest_platform_system_banner (NULL, NULL, _("mcen_ib_invalid_email"));
1968
1969                         /* Return focus to the email address entry: */
1970                         gtk_widget_grab_focus (priv->entry_user_email);
1971                         gtk_editable_select_region (GTK_EDITABLE (priv->entry_user_email), 0, -1);
1972
1973                         return FALSE;
1974                 }
1975         } else if (current_page == priv->page_custom_incoming ||
1976                    current_page == priv->page_custom_outgoing) {
1977
1978                 const gchar *hostname;
1979                 GtkWidget *entry = (current_page == priv->page_custom_incoming) ?
1980                         priv->entry_incomingserver :
1981                         priv->entry_outgoingserver;
1982
1983                 hostname = gtk_entry_get_text (GTK_ENTRY (entry));
1984                 if (!modest_text_utils_validate_domain_name (hostname)) {
1985                         /* Show error */
1986                         modest_platform_information_banner (NULL, NULL, _("mcen_ib_invalid_servername"));
1987
1988                         /* Return focus to the email address entry: */
1989                         gtk_widget_grab_focus (entry);
1990                         gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
1991
1992                         return FALSE;
1993                 }
1994         }
1995
1996         if (next_page == priv->page_custom_incoming) {
1997                 set_default_custom_servernames (self);
1998         } else if (next_page == priv->page_custom_outgoing) {
1999                 set_default_custom_servernames (self);
2000
2001                 /* Check if the server supports secure authentication */
2002                 if (modest_security_options_view_auth_check (MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security)))
2003                         if (!check_has_supported_auth_methods (self))
2004                                 return FALSE;
2005                 gtk_widget_show (priv->outgoing_security);
2006         }
2007
2008         /* If this is the last page, and this is a click on Finish,
2009          * then attempt to create the dialog.
2010          */
2011         if(!next_page &&
2012            current_page != priv->page_account_details) /* This is NULL when this is a click on Finish. */
2013         {
2014                 if (priv->pending_load_settings) {
2015                         save_to_settings (self);
2016                 }
2017
2018                 /* We check if there's already another account with the same configuration */
2019                 if (modest_account_mgr_check_already_configured_account (priv->account_manager, priv->settings)) {
2020                         modest_platform_information_banner (NULL, NULL, _("mail_ib_setting_failed"));
2021                         return FALSE;
2022                 }
2023
2024                 modest_account_mgr_add_account_from_settings (priv->account_manager, priv->settings);
2025         }
2026
2027
2028         return TRUE;
2029 }
2030
2031 static gboolean entry_is_empty (GtkWidget *entry)
2032 {
2033         if (!entry)
2034                 return FALSE;
2035
2036         const gchar* text = hildon_entry_get_text (HILDON_ENTRY (entry));
2037         if ((!text) || (g_utf8_strlen (text, -1) == 0))
2038                 return TRUE;
2039         else {
2040                 /* Strip it of whitespace at the start and end: */
2041                 gchar *stripped = g_strdup (text);
2042                 stripped = g_strstrip (stripped);
2043
2044                 if (!stripped)
2045                         return TRUE;
2046
2047                 const gboolean result = (g_utf8_strlen (stripped, -1) == 0);
2048
2049                 g_free (stripped);
2050                 return result;
2051         }
2052 }
2053
2054 static void
2055 real_enable_buttons (ModestWizardDialog *dialog, gboolean enable_next)
2056 {
2057         GtkNotebook *notebook = NULL;
2058         gboolean is_finish_tab;
2059         GtkWidget *current;
2060         ModestEasysetupWizardDialogPrivate *priv;
2061
2062         /* Get data */
2063         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (dialog);
2064         g_object_get (dialog, "wizard-notebook", &notebook, NULL);
2065
2066         /* Disable the Finish button until we are on the last page,
2067          * because HildonWizardDialog enables this for all but the
2068          * first page */
2069         current = gtk_notebook_get_nth_page (notebook, gtk_notebook_get_current_page (notebook));
2070         is_finish_tab = ((current == priv->page_complete_easysetup) ||
2071                          (current == priv->page_complete_customsetup));
2072
2073         if (is_finish_tab) {
2074                 /* Disable Next on the last page no matter what the
2075                    argument say */
2076                 enable_next = FALSE;
2077         } else {
2078                 /* Not the last one */
2079                 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
2080                                                    MODEST_WIZARD_DIALOG_FINISH,
2081                                                    FALSE);
2082
2083                 /* If the check support is not done then do not enable
2084                    the wizard to continue */
2085                 enable_next = enable_next && priv->pending_check_support == 0;
2086         }
2087
2088         gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
2089                                            MODEST_WIZARD_DIALOG_NEXT,
2090                                            enable_next);
2091 }
2092
2093 static void
2094 on_enable_buttons (ModestWizardDialog *dialog, GtkWidget *current_page)
2095 {
2096         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (dialog);
2097         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2098
2099         gboolean enable_next = TRUE;
2100         if (current_page == priv->page_welcome) {
2101                 enable_next = TRUE;
2102         } else if (current_page == priv->page_account_details) {
2103                 /* The account details title is mandatory: */
2104                 if (entry_is_empty(priv->entry_account_title))
2105                         enable_next = FALSE;
2106         } else if (current_page == priv->page_user_details) {
2107                 /* The user details username is mandatory: */
2108                 if (entry_is_empty(priv->entry_user_username))
2109                         enable_next = FALSE;
2110
2111                 /* The user details email address is mandatory: */
2112                 if (enable_next && entry_is_empty (priv->entry_user_email))
2113                         enable_next = FALSE;
2114         } else if (current_page == priv->page_custom_incoming) {
2115                 /* The custom incoming server is mandatory: */
2116                 if (entry_is_empty(priv->entry_incomingserver))
2117                         enable_next = FALSE;
2118         } else if (MODEST_IS_EASYSETUP_WIZARD_PAGE (current_page)) {
2119                 enable_next = !modest_easysetup_wizard_page_validate (
2120                        MODEST_EASYSETUP_WIZARD_PAGE (current_page));
2121         }
2122
2123         /* Enable/disable buttons */
2124         real_enable_buttons (dialog, enable_next);
2125 }
2126
2127 static void
2128 modest_easysetup_wizard_dialog_class_init (ModestEasysetupWizardDialogClass *klass)
2129 {
2130         GObjectClass *object_class = G_OBJECT_CLASS (klass);
2131         g_type_class_add_private (klass, sizeof (ModestEasysetupWizardDialogPrivate));
2132
2133
2134         object_class->dispose = modest_easysetup_wizard_dialog_dispose;
2135         object_class->finalize = modest_easysetup_wizard_dialog_finalize;
2136
2137         /* Provide a vfunc implementation so we can decide
2138          * when to enable/disable the prev/next buttons.
2139          */
2140         ModestWizardDialogClass *base_klass = (ModestWizardDialogClass*)(klass);
2141         base_klass->before_next = on_before_next;
2142         base_klass->enable_buttons = on_enable_buttons;
2143         base_klass->update_model = on_update_model;
2144         base_klass->save = on_save;
2145 }
2146
2147 static void
2148 check_username_for_provider (const gchar *provider_id,
2149                              const gchar *domain,
2150                              gchar **username)
2151 {
2152         gchar *providers_to_check[] = { "ovi.com", "yahoomailplus.com", "hotmail.com" };
2153         gint i;
2154         gboolean found = FALSE;
2155         gchar *old;
2156
2157         /* Check if the username contains the @hostname, if not then add it */
2158         if (strchr (*username, '@'))
2159                 return;
2160
2161         /* Check if it's one of the providers to check */
2162         for (i = 0; i < G_N_ELEMENTS (providers_to_check) && !found; i++) {
2163                 if (!g_ascii_strncasecmp (providers_to_check[i], provider_id, strlen (providers_to_check[i])))
2164                         found = TRUE;
2165         }
2166
2167         if (!found)
2168                 return;
2169
2170         /* Replace the username */
2171         old = *username;
2172         *username = g_strconcat (*username, "@", domain, NULL);
2173         g_free (old);
2174 }
2175
2176 /**
2177  * save_to_settings:
2178  * @self: a #ModestEasysetupWizardDialog
2179  *
2180  * takes information from all the wizard and stores it in settings
2181  */
2182 static void
2183 save_to_settings (ModestEasysetupWizardDialog *self)
2184 {
2185         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2186         guint special_port;
2187         gchar *provider_id = NULL;
2188         gchar *alternate_username = NULL;
2189         gchar *display_name;
2190         const gchar *username, *password;
2191         gchar *store_hostname, *transport_hostname;
2192         guint store_port, transport_port;
2193         ModestProtocolRegistry *protocol_registry;
2194         ModestProtocolType store_protocol, transport_protocol;
2195         ModestProtocolType store_security, transport_security;
2196         ModestProtocolType store_auth_protocol, transport_auth_protocol;
2197         ModestServerAccountSettings *store_settings, *transport_settings;
2198         const gchar *fullname, *email_address;
2199         ModestProviderPicker *picker;
2200         ModestProviderPickerIdType id_type;
2201
2202         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2203         picker = MODEST_PROVIDER_PICKER (priv->account_serviceprovider_picker);
2204         protocol_registry = modest_runtime_get_protocol_registry ();
2205
2206         /* Get details from the specified presets: */
2207         id_type = modest_provider_picker_get_active_id_type (picker);
2208         provider_id = modest_provider_picker_get_active_provider_id (picker);
2209
2210         /* Let the plugin save the settings. We do a return in order
2211            to save an indentation level */
2212         if (id_type == MODEST_PROVIDER_PICKER_ID_PLUGIN_PROTOCOL) {
2213                 ModestProtocol *protocol;
2214
2215                 protocol = modest_protocol_registry_get_protocol_by_name (
2216                        modest_runtime_get_protocol_registry (),
2217                        MODEST_PROTOCOL_REGISTRY_PROVIDER_PROTOCOLS,
2218                        provider_id);
2219
2220                 if (protocol && MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
2221                         gint n_pages, i = 0;
2222                         GtkNotebook *notebook;
2223                         GList *wizard_pages = NULL;
2224
2225                         g_object_get (self, "wizard-notebook", &notebook, NULL);
2226                         n_pages = gtk_notebook_get_n_pages (notebook);
2227                         for (i = 0; i < n_pages; i++) {
2228                                 GtkWidget *page = gtk_notebook_get_nth_page (notebook, i);
2229                                 if (MODEST_IS_EASYSETUP_WIZARD_PAGE (page))
2230                                         wizard_pages  = g_list_append (wizard_pages, page);
2231                         }
2232                         modest_account_protocol_save_wizard_settings (MODEST_ACCOUNT_PROTOCOL (protocol),
2233                                                                       wizard_pages,
2234                                                                       priv->settings);
2235                         g_list_free (wizard_pages);
2236                 } else {
2237                         g_debug ("The selected protocol is a plugin protocol "//
2238                                  "but it's not a ModestAccountProtocol");
2239                 }
2240
2241                 g_free (provider_id);
2242                 return;
2243         }
2244
2245         /* username and password (for both incoming and outgoing): */
2246         username = hildon_entry_get_text (HILDON_ENTRY (priv->entry_user_username));
2247         password = hildon_entry_get_text (HILDON_ENTRY (priv->entry_user_password));
2248
2249         store_settings = modest_account_settings_get_store_settings (priv->settings);
2250         transport_settings = modest_account_settings_get_transport_settings (priv->settings);
2251
2252         /* Incoming server: */
2253         /* Note: We need something as default for the transport store protocol values,
2254          * or modest_account_mgr_add_server_account will fail. */
2255         store_port = 0;
2256         store_protocol = MODEST_PROTOCOL_REGISTRY_TYPE_INVALID;
2257         store_security = MODEST_PROTOCOLS_CONNECTION_NONE;
2258         store_auth_protocol = MODEST_PROTOCOLS_AUTH_NONE;
2259
2260         if (provider_id) {
2261                 ModestProtocolType store_provider_server_type;
2262                 gboolean store_provider_use_alternate_port;
2263                 gchar *domain = NULL;
2264
2265                 /* Use presets: */
2266                 store_hostname = modest_presets_get_server (priv->presets, provider_id,
2267                                                             TRUE /* store */);
2268
2269                 store_provider_server_type = modest_presets_get_info_server_type (priv->presets,
2270                                                                          provider_id,
2271                                                                          TRUE /* store */);
2272                 store_security  = modest_presets_get_info_server_security (priv->presets,
2273                                                                            provider_id,
2274                                                                            TRUE /* store */);
2275                 store_auth_protocol  = modest_presets_get_info_server_auth (priv->presets,
2276                                                                             provider_id,
2277                                                                             TRUE /* store */);
2278                 store_provider_use_alternate_port  = modest_presets_get_info_server_use_alternate_port (priv->presets,
2279                                                                                                         provider_id,
2280                                                                                                         TRUE /* store */);
2281
2282
2283                 /* This is HORRIBLE, but it seems that somehow it helps users
2284                    that do not like to read the user instructions for their
2285                    email accounts */
2286                 domain = modest_presets_get_domain (priv->presets, provider_id);
2287                 if (domain) {
2288                         alternate_username = g_strdup (username);
2289                         check_username_for_provider (provider_id, domain, &alternate_username);
2290                         g_free (domain);
2291                 }
2292
2293                 /* We don't check for SMTP here as that is impossible for an incoming server. */
2294                 if (store_provider_server_type == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID)
2295                         store_protocol = MODEST_PROTOCOLS_STORE_POP;
2296                 else
2297                         store_protocol = store_provider_server_type;
2298
2299                 /* we check if there is a *special* port */
2300                 special_port = modest_presets_get_port (priv->presets, provider_id, TRUE /* incoming */);
2301                 if (special_port != 0) {
2302                         store_port = special_port;
2303                 } else {
2304                         gboolean use_alternate_port = FALSE;
2305                         if (modest_protocol_registry_protocol_type_is_secure (modest_runtime_get_protocol_registry (),
2306                                                                               store_security))
2307                                 use_alternate_port = TRUE;
2308                         store_port = get_port_from_protocol(store_provider_server_type, use_alternate_port);
2309                 }
2310
2311                 modest_server_account_settings_set_security_protocol (store_settings,
2312                                                                       store_security);
2313                 modest_server_account_settings_set_auth_protocol (store_settings,
2314                                                                   store_auth_protocol);
2315                 if (store_port != 0)
2316                         modest_server_account_settings_set_port (store_settings, store_port);
2317         } else {
2318                 /* Use custom pages because no preset was specified: */
2319                 store_hostname = g_strdup (hildon_entry_get_text (HILDON_ENTRY (priv->entry_incomingserver) ));
2320                 store_protocol = modest_servertype_picker_get_active_servertype (
2321                         MODEST_SERVERTYPE_PICKER (priv->incoming_servertype_picker));
2322
2323                 modest_security_options_view_save_settings (
2324                                     MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security),
2325                                     priv->settings);
2326         }
2327
2328         /* now we store the common store account settings */
2329         modest_server_account_settings_set_hostname (store_settings, store_hostname);
2330         modest_server_account_settings_set_username (store_settings, (alternate_username) ? alternate_username : username);
2331         modest_server_account_settings_set_password (store_settings, password);
2332         modest_server_account_settings_set_protocol (store_settings, store_protocol);
2333
2334         g_object_unref (store_settings);
2335         g_free (store_hostname);
2336
2337         /* Outgoing server: */
2338         transport_hostname = NULL;
2339         transport_protocol = MODEST_PROTOCOL_REGISTRY_TYPE_INVALID;
2340         transport_security = MODEST_PROTOCOLS_CONNECTION_NONE;
2341         transport_auth_protocol = MODEST_PROTOCOLS_AUTH_NONE;
2342         transport_port = 0;
2343
2344         if (provider_id) {
2345                 ModestProtocolType transport_provider_server_type;
2346                 ModestProtocolType transport_provider_security;
2347                 gboolean is_secure;
2348
2349                 /* Use presets */
2350                 transport_hostname = modest_presets_get_server (priv->presets, provider_id,
2351                                                                 FALSE /* transport */);
2352
2353                 transport_provider_server_type = modest_presets_get_info_server_type (priv->presets,
2354                                                                                       provider_id,
2355                                                                                       FALSE /* transport */);
2356                 transport_provider_security = modest_presets_get_info_server_security (priv->presets,
2357                                                                                        provider_id,
2358                                                                                        FALSE /* transport */);
2359
2360                 /* Note: We need something as default, or modest_account_mgr_add_server_account will fail. */
2361                 transport_protocol = transport_provider_server_type;
2362                 transport_security = transport_provider_security;
2363                 is_secure = modest_protocol_registry_protocol_type_is_secure (modest_runtime_get_protocol_registry (),
2364                                                                               transport_security);
2365
2366                 /* we check if there is a *special* port */
2367                 special_port = modest_presets_get_port (priv->presets, provider_id,
2368                                                         FALSE /* transport */);
2369                 if (special_port != 0) {
2370                         transport_port = special_port;
2371                 } else {
2372                         gboolean use_alternate_port = FALSE;
2373                         if (transport_security == MODEST_PROTOCOLS_CONNECTION_SSL)
2374                                 use_alternate_port = TRUE;
2375                         transport_port = get_port_from_protocol(transport_provider_server_type, use_alternate_port);
2376                 }
2377
2378                 if (is_secure)
2379                         transport_auth_protocol = MODEST_PROTOCOLS_AUTH_PASSWORD;
2380                 else
2381                         transport_auth_protocol = MODEST_PROTOCOLS_AUTH_NONE;
2382
2383                 modest_server_account_settings_set_security_protocol (transport_settings,
2384                                                                       transport_security);
2385                 modest_server_account_settings_set_auth_protocol (transport_settings,
2386                                                                   transport_auth_protocol);
2387                 if (transport_port != 0)
2388                         modest_server_account_settings_set_port (transport_settings,
2389                                                                  transport_port);
2390         } else {
2391                 ModestProtocolRegistry *registry;
2392                 ModestProtocol *store_proto;
2393
2394                 registry = modest_runtime_get_protocol_registry ();
2395                 /* Use custom pages because no preset was specified: */
2396                 transport_hostname = g_strdup (hildon_entry_get_text (HILDON_ENTRY (priv->entry_outgoingserver) ));
2397
2398                 store_proto = modest_protocol_registry_get_protocol_by_type (registry,
2399                                                                              store_protocol);
2400
2401                 if (transport_protocol == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2402                         /* fallback to SMTP if none was specified */
2403                         g_warning ("No transport protocol was specified for store %d (%s)",
2404                                    modest_protocol_get_type_id (store_proto),
2405                                    modest_protocol_get_display_name (store_proto));
2406                         transport_protocol = MODEST_PROTOCOLS_TRANSPORT_SMTP;
2407                 }
2408
2409                 modest_security_options_view_save_settings (
2410                                     MODEST_SECURITY_OPTIONS_VIEW (priv->outgoing_security),
2411                                     priv->settings);
2412         }
2413
2414         /* now we store the common transport account settings */
2415         modest_server_account_settings_set_hostname (transport_settings, transport_hostname);
2416         modest_server_account_settings_set_username (transport_settings, (alternate_username) ? alternate_username : username);
2417         modest_server_account_settings_set_password (transport_settings, password);
2418         modest_server_account_settings_set_protocol (transport_settings, transport_protocol);
2419
2420         g_object_unref (transport_settings);
2421         g_free (transport_hostname);
2422         if (alternate_username)
2423                 g_free (alternate_username);
2424
2425         fullname = hildon_entry_get_text (HILDON_ENTRY (priv->entry_user_name));
2426         email_address = hildon_entry_get_text (HILDON_ENTRY (priv->entry_user_email));
2427         modest_account_settings_set_fullname (priv->settings, fullname);
2428         modest_account_settings_set_email_address (priv->settings, email_address);
2429         /* we don't set retrieve type to preserve advanced settings if
2430            any. By default account settings are set to headers only */
2431
2432         /* Save the connection-specific SMTP server accounts. */
2433         if (priv->checkbox_outgoing_smtp_specific) {
2434                 modest_account_settings_set_use_connection_specific_smtp
2435                         (priv->settings,
2436                          hildon_check_button_get_active(HILDON_CHECK_BUTTON(priv->checkbox_outgoing_smtp_specific)));
2437         }
2438
2439         display_name = get_entered_account_title (self);
2440         modest_account_settings_set_display_name (priv->settings, display_name);
2441         g_free (display_name);
2442         g_free (provider_id);
2443
2444         /* This values are hardcoded for Fremantle */
2445         modest_account_settings_set_retrieve_type (priv->settings,
2446                                                    MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS);
2447         modest_account_settings_set_retrieve_limit (priv->settings, 20);
2448 }
2449
2450
2451 static void
2452 on_update_model (ModestWizardDialog *dialog)
2453 {
2454         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (dialog);
2455         save_to_settings (self);
2456
2457 }
2458
2459 static gboolean
2460 on_save (ModestWizardDialog *dialog)
2461 {
2462         ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (dialog);
2463         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2464
2465         save_to_settings (self);
2466
2467         if (modest_account_mgr_check_already_configured_account (priv->account_manager, priv->settings)) {
2468                 modest_platform_information_banner (NULL, NULL, _("mail_ib_setting_failed"));
2469                 return FALSE;
2470         }
2471
2472         return modest_account_mgr_add_account_from_settings (priv->account_manager, priv->settings);
2473
2474 }
2475
2476
2477 static GList*
2478 check_for_supported_auth_methods (ModestEasysetupWizardDialog* self)
2479 {
2480         GError *error = NULL;
2481         ModestProtocolType protocol_type;
2482         const gchar* hostname;
2483         const gchar* username;
2484         ModestProtocolType security_protocol_incoming_type;
2485         ModestProtocolRegistry *registry;
2486         int port_num;
2487         GList *list_auth_methods;
2488         ModestEasysetupWizardDialogPrivate *priv;
2489
2490         priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2491         registry = modest_runtime_get_protocol_registry ();
2492         protocol_type = modest_servertype_picker_get_active_servertype (
2493                 MODEST_SERVERTYPE_PICKER (priv->incoming_servertype_picker));
2494         hostname = gtk_entry_get_text(GTK_ENTRY(priv->entry_incomingserver));
2495         username = gtk_entry_get_text(GTK_ENTRY(priv->entry_user_username));
2496         security_protocol_incoming_type = modest_security_options_view_get_connection_protocol
2497                 (MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security));
2498         port_num = get_port_from_protocol(protocol_type, FALSE);
2499         list_auth_methods = modest_utils_get_supported_secure_authentication_methods (protocol_type, hostname, port_num,
2500                                                                                       username, GTK_WINDOW (self), &error);
2501
2502         if (list_auth_methods) {
2503                 /* TODO: Select the correct method */
2504                 GList* list = NULL;
2505                 GList* method;
2506                 for (method = list_auth_methods; method != NULL; method = g_list_next(method)) {
2507                         ModestProtocolType auth_protocol_type = (ModestProtocolType) (GPOINTER_TO_INT(method->data));
2508                         if (modest_protocol_registry_protocol_type_has_tag (registry, auth_protocol_type,
2509                                                                             MODEST_PROTOCOL_REGISTRY_SECURE_PROTOCOLS)) {
2510                                 list = g_list_append(list, GINT_TO_POINTER(auth_protocol_type));
2511                         }
2512                 }
2513
2514                 g_list_free(list_auth_methods);
2515
2516                 if (list)
2517                         return list;
2518         }
2519
2520         if(error == NULL || error->domain != modest_utils_get_supported_secure_authentication_error_quark() ||
2521                         error->code != MODEST_UTILS_GET_SUPPORTED_SECURE_AUTHENTICATION_ERROR_CANCELED)
2522         {
2523                 modest_platform_information_banner (GTK_WIDGET(self), NULL,
2524                                                     _("mcen_ib_unableto_discover_auth_methods"));
2525         }
2526
2527         if(error != NULL)
2528                 g_error_free(error);
2529
2530         return NULL;
2531 }
2532
2533 static gboolean
2534 check_has_supported_auth_methods(ModestEasysetupWizardDialog* self)
2535 {
2536         GList* methods = check_for_supported_auth_methods(self);
2537         if (!methods)
2538         {
2539                 return FALSE;
2540         }
2541
2542         g_list_free(methods);
2543         return TRUE;
2544 }
2545
2546 static gboolean
2547 check_support_show_progress (gpointer userdata)
2548 {
2549         ModestEasysetupWizardDialog *self = (ModestEasysetupWizardDialog *) userdata;
2550         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2551
2552         priv->check_support_show_progress_id = 0;
2553
2554         if (priv->destroyed)
2555                 return FALSE;
2556
2557         hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
2558
2559         return FALSE;
2560 }
2561
2562 static gboolean
2563 check_support_progress_pulse (gpointer userdata)
2564 {
2565         ModestEasysetupWizardDialog *self = (ModestEasysetupWizardDialog *) userdata;
2566         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2567
2568         if (priv->destroyed || priv->check_support_progress == NULL) {
2569                 priv->check_support_progress_pulse_id = 0;
2570                 return FALSE;
2571         }
2572
2573         gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->check_support_progress));
2574
2575         return TRUE;
2576 }
2577
2578 static void
2579 check_support_callback (ModestAccountProtocol *protocol,
2580                         gboolean supported,
2581                         gpointer userdata)
2582 {
2583         ModestEasysetupWizardDialog *self = (ModestEasysetupWizardDialog *) userdata;
2584         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2585
2586         priv->pending_check_support --;
2587
2588         if (priv->check_support_show_progress_id > 0) {
2589                 g_source_remove (priv->check_support_show_progress_id);
2590                 priv->check_support_show_progress_id = 0;
2591         }
2592
2593         if (priv->pending_check_support == 0) {
2594                 priv->check_support_done = TRUE;
2595
2596                 if (priv->check_support_cancel_note) {
2597                         gtk_widget_destroy (priv->check_support_cancel_note);
2598                         priv->check_support_cancel_note = NULL;
2599                         priv->check_support_progress = NULL;
2600                 }
2601
2602                 if (!priv->destroyed) {
2603                         if (priv->presets)
2604                                 fill_providers (self);
2605                         hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), FALSE);
2606                         invoke_enable_buttons_vfunc (self);
2607                         gtk_dialog_response (GTK_DIALOG (self), MODEST_WIZARD_DIALOG_NEXT);
2608                 }
2609         }
2610         g_object_unref (self);
2611 }
2612
2613 static void
2614 on_check_support_cancel (GtkDialog *cancel_note,
2615                          gint response,
2616                          ModestEasysetupWizardDialog *self)
2617 {
2618         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2619         ModestProtocolRegistry *registry;
2620         GSList *provider_protos, *node;
2621
2622         registry = modest_runtime_get_protocol_registry ();
2623         provider_protos = modest_protocol_registry_get_by_tag (registry,
2624                                                                MODEST_PROTOCOL_REGISTRY_PROVIDER_PROTOCOLS);
2625
2626         for (node = provider_protos; node != NULL; node = g_slist_next (node)) {
2627                 ModestProtocol *proto = MODEST_PROTOCOL (node->data);
2628
2629                 if (!modest_protocol_registry_protocol_type_has_tag (registry,
2630                                                                      modest_protocol_get_type_id (proto),
2631                                                                      MODEST_PROTOCOL_REGISTRY_STORE_PROTOCOLS))
2632                         continue;
2633
2634                 if (modest_protocol_registry_protocol_type_has_tag
2635                     (registry,
2636                      modest_protocol_get_type_id (proto),
2637                      MODEST_PROTOCOL_REGISTRY_SINGLETON_PROVIDER_PROTOCOLS)) {
2638                         /* Check if there's already an account configured with this account type */
2639                         if (modest_account_mgr_singleton_protocol_exists (modest_runtime_get_account_mgr (),
2640                                                                           modest_protocol_get_type_id (proto)))
2641                                 continue;
2642                 }
2643
2644                 if (MODEST_ACCOUNT_PROTOCOL (proto)) {
2645                         modest_account_protocol_cancel_check_support (MODEST_ACCOUNT_PROTOCOL (proto));
2646                 }
2647         }
2648         g_slist_free (provider_protos);
2649
2650         gtk_widget_destroy (GTK_WIDGET (cancel_note));
2651         priv->check_support_cancel_note = NULL;
2652         priv->check_support_progress = NULL;
2653 }
2654
2655 static void
2656 check_support_of_protocols (ModestEasysetupWizardDialog *self)
2657 {
2658         ModestProtocolRegistry *registry;
2659         GSList *provider_protos, *node, *check_support_providers;
2660         ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
2661
2662         registry = modest_runtime_get_protocol_registry ();
2663         provider_protos = modest_protocol_registry_get_by_tag (registry,
2664                                                                MODEST_PROTOCOL_REGISTRY_PROVIDER_PROTOCOLS);
2665
2666         check_support_providers = NULL;
2667         for (node = provider_protos; node != NULL; node = g_slist_next (node)) {
2668                 ModestProtocol *proto = MODEST_PROTOCOL (node->data);
2669
2670                 if (!modest_protocol_registry_protocol_type_has_tag (registry,
2671                                                                      modest_protocol_get_type_id (proto),
2672                                                                      MODEST_PROTOCOL_REGISTRY_STORE_PROTOCOLS))
2673                         continue;
2674
2675                 if (modest_protocol_registry_protocol_type_has_tag
2676                     (registry,
2677                      modest_protocol_get_type_id (proto),
2678                      MODEST_PROTOCOL_REGISTRY_SINGLETON_PROVIDER_PROTOCOLS)) {
2679                         /* Check if there's already an account configured with this account type */
2680                         if (modest_account_mgr_singleton_protocol_exists (modest_runtime_get_account_mgr (),
2681                                                                           modest_protocol_get_type_id (proto)))
2682                                 continue;
2683                 }
2684
2685                 if (MODEST_ACCOUNT_PROTOCOL (proto)) {
2686                         priv->pending_check_support ++;
2687                         check_support_providers = g_slist_prepend (check_support_providers, proto);
2688                 }
2689         }
2690         g_slist_free (provider_protos);
2691         
2692         for (node = check_support_providers; node != NULL; node = g_slist_next (node)) {
2693                 ModestProtocol *proto = MODEST_PROTOCOL (node->data);
2694
2695                 modest_account_protocol_check_support (MODEST_ACCOUNT_PROTOCOL (proto),
2696                                                        check_support_callback,
2697                                                        g_object_ref (self));
2698         }
2699         g_slist_free (check_support_providers);
2700
2701         if (priv->pending_check_support > 0) {
2702                 priv->check_support_show_progress_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 1000,
2703                                                                            check_support_show_progress,
2704                                                                            g_object_ref (self), g_object_unref);
2705                 priv->check_support_progress_pulse_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 200,
2706                                                                            check_support_progress_pulse,
2707                                                                            g_object_ref (self), g_object_unref);
2708                 priv->check_support_progress = gtk_progress_bar_new ();
2709                 priv->check_support_cancel_note = hildon_note_new_cancel_with_progress_bar (GTK_WINDOW (self),
2710                                                                                             _("mcen_cn_availability_check"),
2711                                                                                             GTK_PROGRESS_BAR (priv->check_support_progress));
2712                 gtk_widget_show (priv->check_support_cancel_note);
2713                 g_signal_connect (priv->check_support_cancel_note, "response", G_CALLBACK (on_check_support_cancel), self);
2714         } else {
2715                 priv->check_support_done = TRUE;
2716         }
2717         invoke_enable_buttons_vfunc (self);
2718 }