* src/gnome/modest-account-assistant.[ch]:
[modest] / src / gnome / modest-account-assistant.c
index 36d670a..ad7e7de 100644 (file)
 #include "modest-store-widget.h"
 #include "modest-transport-widget.h"
 #include "modest-text-utils.h"
+#include "modest-runtime.h"
+#include "modest-utils.h"
 #include <modest-protocol-info.h>
+#include "modest-platform.h"
 
 #include <string.h>
 
 static void       modest_account_assistant_class_init    (ModestAccountAssistantClass *klass);
 static void       modest_account_assistant_init          (ModestAccountAssistant *obj);
 static void       modest_account_assistant_finalize      (GObject *obj);
+static gboolean   on_before_next (ModestWizardDialog *dialog, GtkWidget *current_page, GtkWidget *next_page);
+static void       on_response (ModestWizardDialog *wizard_dialog,
+                              gint response_id,
+                              gpointer user_data);
+static void       on_response_before (ModestWizardDialog *wizard_dialog,
+                                     gint response_id,
+                                     gpointer user_data);
 
 /* list my signals */
 enum {
@@ -55,6 +65,10 @@ typedef struct _ModestAccountAssistantPrivate ModestAccountAssistantPrivate;
 struct _ModestAccountAssistantPrivate {
 
        ModestAccountMgr *account_mgr;
+       ModestAccountSettings *settings;
+       gboolean   dirty;
+
+       GtkWidget *notebook;
 
        GtkWidget *account_name;
        GtkWidget *fullname;
@@ -66,6 +80,9 @@ struct _ModestAccountAssistantPrivate {
        GtkWidget *store_protocol_combo;
        GtkWidget *store_security_combo;
        GtkWidget *store_secure_auth;
+       GtkWidget *transport_server_widget;
+       GtkWidget *transport_security_combo;
+       GtkWidget *transport_secure_auth_combo;
        
        GtkWidget *transport_widget;
 
@@ -74,6 +91,8 @@ struct _ModestAccountAssistantPrivate {
        ModestPairList *receiving_transport_store_protos;
        ModestPairList *sending_transport_store_protos;
        ModestPairList *security_protos;
+       ModestPairList *transport_security_protos;
+       ModestPairList *transport_auth_protos;
 };
 
 #define MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
@@ -85,6 +104,8 @@ static GtkAssistantClass *parent_class = NULL;
 /* uncomment the following if you have defined any signals */
 /* static guint signals[LAST_SIGNAL] = {0}; */
 
+static void save_to_settings (ModestAccountAssistant *self);
+
 GType
 modest_account_assistant_get_type (void)
 {
@@ -102,7 +123,7 @@ modest_account_assistant_get_type (void)
                        (GInstanceInitFunc) modest_account_assistant_init,
                        NULL
                };
-               my_type = g_type_register_static (GTK_TYPE_ASSISTANT,
+               my_type = g_type_register_static (MODEST_TYPE_WIZARD_DIALOG,
                                                  "ModestAccountAssistant",
                                                  &my_info, 0);
        }
@@ -120,20 +141,82 @@ modest_account_assistant_class_init (ModestAccountAssistantClass *klass)
 
        g_type_class_add_private (gobject_class, sizeof(ModestAccountAssistantPrivate));
 
-       /* signal definitions go here, e.g.: */
-/*     signals[MY_SIGNAL_1] = */
-/*             g_signal_new ("my_signal_1",....); */
-/*     signals[MY_SIGNAL_2] = */
-/*             g_signal_new ("my_signal_2",....); */
-/*     etc. */
+       ModestWizardDialogClass *base_klass = (ModestWizardDialogClass*)(klass);
+       base_klass->before_next = on_before_next;
+}
+
+static gboolean
+on_delete_event (GtkWidget *widget,
+                GdkEvent *event,
+                ModestAccountAssistant *assistant)
+{
+       gtk_dialog_response (GTK_DIALOG (assistant), GTK_RESPONSE_CANCEL);
+       return TRUE;
+}
+
+static void
+on_assistant_changed(GtkWidget* widget, ModestAccountAssistant* assistant)
+{
+       ModestAccountAssistantPrivate* priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(assistant);
+       g_return_if_fail (priv != NULL);
+       priv->dirty = TRUE;
+}
+
+static void
+on_incoming_security_changed(GtkWidget* widget, ModestAccountAssistant* assistant)
+{
+       ModestAccountAssistantPrivate* priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(assistant);
+       ModestConnectionProtocol protocol_security_incoming;
+       const gchar *name;
+
+       g_return_if_fail (priv != NULL);
+       name = (const gchar *) modest_combo_box_get_active_id  (MODEST_COMBO_BOX (priv->store_security_combo));
+       protocol_security_incoming = modest_protocol_info_get_transport_store_protocol (name);
+
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->store_secure_auth), modest_protocol_info_is_secure (protocol_security_incoming));
+       gtk_widget_set_sensitive (priv->store_secure_auth, !modest_protocol_info_is_secure (protocol_security_incoming));
+       
+       on_assistant_changed (widget, assistant);
 }
 
