2007-07-07 Armin Burgmeier <armin@openismus.com>
[modest] / src / maemo / easysetup / modest-easysetup-wizard.c
index 1606b79..881e376 100644 (file)
@@ -82,9 +82,20 @@ struct _ModestEasysetupWizardDialogPrivate
        /* Remember what fields the user edited manually to not prefill them
         * again. */
        ModestEasysetupWizardDialogServerChanges server_changes;
+       
+       /* Check if the user changes a field to show a confirmation dialog */
+       gboolean dirty;
 };
 
 static void
+on_easysetup_changed(GtkWidget* widget, ModestEasysetupWizardDialog* wizard)
+{
+       ModestEasysetupWizardDialogPrivate* priv = WIZARD_DIALOG_GET_PRIVATE(wizard);
+       g_return_if_fail (priv != NULL);
+       priv->dirty = TRUE;
+}
+
+static void
 modest_easysetup_wizard_dialog_get_property (GObject *object, guint property_id,
                                             GValue *value, GParamSpec *pspec)
 {
@@ -195,11 +206,7 @@ static GList* check_for_supported_auth_methods(ModestEasysetupWizardDialog* acco
        if(error == NULL || error->domain != modest_maemo_utils_get_supported_secure_authentication_error_quark() ||
                        error->code != MODEST_MAEMO_UTILS_GET_SUPPORTED_SECURE_AUTHENTICATION_ERROR_CANCELED)
        {
-               GtkWidget* error_dialog = gtk_message_dialog_new(GTK_WINDOW(account_wizard),
-                                                                GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
-                                                                GTK_BUTTONS_OK, (error != NULL) ? error->message : _("Server does not support secure authentication!"));
-               gtk_dialog_run(GTK_DIALOG(error_dialog));
-               gtk_widget_destroy(error_dialog);
+               show_error (GTK_WINDOW (account_wizard), _("Could not discover supported secure authentication methods."));
        }
 
        if(error != NULL) g_error_free(error);
@@ -303,6 +310,8 @@ on_combo_account_country (GtkComboBox *widget, gpointer user_data)
        g_assert(self);
        ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE (self);
        
+       priv->dirty = TRUE;
+       
        /* Fill the providers combo, based on the selected country: */
        GSList *list_mcc_ids = easysetup_country_combo_box_get_active_country_ids (
                EASYSETUP_COUNTRY_COMBO_BOX (self->combo_account_country));
@@ -317,6 +326,8 @@ on_combo_account_serviceprovider (GtkComboBox *widget, gpointer user_data)
        g_assert(self);
        ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE (self);
        
+       priv->dirty = TRUE;
+       
        /* Fill the providers combo, based on the selected country: */
        gchar* provider_id = easysetup_provider_combo_box_get_active_provider_id (
                EASYSETUP_PROVIDER_COMBO_BOX (self->combo_account_serviceprovider));
@@ -340,7 +351,18 @@ static void
 on_entry_max (ModestValidatingEntry *self, gpointer user_data)
 {
        ModestEasysetupWizardDialog *dialog = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
-       show_error (GTK_WINDOW (dialog), _("ckdg_ib_maximum_characters_reached"));
+       show_error (GTK_WINDOW (dialog), _CS("ckdg_ib_maximum_characters_reached"));
+}
+
+static void
+on_entry_invalid_character (ModestValidatingEntry *self, const gchar* character, gpointer user_data)
+{
+       ModestEasysetupWizardDialog *dialog = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);       
+       /* We could add a special case for whitespace here 
+       if (character == NULL) ...
+       */
+       hildon_banner_show_information (
+                                               GTK_WIDGET(dialog), NULL, _("ckdg_ib_illegal_characters_entered"));
 }
 
 static GtkWidget*
@@ -427,6 +449,8 @@ create_page_account_details (ModestEasysetupWizardDialog *self)
        
        /* The description widgets: */  
        self->entry_account_title = GTK_WIDGET (modest_validating_entry_new ());
+       g_signal_connect(G_OBJECT(self->entry_account_title), "changed",
+                                                                        G_CALLBACK(on_easysetup_changed), self);
        /* Do use auto-capitalization: */
        hildon_gtk_entry_set_input_mode (GTK_ENTRY (self->entry_account_title), 
                                         HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
@@ -466,6 +490,8 @@ create_page_account_details (ModestEasysetupWizardDialog *self)
        modest_validating_entry_set_unallowed_characters (
                MODEST_VALIDATING_ENTRY (self->entry_account_title), list_prevent);
        g_list_free (list_prevent);
+       modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(self->entry_account_title),
+                                                                                                                                        on_entry_invalid_character, self);
        
        /* Set max length as in the UI spec:
         * The UI spec seems to want us to show a dialog if we hit the maximum. */
@@ -499,6 +525,8 @@ create_page_user_details (ModestEasysetupWizardDialog *self)
                                              on_entry_max, self);
        GtkWidget *caption = create_caption_new_with_asterisk (self, sizegroup, 
                                                              _("mcen_li_emailsetup_name"), self->entry_user_name, NULL, HILDON_CAPTION_OPTIONAL);
