From 9ee9c1e0296c01b8bdf9f97123aad5a5a13e5643 Mon Sep 17 00:00:00 2001 From: Jose Dapena Paz Date: Tue, 10 Jun 2008 20:15:48 +0000 Subject: [PATCH] * src/gnome/modest-account-assistant.[ch]: * Now it inherits from ModestWizardDialog * Save account after edition. * Finish implementation of controls. * Layout fixes. * src/gnome/modest-account-view-window.c: * Use same confirmation dialog for removing accounts we use in maemo. * Make dialog really close when finished. * Show account wizard on pressing new account. * Properly start dimming of account view. * src/gnome/modest-msg-edit-window.c: * Fix build. * src/gnome/modest-platform.c: * Use new account assistant. * Use new account settings dialog. * Some build fixes. * src/gnome/modest-account-settings-dialog.c: * Remove unused private area. * Remove scrolled windows in dialog tabs (to avoid the strange grey area surronding fields). * Dim fields that can break message cache. * src/gnome/modest-main-window.c: * Save messages paned position. * src/gnome/modest-gnome-global-settings-dialog.c: * Remove separator * Some layout fixes. * Now we retrieve configuration from modest conf, and we also store it back properly. * Now we properly use the updatable fields in common global settings dialog private area. * Now we set the dialog action buttons using gnome stocks. * src/widgets/modest-header-view.c: * Cell renderers fixed size only used in maemo platform. * Moved src/maemo/easysetup/modest-wizard-dialog.[ch] to src/widgets. * Specific maemo and gnome code (in gnome we use stocks buttons). * src/widgets/modest-global-settings-dialog.c: * Now dialog buttons are created in specific implementations. This way we get maemo buttons or gnome stock buttons depending on the platform. * src/widgets/Makefile.am, src/maemo/easysetup/Makefile.am: * Now wizard dialog is in widgets directory. * src/modest-init.c: * Added default value for msg paned. * src/maemo/modest-maemo-global-settings-dialog.c: * Now we create the action buttons in platform implementations. * src/maemo/easysetup/modest-easysetup-wizard-dialog.h: * Use the new path for wizard dialog include. pmo-trunk-r4637 --- src/gnome/modest-account-assistant.c | 789 +++++++++++++------- src/gnome/modest-account-assistant.h | 6 +- src/gnome/modest-account-settings-dialog.c | 69 +- src/gnome/modest-account-view-window.c | 102 ++- src/gnome/modest-gnome-global-settings-dialog.c | 77 +- src/gnome/modest-main-window.c | 2 + src/gnome/modest-msg-edit-window.c | 6 +- src/gnome/modest-platform.c | 18 +- src/maemo/easysetup/Makefile.am | 1 - .../easysetup/modest-easysetup-wizard-dialog.h | 2 +- src/maemo/easysetup/modest-wizard-dialog.c | 654 ---------------- src/maemo/easysetup/modest-wizard-dialog.h | 107 --- src/maemo/modest-maemo-global-settings-dialog.c | 6 +- src/modest-init.c | 10 + src/widgets/Makefile.am | 2 + src/widgets/modest-global-settings-dialog.c | 4 - src/widgets/modest-header-view.c | 8 + src/widgets/modest-wizard-dialog.c | 671 +++++++++++++++++ src/widgets/modest-wizard-dialog.h | 107 +++ 19 files changed, 1450 insertions(+), 1191 deletions(-) delete mode 100644 src/maemo/easysetup/modest-wizard-dialog.c delete mode 100644 src/maemo/easysetup/modest-wizard-dialog.h create mode 100644 src/widgets/modest-wizard-dialog.c create mode 100644 src/widgets/modest-wizard-dialog.h diff --git a/src/gnome/modest-account-assistant.c b/src/gnome/modest-account-assistant.c index 36d670a..ad7e7de 100644 --- a/src/gnome/modest-account-assistant.c +++ b/src/gnome/modest-account-assistant.c @@ -35,7 +35,10 @@ #include "modest-store-widget.h" #include "modest-transport-widget.h" #include "modest-text-utils.h" +#include "modest-runtime.h" +#include "modest-utils.h" #include +#include "modest-platform.h" #include @@ -43,6 +46,13 @@ 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", ¬ebook, 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), _("Outgoing server")); + 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), _("Security options")); + 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"); + } + } + } +} + diff --git a/src/gnome/modest-account-assistant.h b/src/gnome/modest-account-assistant.h index cf54640..753e4b0 100644 --- a/src/gnome/modest-account-assistant.h +++ b/src/gnome/modest-account-assistant.h @@ -30,8 +30,8 @@ #ifndef __MODEST_ACCOUNT_ASSISTANT_H__ #define __MODEST_ACCOUNT_ASSISTANT_H__ -#include #include +#include G_BEGIN_DECLS @@ -47,12 +47,12 @@ typedef struct _ModestAccountAssistant ModestAccountAssistant; typedef struct _ModestAccountAssistantClass ModestAccountAssistantClass; struct _ModestAccountAssistant { - GtkAssistant parent; + ModestWizardDialog parent; /* insert public members, if any */ }; struct _ModestAccountAssistantClass { - GtkAssistantClass parent_class; + ModestWizardDialogClass parent_class; /* insert signal callback declarations, eg. */ /* void (* my_event) (ModestAccountAssistant* obj); */ }; diff --git a/src/gnome/modest-account-settings-dialog.c b/src/gnome/modest-account-settings-dialog.c index 5f7e83f..9dedb33 100644 --- a/src/gnome/modest-account-settings-dialog.c +++ b/src/gnome/modest-account-settings-dialog.c @@ -72,15 +72,6 @@ G_DEFINE_TYPE (ModestAccountSettingsDialog, modest_account_settings_dialog, GTK_TYPE_DIALOG); -#define ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_ACCOUNT_SETTINGS_DIALOG, ModestAccountSettingsDialogPrivate)) - -typedef struct _ModestAccountSettingsDialogPrivate ModestAccountSettingsDialogPrivate; - -struct _ModestAccountSettingsDialogPrivate -{ -}; - static void enable_buttons (ModestAccountSettingsDialog *self); @@ -308,13 +299,9 @@ create_page_account_details (ModestAccountSettingsDialog *self) { GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE); GtkAdjustment *focus_adjustment = NULL; - GtkAlignment *alignment; + GtkWidget *alignment; GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - GtkWidget *scrollwin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - /* The description widgets: */ self->entry_account_title = GTK_WIDGET (modest_validating_entry_new ()); GtkWidget *field = create_field (self, sizegroup, _("mcen_fi_account_title"), @@ -381,18 +368,10 @@ create_page_account_details (ModestAccountSettingsDialog *self) gtk_widget_show (self->caption_leave_messages); gtk_widget_show (GTK_WIDGET (box)); - - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwin), box); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_NONE); - gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (scrollwin))), GTK_SHADOW_NONE); - gtk_widget_show (scrollwin); - - focus_adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrollwin)); - gtk_container_set_focus_vadjustment (GTK_CONTAINER (box), focus_adjustment); alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12); - gtk_container_add (GTK_CONTAINER (alignment), scrollwin); + gtk_container_add (GTK_CONTAINER (alignment), box); gtk_widget_show (alignment); return GTK_WIDGET (alignment); @@ -465,13 +444,9 @@ create_page_user_details (ModestAccountSettingsDialog *self) { GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE); GtkAdjustment *focus_adjustment = NULL; - GtkAlignment *alignment; + GtkWidget *alignment; GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - GtkWidget *scrollwin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_NONE); /* The name widgets: */ self->entry_user_name = GTK_WIDGET (modest_validating_entry_new ()); @@ -560,16 +535,10 @@ create_page_user_details (ModestAccountSettingsDialog *self) G_CALLBACK (on_button_signature), self); gtk_widget_show (GTK_WIDGET (box)); - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwin), box); - gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (scrollwin)), GTK_SHADOW_NONE); - gtk_widget_show (scrollwin); - focus_adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrollwin)); - gtk_container_set_focus_vadjustment (GTK_CONTAINER (box), focus_adjustment); - alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12); - gtk_container_add (GTK_CONTAINER (alignment), scrollwin); + gtk_container_add (GTK_CONTAINER (alignment), box); gtk_widget_show (alignment); return GTK_WIDGET (alignment); @@ -614,7 +583,7 @@ static void update_incoming_server_security_choices (ModestAccountSettingsDialog static GtkWidget* create_page_incoming (ModestAccountSettingsDialog *self) { GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE); - GtkAlignment *alignment; + GtkWidget *alignment; GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); @@ -770,14 +739,7 @@ static GtkWidget* create_page_outgoing (ModestAccountSettingsDialog *self) { GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE); GtkAdjustment *focus_adjustment = NULL; - GtkAlignment *alignment; - - /* Put it all in a scrolled window, so that all widgets can be - * accessed even when the on-screen keyboard is visible: */ - GtkWidget *scrollwin = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_NONE); + GtkWidget *alignment; GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); @@ -896,16 +858,10 @@ static GtkWidget* create_page_outgoing (ModestAccountSettingsDialog *self) G_CALLBACK (on_button_outgoing_smtp_servers), self); gtk_widget_show (GTK_WIDGET (box)); - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrollwin), box); - gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (scrollwin)), GTK_SHADOW_NONE); - gtk_widget_show(scrollwin); - - focus_adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrollwin)); - gtk_container_set_focus_vadjustment (GTK_CONTAINER (box), focus_adjustment); alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12); - gtk_container_add (GTK_CONTAINER (alignment), scrollwin); + gtk_container_add (GTK_CONTAINER (alignment), box); gtk_widget_show (alignment); return GTK_WIDGET (alignment); @@ -1113,8 +1069,7 @@ on_response (GtkDialog *wizard_dialog, g_object_unref (store_settings); g_object_unref (transport_settings); - if (!self->save_password) - modest_platform_information_banner(NULL, NULL, _("mcen_ib_advsetup_settings_saved")); + modest_platform_information_banner(NULL, NULL, _("mcen_ib_advsetup_settings_saved")); } } else { modest_platform_information_banner (NULL, NULL, _("mail_ib_setting_failed")); @@ -1175,7 +1130,6 @@ modest_account_settings_dialog_init (ModestAccountSettingsDialog *self) G_CALLBACK (on_response), self); self->modified = FALSE; - self->save_password; /* When this window is shown, hibernation should not be possible, * because there is no sensible way to save the state: */ @@ -1620,8 +1574,8 @@ modest_account_settings_dialog_check_allow_changes (ModestAccountSettingsDialog /* Enable or disable widgets */ gtk_widget_set_sensitive (self->entry_user_username, !username_known); gtk_widget_set_sensitive (self->entry_incomingserver, !username_known); - gtk_widget_set_sensitive (self->entry_outgoingserver, !username_known); - gtk_widget_set_sensitive (self->entry_outgoing_username, !username_known); + gtk_widget_set_sensitive (self->entry_incoming_port, !username_known); + gtk_widget_set_sensitive (self->combo_incoming_security, !username_known); } void @@ -1629,7 +1583,6 @@ modest_account_settings_dialog_save_password (ModestAccountSettingsDialog *dialo { g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS_DIALOG (dialog)); - dialog->save_password = TRUE; dialog->modified = TRUE; } @@ -1637,8 +1590,6 @@ static void modest_account_settings_dialog_class_init (ModestAccountSettingsDialogClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (klass, sizeof (ModestAccountSettingsDialogPrivate)); - object_class->get_property = modest_account_settings_dialog_get_property; object_class->set_property = modest_account_settings_dialog_set_property; diff --git a/src/gnome/modest-account-view-window.c b/src/gnome/modest-account-view-window.c index c71ad66..7827f80 100644 --- a/src/gnome/modest-account-view-window.c +++ b/src/gnome/modest-account-view-window.c @@ -38,12 +38,14 @@ #include #include "modest-account-assistant.h" #include "modest-tny-platform-factory.h" +#include "modest-platform.h" /* 'private'/'protected' functions */ static void modest_account_view_window_class_init (ModestAccountViewWindowClass *klass); static void modest_account_view_window_init (ModestAccountViewWindow *obj); static void modest_account_view_window_finalize (GObject *obj); - +static gboolean check_for_active_account (ModestAccountViewWindow *self, + const gchar* account_name); /* list my signals */ enum { /* MY_SIGNAL_1, */ @@ -150,33 +152,40 @@ on_remove_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) { ModestAccountViewWindowPrivate *priv; ModestAccountMgr *account_mgr; - gchar *account_name; + gchar *account_name, *account_title; + priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self); account_mgr = modest_runtime_get_account_mgr(); account_name = modest_account_view_get_selected_account (priv->account_view); - if (account_name) { + if (!account_name) + return; + + account_title = modest_account_mgr_get_display_name(account_mgr, account_name); + if (!account_title) + return; + + if (check_for_active_account (self, account_name)) { gboolean removed; - GtkWidget *dialog; gchar *txt; + gint response; - dialog = gtk_dialog_new_with_buttons (_("Confirmation dialog"), - GTK_WINDOW (self), - GTK_DIALOG_MODAL, - GTK_STOCK_CANCEL, - GTK_RESPONSE_REJECT, - GTK_STOCK_OK, - GTK_RESPONSE_ACCEPT, - NULL); - txt = g_strdup_printf (_("Do you really want to delete the account %s?"), account_name); - gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), - gtk_label_new (txt), FALSE, FALSE, 0); -/* gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox)); */ + if (modest_account_mgr_get_store_protocol (account_mgr, account_name) + == MODEST_PROTOCOL_STORE_POP) { + txt = g_strdup_printf (_("emev_nc_delete_mailbox"), + account_title); + } else { + txt = g_strdup_printf (_("emev_nc_delete_mailboximap"), + account_title); + } + + response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self), txt); g_free (txt); + txt = NULL; - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + if (response == GTK_RESPONSE_OK) { /* Remove account. If succeeded it removes also the account from the ModestAccountView */ removed = modest_account_mgr_remove_account (account_mgr, @@ -188,7 +197,6 @@ on_remove_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) g_warning ("Error removing account %s", account_name); } } - gtk_widget_destroy (dialog); g_free (account_name); } } @@ -275,17 +283,54 @@ on_edit_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) } static void +on_wizard_response (GtkDialog *dialog, + gint response, + gpointer user_data) +{ + /* The response has already been handled by the wizard dialog itself, + * creating the new account. + */ + if (dialog) + gtk_widget_destroy (GTK_WIDGET (dialog)); + + /* Re-focus the account list view widget */ + if (MODEST_IS_ACCOUNT_VIEW_WINDOW (user_data)) { + ModestAccountViewWindowPrivate *priv; + priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE (user_data); + gtk_widget_grab_focus (GTK_WIDGET (priv->account_view)); + } +} + +static void on_add_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) { - GtkWidget *assistant; - ModestAccountViewWindowPrivate *priv; + GtkDialog *wizard; + GtkWindow *dialog; + + /* Show the easy-setup wizard: */ + dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr()); + if (dialog && MODEST_IS_ACCOUNT_ASSISTANT (dialog)) { + /* old wizard is active already; + */ + gtk_window_present (dialog); + return; + } - priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self); - assistant = modest_account_assistant_new (modest_runtime_get_account_mgr()); - gtk_window_set_transient_for (GTK_WINDOW(assistant), - GTK_WINDOW(self)); - - gtk_widget_show (GTK_WIDGET(assistant)); + /* there is no such wizard yet */ + wizard = GTK_DIALOG (modest_account_assistant_new (modest_runtime_get_account_mgr ())); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), + GTK_WINDOW (wizard)); + + /* if there is already another modal dialog, make it non-modal */ + if (dialog) + gtk_window_set_modal (GTK_WINDOW(dialog), FALSE); + + gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); + gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (self)); + /* Destroy the dialog when it is closed: */ + g_signal_connect (G_OBJECT (wizard), "response", G_CALLBACK + (on_wizard_response), self); + gtk_widget_show (GTK_WIDGET (wizard)); } @@ -364,15 +409,16 @@ window_vbox_new (ModestAccountViewWindow *self) main_vbox = gtk_vbox_new (FALSE, 0); main_hbox = gtk_hbox_new (FALSE, 12); + button_box = button_box_new (self); + priv->account_view = modest_account_view_new (modest_runtime_get_account_mgr()); gtk_widget_set_size_request (GTK_WIDGET(priv->account_view), 300, 400); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->account_view)); + on_selection_changed (sel, self); g_signal_connect (G_OBJECT(sel), "changed", G_CALLBACK(on_selection_changed), self); - button_box = button_box_new (self); - scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); diff --git a/src/gnome/modest-gnome-global-settings-dialog.c b/src/gnome/modest-gnome-global-settings-dialog.c index 57cb86c..e855bcb 100644 --- a/src/gnome/modest-gnome-global-settings-dialog.c +++ b/src/gnome/modest-gnome-global-settings-dialog.c @@ -122,6 +122,8 @@ modest_gnome_global_settings_dialog_init (ModestGnomeGlobalSettingsDialog *self) ppriv = MODEST_GLOBAL_SETTINGS_DIALOG_GET_PRIVATE (self); + gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE); + ppriv->updating_page = create_updating_page (self); ppriv->composing_page = create_composing_page (self); @@ -132,7 +134,19 @@ modest_gnome_global_settings_dialog_init (ModestGnomeGlobalSettingsDialog *self) gtk_label_new (_("mcen_ti_options_composing"))); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (self)->vbox), ppriv->notebook); - gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (self)->vbox), MODEST_MARGIN_HALF); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (self)->vbox), 12); + gtk_container_set_border_width (GTK_CONTAINER (self), 12); + gtk_window_set_default_size (GTK_WINDOW (self), 480, -1); + + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (self)->action_area), 0); + + /* Load current config */ + _modest_global_settings_dialog_load_conf (MODEST_GLOBAL_SETTINGS_DIALOG (self)); + + /* Add the buttons: */ + gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_SAVE, GTK_RESPONSE_OK); + gtk_widget_show_all (ppriv->notebook); } @@ -166,14 +180,14 @@ add_to_table (GtkTable *table, gtk_table_attach (table, left, 0, 1, n_rows, n_rows + 1, - GTK_SHRINK|GTK_FILL, - GTK_SHRINK|GTK_FILL, + GTK_FILL, + GTK_FILL, 0, 0); gtk_table_attach (table, right, 1, 2, n_rows, n_rows + 1, - GTK_EXPAND|GTK_FILL, - GTK_SHRINK|GTK_FILL, + GTK_EXPAND | GTK_FILL, + GTK_FILL, 0, 0); } @@ -188,6 +202,7 @@ create_label (const gchar *text) label_name = g_strdup_printf ("%s:", text); label = gtk_label_new (label_name); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); g_free (label_name); return label; @@ -200,35 +215,35 @@ static GtkWidget* create_updating_page (ModestGnomeGlobalSettingsDialog *self) { GtkWidget *vbox, *table_update, *table_limit; - GtkWidget *label, *check, *combo, *spin; + GtkWidget *label; + ModestGlobalSettingsDialogPrivate *ppriv; - vbox = gtk_vbox_new (FALSE, MODEST_MARGIN_DEFAULT); + ppriv = MODEST_GLOBAL_SETTINGS_DIALOG_GET_PRIVATE (self); + + vbox = gtk_vbox_new (FALSE, 0); table_update = gtk_table_new (3, 2, FALSE); table_limit = gtk_table_new (2, 2, FALSE); /* FIXME: set proper values (HIG) */ - gtk_table_set_row_spacings (GTK_TABLE (table_update), 6); + gtk_table_set_row_spacings (GTK_TABLE (table_update), 3); gtk_table_set_col_spacings (GTK_TABLE (table_update), 12); - gtk_table_set_row_spacings (GTK_TABLE (table_limit), 6); + gtk_table_set_row_spacings (GTK_TABLE (table_limit), 3); gtk_table_set_col_spacings (GTK_TABLE (table_limit), 12); /* Autoupdate */ label = create_label (_("mcen_fi_options_autoupdate")); - check = gtk_check_button_new (); - add_to_table (GTK_TABLE (table_update), label, check); + ppriv->auto_update = gtk_check_button_new (); + add_to_table (GTK_TABLE (table_update), label, ppriv->auto_update); /* Connected via */ label = create_label (_("mcen_fi_options_connectiontype")); - ModestGlobalSettingsDialogPrivate *ppriv = - MODEST_GLOBAL_SETTINGS_DIALOG_GET_PRIVATE (self); - /* 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. */ ppriv->connect_via_list = _modest_global_settings_dialog_get_connected_via (); - combo = modest_combo_box_new (ppriv->connect_via_list, g_int_equal); + ppriv->connect_via = modest_combo_box_new (ppriv->connect_via_list, g_int_equal); - add_to_table (GTK_TABLE (table_update), label, combo); + add_to_table (GTK_TABLE (table_update), label, ppriv->connect_via); /* Update interval */ label = create_label (_("mcen_fi_options_updateinterval")); @@ -237,9 +252,9 @@ create_updating_page (ModestGnomeGlobalSettingsDialog *self) * that uses it, because the ModestComboBox uses the ID opaquely, * so it can't know how to manage its memory. */ ppriv->update_interval_list = _modest_global_settings_dialog_get_update_interval (); - combo = modest_combo_box_new (ppriv->update_interval_list, g_int_equal); + ppriv->update_interval = modest_combo_box_new (ppriv->update_interval_list, g_int_equal); - add_to_table (GTK_TABLE (table_update), label, combo); + add_to_table (GTK_TABLE (table_update), label, ppriv->update_interval); /* Add to vbox */ gtk_box_pack_start (GTK_BOX (vbox), table_update, FALSE, FALSE, MODEST_MARGIN_HALF); @@ -249,16 +264,17 @@ create_updating_page (ModestGnomeGlobalSettingsDialog *self) /* Limits */ label = create_label (_("mcen_fi_advsetup_sizelimit")); - spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1000, 1, 5000, 1, 1, 16)), - 1, 0); - add_to_table (GTK_TABLE (table_limit), label, spin); + ppriv->size_limit = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1000, 1, 5000, 1, 1, 16)), + 1, 0); + add_to_table (GTK_TABLE (table_limit), label, ppriv->size_limit); label = create_label (_("mcen_fi_options_playsound")); - check = gtk_check_button_new (); - add_to_table (GTK_TABLE (table_limit), label, check); + ppriv->play_sound = gtk_check_button_new (); + add_to_table (GTK_TABLE (table_limit), label, ppriv->play_sound); /* Add to vbox */ gtk_box_pack_start (GTK_BOX (vbox), table_limit, FALSE, FALSE, MODEST_MARGIN_HALF); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); return vbox; } @@ -270,12 +286,12 @@ static GtkWidget* create_composing_page (ModestGnomeGlobalSettingsDialog *self) { GtkWidget *vbox, *table; - GtkWidget *label, *check, *combo; + GtkWidget *label; vbox = gtk_vbox_new (FALSE, MODEST_MARGIN_DEFAULT); table = gtk_table_new (2, 2, FALSE); /* FIXME: set proper values */ - gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_row_spacings (GTK_TABLE (table), 3); gtk_table_set_col_spacings (GTK_TABLE (table), 12); /* Update interval */ @@ -288,16 +304,13 @@ create_composing_page (ModestGnomeGlobalSettingsDialog *self) * that uses it, because the ModestComboBox uses the ID opaquely, * so it can't know how to manage its memory. */ ppriv->msg_format_list = _modest_global_settings_dialog_get_msg_formats (); - combo = modest_combo_box_new (ppriv->msg_format_list, g_int_equal); - - add_to_table (GTK_TABLE (table), label, combo); + ppriv->msg_format = modest_combo_box_new (ppriv->msg_format_list, g_int_equal); - label = create_label (_("mcen_va_options_include_original_inreply")); - check = gtk_check_button_new (); - add_to_table (GTK_TABLE (table), label, check); + add_to_table (GTK_TABLE (table), label, ppriv->msg_format); /* Add to vbox */ - gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, MODEST_MARGIN_HALF); + gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); return vbox; } diff --git a/src/gnome/modest-main-window.c b/src/gnome/modest-main-window.c index f9ec0ed..d7cc553 100644 --- a/src/gnome/modest-main-window.c +++ b/src/gnome/modest-main-window.c @@ -896,6 +896,8 @@ save_state (ModestWindow *window) MODEST_CONF_MAIN_WINDOW_KEY); modest_widget_memory_save (conf, G_OBJECT(priv->main_paned), MODEST_CONF_MAIN_PANED_KEY); + modest_widget_memory_save (conf, G_OBJECT(priv->msg_paned), + MODEST_CONF_MSG_PANED_KEY); modest_widget_memory_save (conf, G_OBJECT(priv->folder_view), MODEST_CONF_FOLDER_VIEW_KEY); } diff --git a/src/gnome/modest-msg-edit-window.c b/src/gnome/modest-msg-edit-window.c index 19b2dce..684dbee 100644 --- a/src/gnome/modest-msg-edit-window.c +++ b/src/gnome/modest-msg-edit-window.c @@ -1064,8 +1064,8 @@ modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window, ModestMsgEditWindowPrivate *priv; GnomeVFSResult result; - g_return_if_fail (window); - g_return_if_fail (uri); + g_return_val_if_fail (window, 0); + g_return_val_if_fail (uri, 0); priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); @@ -1120,6 +1120,8 @@ modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window, g_object_unref (mime_part); gnome_vfs_file_info_unref (info); } + /* TODO: return proper file size */ + return 0; } void diff --git a/src/gnome/modest-platform.c b/src/gnome/modest-platform.c index c11e23b..d7b4b8c 100644 --- a/src/gnome/modest-platform.c +++ b/src/gnome/modest-platform.c @@ -38,6 +38,8 @@ #include "modest-runtime.h" #include "gnome/modest-gnome-global-settings-dialog.h" +#include "widgets/modest-account-settings-dialog.h" +#include "gnome/modest-account-assistant.h" gboolean modest_platform_init (int argc, char *argv[]) @@ -417,7 +419,7 @@ modest_platform_double_connect_and_perform (GtkWindow *parent_window, DoubleConnectionInfo *connect_info) { if (connect_info->callback) - connect_info->callback (FALSE, NULL, parent_window, folder_store, connect_info->data); + connect_info->callback (FALSE, NULL, parent_window, TNY_ACCOUNT (folder_store), connect_info->data); } void @@ -482,19 +484,17 @@ modest_platform_show_addressbook (GtkWindow *parent_window) GtkWidget * modest_platform_get_account_settings_dialog (ModestAccountSettings *settings) { - GtkWidget *dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "NOT IMPLEMENTED"); - return dialog; + ModestAccountSettingsDialog *dialog = modest_account_settings_dialog_new (); + + modest_account_settings_dialog_set_account (dialog, settings); + return GTK_WIDGET (dialog); } GtkWidget * modest_platform_get_account_settings_wizard (void) { - GtkWidget *dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "NOT IMPLEMENTED"); - return dialog; + GtkWidget *widget = modest_account_assistant_new (modest_runtime_get_account_mgr ()); + return widget; } diff --git a/src/maemo/easysetup/Makefile.am b/src/maemo/easysetup/Makefile.am index bd1e328..31d60f5 100644 --- a/src/maemo/easysetup/Makefile.am +++ b/src/maemo/easysetup/Makefile.am @@ -47,7 +47,6 @@ noinst_LTLIBRARIES=\ libmodest-easysetup.la libmodest_easysetup_la_SOURCES= \ - modest-wizard-dialog.h modest-wizard-dialog.c \ modest-presets.h modest-presets.c \ modest-easysetup-wizard-dialog.h modest-easysetup-wizard-dialog.c \ modest-easysetup-country-combo-box.h modest-easysetup-country-combo-box.c \ diff --git a/src/maemo/easysetup/modest-easysetup-wizard-dialog.h b/src/maemo/easysetup/modest-easysetup-wizard-dialog.h index 8ebac3f..ca075dc 100644 --- a/src/maemo/easysetup/modest-easysetup-wizard-dialog.h +++ b/src/maemo/easysetup/modest-easysetup-wizard-dialog.h @@ -31,7 +31,7 @@ #define _MODEST_EAYSETUP_WIZARD_DIALOG /* #include */ -#include "modest-wizard-dialog.h" /* We use a copied-and-improved HildonWizardDialog. */ +#include "widgets/modest-wizard-dialog.h" /* We use a copied-and-improved HildonWizardDialog. */ #include "modest-account-mgr.h" #include diff --git a/src/maemo/easysetup/modest-wizard-dialog.c b/src/maemo/easysetup/modest-wizard-dialog.c deleted file mode 100644 index fbb25e3..0000000 --- a/src/maemo/easysetup/modest-wizard-dialog.c +++ /dev/null @@ -1,654 +0,0 @@ -/* Copyright (c) 2006, Nokia Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the Nokia Corporation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * SECTION:modest-wizard-dialog - * @short_description: A widget to create a guided installation - * process wizard - * - * #ModestWizardDialog is a widget to create a guided installation - * process. The dialog has four standard buttons, previous, next, - * finish, cancel, and contains several pages with optional icons. - * Response buttons are dimmed/undimmed automatically and the standard - * icon is shown/hidden in response to page navigation. The notebook - * widget provided by users contains the actual wizard pages. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef MODEST_HAVE_HILDON0_WIDGETS -#include -#else -#include -#endif /*MODEST_HAVE_HILDON0_WIDGETS*/ - -#include "modest-wizard-dialog.h" - -#include - -/* Specify the hildon-libs translation domain, - * so we can reuse its translations - * instead of repeating them in our own translations. - */ -/* #define _(String) dgettext(PACKAGE, String) */ - -#define _(String) dgettext("hildon-libs", String) - -static GtkDialogClass *parent_class; - -static void class_init (ModestWizardDialogClass *wizard_dialog_class); - -static void init (ModestWizardDialog *wizard_dialog); - -static void create_title (ModestWizardDialog *wizard_dialog); - -static void set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); - -static void get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); - -static void finalize (GObject *object); - -static void response (ModestWizardDialog *wizard, - gint response_id, - gpointer unused); - -static void make_buttons_sensitive (ModestWizardDialog *wizard_dialog, - gboolean previous, - gboolean finish, - gboolean next); - -static gboolean invoke_before_next_vfunc (ModestWizardDialog *wizard_dialog); -static void invoke_enable_buttons_vfunc (ModestWizardDialog *wizard_dialog); - -enum { - PROP_ZERO, - PROP_WIZARD_NAME, - PROP_WIZARD_NOTEBOOK, - PROP_WIZARD_AUTOTITLE -}; - -struct _ModestWizardDialogPrivate { - gchar *wizard_name; - GtkNotebook *notebook; - GtkBox *box; - GtkWidget *image; - gboolean autotitle; -}; - - -GType -modest_wizard_dialog_get_type (void) -{ - static GType wizard_dialog_type = 0; - - if (!wizard_dialog_type) { - - static const GTypeInfo wizard_dialog_info = { - sizeof (ModestWizardDialogClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (ModestWizardDialog), - 0, /* n_preallocs */ - (GInstanceInitFunc) init, - }; - - wizard_dialog_type = g_type_register_static (GTK_TYPE_DIALOG, - "ModestWizardDialog", - &wizard_dialog_info, - 0); - } - - return wizard_dialog_type; -} - -static void -class_init (ModestWizardDialogClass *wizard_dialog_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (wizard_dialog_class); - - parent_class = g_type_class_peek_parent (wizard_dialog_class); - - g_type_class_add_private (wizard_dialog_class, - sizeof(ModestWizardDialogPrivate)); - - /* Override virtual methods */ - object_class->set_property = set_property; - object_class->get_property = get_property; - object_class->finalize = finalize; - - /** - * ModestWizardDialog:wizard-name: - * - * The name of the wizard. - */ - g_object_class_install_property (object_class, PROP_WIZARD_NAME, - g_param_spec_string - ("wizard-name", - "Wizard Name", - "The name of the ModestWizardDialog", - NULL, - G_PARAM_READWRITE)); - - /** - * ModestWizardDialog:wizard-notebook: - * - * The notebook object, which is used by the ModestWizardDialog. - */ - g_object_class_install_property(object_class, PROP_WIZARD_NOTEBOOK, - g_param_spec_object - ("wizard-notebook", - "Wizard Notebook", - "GtkNotebook object to be used in the " - "ModestWizardDialog", - GTK_TYPE_NOTEBOOK, G_PARAM_READWRITE)); - - /** - * ModestWizardDialog:autotitle - * - * If the wizard should automatically try to change the window title when changing steps. - * Set to FALSE if you'd like to override the default behaviour. - * - * Since: 0.14.5 - */ - g_object_class_install_property(object_class, PROP_WIZARD_AUTOTITLE, - g_param_spec_boolean - ("autotitle", - "AutoTitle", - "If the wizard should autotitle itself", - TRUE, - G_PARAM_READWRITE)); -} - -static void -finalize (GObject *object) -{ - ModestWizardDialog *dialog = MODEST_WIZARD_DIALOG (object); - g_return_if_fail (dialog != NULL); - - if (dialog->priv->wizard_name != NULL) - g_free (MODEST_WIZARD_DIALOG (object)->priv->wizard_name); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize(object); -} - -/* Disable or enable the Previous, Next and Finish buttons */ -static void -make_buttons_sensitive (ModestWizardDialog *wizard_dialog, - gboolean previous, - gboolean finish, - gboolean next) -{ - gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog), - MODEST_WIZARD_DIALOG_PREVIOUS, - previous); - - gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog), - MODEST_WIZARD_DIALOG_FINISH, - finish); - - gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog), - MODEST_WIZARD_DIALOG_NEXT, - next); -} - -static void -init (ModestWizardDialog *wizard_dialog) -{ - /* Initialize private structure for faster member access */ - ModestWizardDialogPrivate *priv = - G_TYPE_INSTANCE_GET_PRIVATE (wizard_dialog, - MODEST_TYPE_WIZARD_DIALOG, - ModestWizardDialogPrivate); - - GtkDialog *dialog = GTK_DIALOG (wizard_dialog); - - /* Init internal widgets */ - GtkWidget *vbox = gtk_vbox_new (FALSE, 0); - gtk_dialog_set_has_separator (dialog, FALSE); - wizard_dialog->priv = priv; - priv->box = GTK_BOX (gtk_hbox_new (FALSE, 0)); -#ifdef MODEST_HAVE_HILDON0_WIDGETS - priv->image = gtk_image_new_from_icon_name ("qgn_widg_wizard", - HILDON_ICON_SIZE_WIDG_WIZARD); -#else - static int icon_size = 0; - if (!icon_size) - icon_size = gtk_icon_size_register("modest_wizard", 50, 50); - priv->image = gtk_image_new_from_icon_name ("qgn_widg_wizard", - icon_size); -#endif /*MODEST_HILDON_VERSION_0*/ - /* Default values for user provided properties */ - priv->notebook = NULL; - priv->wizard_name = NULL; - priv->autotitle = TRUE; - - /* Build wizard layout */ - gtk_box_pack_start_defaults (GTK_BOX (dialog->vbox), GTK_WIDGET (priv->box)); - gtk_box_pack_start_defaults (GTK_BOX (priv->box), GTK_WIDGET (vbox)); - gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->image), FALSE, FALSE, 0); - - /* Add response buttons: finish, previous, next, cancel */ - gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_finish"), MODEST_WIZARD_DIALOG_FINISH); - gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_previous"), MODEST_WIZARD_DIALOG_PREVIOUS); - gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_next"), MODEST_WIZARD_DIALOG_NEXT); - gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_cancel"), MODEST_WIZARD_DIALOG_CANCEL); - - /* Set initial button states: previous and finish buttons are disabled */ - make_buttons_sensitive (wizard_dialog, FALSE, FALSE, TRUE); - - /* Show all the internal widgets */ - gtk_widget_show_all (GTK_WIDGET (dialog->vbox)); - - /* connect to dialog's response signal */ - g_signal_connect (G_OBJECT (dialog), "response", - G_CALLBACK (response), NULL); -} - -#if GTK_CHECK_VERSION(2, 10, 0) /* These signals were added in GTK+ 2.10: */ -static void on_notebook_page_added(GtkNotebook *notebook, - GtkWidget *child, - guint page_num, - gpointer user_data) -{ - ModestWizardDialog* dialog = NULL; - - g_return_if_fail (MODEST_IS_WIZARD_DIALOG(user_data)); - dialog = MODEST_WIZARD_DIALOG(user_data); - - /* The title should show the total number of pages: */ - create_title (dialog); -} - -static void on_notebook_page_removed(GtkNotebook *notebook, - GtkWidget *child, - guint page_num, - gpointer user_data) -{ - ModestWizardDialog* dialog = NULL; - - g_return_if_fail (MODEST_IS_WIZARD_DIALOG(user_data)); - dialog = MODEST_WIZARD_DIALOG(user_data); - - /* The title should show the total number of pages: */ - create_title (dialog); -} -#endif /* GTK_CHECK_VERSION */ - -static void -connect_to_notebook_signals(ModestWizardDialog* dialog) -{ -#if GTK_CHECK_VERSION(2, 10, 0) /* These signals were added in GTK+ 2.10: */ - ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG(dialog)->priv; - g_return_if_fail (priv->notebook); - - /* Connect to the notebook signals, - * so we can update the title when necessary: */ - g_signal_connect (G_OBJECT (priv->notebook), "page-added", - G_CALLBACK (on_notebook_page_added), dialog); - g_signal_connect (G_OBJECT (priv->notebook), "page-removed", - G_CALLBACK (on_notebook_page_removed), dialog); -#endif /* GTK_CHECK_VERSION */ -} - - -static void -set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG(object)->priv; - - switch (property_id) { - - case PROP_WIZARD_AUTOTITLE: - - priv->autotitle = g_value_get_boolean (value); - - if (priv->autotitle && - priv->wizard_name && - priv->notebook) - create_title (MODEST_WIZARD_DIALOG (object)); - else if (priv->wizard_name) - gtk_window_set_title (GTK_WINDOW (object), priv->wizard_name); - - break; - - case PROP_WIZARD_NAME: - - /* Set new wizard name. This name will appear in titlebar */ - if (priv->wizard_name) - g_free (priv->wizard_name); - - gchar *str = (gchar *) g_value_get_string (value); - g_return_if_fail (str != NULL); - - priv->wizard_name = g_strdup (str); - - /* We need notebook in order to create title, since page information - is used in title generation */ - - if (priv->notebook && priv->autotitle) - create_title (MODEST_WIZARD_DIALOG (object)); - - break; - - case PROP_WIZARD_NOTEBOOK: { - - GtkNotebook *book = GTK_NOTEBOOK (g_value_get_object (value)); - g_return_if_fail (book != NULL); - - priv->notebook = book; - - /* Set the default properties for the notebook (disable tabs, - * and remove borders) to make it look like a nice wizard widget */ - gtk_notebook_set_show_tabs (priv->notebook, FALSE); - gtk_notebook_set_show_border (priv->notebook, FALSE); - gtk_box_pack_start_defaults (GTK_BOX( priv->box), GTK_WIDGET (priv->notebook)); - - /* Show the notebook so that a gtk_widget_show on the dialog is - * all that is required to display the dialog correctly */ - gtk_widget_show ( GTK_WIDGET (priv->notebook)); - - /* Update dialog title to reflect current page stats etc */ - ModestWizardDialog *wizard_dialog = MODEST_WIZARD_DIALOG (object); - if (priv->wizard_name && priv->autotitle) - create_title (wizard_dialog); - - connect_to_notebook_signals (wizard_dialog); - - }break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG (object)->priv; - - switch (property_id) { - - case PROP_WIZARD_NAME: - g_value_set_string (value, priv->wizard_name); - break; - - case PROP_WIZARD_NOTEBOOK: - g_value_set_object (value, priv->notebook); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -/* - * Creates the title of the dialog taking into account the current - * page of the notebook. - */ -static void -create_title (ModestWizardDialog *wizard_dialog) -{ - gchar *str = NULL; - ModestWizardDialogPrivate *priv = NULL; - GtkNotebook *notebook = NULL; - - g_return_if_fail (MODEST_IS_WIZARD_DIALOG(wizard_dialog)); - g_return_if_fail (wizard_dialog->priv != NULL); - - priv = wizard_dialog->priv; - notebook = priv->notebook; - - if (!notebook) - return; - - /* Get page information, we'll need that when creating title */ - gint pages = gtk_notebook_get_n_pages (notebook); - if (pages == 0) - return; - - gint current = gtk_notebook_get_current_page (priv->notebook); - if (current < 0) - current = 0; - - /* the welcome title on the initial page */ - /* This is the standard wizard title, with, e.g., 1/4 at the end, - * but the Modest UI spec does not want this. */ - /* - if (current == 0) { - str = g_strdup_printf (_("ecdg_ti_wizard_welcome"), - priv->wizard_name, pages); - } else { - */ - const gchar *steps = gtk_notebook_get_tab_label_text (notebook, - gtk_notebook_get_nth_page (notebook, current)); - - /* This is the standard wizard title, with, e.g., 1/4 at the end, - * but the Modest UI spec does not want this. - */ - /* - str = g_strdup_printf (_("ecdg_ti_wizard_step"), - priv->wizard_name, current + 1, pages, steps); - */ - - str = g_strdup_printf (_("%s: %s"), - priv->wizard_name, steps); - /* } */ - - /* Update the dialog to display the generated title */ - gtk_window_set_title (GTK_WINDOW (wizard_dialog), str); - g_free (str); -} - -/* - * Response signal handler. This function is needed because GtkDialog's - * handler for this signal closes the dialog and we don't want that, we - * want to change pages and, dim certain response buttons. Overriding the - * virtual function would not work because that would be called after the - * signal handler implemented by GtkDialog. - * FIXME: There is a much saner way to do that [MDK] - */ -static void -response (ModestWizardDialog *wizard_dialog, - gint response_id, - gpointer unused) -{ - ModestWizardDialogPrivate *priv = wizard_dialog->priv; - GtkNotebook *notebook = priv->notebook; - gint current = 0; - gboolean is_first, is_last; - - switch (response_id) { - - case MODEST_WIZARD_DIALOG_PREVIOUS: - gtk_notebook_prev_page (notebook); /* go to previous page */ - break; - - case MODEST_WIZARD_DIALOG_NEXT: - if (invoke_before_next_vfunc (wizard_dialog)) - gtk_notebook_next_page (notebook); /* go to next page */ - - break; - - case MODEST_WIZARD_DIALOG_CANCEL: - return; - break; - case MODEST_WIZARD_DIALOG_FINISH: - if (invoke_before_next_vfunc (wizard_dialog)) - return; - - break; - - } - - current = gtk_notebook_get_current_page (notebook); - gint last = gtk_notebook_get_n_pages (notebook) - 1; - is_last = current == last; - is_first = current == 0; - - /* If first page, previous and finish are disabled, - if last page, next is disabled */ - make_buttons_sensitive (wizard_dialog, - !is_first /* previous */, !is_first /* finish */, !is_last /* next*/); - - /* Allow derived classes to disable buttons to prevent navigation, - * according to their own validation logic: */ - invoke_enable_buttons_vfunc (wizard_dialog); - - /* Don't let the dialog close */ - g_signal_stop_emission_by_name (wizard_dialog, "response"); - - /* We show the default image on first and last pages */ - last = gtk_notebook_get_n_pages (notebook) - 1; - if (current == last || current == 0) - gtk_widget_show (GTK_WIDGET(priv->image)); - else - gtk_widget_hide (GTK_WIDGET(priv->image)); - - /* New page number may appear in the title, update it */ - if (priv->autotitle) - create_title (wizard_dialog); -} - -/** - * modest_wizard_dialog_new: - * @parent: a #GtkWindow - * @wizard_name: the name of dialog - * @notebook: the notebook to be shown on the dialog - * - * Creates a new #ModestWizardDialog. - * - * Returns: a new #ModestWizardDialog - */ -GtkWidget* -modest_wizard_dialog_new (GtkWindow *parent, - const char *wizard_name, - GtkNotebook *notebook) -{ - GtkWidget *widget; - - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); - - widget = GTK_WIDGET (g_object_new - (MODEST_TYPE_WIZARD_DIALOG, - "wizard-name", wizard_name, - "wizard-notebook", notebook, NULL)); - - if (parent) - gtk_window_set_transient_for (GTK_WINDOW (widget), parent); - - return widget; -} - -/** - * modest_wizard_dialog_force_title_update: - * @wizard_dialog: The wizard dialog - * - * Force the title to be rebuilt, for instance when you have added or - * removed notebook pages. This function is not necessary when using GTK+ 2.10, - * because that has GtkNotebook signals that will be used to update the title - * automatically. - */ -void -modest_wizard_dialog_force_title_update (ModestWizardDialog *wizard_dialog) -{ - create_title (wizard_dialog); -} - -static gboolean -invoke_before_next_vfunc (ModestWizardDialog *wizard_dialog) -{ - ModestWizardDialogClass *klass = MODEST_WIZARD_DIALOG_GET_CLASS (wizard_dialog); - - /* Call the vfunc, which may be overridden by derived classes: */ - if (klass->before_next) { - ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG(wizard_dialog)->priv; - - gint current_page_num = gtk_notebook_get_current_page (priv->notebook); - - /* Get widgets for the two pages: */ - GtkWidget* current_page_widget = gtk_notebook_get_nth_page (priv->notebook, current_page_num); - - GtkWidget* next_page_widget = NULL; - if ((current_page_num + 1) < gtk_notebook_get_n_pages (priv->notebook)) - next_page_widget = gtk_notebook_get_nth_page (priv->notebook, current_page_num + 1); - - /* Ask the vfunc implementation whether navigation should be allowed: */ - return (*(klass->before_next))(wizard_dialog, current_page_widget, next_page_widget); - } - - /* Allow navigation by default if there is no vfunc implementation: */ - return TRUE; -} - -static void -invoke_enable_buttons_vfunc (ModestWizardDialog *wizard_dialog) -{ - ModestWizardDialogClass *klass = MODEST_WIZARD_DIALOG_GET_CLASS (wizard_dialog); - - /* Call the vfunc, which may be overridden by derived classes: */ - if (klass->enable_buttons) { - ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG(wizard_dialog)->priv; - - gint current_page_num = gtk_notebook_get_current_page (priv->notebook); - - GtkWidget* current_page_widget = gtk_notebook_get_nth_page (priv->notebook, current_page_num); - - (*(klass->enable_buttons))(wizard_dialog, current_page_widget); - } -} diff --git a/src/maemo/easysetup/modest-wizard-dialog.h b/src/maemo/easysetup/modest-wizard-dialog.h deleted file mode 100644 index c7bdbe1..0000000 --- a/src/maemo/easysetup/modest-wizard-dialog.h +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright (c) 2006, Nokia Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the Nokia Corporation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef __MODEST_WIZARD_DIALOG_H__ -#define __MODEST_WIZARD_DIALOG_H__ - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define MODEST_TYPE_WIZARD_DIALOG (modest_wizard_dialog_get_type()) - -#define MODEST_WIZARD_DIALOG(obj) (GTK_CHECK_CAST ((obj), \ - MODEST_TYPE_WIZARD_DIALOG, ModestWizardDialog)) - -#define MODEST_WIZARD_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \ - MODEST_TYPE_WIZARD_DIALOG, ModestWizardDialogClass)) - -#define MODEST_IS_WIZARD_DIALOG(obj) (GTK_CHECK_TYPE ((obj), \ - MODEST_TYPE_WIZARD_DIALOG)) - -#define MODEST_IS_WIZARD_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \ - MODEST_TYPE_WIZARD_DIALOG)) - -#define MODEST_WIZARD_DIALOG_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - MODEST_TYPE_WIZARD_DIALOG, ModestWizardDialogClass)) - -typedef struct _ModestWizardDialog ModestWizardDialog; - -typedef struct _ModestWizardDialogClass ModestWizardDialogClass; - -typedef struct _ModestWizardDialogPrivate ModestWizardDialogPrivate; - -/* button response IDs */ -enum { - MODEST_WIZARD_DIALOG_CANCEL = GTK_RESPONSE_CANCEL, - MODEST_WIZARD_DIALOG_PREVIOUS = 0, - MODEST_WIZARD_DIALOG_NEXT, - MODEST_WIZARD_DIALOG_FINISH -}; - -struct _ModestWizardDialog { - GtkDialog parent; - ModestWizardDialogPrivate *priv; -}; - -struct _ModestWizardDialogClass { - GtkDialogClass parent_class; - - /** Implementations of this vfunc should prepare the next page if necessary, - * and only return TRUE if the navigation should be allowed. - * You may even change the next page, via the GtkNotebook API, in the signal handler. */ - gboolean (* before_next) (ModestWizardDialog *dialog, GtkWidget *current_page, GtkWidget *next_page); - - /** Implementations of this vfunc should enable or disable - * the next/forward buttons appropriately, based on the entered data. */ - void (* enable_buttons) (ModestWizardDialog *dialog, GtkWidget *current_page); - - - void (*_gtk_reserved2) (void); - void (*_gtk_reserved3) (void); - void (*_gtk_reserved4) (void); -}; - - -GType modest_wizard_dialog_get_type (void) G_GNUC_CONST; - -GtkWidget* modest_wizard_dialog_new (GtkWindow *parent, - const char *wizard_name, - GtkNotebook *notebook); - -void modest_wizard_dialog_force_title_update (ModestWizardDialog* wizard_dialog); - -G_END_DECLS - -#endif /* __MODEST_WIZARD_DIALOG_H__ */ diff --git a/src/maemo/modest-maemo-global-settings-dialog.c b/src/maemo/modest-maemo-global-settings-dialog.c index 4d6286f..48c96bf 100644 --- a/src/maemo/modest-maemo-global-settings-dialog.c +++ b/src/maemo/modest-maemo-global-settings-dialog.c @@ -217,7 +217,11 @@ modest_maemo_global_settings_dialog_init (ModestMaemoGlobalSettingsDialog *self) ppriv->updating_page = create_updating_page (self); ppriv->composing_page = create_composing_page (self); - + + /* Add the buttons: */ + gtk_dialog_add_button (GTK_DIALOG (self), _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK); + gtk_dialog_add_button (GTK_DIALOG (self), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL); + /* Set the default focusable widgets */ g_object_set_data (G_OBJECT(ppriv->updating_page), DEFAULT_FOCUS_WIDGET, (gpointer)ppriv->auto_update); diff --git a/src/modest-init.c b/src/modest-init.c index c06fae9..8a3b868 100644 --- a/src/modest-init.c +++ b/src/modest-init.c @@ -80,6 +80,7 @@ typedef struct { static const guint MODEST_MAIN_PANED_POS_PERCENTAGE = 30; +static const guint MODEST_MSG_PANED_POS_PERCENTAGE = 50; static const FolderCols INBOX_COLUMNS_DETAILS[] = { {MODEST_HEADER_VIEW_COLUMN_MSGTYPE, 40, 0}, @@ -431,6 +432,15 @@ init_header_columns (ModestConf *conf, gboolean overwrite) modest_conf_set_int (conf, key, MODEST_MAIN_PANED_POS_PERCENTAGE, NULL); g_free (key); + + key = _modest_widget_memory_get_keyname (MODEST_CONF_MSG_PANED_KEY, + MODEST_WIDGET_MEMORY_PARAM_POS); + /* if we're not in overwrite mode, only write stuff it + * there was nothing before */ + if (overwrite || !modest_conf_key_exists(conf, key, NULL)) + modest_conf_set_int (conf, key, MODEST_MSG_PANED_POS_PERCENTAGE, NULL); + + g_free (key); return TRUE; } diff --git a/src/widgets/Makefile.am b/src/widgets/Makefile.am index b5b314d..857e693 100644 --- a/src/widgets/Makefile.am +++ b/src/widgets/Makefile.am @@ -86,6 +86,8 @@ libmodest_widgets_la_SOURCES= \ modest-window.h \ modest-window-mgr.h \ modest-window-mgr.c \ + modest-wizard-dialog.h \ + modest-wizard-dialog.c \ modest-zoomable.h \ modest-zoomable.c diff --git a/src/widgets/modest-global-settings-dialog.c b/src/widgets/modest-global-settings-dialog.c index 1cfb1b2..9c0d724 100644 --- a/src/widgets/modest-global-settings-dialog.c +++ b/src/widgets/modest-global-settings-dialog.c @@ -126,10 +126,6 @@ modest_global_settings_dialog_init (ModestGlobalSettingsDialog *self) priv->notebook = gtk_notebook_new (); - /* Add the buttons: */ - gtk_dialog_add_button (GTK_DIALOG (self), _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK); - gtk_dialog_add_button (GTK_DIALOG (self), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL); - /* Connect to the dialog's response signal: */ g_signal_connect (G_OBJECT (self), "response", G_CALLBACK (on_response), self); diff --git a/src/widgets/modest-header-view.c b/src/widgets/modest-header-view.c index 6338898..7284672 100644 --- a/src/widgets/modest-header-view.c +++ b/src/widgets/modest-header-view.c @@ -380,8 +380,10 @@ modest_header_view_set_columns (ModestHeaderView *self, const GList *columns, Tn g_object_set_data (G_OBJECT (renderer_recpt_box), "date-renderer", renderer_compact_date_or_status); g_object_set (G_OBJECT (renderer_subject_box), "yalign", 1.0, NULL); +#ifdef MAEMO_PLATFORM gtk_cell_renderer_set_fixed_size (renderer_subject_box, -1, 32); gtk_cell_renderer_set_fixed_size (renderer_recpt_box, -1, 32); +#endif g_object_set (G_OBJECT (renderer_recpt_box), "yalign", 0.0, NULL); g_object_set(G_OBJECT(renderer_header), "ellipsize", PANGO_ELLIPSIZE_END, @@ -403,9 +405,15 @@ modest_header_view_set_columns (ModestHeaderView *self, const GList *columns, Tn g_object_set (G_OBJECT (renderer_attach), "yalign", 0.0, NULL); +#ifdef MAEMO_PLATFORM gtk_cell_renderer_set_fixed_size (renderer_attach, 32, 26); gtk_cell_renderer_set_fixed_size (renderer_priority, 32, 26); gtk_cell_renderer_set_fixed_size (renderer_compact_header, -1, 64); +#else + gtk_cell_renderer_set_fixed_size (renderer_attach, 26, 26); + gtk_cell_renderer_set_fixed_size (renderer_priority, 26, 26); + /* gtk_cell_renderer_set_fixed_size (renderer_compact_header, -1, 64); */ +#endif remove_all_columns (self); diff --git a/src/widgets/modest-wizard-dialog.c b/src/widgets/modest-wizard-dialog.c new file mode 100644 index 0000000..8e6e667 --- /dev/null +++ b/src/widgets/modest-wizard-dialog.c @@ -0,0 +1,671 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * SECTION:modest-wizard-dialog + * @short_description: A widget to create a guided installation + * process wizard + * + * #ModestWizardDialog is a widget to create a guided installation + * process. The dialog has four standard buttons, previous, next, + * finish, cancel, and contains several pages with optional icons. + * Response buttons are dimmed/undimmed automatically and the standard + * icon is shown/hidden in response to page navigation. The notebook + * widget provided by users contains the actual wizard pages. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef MODEST_PLATFORM_MAEMO +#ifdef MODEST_HAVE_HILDON0_WIDGETS +#include +#else +#include +#endif /*MODEST_HAVE_HILDON0_WIDGETS*/ +#endif /*MODEST_PLATFORM_MAEMO*/ + +#include "modest-wizard-dialog.h" + +#include + +#ifdef MODEST_PLATFORM_MAEMO +/* Specify the hildon-libs translation domain, + * so we can reuse its translations + * instead of repeating them in our own translations. + */ +/* #define _(String) dgettext(PACKAGE, String) */ + +#define _(String) dgettext("hildon-libs", String) +#else +#define _(String) gettext(String) +#endif + +static GtkDialogClass *parent_class; + +static void class_init (ModestWizardDialogClass *wizard_dialog_class); + +static void init (ModestWizardDialog *wizard_dialog); + +static void create_title (ModestWizardDialog *wizard_dialog); + +static void set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); + +static void get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void finalize (GObject *object); + +static void response (ModestWizardDialog *wizard, + gint response_id, + gpointer unused); + +static void make_buttons_sensitive (ModestWizardDialog *wizard_dialog, + gboolean previous, + gboolean finish, + gboolean next); + +static gboolean invoke_before_next_vfunc (ModestWizardDialog *wizard_dialog); +static void invoke_enable_buttons_vfunc (ModestWizardDialog *wizard_dialog); + +enum { + PROP_ZERO, + PROP_WIZARD_NAME, + PROP_WIZARD_NOTEBOOK, + PROP_WIZARD_AUTOTITLE +}; + +struct _ModestWizardDialogPrivate { + gchar *wizard_name; + GtkNotebook *notebook; + GtkBox *box; + GtkWidget *image; + gboolean autotitle; +}; + + +GType +modest_wizard_dialog_get_type (void) +{ + static GType wizard_dialog_type = 0; + + if (!wizard_dialog_type) { + + static const GTypeInfo wizard_dialog_info = { + sizeof (ModestWizardDialogClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ModestWizardDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) init, + }; + + wizard_dialog_type = g_type_register_static (GTK_TYPE_DIALOG, + "ModestWizardDialog", + &wizard_dialog_info, + 0); + } + + return wizard_dialog_type; +} + +static void +class_init (ModestWizardDialogClass *wizard_dialog_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (wizard_dialog_class); + + parent_class = g_type_class_peek_parent (wizard_dialog_class); + + g_type_class_add_private (wizard_dialog_class, + sizeof(ModestWizardDialogPrivate)); + + /* Override virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + /** + * ModestWizardDialog:wizard-name: + * + * The name of the wizard. + */ + g_object_class_install_property (object_class, PROP_WIZARD_NAME, + g_param_spec_string + ("wizard-name", + "Wizard Name", + "The name of the ModestWizardDialog", + NULL, + G_PARAM_READWRITE)); + + /** + * ModestWizardDialog:wizard-notebook: + * + * The notebook object, which is used by the ModestWizardDialog. + */ + g_object_class_install_property(object_class, PROP_WIZARD_NOTEBOOK, + g_param_spec_object + ("wizard-notebook", + "Wizard Notebook", + "GtkNotebook object to be used in the " + "ModestWizardDialog", + GTK_TYPE_NOTEBOOK, G_PARAM_READWRITE)); + + /** + * ModestWizardDialog:autotitle + * + * If the wizard should automatically try to change the window title when changing steps. + * Set to FALSE if you'd like to override the default behaviour. + * + * Since: 0.14.5 + */ + g_object_class_install_property(object_class, PROP_WIZARD_AUTOTITLE, + g_param_spec_boolean + ("autotitle", + "AutoTitle", + "If the wizard should autotitle itself", + TRUE, + G_PARAM_READWRITE)); +} + +static void +finalize (GObject *object) +{ + ModestWizardDialog *dialog = MODEST_WIZARD_DIALOG (object); + g_return_if_fail (dialog != NULL); + + if (dialog->priv->wizard_name != NULL) + g_free (MODEST_WIZARD_DIALOG (object)->priv->wizard_name); + + if (G_OBJECT_CLASS (parent_class)->finalize) + G_OBJECT_CLASS (parent_class)->finalize(object); +} + +/* Disable or enable the Previous, Next and Finish buttons */ +static void +make_buttons_sensitive (ModestWizardDialog *wizard_dialog, + gboolean previous, + gboolean finish, + gboolean next) +{ + gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog), + MODEST_WIZARD_DIALOG_PREVIOUS, + previous); + + gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog), + MODEST_WIZARD_DIALOG_FINISH, + finish); + + gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog), + MODEST_WIZARD_DIALOG_NEXT, + next); +} + +static void +init (ModestWizardDialog *wizard_dialog) +{ + /* Initialize private structure for faster member access */ + ModestWizardDialogPrivate *priv = + G_TYPE_INSTANCE_GET_PRIVATE (wizard_dialog, + MODEST_TYPE_WIZARD_DIALOG, + ModestWizardDialogPrivate); + + GtkDialog *dialog = GTK_DIALOG (wizard_dialog); + + /* Init internal widgets */ + GtkWidget *vbox = gtk_vbox_new (FALSE, 0); + gtk_dialog_set_has_separator (dialog, FALSE); + wizard_dialog->priv = priv; + priv->box = GTK_BOX (gtk_hbox_new (FALSE, 0)); +#ifdef MODEST_PLATFORM_MAEMO +#ifdef MODEST_HAVE_HILDON0_WIDGETS + priv->image = gtk_image_new_from_icon_name ("qgn_widg_wizard", + HILDON_ICON_SIZE_WIDG_WIZARD); +#else + static int icon_size = 0; + if (!icon_size) + icon_size = gtk_icon_size_register("modest_wizard", 50, 50); + priv->image = gtk_image_new_from_icon_name ("qgn_widg_wizard", + icon_size); +#endif /*MODEST_HILDON_VERSION_0*/ +#else /*MODEST_PLATFORM_MAEMO*/ + priv->image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_DIALOG); +#endif /*MODEST_PLATFORM_MAEMO*/ + /* Default values for user provided properties */ + priv->notebook = NULL; + priv->wizard_name = NULL; + priv->autotitle = TRUE; + + /* Build wizard layout */ + gtk_box_pack_start_defaults (GTK_BOX (dialog->vbox), GTK_WIDGET (priv->box)); + gtk_box_pack_start_defaults (GTK_BOX (priv->box), GTK_WIDGET (vbox)); + gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->image), FALSE, FALSE, 0); + + /* Add response buttons: finish, previous, next, cancel */ +#ifdef MODEST_PLATFORM_MAEMO + gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_finish"), MODEST_WIZARD_DIALOG_FINISH); + gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_previous"), MODEST_WIZARD_DIALOG_PREVIOUS); + gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_next"), MODEST_WIZARD_DIALOG_NEXT); + gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_cancel"), MODEST_WIZARD_DIALOG_CANCEL); +#else + gtk_dialog_add_button (dialog, GTK_STOCK_SAVE, MODEST_WIZARD_DIALOG_FINISH); + gtk_dialog_add_button (dialog, GTK_STOCK_GO_BACK, MODEST_WIZARD_DIALOG_PREVIOUS); + gtk_dialog_add_button (dialog, GTK_STOCK_GO_FORWARD, MODEST_WIZARD_DIALOG_NEXT); + gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, MODEST_WIZARD_DIALOG_CANCEL); +#endif + + /* Set initial button states: previous and finish buttons are disabled */ + make_buttons_sensitive (wizard_dialog, FALSE, FALSE, TRUE); + + /* Show all the internal widgets */ + gtk_widget_show_all (GTK_WIDGET (dialog->vbox)); + + /* connect to dialog's response signal */ + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (response), NULL); +} + +#if GTK_CHECK_VERSION(2, 10, 0) /* These signals were added in GTK+ 2.10: */ +static void on_notebook_page_added(GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + gpointer user_data) +{ + ModestWizardDialog* dialog = NULL; + + g_return_if_fail (MODEST_IS_WIZARD_DIALOG(user_data)); + dialog = MODEST_WIZARD_DIALOG(user_data); + + /* The title should show the total number of pages: */ + create_title (dialog); +} + +static void on_notebook_page_removed(GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + gpointer user_data) +{ + ModestWizardDialog* dialog = NULL; + + g_return_if_fail (MODEST_IS_WIZARD_DIALOG(user_data)); + dialog = MODEST_WIZARD_DIALOG(user_data); + + /* The title should show the total number of pages: */ + create_title (dialog); +} +#endif /* GTK_CHECK_VERSION */ + +static void +connect_to_notebook_signals(ModestWizardDialog* dialog) +{ +#if GTK_CHECK_VERSION(2, 10, 0) /* These signals were added in GTK+ 2.10: */ + ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG(dialog)->priv; + g_return_if_fail (priv->notebook); + + /* Connect to the notebook signals, + * so we can update the title when necessary: */ + g_signal_connect (G_OBJECT (priv->notebook), "page-added", + G_CALLBACK (on_notebook_page_added), dialog); + g_signal_connect (G_OBJECT (priv->notebook), "page-removed", + G_CALLBACK (on_notebook_page_removed), dialog); +#endif /* GTK_CHECK_VERSION */ +} + + +static void +set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG(object)->priv; + + switch (property_id) { + + case PROP_WIZARD_AUTOTITLE: + + priv->autotitle = g_value_get_boolean (value); + + if (priv->autotitle && + priv->wizard_name && + priv->notebook) + create_title (MODEST_WIZARD_DIALOG (object)); + else if (priv->wizard_name) + gtk_window_set_title (GTK_WINDOW (object), priv->wizard_name); + + break; + + case PROP_WIZARD_NAME: + + /* Set new wizard name. This name will appear in titlebar */ + if (priv->wizard_name) + g_free (priv->wizard_name); + + gchar *str = (gchar *) g_value_get_string (value); + g_return_if_fail (str != NULL); + + priv->wizard_name = g_strdup (str); + + /* We need notebook in order to create title, since page information + is used in title generation */ + + if (priv->notebook && priv->autotitle) + create_title (MODEST_WIZARD_DIALOG (object)); + + break; + + case PROP_WIZARD_NOTEBOOK: { + + GtkNotebook *book = GTK_NOTEBOOK (g_value_get_object (value)); + g_return_if_fail (book != NULL); + + priv->notebook = book; + + /* Set the default properties for the notebook (disable tabs, + * and remove borders) to make it look like a nice wizard widget */ + gtk_notebook_set_show_tabs (priv->notebook, FALSE); + gtk_notebook_set_show_border (priv->notebook, FALSE); + gtk_box_pack_start_defaults (GTK_BOX( priv->box), GTK_WIDGET (priv->notebook)); + + /* Show the notebook so that a gtk_widget_show on the dialog is + * all that is required to display the dialog correctly */ + gtk_widget_show ( GTK_WIDGET (priv->notebook)); + + /* Update dialog title to reflect current page stats etc */ + ModestWizardDialog *wizard_dialog = MODEST_WIZARD_DIALOG (object); + if (priv->wizard_name && priv->autotitle) + create_title (wizard_dialog); + + connect_to_notebook_signals (wizard_dialog); + + }break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG (object)->priv; + + switch (property_id) { + + case PROP_WIZARD_NAME: + g_value_set_string (value, priv->wizard_name); + break; + + case PROP_WIZARD_NOTEBOOK: + g_value_set_object (value, priv->notebook); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +/* + * Creates the title of the dialog taking into account the current + * page of the notebook. + */ +static void +create_title (ModestWizardDialog *wizard_dialog) +{ + gchar *str = NULL; + ModestWizardDialogPrivate *priv = NULL; + GtkNotebook *notebook = NULL; + + g_return_if_fail (MODEST_IS_WIZARD_DIALOG(wizard_dialog)); + g_return_if_fail (wizard_dialog->priv != NULL); + + priv = wizard_dialog->priv; + notebook = priv->notebook; + + if (!notebook) + return; + + /* Get page information, we'll need that when creating title */ + gint pages = gtk_notebook_get_n_pages (notebook); + if (pages == 0) + return; + + gint current = gtk_notebook_get_current_page (priv->notebook); + if (current < 0) + current = 0; + + /* the welcome title on the initial page */ + /* This is the standard wizard title, with, e.g., 1/4 at the end, + * but the Modest UI spec does not want this. */ + /* + if (current == 0) { + str = g_strdup_printf (_("ecdg_ti_wizard_welcome"), + priv->wizard_name, pages); + } else { + */ + const gchar *steps = gtk_notebook_get_tab_label_text (notebook, + gtk_notebook_get_nth_page (notebook, current)); + + /* This is the standard wizard title, with, e.g., 1/4 at the end, + * but the Modest UI spec does not want this. + */ + /* + str = g_strdup_printf (_("ecdg_ti_wizard_step"), + priv->wizard_name, current + 1, pages, steps); + */ + + str = g_strdup_printf (_("%s: %s"), + priv->wizard_name, steps); + /* } */ + + /* Update the dialog to display the generated title */ + gtk_window_set_title (GTK_WINDOW (wizard_dialog), str); + g_free (str); +} + +/* + * Response signal handler. This function is needed because GtkDialog's + * handler for this signal closes the dialog and we don't want that, we + * want to change pages and, dim certain response buttons. Overriding the + * virtual function would not work because that would be called after the + * signal handler implemented by GtkDialog. + * FIXME: There is a much saner way to do that [MDK] + */ +static void +response (ModestWizardDialog *wizard_dialog, + gint response_id, + gpointer unused) +{ + ModestWizardDialogPrivate *priv = wizard_dialog->priv; + GtkNotebook *notebook = priv->notebook; + gint current = 0; + gboolean is_first, is_last; + + switch (response_id) { + + case MODEST_WIZARD_DIALOG_PREVIOUS: + gtk_notebook_prev_page (notebook); /* go to previous page */ + break; + + case MODEST_WIZARD_DIALOG_NEXT: + if (invoke_before_next_vfunc (wizard_dialog)) + gtk_notebook_next_page (notebook); /* go to next page */ + + break; + + case MODEST_WIZARD_DIALOG_CANCEL: + return; + break; + case MODEST_WIZARD_DIALOG_FINISH: + if (invoke_before_next_vfunc (wizard_dialog)) + return; + + break; + + } + + current = gtk_notebook_get_current_page (notebook); + gint last = gtk_notebook_get_n_pages (notebook) - 1; + is_last = current == last; + is_first = current == 0; + + /* If first page, previous and finish are disabled, + if last page, next is disabled */ + make_buttons_sensitive (wizard_dialog, + !is_first /* previous */, !is_first /* finish */, !is_last /* next*/); + + /* Allow derived classes to disable buttons to prevent navigation, + * according to their own validation logic: */ + invoke_enable_buttons_vfunc (wizard_dialog); + + /* Don't let the dialog close */ + g_signal_stop_emission_by_name (wizard_dialog, "response"); + + /* We show the default image on first and last pages */ + last = gtk_notebook_get_n_pages (notebook) - 1; + if (current == last || current == 0) + gtk_widget_show (GTK_WIDGET(priv->image)); + else + gtk_widget_hide (GTK_WIDGET(priv->image)); + + /* New page number may appear in the title, update it */ + if (priv->autotitle) + create_title (wizard_dialog); +} + +/** + * modest_wizard_dialog_new: + * @parent: a #GtkWindow + * @wizard_name: the name of dialog + * @notebook: the notebook to be shown on the dialog + * + * Creates a new #ModestWizardDialog. + * + * Returns: a new #ModestWizardDialog + */ +GtkWidget* +modest_wizard_dialog_new (GtkWindow *parent, + const char *wizard_name, + GtkNotebook *notebook) +{ + GtkWidget *widget; + + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + + widget = GTK_WIDGET (g_object_new + (MODEST_TYPE_WIZARD_DIALOG, + "wizard-name", wizard_name, + "wizard-notebook", notebook, NULL)); + + if (parent) + gtk_window_set_transient_for (GTK_WINDOW (widget), parent); + + return widget; +} + +/** + * modest_wizard_dialog_force_title_update: + * @wizard_dialog: The wizard dialog + * + * Force the title to be rebuilt, for instance when you have added or + * removed notebook pages. This function is not necessary when using GTK+ 2.10, + * because that has GtkNotebook signals that will be used to update the title + * automatically. + */ +void +modest_wizard_dialog_force_title_update (ModestWizardDialog *wizard_dialog) +{ + create_title (wizard_dialog); +} + +static gboolean +invoke_before_next_vfunc (ModestWizardDialog *wizard_dialog) +{ + ModestWizardDialogClass *klass = MODEST_WIZARD_DIALOG_GET_CLASS (wizard_dialog); + + /* Call the vfunc, which may be overridden by derived classes: */ + if (klass->before_next) { + ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG(wizard_dialog)->priv; + + gint current_page_num = gtk_notebook_get_current_page (priv->notebook); + + /* Get widgets for the two pages: */ + GtkWidget* current_page_widget = gtk_notebook_get_nth_page (priv->notebook, current_page_num); + + GtkWidget* next_page_widget = NULL; + if ((current_page_num + 1) < gtk_notebook_get_n_pages (priv->notebook)) + next_page_widget = gtk_notebook_get_nth_page (priv->notebook, current_page_num + 1); + + /* Ask the vfunc implementation whether navigation should be allowed: */ + return (*(klass->before_next))(wizard_dialog, current_page_widget, next_page_widget); + } + + /* Allow navigation by default if there is no vfunc implementation: */ + return TRUE; +} + +static void +invoke_enable_buttons_vfunc (ModestWizardDialog *wizard_dialog) +{ + ModestWizardDialogClass *klass = MODEST_WIZARD_DIALOG_GET_CLASS (wizard_dialog); + + /* Call the vfunc, which may be overridden by derived classes: */ + if (klass->enable_buttons) { + ModestWizardDialogPrivate *priv = MODEST_WIZARD_DIALOG(wizard_dialog)->priv; + + gint current_page_num = gtk_notebook_get_current_page (priv->notebook); + + GtkWidget* current_page_widget = gtk_notebook_get_nth_page (priv->notebook, current_page_num); + + (*(klass->enable_buttons))(wizard_dialog, current_page_widget); + } +} diff --git a/src/widgets/modest-wizard-dialog.h b/src/widgets/modest-wizard-dialog.h new file mode 100644 index 0000000..c7bdbe1 --- /dev/null +++ b/src/widgets/modest-wizard-dialog.h @@ -0,0 +1,107 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __MODEST_WIZARD_DIALOG_H__ +#define __MODEST_WIZARD_DIALOG_H__ + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define MODEST_TYPE_WIZARD_DIALOG (modest_wizard_dialog_get_type()) + +#define MODEST_WIZARD_DIALOG(obj) (GTK_CHECK_CAST ((obj), \ + MODEST_TYPE_WIZARD_DIALOG, ModestWizardDialog)) + +#define MODEST_WIZARD_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \ + MODEST_TYPE_WIZARD_DIALOG, ModestWizardDialogClass)) + +#define MODEST_IS_WIZARD_DIALOG(obj) (GTK_CHECK_TYPE ((obj), \ + MODEST_TYPE_WIZARD_DIALOG)) + +#define MODEST_IS_WIZARD_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \ + MODEST_TYPE_WIZARD_DIALOG)) + +#define MODEST_WIZARD_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + MODEST_TYPE_WIZARD_DIALOG, ModestWizardDialogClass)) + +typedef struct _ModestWizardDialog ModestWizardDialog; + +typedef struct _ModestWizardDialogClass ModestWizardDialogClass; + +typedef struct _ModestWizardDialogPrivate ModestWizardDialogPrivate; + +/* button response IDs */ +enum { + MODEST_WIZARD_DIALOG_CANCEL = GTK_RESPONSE_CANCEL, + MODEST_WIZARD_DIALOG_PREVIOUS = 0, + MODEST_WIZARD_DIALOG_NEXT, + MODEST_WIZARD_DIALOG_FINISH +}; + +struct _ModestWizardDialog { + GtkDialog parent; + ModestWizardDialogPrivate *priv; +}; + +struct _ModestWizardDialogClass { + GtkDialogClass parent_class; + + /** Implementations of this vfunc should prepare the next page if necessary, + * and only return TRUE if the navigation should be allowed. + * You may even change the next page, via the GtkNotebook API, in the signal handler. */ + gboolean (* before_next) (ModestWizardDialog *dialog, GtkWidget *current_page, GtkWidget *next_page); + + /** Implementations of this vfunc should enable or disable + * the next/forward buttons appropriately, based on the entered data. */ + void (* enable_buttons) (ModestWizardDialog *dialog, GtkWidget *current_page); + + + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + void (*_gtk_reserved4) (void); +}; + + +GType modest_wizard_dialog_get_type (void) G_GNUC_CONST; + +GtkWidget* modest_wizard_dialog_new (GtkWindow *parent, + const char *wizard_name, + GtkNotebook *notebook); + +void modest_wizard_dialog_force_title_update (ModestWizardDialog* wizard_dialog); + +G_END_DECLS + +#endif /* __MODEST_WIZARD_DIALOG_H__ */ -- 1.7.9.5