+static void
+invoke_enable_buttons_vfunc (ModestAccountAssistant *assistant)
+{
+       ModestWizardDialogClass *klass = MODEST_WIZARD_DIALOG_GET_CLASS (assistant);
+       
+       /* Call the vfunc, which may be overridden by derived classes: */
+       if (klass->enable_buttons) {
+               GtkNotebook *notebook = NULL;
+               g_object_get (assistant, "wizard-notebook", &notebook, NULL);
+               
+               const gint current_page_num = gtk_notebook_get_current_page (notebook);
+               if (current_page_num == -1)
+                       return;
+                       
+               GtkWidget* current_page_widget = gtk_notebook_get_nth_page (notebook, current_page_num);
+               (*(klass->enable_buttons))(MODEST_WIZARD_DIALOG (assistant), current_page_widget);
+       }
+}
 
+static void
+on_entry_changed (GtkEditable *editable, gpointer userdata)
+{
+       on_assistant_changed (NULL, MODEST_ACCOUNT_ASSISTANT (userdata));
+       invoke_enable_buttons_vfunc(MODEST_ACCOUNT_ASSISTANT (userdata));
+}
+
+static void
+on_combo_changed (GtkComboBox *combo, gpointer userdata)
+{
+       on_assistant_changed (NULL, MODEST_ACCOUNT_ASSISTANT (userdata));
+       invoke_enable_buttons_vfunc(MODEST_ACCOUNT_ASSISTANT (userdata));
+}
 
 static void
 add_intro_page (ModestAccountAssistant *assistant)
 {
        GtkWidget *page, *label;
+       ModestAccountAssistantPrivate *priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE (assistant);
        
        page = gtk_vbox_new (FALSE, 12);
        
@@ -145,14 +228,14 @@ add_intro_page (ModestAccountAssistant *assistant)
        gtk_widget_set_size_request (label, 400, -1);
        gtk_widget_show_all (page);
        
-       gtk_assistant_append_page (GTK_ASSISTANT(assistant), page);
+       gtk_notebook_append_page (GTK_NOTEBOOK(priv->notebook), page, NULL);
                
-       gtk_assistant_set_page_title (GTK_ASSISTANT(assistant), page,
+       gtk_notebook_set_tab_label_text (GTK_NOTEBOOK(priv->notebook), page,
                                      _("mcen_ti_emailsetup_welcome"));
-       gtk_assistant_set_page_type (GTK_ASSISTANT(assistant), page,
-                                    GTK_ASSISTANT_PAGE_INTRO);
-       gtk_assistant_set_page_complete (GTK_ASSISTANT(assistant),
-                                        page, TRUE);
+       /* gtk_notebook_set_page_type (GTK_NOTEBOOK(assistant), page, */
+       /*                           GTK_ASSISTANT_PAGE_INTRO); */
+       /* gtk_notebook_set_page_complete (GTK_ASSISTANT(assistant), */
+       /*                               page, TRUE); */
 }
 
 
@@ -161,46 +244,19 @@ set_current_page_complete (ModestAccountAssistant *self, gboolean complete)
 {
        GtkWidget *page;
        gint pageno;
-
-       pageno = gtk_assistant_get_current_page (GTK_ASSISTANT(self));
-
-       if (pageno != -1) {
-               page   = gtk_assistant_get_nth_page (GTK_ASSISTANT(self), pageno);
-               gtk_assistant_set_page_complete (GTK_ASSISTANT(self), page, complete);
-       }
-}
-
-
-static void
-identity_page_update_completeness (GtkEditable *editable,
-                                  ModestAccountAssistant *self)
-{
        ModestAccountAssistantPrivate *priv;
-       const gchar *txt;
 
-       priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
+       priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE (self);
 
-       txt = gtk_entry_get_text (GTK_ENTRY(priv->fullname));
-       if (!txt || strlen(txt) == 0) {
-               set_current_page_complete (self, FALSE);
-               return;
-       }
+       pageno = gtk_notebook_get_current_page (GTK_NOTEBOOK(priv->notebook));
 
-       /* FIXME: regexp check for email address */
-       txt = gtk_entry_get_text (GTK_ENTRY(priv->email));
-       if (!modest_text_utils_validate_email_address (txt, NULL)) {
-               set_current_page_complete (self, FALSE);
-               return;
-       }
-
-       txt = gtk_entry_get_text (GTK_ENTRY(priv->username));
-       if (!txt || txt[0] == '\0') {
-               set_current_page_complete (self, FALSE);
-               return;
+       if (pageno != -1) {
+               page   = gtk_notebook_get_nth_page (GTK_NOTEBOOK(priv->notebook), pageno);
+               /* gtk_assistant_set_page_complete (GTK_NOTEBOOK(priv->notebook), page, complete); */
        }
-       set_current_page_complete (self, TRUE);
 }
 
+
 static GtkWidget *
 field_name_label (const gchar *text)
 {
@@ -225,13 +281,17 @@ add_identity_page (ModestAccountAssistant *self)
        priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
 
        priv->account_name = gtk_entry_new ();
-       gtk_entry_set_max_length (GTK_ENTRY (priv->fullname), 40);
+       gtk_entry_set_max_length (GTK_ENTRY (priv->account_name), 40);
+       g_signal_connect (G_OBJECT (priv->account_name), "changed", G_CALLBACK (on_entry_changed), self);
        priv->fullname = gtk_entry_new ();
        gtk_entry_set_max_length (GTK_ENTRY (priv->fullname), 40);
+       g_signal_connect (G_OBJECT (priv->fullname), "changed", G_CALLBACK (on_entry_changed), self);
        priv->email    = gtk_entry_new ();
        gtk_entry_set_width_chars (GTK_ENTRY (priv->email), 40);
+       g_signal_connect (G_OBJECT (priv->email), "changed", G_CALLBACK (on_entry_changed), self);
        priv->username = gtk_entry_new ();
        gtk_entry_set_width_chars (GTK_ENTRY (priv->username), 40);
+       g_signal_connect (G_OBJECT (priv->username), "changed", G_CALLBACK (on_entry_changed), self);
        priv->password = gtk_entry_new ();
        gtk_entry_set_width_chars (GTK_ENTRY (priv->password), 40);
        gtk_entry_set_visibility (GTK_ENTRY (priv->password), FALSE);
@@ -303,36 +363,19 @@ add_identity_page (ModestAccountAssistant *self)
        gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
        gtk_container_add (GTK_CONTAINER (frame), alignment);
        gtk_box_pack_start (GTK_BOX(page), frame, FALSE, FALSE, 0);
-
-       g_signal_connect (G_OBJECT(priv->fullname), "changed",
-                         G_CALLBACK(identity_page_update_completeness),
-                         self);
-       g_signal_connect (G_OBJECT(priv->username), "changed",
-                         G_CALLBACK(identity_page_update_completeness),
-                         self);
-       g_signal_connect (G_OBJECT(priv->password), "changed",
-                         G_CALLBACK(identity_page_update_completeness),
-                         self);
-       g_signal_connect (G_OBJECT(priv->email), "changed",
-                         G_CALLBACK(identity_page_update_completeness),
-                         self);
-       g_signal_connect (G_OBJECT(priv->account_name), "changed",
-                         G_CALLBACK(identity_page_update_completeness),
-                         self);
-       
        
        alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
        gtk_container_add (GTK_CONTAINER (alignment), page);
        gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12);
        gtk_widget_show_all (alignment);
-       gtk_assistant_append_page (GTK_ASSISTANT(self), alignment);
+       gtk_notebook_append_page (GTK_NOTEBOOK(priv->notebook), alignment, NULL);
        
-       gtk_assistant_set_page_title (GTK_ASSISTANT(self), alignment,
+       gtk_notebook_set_tab_label_text (GTK_NOTEBOOK(priv->notebook), alignment,
                                      _("Identity"));
-       gtk_assistant_set_page_type (GTK_ASSISTANT(self), alignment,
-                                    GTK_ASSISTANT_PAGE_CONTENT);
-       gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
-                                        alignment, FALSE);
+       /* gtk_assistant_set_page_type (GTK_ASSISTANT(self), alignment, */
+       /*                           GTK_ASSISTANT_PAGE_CONTENT); */
+       /* gtk_assistant_set_page_complete (GTK_ASSISTANT(self), */
+       /*                               alignment, FALSE); */
 }      
 
 
@@ -369,7 +412,7 @@ add_receiving_page (ModestAccountAssistant *self)
        gtk_container_add (GTK_CONTAINER (page), vbox);
 
        /* Warning label on top */
-       label = gtk_label_new (_("TODO: Note unable to..."));
+       label = gtk_label_new (_("Setting details for the incoming mail server."));
        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
        gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
        gtk_box_pack_start (GTK_BOX(vbox),
@@ -446,14 +489,10 @@ add_receiving_page (ModestAccountAssistant *self)
        gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, FALSE, 0);
        
        /* Setup assistant page */
-       gtk_assistant_append_page (GTK_ASSISTANT(self), page);
+       gtk_notebook_append_page (GTK_NOTEBOOK(priv->notebook), page, NULL);
                
-       gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
-                                     _("Receiving mail"));
-       gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
-                                    GTK_ASSISTANT_PAGE_CONTENT);
-       gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
-                                        page, FALSE);
+       gtk_notebook_set_tab_label_text (GTK_NOTEBOOK(priv->notebook), page,
+                                        _("Incoming details"));
        gtk_widget_show_all (page);
 }
 