+       g_signal_connect(G_OBJECT(self->entry_user_name), "changed", 
+                                                                        G_CALLBACK(on_easysetup_changed), self);
        gtk_widget_show (self->entry_user_name);
        gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
        gtk_widget_show (caption);
@@ -510,6 +538,8 @@ create_page_user_details (ModestEasysetupWizardDialog *self)
        list_prevent = g_list_append (list_prevent, ">");
        modest_validating_entry_set_unallowed_characters (
                MODEST_VALIDATING_ENTRY (self->entry_user_name), list_prevent);
+       modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(self->entry_account_title),
+                                                                                                                                        on_entry_invalid_character, self);
        g_list_free (list_prevent);
        
        /* The username widgets: */     
@@ -520,12 +550,16 @@ create_page_user_details (ModestEasysetupWizardDialog *self)
                                                   self->entry_user_username, NULL, HILDON_CAPTION_MANDATORY);
        gtk_widget_show (self->entry_user_username);
        gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       g_signal_connect(G_OBJECT(self->entry_user_username), "changed", 
+                                                                        G_CALLBACK(on_easysetup_changed), self);
        gtk_widget_show (caption);
        
        /* Prevent the use of some characters in the username, 
         * as required by our UI specification: */
        modest_validating_entry_set_unallowed_characters_whitespace (
                MODEST_VALIDATING_ENTRY (self->entry_user_username));
+       modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(self->entry_account_title),
+                                                                                                                                        on_entry_invalid_character, self);
        
        /* Set max length as in the UI spec:
         * The UI spec seems to want us to show a dialog if we hit the maximum. */
@@ -542,6 +576,8 @@ create_page_user_details (ModestEasysetupWizardDialog *self)
        /* gtk_entry_set_invisible_char (GTK_ENTRY (self->entry_user_password), '*'); */
        caption = create_caption_new_with_asterisk (self, sizegroup, 
                                                   _("mail_fi_password"), self->entry_user_password, NULL, HILDON_CAPTION_OPTIONAL);
+       g_signal_connect(G_OBJECT(self->entry_user_password), "changed", 
+                                                                        G_CALLBACK(on_easysetup_changed), self);
        gtk_widget_show (self->entry_user_password);
        gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
        gtk_widget_show (caption);
@@ -555,6 +591,8 @@ create_page_user_details (ModestEasysetupWizardDialog *self)
        gtk_entry_set_text (GTK_ENTRY (self->entry_user_email), EXAMPLE_EMAIL_ADDRESS); /* Default text. */
        gtk_widget_show (self->entry_user_email);
        gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       g_signal_connect(G_OBJECT(self->entry_user_email), "changed", 
+                                                                        G_CALLBACK(on_easysetup_changed), self);
        gtk_widget_show (caption);
        
        /* Set max length as in the UI spec:
@@ -583,6 +621,12 @@ static GtkWidget* create_page_complete_easysetup (ModestEasysetupWizardDialog *s
        label = gtk_label_new (_("mcen_ia_easysetup_complete"));
        gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
        gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
+       
+       /* The documentation for gtk_label_set_line_wrap() says that we must 
+        * call gtk_widget_set_size_request() with a hard-coded width, 
+        * though I wonder why gtk_label_set_max_width_chars() isn't enough. */
+       gtk_widget_set_size_request (label, 400, -1);
+       
        gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
        gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
        gtk_widget_show (label);