@@ -480,6 +519,7 @@ on_sending_combo_box_changed (GtkComboBox *combo, ModestAccountAssistant *self)
                           priv->transport_widget);
 
        gtk_widget_show_all (priv->transport_holder);
+       on_assistant_changed (NULL, MODEST_ACCOUNT_ASSISTANT (self));
 }
 
 
@@ -487,91 +527,89 @@ on_sending_combo_box_changed (GtkComboBox *combo, ModestAccountAssistant *self)
 static void
 add_sending_page (ModestAccountAssistant *self)
 {
-       GtkWidget *page, *box, *combo;
+       GtkWidget *page, *vbox;
+       GtkWidget *table, *frame;
+       GtkWidget *alignment;
        ModestAccountAssistantPrivate *priv;
+       GtkWidget *label;
 
        priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
-       page = gtk_vbox_new (FALSE, 6);
-       
-       gtk_box_pack_start (GTK_BOX(page),
-                           gtk_label_new (
-                                   _("Please select among the following options")),
-                           FALSE, FALSE, 0);
-       box = gtk_hbox_new (FALSE, 0);
-       gtk_box_pack_start (GTK_BOX(box),
-                           gtk_label_new(_("Server type")),
-                           FALSE,FALSE,0);
-       
-       /* Note: This ModestPairList* must exist for as long as the combo
-        * that uses it, because the ModestComboBox uses the ID opaquely, 
-        * so it can't know how to manage its memory. */
-       priv->sending_transport_store_protos = modest_protocol_info_get_transport_store_protocol_pair_list ();
-       combo = modest_combo_box_new (priv->sending_transport_store_protos, g_str_equal);
-
-       g_signal_connect (G_OBJECT(combo), "changed",
-                         G_CALLBACK(on_sending_combo_box_changed), self);
-
-       gtk_box_pack_start (GTK_BOX(box), combo, FALSE,FALSE,0);
-       gtk_box_pack_start (GTK_BOX(page), box, FALSE,FALSE, 0);
-
-       gtk_box_pack_start (GTK_BOX(page), gtk_hseparator_new(), FALSE, FALSE, 0);
+       page = gtk_alignment_new (0.5, 0.0, 1.0, 0.0);
+       gtk_alignment_set_padding (GTK_ALIGNMENT (page), 12, 12, 12, 12);
+       vbox = gtk_vbox_new (FALSE, 24);
+       gtk_container_add (GTK_CONTAINER (page), vbox);
 
-       priv->transport_holder = gtk_hbox_new (FALSE, 0);
-       gtk_box_pack_start (GTK_BOX(page), priv->transport_holder,
+       /* Warning label on top */
+       label = gtk_label_new (_("Settings for the outgoing mail server"));
+       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       gtk_box_pack_start (GTK_BOX(vbox),
+                           label,
                            FALSE, FALSE, 0);
 
-       /* Force the selection */
-       on_sending_combo_box_changed (GTK_COMBO_BOX (combo), self);
-
-       gtk_assistant_append_page (GTK_ASSISTANT(self), page);
-               
-       gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
-                                     _("Sending mail"));
-       gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
-                                    GTK_ASSISTANT_PAGE_INTRO);
-       gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
-                                        page, TRUE);
-       gtk_widget_show_all (page);
-}
-
-
+       priv->transport_server_widget = gtk_entry_new ();
+       /* Setup incoming server frame */
+       frame = gtk_frame_new (NULL);
+       label = gtk_label_new (NULL);
+       gtk_label_set_markup (GTK_LABEL (label), _("<b>Outgoing server</b>"));
+       gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+       table = gtk_table_new (2, 2, FALSE);
+       gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+       gtk_table_set_row_spacings (GTK_TABLE (table), 3);
+       gtk_table_attach (GTK_TABLE (table), field_name_label (_("Outgoing server (SMTP)")),
+                         0, 1, 0, 1,
+                         GTK_FILL, GTK_FILL, 0, 0);
+       gtk_table_attach (GTK_TABLE (table), priv->transport_server_widget,
+                         1, 2, 0, 1,
+                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+       alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
+       gtk_container_add (GTK_CONTAINER (alignment), table);
+       gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+       gtk_container_add (GTK_CONTAINER (frame), alignment);
+       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
 
-static void
-add_final_page (ModestAccountAssistant *self)
-{
-       GtkWidget *page, *box;
-       ModestAccountAssistantPrivate *priv;
+       /* Setup security information widgets */
+       priv->transport_security_protos = 
+               modest_protocol_info_get_connection_protocol_pair_list ();
+       priv->transport_security_combo = modest_combo_box_new (priv->security_protos, g_str_equal);
+       priv->transport_auth_protos = modest_protocol_info_get_auth_protocol_pair_list ();
+       priv->transport_secure_auth_combo = GTK_WIDGET (modest_combo_box_new (priv->transport_auth_protos, g_str_equal));
 
-       priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
-       page = gtk_vbox_new (FALSE, 6);
-       
-       gtk_box_pack_start (GTK_BOX(page),
-                           gtk_label_new (
-                                   _("We're almost done. Press 'Apply' to store this new account")),
-                           FALSE, FALSE, 6);
-       box = gtk_hbox_new (FALSE, 6);
-       priv->account_name =
-               gtk_entry_new_with_max_length (40);
-       gtk_entry_set_text (GTK_ENTRY(priv->account_name),
-                           gtk_entry_get_text(GTK_ENTRY(priv->email)));
-       gtk_box_pack_start (GTK_BOX(box),gtk_label_new(_("Account name:")),
-                           FALSE,FALSE,6);
-       gtk_box_pack_start (GTK_BOX(box),priv->account_name , FALSE,FALSE,6);
-       
-       gtk_box_pack_start (GTK_BOX(page), box, FALSE, FALSE, 6);
+       /* Setup security frame */
+       frame = gtk_frame_new (NULL);
+       label = gtk_label_new (NULL);
+       gtk_label_set_markup (GTK_LABEL (label), _("<b>Security options</b>"));
+       gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+       table = gtk_table_new (2, 2, FALSE);
+       gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+       gtk_table_set_row_spacings (GTK_TABLE (table), 3);
+       gtk_table_attach (GTK_TABLE (table), field_name_label (_("Secure connection")),
+                         0, 1, 0, 1,
+                         GTK_FILL, 0, 0, 0);
+       gtk_table_attach (GTK_TABLE (table), priv->transport_security_combo,
+                         1, 2, 0, 1,
+                         GTK_FILL | GTK_EXPAND, 0, 0, 0);
+       gtk_table_attach (GTK_TABLE (table), field_name_label (_("Secure authentication")),
+                         0, 1, 1, 2,
+                         GTK_FILL, GTK_FILL, 0, 0);
+       gtk_table_attach_defaults (GTK_TABLE (table), priv->transport_secure_auth_combo,
+                                  1, 2, 1, 2);
+       alignment = gtk_alignment_new (0.0, 0.0, 1.0, 0.0);
+       gtk_container_add (GTK_CONTAINER (alignment), table);
+       gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+       gtk_container_add (GTK_CONTAINER (frame), alignment);
+       gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, FALSE, 0);
        
-       gtk_assistant_append_page (GTK_ASSISTANT(self), page);
+       /* Setup assistant page */
+       gtk_notebook_append_page (GTK_NOTEBOOK(priv->notebook), page, NULL);
                
-       gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
-                                     _("Account Management"));
-       gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
-                                    GTK_ASSISTANT_PAGE_CONFIRM);
-
-       gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
-                                        page, TRUE);
+       gtk_notebook_set_tab_label_text (GTK_NOTEBOOK(priv->notebook), page,
+                                        _("Outgoing details"));
        gtk_widget_show_all (page);
-}
 
+}
 
 static void
 modest_account_assistant_init (ModestAccountAssistant *obj)
@@ -583,6 +621,35 @@ modest_account_assistant_init (ModestAccountAssistant *obj)
 
        priv->store_server_widget       = NULL;
        priv->transport_widget  = NULL;
+       priv->settings = modest_account_settings_new ();
+       priv->dirty = FALSE;
+
+       priv->notebook = gtk_notebook_new ();
+       gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
+
+       g_object_set (obj, "wizard-notebook", priv->notebook, NULL);
+       g_object_set (obj, "wizard-name", _("Account wizard"), NULL);
+
+       add_intro_page (obj);
+       add_identity_page (obj); 
+       add_receiving_page (obj); 
+       add_sending_page (obj);
+
+       gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->notebook), 0);
+       gtk_window_set_resizable (GTK_WINDOW(obj), TRUE);       
+       gtk_window_set_default_size (GTK_WINDOW(obj), 400, 400);
+       
+       gtk_window_set_modal (GTK_WINDOW(obj), TRUE);
+
+       g_signal_connect_after (G_OBJECT (obj), "response",
+                               G_CALLBACK (on_response), obj);
+
+       /* This is to show a confirmation dialog when the user hits cancel */
+       g_signal_connect (G_OBJECT (obj), "response",
+                         G_CALLBACK (on_response_before), obj);
+
+       g_signal_connect (G_OBJECT (obj), "delete-event",
+                         G_CALLBACK (on_delete_event), obj);
 }
 
 static void