@@ -629,6 +673,10 @@ static void update_incoming_server_security_choices (ModestEasysetupWizardDialog
 static void on_combo_servertype_changed(GtkComboBox *combobox, gpointer user_data)
 {
        ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE(self);
+       
+       priv->dirty = TRUE;
+       
        update_incoming_server_title (self);
        update_incoming_server_security_choices (self);
 
@@ -639,6 +687,7 @@ static void on_entry_incoming_servername_changed(GtkEntry *entry, gpointer user_
 {
        ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
        ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_GET_PRIVATE (self);
+       priv->dirty = TRUE;
        priv->server_changes |= MODEST_EASYSETUP_WIZARD_DIALOG_INCOMING_CHANGED;
 }
 
@@ -670,7 +719,11 @@ static GtkWidget* create_page_custom_incoming (ModestEasysetupWizardDialog *self
        gtk_widget_show (caption);
        
        if(!self->entry_incomingserver)
+       {
                self->entry_incomingserver = gtk_entry_new ();
+               g_signal_connect(G_OBJECT(self->entry_incomingserver), "changed",
+                                                                                G_CALLBACK(on_easysetup_changed), self);
+       }
        /* Auto-capitalization is the default, so let's turn it off: */
        hildon_gtk_entry_set_input_mode (GTK_ENTRY (self->entry_incomingserver), HILDON_GTK_INPUT_MODE_FULL);
        set_default_custom_servernames (self);
@@ -705,14 +758,21 @@ static GtkWidget* create_page_custom_incoming (ModestEasysetupWizardDialog *self
                MODEST_SERVERSECURITY_COMBO_BOX (self->combo_incoming_security), MODEST_PROTOCOL_CONNECTION_NORMAL);
        caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_connection"), 
                                      self->combo_incoming_security, NULL, HILDON_CAPTION_OPTIONAL);
+       g_signal_connect (G_OBJECT (self->combo_incoming_security), "changed",
+                         G_CALLBACK (on_easysetup_changed), self);
        gtk_widget_show (self->combo_incoming_security);
        gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
        gtk_widget_show (caption);
        
        if(!self->checkbox_incoming_auth)
+       {
                self->checkbox_incoming_auth = gtk_check_button_new ();
+               g_signal_connect (G_OBJECT (self->checkbox_incoming_auth), "toggled",
+                         G_CALLBACK (on_easysetup_changed), self);
+       }
        caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_authentication"), 
                                      self->checkbox_incoming_auth, NULL, HILDON_CAPTION_OPTIONAL);
+       
        gtk_widget_show (self->checkbox_incoming_auth);
        gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
        gtk_widget_show (caption);
@@ -748,6 +808,11 @@ static void
 on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data)
 {
        ModestEasysetupWizardDialog * self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       ModestEasysetupWizardDialogPrivate* priv = WIZARD_DIALOG_GET_PRIVATE(self);
+       
+       /* We set dirty here because setting it depending on the connection specific dialog
+       seems overkill */
+       priv->dirty = TRUE;
        
        /* Create the window, if necessary: */
        if (!(self->specific_window)) {
@@ -780,7 +845,11 @@ static GtkWidget* create_page_custom_outgoing (ModestEasysetupWizardDialog *self
         
        /* The outgoing server widgets: */
        if (!self->entry_outgoingserver)
+       {
                self->entry_outgoingserver = gtk_entry_new ();
+               g_signal_connect (G_OBJECT (self->entry_outgoingserver), "changed",
+                         G_CALLBACK (on_easysetup_changed), self);
+       }
        /* Auto-capitalization is the default, so let's turn it off: */
        hildon_gtk_entry_set_input_mode (GTK_ENTRY (self->entry_outgoingserver), HILDON_GTK_INPUT_MODE_FULL);
        GtkWidget *caption = create_caption_new_with_asterisk (self, sizegroup, 
@@ -792,7 +861,11 @@ static GtkWidget* create_page_custom_outgoing (ModestEasysetupWizardDialog *self
        
        /* The secure connection widgets: */    
        if (!self->combo_outgoing_security)
+       {
                self->combo_outgoing_security = GTK_WIDGET (modest_serversecurity_combo_box_new ());
+               g_signal_connect (G_OBJECT (self->combo_outgoing_security), "changed",
+                         G_CALLBACK (on_easysetup_changed), self);
+       }
        modest_serversecurity_combo_box_fill (
                MODEST_SERVERSECURITY_COMBO_BOX (self->combo_outgoing_security), MODEST_PROTOCOL_TRANSPORT_SMTP);
        modest_serversecurity_combo_box_set_active_serversecurity (
@@ -805,7 +878,11 @@ static GtkWidget* create_page_custom_outgoing (ModestEasysetupWizardDialog *self
        
        /* The secure authentication widgets: */
        if (!self->combo_outgoing_auth)
+       {
                self->combo_outgoing_auth = GTK_WIDGET (modest_secureauth_combo_box_new ());
+                               g_signal_connect (G_OBJECT (self->combo_outgoing_auth), "changed",
+                         G_CALLBACK (on_easysetup_changed), self);
+       }
        caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_authentication"), 
                                      self->combo_outgoing_auth, NULL, HILDON_CAPTION_OPTIONAL);
        gtk_widget_show (self->combo_outgoing_auth);
@@ -821,6 +898,9 @@ static GtkWidget* create_page_custom_outgoing (ModestEasysetupWizardDialog *self
                self->checkbox_outgoing_smtp_specific = gtk_check_button_new ();
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->checkbox_outgoing_smtp_specific), 
                                              FALSE);
+               g_signal_connect (G_OBJECT (self->checkbox_outgoing_smtp_specific), "toggled",
+                         G_CALLBACK (on_easysetup_changed), self);
+
        }
        caption = hildon_caption_new (sizegroup, _("mcen_fi_advsetup_connection_smtp"), 
                                      self->checkbox_outgoing_smtp_specific, NULL, HILDON_CAPTION_OPTIONAL);
@@ -936,18 +1016,46 @@ on_response (ModestWizardDialog *wizard_dialog,
             gpointer user_data)
 {
        ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (wizard_dialog);
-       
        if (response_id == GTK_RESPONSE_CANCEL) {
                /* Remove any temporarily-saved account that will not actually be needed: */
                if (self->saved_account_name) {
                        modest_account_mgr_remove_account (self->account_manager,
                                                           self->saved_account_name, FALSE);
-               }       
+               }
        }
-       
+
        invoke_enable_buttons_vfunc (self);
 }
 
+static void 
+on_response_before (ModestWizardDialog *wizard_dialog,
+                    gint response_id,
+                    gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (wizard_dialog);
+       ModestEasysetupWizardDialogPrivate *priv = WIZARD_DIALOG_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)
+               {
+                       GtkDialog *dialog = GTK_DIALOG (hildon_note_new_confirmation (GTK_WINDOW (self), 
+                               _("imum_nc_wizard_confirm_lose_changes")));
+                       /* TODO: These button names will be ambiguous, and not specified in the UI specification. */
+
+                       const gint dialog_response = gtk_dialog_run (dialog);
+                       gtk_widget_destroy (GTK_WIDGET (dialog));
+
+                       if (dialog_response != GTK_RESPONSE_OK)
+                       {
+                               /* This is a nasty hack. murrayc. */
+                               /* Don't let the dialog close */
+                               g_signal_stop_emission_by_name (wizard_dialog, "response");
+                       }
+               }
+       }
+}
+
 static void
 modest_easysetup_wizard_dialog_init (ModestEasysetupWizardDialog *self)
 {
@@ -1021,6 +1129,13 @@ modest_easysetup_wizard_dialog_init (ModestEasysetupWizardDialog *self)
        g_signal_connect_after (G_OBJECT (self), "response",
                                G_CALLBACK (on_response), self);
 
+       /* This is to show a confirmation dialog when the user hits cancel */
+       g_signal_connect (G_OBJECT (self), "response",
+                         G_CALLBACK (on_response_before), self);
+
+       /* Reset dirty, because there was no user input until now */
+       priv->dirty = FALSE;
+       
        /* When this window is shown, hibernation should not be possible, 
         * because there is no sensible way to save the state: */
        modest_window_mgr_prevent_hibernation_while_window_is_shown (
@@ -1226,7 +1341,7 @@ on_before_next (ModestWizardDialog *dialog, GtkWidget *current_page, GtkWidget *
 
                if (name_in_use) {
                        /* Warn the user via a dialog: */
-                       show_error (GTK_WINDOW (account_wizard), _("mail_ib_account_name_already_existing"));
+                       hildon_banner_show_information(NULL, NULL, _("mail_ib_account_name_already_existing"));
             
                        return FALSE;
                }
@@ -1237,7 +1352,7 @@ on_before_next (ModestWizardDialog *dialog, GtkWidget *current_page, GtkWidget *
                if ((!email_address) || (strlen(email_address) == 0))
                        return FALSE;
                        
-               if (!modest_text_utils_validate_email_address (email_address)) {
+               if (!modest_text_utils_validate_email_address (email_address, NULL)) {
                        /* Warn the user via a dialog: */
                        hildon_banner_show_information (NULL, NULL, _("mcen_ib_invalid_email"));