@@ -596,6 +663,11 @@ modest_account_assistant_finalize (GObject *obj)
                g_object_unref (G_OBJECT(priv->account_mgr));
                priv->account_mgr = NULL;
        }
+
+       if (priv->settings) {
+               g_object_unref (G_OBJECT (priv->settings));
+               priv->settings = NULL;
+       }
        
        /* These had to stay alive for as long as the comboboxes that used them: */
        modest_pair_list_free (priv->receiving_transport_store_protos);
@@ -604,46 +676,6 @@ modest_account_assistant_finalize (GObject *obj)
        G_OBJECT_CLASS(parent_class)->finalize (obj);
 }
 
-static void
-on_cancel (ModestAccountAssistant *self, gpointer user_data)
-{
-       GtkWidget *label;
-       GtkWidget *dialog;
-       int response;
-       
-       label = gtk_label_new (_("Are you sure you want to cancel\n"
-                                "setting up a new account?"));
-       
-       dialog = gtk_dialog_new_with_buttons (_("Cancel"),
-                                             GTK_WINDOW(self),
-                                             GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
-                                             GTK_STOCK_YES, GTK_RESPONSE_ACCEPT,
-                                             GTK_STOCK_NO,  GTK_RESPONSE_CANCEL,
-                                             NULL);
-       
-       gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
-                           label, FALSE, FALSE, 6);
-
-       gtk_widget_show_all ((GTK_DIALOG(dialog)->vbox));
-       
-       gtk_window_set_resizable (GTK_WINDOW(dialog), FALSE);
-       
-       response = gtk_dialog_run (GTK_DIALOG(dialog));
-       gtk_widget_destroy (dialog);
-
-       switch (response) {
-       case GTK_RESPONSE_ACCEPT:
-               /* close the assistant */
-               gtk_widget_hide (GTK_WIDGET(self));
-               break;
-       case GTK_RESPONSE_CANCEL:
-               /* don't do anything */
-               break;
-       default: g_assert_not_reached ();
-
-       };                           
-}
-
 static const gchar*
 get_account_name (ModestAccountAssistant *self)
 {
@@ -674,12 +706,6 @@ get_email (ModestAccountAssistant *self)
 }
 
 
-static void
-on_close (ModestAccountAssistant *self, gpointer user_data)
-{
-       gtk_widget_hide (GTK_WIDGET (self));
-}
-
 
 /*
  * FIXME: hmmmm this a Camel internal thing, should move this
@@ -725,80 +751,6 @@ get_new_server_account_name (ModestAccountMgr* acc_mgr, ModestTransportStoreProt
 }
 
 
-static void
-on_apply (ModestAccountAssistant *self, gpointer user_data)
-{
-/*     ModestAccountAssistantPrivate *priv; */
-/*     ModestTransportStoreProtocol proto = MODEST_PROTOCOL_TRANSPORT_STORE_UNKNOWN; */
-/*     ModestAuthProtocol security = MODEST_PROTOCOL_CONNECTION_NORMAL; */
-/*     ModestConnectionProtocol auth = MODEST_PROTOCOL_AUTH_NONE; */
-/*     gchar *store_name, *transport_name; */
-/*     const gchar *account_name, *username, *servername, *path; */
-/*     ModestTransportWidget *transport; */
-
-/*     priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self); */
-
-/*     /\* create server account -> store *\/ */
-/*     store = MODEST_STORE_WIDGET(priv->store_widget); */
-/*     proto    = modest_store_widget_get_proto (store); */
-/*     username = modest_store_widget_get_username (store); */
-/*     servername = modest_store_widget_get_servername (store); */
-/*     path       = modest_store_widget_get_path (store); */
-/*     security = modest_store_widget_get_security (store); */
-/*     auth = modest_store_widget_get_auth (store); */
-/*     store_name = get_new_server_account_name (priv->account_mgr, proto,username, servername); */
-
-/*     if (proto == MODEST_PROTOCOL_STORE_MAILDIR || */
-/*         proto == MODEST_PROTOCOL_STORE_MBOX) { */
-/*             gchar *uri = get_account_uri (proto, path); */
-/*             modest_account_mgr_add_server_account_uri (priv->account_mgr, store_name, proto, uri); */
-/*             g_free (uri); */
-/*     } else */
-/*             modest_account_mgr_add_server_account (priv->account_mgr, */
-/*                                                    store_name,  */
-/*                                                    servername, */
-/*                                                    0, /\* FIXME: does this mean default?*\/ */
-/*                                                    username, */
-/*                                                    NULL,  */
-/*                                                    proto,  */
-/*                                                    security,  */
-/*                                                    auth); */
-               
-/*     /\* create server account -> transport *\/ */
-/*     transport = MODEST_TRANSPORT_WIDGET(priv->transport_widget); */
-/*     proto = modest_transport_widget_get_proto (transport); */
-/*     username   = NULL; */
-/*     servername = NULL; */
-/*     if (proto == MODEST_PROTOCOL_TRANSPORT_SMTP) { */
-/*             servername = modest_transport_widget_get_servername (transport); */
-/*             if (modest_transport_widget_get_requires_auth (transport)) */
-/*                     username = modest_transport_widget_get_username (transport); */
-/*     } */
-       
-/*     transport_name = get_new_server_account_name (priv->account_mgr, proto,username, servername); */
-/*     modest_account_mgr_add_server_account (priv->account_mgr, */
-/*                                            transport_name,  servername, */
-/*                                            0, /\* FIXME: does this mean default?*\/ */
-/*                                            username, NULL, */
-/*                                            proto, security, auth); */
-
-/*     /\* create account *\/ */
-/*     account_name = get_account_name (self); */
-/*     modest_account_mgr_add_account (priv->account_mgr, */
-/*                                     account_name, */
-/*                                     account_name, */
-/*                                     get_fullname (self), */
-/*                                     get_email (self), */
-/*                                     MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY, */
-/*                                     store_name, */
-/*                                     transport_name, TRUE); */
-
-/*     /\* Frees *\/    */
-/*     g_free (store_name); */
-/*     g_free (transport_name); */
-}
-
-
 
 GtkWidget*
 modest_account_assistant_new (ModestAccountMgr *account_mgr)
@@ -817,26 +769,283 @@ modest_account_assistant_new (ModestAccountMgr *account_mgr)
        g_object_ref (account_mgr);
        priv->account_mgr = account_mgr;
 
-       add_intro_page (self);
-       add_identity_page (self); 
-       add_receiving_page (self); 
-       add_sending_page (self);
-       add_final_page (self);
-
-       gtk_assistant_set_current_page (GTK_ASSISTANT(self), 0);
-       gtk_window_set_title (GTK_WINDOW(self),
-                             _("Modest Account Wizard"));
-       gtk_window_set_resizable (GTK_WINDOW(self), TRUE);      
-       gtk_window_set_default_size (GTK_WINDOW(self), 400, 400);
+       return GTK_WIDGET(self);
+}
+
+static gchar*
+get_entered_account_title (ModestAccountAssistant *self)
+{
+       ModestAccountAssistantPrivate *priv;
+       const gchar* account_title;
+
+       priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
+       account_title = gtk_entry_get_text (GTK_ENTRY (priv->account_name));
+
+       if (!account_title || (strlen (account_title) == 0)) {
+               return NULL;
+       } else {
+               /* Strip it of whitespace at the start and end: */
+               gchar *result = g_strdup (account_title);
+               result = g_strstrip (result);
+               
+               if (!result)
+                       return NULL;
+                       
+               if (strlen (result) == 0) {
+                       g_free (result);
+                       return NULL;    
+               }
+               
+               return result;
+       }
+}
+
+static gboolean
+on_before_next (ModestWizardDialog *dialog, GtkWidget *current_page, GtkWidget *next_page)
+{
+       ModestAccountAssistant *self = MODEST_ACCOUNT_ASSISTANT (dialog);
+       ModestAccountAssistantPrivate *priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE (self);
+
+       /* Do extra validation that couldn't be done for every key press,
+        * either because it was too slow,
+        * or because it requires interaction:
+        */
+       if(!next_page) /* This is NULL when this is a click on Finish. */
+       {
+               save_to_settings (self);
+               modest_account_mgr_add_account_from_settings (modest_runtime_get_account_mgr (), priv->settings);
+       }
+       
+       
+       return TRUE;
+}
+
+static gint get_serverport_incoming(ModestTransportStoreProtocol protocol,
+                                    ModestConnectionProtocol security)
+{
+       int serverport_incoming = 0;
+               /* We don't check for SMTP here as that is impossible for an incoming server. */
+               if (protocol == MODEST_PROTOCOL_STORE_IMAP) {
+                       switch (security) {
+                       case MODEST_PROTOCOL_CONNECTION_NORMAL:
+                       case MODEST_PROTOCOL_CONNECTION_TLS:
+                       case MODEST_PROTOCOL_CONNECTION_TLS_OP:
+                               serverport_incoming = 143;
+                               break;
+                       case MODEST_PROTOCOL_CONNECTION_SSL:
+                               serverport_incoming = 993;
+                               break;
+                       }
+               } else if (protocol == MODEST_PROTOCOL_STORE_POP) {
+                       switch (security) {
+                       case MODEST_PROTOCOL_CONNECTION_NORMAL:
+                       case MODEST_PROTOCOL_CONNECTION_TLS:
+                       case MODEST_PROTOCOL_CONNECTION_TLS_OP:
+                               serverport_incoming = 110;
+                               break;
+                       case MODEST_PROTOCOL_CONNECTION_SSL:
+                               serverport_incoming = 995;
+                               break;
+                       }
+               }
+       return serverport_incoming;
+}
+
+static GList* 
+check_for_supported_auth_methods (ModestAccountAssistant* self)
+{
+       GError *error = NULL;
+       ModestTransportStoreProtocol protocol;
+       const gchar* hostname;
+       const gchar* username;
+       gchar *store_protocol_name, *store_security_name;
+       ModestConnectionProtocol security_protocol;
+       int port_num; 
+       GList *list_auth_methods;
+       ModestAccountAssistantPrivate *priv;
        
-       gtk_window_set_modal (GTK_WINDOW(self), TRUE);
+       priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE (self);
+       hostname = gtk_entry_get_text(GTK_ENTRY(priv->store_server_widget));
+       username = gtk_entry_get_text(GTK_ENTRY(priv->username));
+       store_protocol_name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (priv->store_protocol_combo));
+       protocol = modest_protocol_info_get_transport_store_protocol (store_protocol_name);
+       g_free (store_protocol_name);
+       store_security_name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (priv->store_security_combo));
+       security_protocol = modest_protocol_info_get_connection_protocol (store_security_name);
+       g_free (store_security_name);
+       port_num = get_serverport_incoming(protocol, security_protocol); 
+       list_auth_methods = modest_utils_get_supported_secure_authentication_methods (protocol, hostname, port_num, 
+                                                                                     username, GTK_WINDOW (self), &error);
+
+       if (list_auth_methods) {
+               /* TODO: Select the correct method */
+               GList* list = NULL;
+               GList* method;
+               for (method = list_auth_methods; method != NULL; method = g_list_next(method)) {
+                       ModestAuthProtocol auth = (ModestAuthProtocol) (GPOINTER_TO_INT(method->data));
+                       if (modest_protocol_info_auth_is_secure(auth)) {
+                               list = g_list_append(list, GINT_TO_POINTER(auth));
+                       }
+               }
+
+               g_list_free(list_auth_methods);
+
+               if (list)
+                       return list;
+       }
 
-       g_signal_connect (G_OBJECT(self), "apply",
-                         G_CALLBACK(on_apply), NULL);
-       g_signal_connect (G_OBJECT(self), "cancel",
-                         G_CALLBACK(on_cancel), NULL);
-       g_signal_connect (G_OBJECT(self), "close",
-                         G_CALLBACK(on_close), NULL);
+       if(error != NULL)
+               g_error_free(error);
 
-       return GTK_WIDGET(self);
+       return NULL;
 }
+
+static ModestAuthProtocol check_first_supported_auth_method(ModestAccountAssistant* self)
+{
+       ModestAuthProtocol result = MODEST_PROTOCOL_AUTH_PASSWORD;
+
+       GList* methods = check_for_supported_auth_methods(self);
+       if (methods)
+       {
+               /* Use the first one: */
+               result = (ModestAuthProtocol) (GPOINTER_TO_INT(methods->data));
+               g_list_free(methods);
+       }
+
+       return result;
+}
+
+/**
+ * save_to_settings:
+ * @self: a #ModestEasysetupWizardDialog
+ *
+ * takes information from all the wizard and stores it in settings
+ */
+static void
+save_to_settings (ModestAccountAssistant *self)
+{
+       ModestAccountAssistantPrivate *priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE (self);
+       gchar* display_name;
+       const gchar *username, *password;
+       gchar *store_hostname, *transport_hostname;
+       guint store_port, transport_port;
+       ModestTransportStoreProtocol store_protocol, transport_protocol;
+       ModestConnectionProtocol store_security, transport_security;
+       ModestAuthProtocol store_auth_protocol, transport_auth_protocol;
+       ModestServerAccountSettings *store_settings, *transport_settings;
+       const gchar *fullname, *email_address;
+
+       /* username and password (for both incoming and outgoing): */
+       username = gtk_entry_get_text (GTK_ENTRY (priv->username));
+       password = gtk_entry_get_text (GTK_ENTRY (priv->password));
+
+       /* Incoming server: */
+       /* Note: We need something as default for the ModestTransportStoreProtocol* values, 
+        * or modest_account_mgr_add_server_account will fail. */
+       store_port = 0;
+       store_protocol = MODEST_PROTOCOL_STORE_POP;
+       store_security = MODEST_PROTOCOL_CONNECTION_NORMAL;
+       store_auth_protocol = MODEST_PROTOCOL_AUTH_NONE;
+
+       /* Use custom pages because no preset was specified: */
+       store_hostname = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->store_server_widget) ));                
+       store_protocol = modest_protocol_info_get_transport_store_protocol (modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->store_protocol_combo)));
+       store_security = modest_protocol_info_get_connection_protocol (modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->store_security_combo)));
+
+       /* The UI spec says: 
+        * If secure authentication is unchecked, allow sending username and password also as plain text.
+        * If secure authentication is checked, require one of the secure methods during 
+        * connection: SSL, TLS, CRAM-MD5 etc. */
+       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->store_secure_auth)) &&
+           !modest_protocol_info_is_secure(store_security)) {
+               store_auth_protocol = check_first_supported_auth_method (self);
+       } else {
+               store_auth_protocol = MODEST_PROTOCOL_AUTH_PASSWORD;
+       }
+
+       /* now we store the store account settings */
+       store_settings = modest_account_settings_get_store_settings (priv->settings);
+       modest_server_account_settings_set_hostname (store_settings, store_hostname);
+       modest_server_account_settings_set_username (store_settings, username);
+       modest_server_account_settings_set_password (store_settings, password);
+       modest_server_account_settings_set_protocol (store_settings, store_protocol);
+       modest_server_account_settings_set_security (store_settings, store_security);
+       modest_server_account_settings_set_auth_protocol (store_settings, store_auth_protocol);
+       if (store_port != 0)
+               modest_server_account_settings_set_port (store_settings, store_port);
+
+       g_object_unref (store_settings);
+       g_free (store_hostname);
+       
+       /* Outgoing server: */
+       transport_hostname = NULL;
+       transport_protocol = MODEST_PROTOCOL_STORE_POP;
+       transport_security = MODEST_PROTOCOL_CONNECTION_NORMAL;
+       transport_auth_protocol = MODEST_PROTOCOL_AUTH_NONE;
+       transport_port = 0;
+       
+       transport_hostname = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->transport_server_widget) ));
+       transport_protocol = MODEST_PROTOCOL_TRANSPORT_SMTP; /* It's always SMTP for outgoing. */
+       transport_security = modest_protocol_info_get_connection_protocol (modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->transport_security_combo)));
+       transport_auth_protocol = modest_protocol_info_get_auth_protocol (modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->transport_secure_auth_combo)));
+           
+       /* now we transport the transport account settings */
+       transport_settings = modest_account_settings_get_transport_settings (priv->settings);
+       modest_server_account_settings_set_hostname (transport_settings, transport_hostname);
+       modest_server_account_settings_set_username (transport_settings, username);
+       modest_server_account_settings_set_password (transport_settings, password);
+       modest_server_account_settings_set_protocol (transport_settings, transport_protocol);
+       modest_server_account_settings_set_security (transport_settings, transport_security);
+       modest_server_account_settings_set_auth_protocol (transport_settings, transport_auth_protocol);
+       if (transport_port != 0)
+               modest_server_account_settings_set_port (transport_settings, transport_port);
+
+       g_object_unref (transport_settings);
+       g_free (transport_hostname);
+       
+       fullname = gtk_entry_get_text (GTK_ENTRY (priv->fullname));
+       email_address = gtk_entry_get_text (GTK_ENTRY (priv->email));
+       modest_account_settings_set_fullname (priv->settings, fullname);
+       modest_account_settings_set_email_address (priv->settings, email_address);
+       /* we don't set retrieve type to preserve advanced settings if any. By default account settings
+          are set to headers only */
+       
+       display_name = get_entered_account_title (self);
+       modest_account_settings_set_display_name (priv->settings, display_name);
+       g_free (display_name);
+
+}
+
+static void 
+on_response (ModestWizardDialog *wizard_dialog,
+            gint response_id,
+            gpointer user_data)
+{
+       ModestAccountAssistant *self = MODEST_ACCOUNT_ASSISTANT (wizard_dialog);
+
+       invoke_enable_buttons_vfunc (self);
+}
+
+static void 
+on_response_before (ModestWizardDialog *wizard_dialog,
+                    gint response_id,
+                    gpointer user_data)
+{
+       ModestAccountAssistant *self = MODEST_ACCOUNT_ASSISTANT (wizard_dialog);
+       ModestAccountAssistantPrivate *priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(wizard_dialog);
+
+       if (response_id == GTK_RESPONSE_CANCEL) {
+               /* This is mostly copied from
+                * src/maemo/modest-account-settings-dialog.c */
+               if (priv->dirty) {
+                       gint dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self), 
+                                                                                       _("imum_nc_wizard_confirm_lose_changes"));
+
+                       if (dialog_response != GTK_RESPONSE_OK) {
+                               /* Don't let the dialog close */
+                               g_signal_stop_emission_by_name (wizard_dialog, "response");
+                       }
+               }
+       }
+}
+