From cc379b2109f5c1b1a70419454d1a0e53c26559e6 Mon Sep 17 00:00:00 2001 From: Jose Dapena Paz Date: Wed, 8 Oct 2008 17:39:04 +0000 Subject: [PATCH] After a deep refactoring, finally finished to split the window manager in a parent class and a child with hildon1 specific behavior. This way I will be able to implement a hildon2 based window manager. Responsibility of window manager: * Hibernation management. * Preregistered UIDs * Preload cache for view and editor. * Banners counting * Fetching help id's * In registering process, the part of removing the uid from preregistered uids list. * Keeping a reference to main window. * Saving window states. * Counting number of windows (maintaining the list is responsibility of children). Responsibility of child: * Implementation of close all windows. * In finding registered headers, checking also in windows. * Show toolbar status. * Fullscreen status. * Registering window stuff (in particular also related to message changes in view). * Destroy operations, and cancelling operations on close window. * Fetching the main window implementation. * Maintaining the list of modal dialogs. pmo-trunk-r5966 --- src/dbus_api/modest-dbus-callbacks.c | 7 +- src/gnome/modest-account-view-window.c | 2 +- src/hildon2/modest-account-view-window.c | 19 +- src/hildon2/modest-address-book.c | 4 +- .../modest-connection-specific-smtp-window.c | 2 +- .../modest-default-account-settings-dialog.c | 4 +- src/hildon2/modest-easysetup-wizard-dialog.c | 4 +- src/hildon2/modest-hildon-includes.h | 1 + src/hildon2/modest-msg-edit-window.c | 10 +- src/hildon2/modest-msg-view-window.c | 22 +- src/hildon2/modest-platform.c | 14 +- .../easysetup/modest-easysetup-wizard-dialog.c | 6 +- src/maemo/modest-account-view-window.c | 4 +- src/maemo/modest-address-book.c | 4 +- src/maemo/modest-connection-specific-smtp-window.c | 4 +- src/maemo/modest-default-account-settings-dialog.c | 6 +- src/maemo/modest-main-window.c | 5 +- src/maemo/modest-msg-edit-window.c | 11 +- src/maemo/modest-msg-view-window.c | 2 +- src/maemo/modest-platform.c | 15 +- src/modest-account-protocol.c | 4 - src/modest-main.c | 2 - src/modest-singletons.c | 3 +- src/modest-tny-account-store.c | 1 + src/modest-ui-actions.c | 38 +- src/modest-utils.c | 2 +- src/widgets/Makefile.am | 2 + src/widgets/modest-hildon1-window-mgr.c | 1020 ++++++++++++++++++++ src/widgets/modest-hildon1-window-mgr.h | 69 ++ src/widgets/modest-window-mgr.c | 898 +++-------------- src/widgets/modest-window-mgr.h | 56 +- src/widgets/modest-window.c | 4 + src/widgets/modest-window.h | 9 + 33 files changed, 1397 insertions(+), 857 deletions(-) create mode 100644 src/widgets/modest-hildon1-window-mgr.c create mode 100644 src/widgets/modest-hildon1-window-mgr.h diff --git a/src/dbus_api/modest-dbus-callbacks.c b/src/dbus_api/modest-dbus-callbacks.c index e551240..6e1f505 100644 --- a/src/dbus_api/modest-dbus-callbacks.c +++ b/src/dbus_api/modest-dbus-callbacks.c @@ -537,7 +537,7 @@ find_msg_async_cb (TnyFolder *folder, } if (msg_view != NULL) { - modest_window_mgr_register_window (win_mgr, msg_view); + modest_window_mgr_register_window (win_mgr, msg_view, NULL); gtk_widget_show_all (GTK_WIDGET (msg_view)); } } @@ -1168,11 +1168,6 @@ on_idle_top_application (gpointer user_data) } if (main_win) { - /* Ideally, we would just use gtk_widget_show(), - * but this widget is not coded correctly to support that: */ - gtk_widget_show_all (GTK_WIDGET (main_win)); - gtk_window_present (GTK_WINDOW (main_win)); - /* If we're showing an already existing window then reselect the INBOX */ if (!new_window) { diff --git a/src/gnome/modest-account-view-window.c b/src/gnome/modest-account-view-window.c index 5465c78..fce5fb0 100644 --- a/src/gnome/modest-account-view-window.c +++ b/src/gnome/modest-account-view-window.c @@ -335,7 +335,7 @@ on_add_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) /* 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)); + GTK_WINDOW (wizard), self); /* if there is already another modal dialog, make it non-modal */ if (dialog) diff --git a/src/hildon2/modest-account-view-window.c b/src/hildon2/modest-account-view-window.c index 8c7e36c..060f324 100644 --- a/src/hildon2/modest-account-view-window.c +++ b/src/hildon2/modest-account-view-window.c @@ -343,6 +343,7 @@ on_edit_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) if (proto && MODEST_IS_ACCOUNT_PROTOCOL (proto)) { ModestAccountSettingsDialog *dialog = modest_account_protocol_get_account_settings_dialog (proto, account_name); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (self)); gtk_widget_show (GTK_WIDGET (dialog)); } } @@ -372,26 +373,12 @@ static void on_new_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) { GtkDialog *wizard; - GtkWindow *dialog; - - /* Show the easy-setup wizard: */ - dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr()); - if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) { - /* old wizard is active already; - */ - gtk_window_present (dialog); - return; - } - + /* there is no such wizard yet */ wizard = GTK_DIALOG (modest_easysetup_wizard_dialog_new ()); modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), - GTK_WINDOW (wizard)); + GTK_WINDOW (wizard), GTK_WINDOW (self)); - /* 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: */ diff --git a/src/hildon2/modest-address-book.c b/src/hildon2/modest-address-book.c index b636c6e..467c88d 100644 --- a/src/hildon2/modest-address-book.c +++ b/src/hildon2/modest-address-book.c @@ -174,6 +174,7 @@ modest_address_book_select_addresses (ModestRecptEditor *recpt_editor) #if MODEST_ABOOK_API < 4 GtkWidget *contact_view = NULL; GtkWidget *contact_dialog; + GtkWidget *toplevel; #else /* MODEST_ABOOK_API < 4 */ OssoABookContactChooser *contact_chooser = NULL; #endif /* MODEST_ABOOK_API < 4 */ @@ -200,7 +201,8 @@ modest_address_book_select_addresses (ModestRecptEditor *recpt_editor) contact_dialog = osso_abook_select_dialog_new (OSSO_ABOOK_TREE_VIEW (contact_view)); gtk_window_set_title (GTK_WINDOW (contact_dialog), _("mcen_ti_select_recipients")); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (contact_dialog)); + toplevel = gtk_widget_get_toplevel (recpt_editor); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (contact_dialog), toplevel); gtk_widget_show (contact_dialog); diff --git a/src/hildon2/modest-connection-specific-smtp-window.c b/src/hildon2/modest-connection-specific-smtp-window.c index 3f98ded..68a268d 100644 --- a/src/hildon2/modest-connection-specific-smtp-window.c +++ b/src/hildon2/modest-connection-specific-smtp-window.c @@ -267,7 +267,7 @@ on_button_edit (ModestConnectionSpecificSmtpWindow *self) server_settings = NULL; } - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (window)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (window), GTK_WINDOW (self)); gint response = gtk_dialog_run (GTK_DIALOG (window)); if (response == GTK_RESPONSE_OK) { diff --git a/src/hildon2/modest-default-account-settings-dialog.c b/src/hildon2/modest-default-account-settings-dialog.c index 24b854f..d40117a 100644 --- a/src/hildon2/modest-default-account-settings-dialog.c +++ b/src/hildon2/modest-default-account-settings-dialog.c @@ -458,7 +458,7 @@ on_button_signature (GtkButton *button, gpointer user_data) /* Show the window: */ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (priv->signature_dialog)); + GTK_WINDOW (priv->signature_dialog), GTK_WINDOW (self)); response = gtk_dialog_run (GTK_DIALOG (priv->signature_dialog)); gtk_widget_hide (priv->signature_dialog); @@ -703,7 +703,7 @@ on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data) modest_connection_specific_smtp_window_fill_with_connections (smtp_win, priv->account_manager); /* Show the window: */ - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (smtp_win)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (smtp_win), GTK_WINDOW (self)); gtk_widget_show (GTK_WIDGET (smtp_win)); priv->modified = TRUE; } diff --git a/src/hildon2/modest-easysetup-wizard-dialog.c b/src/hildon2/modest-easysetup-wizard-dialog.c index 6c6ab47..d94262e 100644 --- a/src/hildon2/modest-easysetup-wizard-dialog.c +++ b/src/hildon2/modest-easysetup-wizard-dialog.c @@ -796,7 +796,7 @@ on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data) modest_connection_specific_smtp_window_fill_with_connections (MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), priv->account_manager); /* Show the window */ - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (specific_window)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (specific_window), GTK_WINDOW (self)); gtk_widget_show (specific_window); } @@ -899,7 +899,7 @@ show_advanced_edit(gpointer user_data) } modest_account_settings_dialog_load_settings (dialog, priv->settings); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (self)); response = gtk_dialog_run (GTK_DIALOG (dialog)); diff --git a/src/hildon2/modest-hildon-includes.h b/src/hildon2/modest-hildon-includes.h index 0609d4d..b55bc09 100644 --- a/src/hildon2/modest-hildon-includes.h +++ b/src/hildon2/modest-hildon-includes.h @@ -75,6 +75,7 @@ k * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #include #include #include +#include /* backward compatibility... */ diff --git a/src/hildon2/modest-msg-edit-window.c b/src/hildon2/modest-msg-edit-window.c index df85374..35e2c1e 100644 --- a/src/hildon2/modest-msg-edit-window.c +++ b/src/hildon2/modest-msg-edit-window.c @@ -2169,7 +2169,7 @@ modest_msg_edit_window_insert_image (ModestMsgEditWindow *window) modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog)); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), GTK_WINDOW (window)); response = gtk_dialog_run (GTK_DIALOG (dialog)); switch (response) { @@ -2283,7 +2283,7 @@ modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window) dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN); gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title")); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (window)); response = gtk_dialog_run (GTK_DIALOG (dialog)); switch (response) { @@ -2862,7 +2862,7 @@ modest_msg_edit_window_select_font (ModestMsgEditWindow *window) dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL); modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), - GTK_WINDOW(dialog)); + GTK_WINDOW(dialog), GTK_WINDOW (window)); /* First we get the currently selected font information */ wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE); @@ -2899,7 +2899,7 @@ modest_msg_edit_window_select_font (ModestMsgEditWindow *window) NULL); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), GTK_WINDOW (window)); gtk_widget_show_all (dialog); priv->font_dialog = dialog; response = gtk_dialog_run (GTK_DIALOG (dialog)); @@ -3554,7 +3554,7 @@ modest_msg_edit_window_set_draft (ModestMsgEditWindow *window, } priv->msg_uid = modest_tny_folder_get_header_unique_id (header); if (GTK_WIDGET_REALIZED (window)) - modest_window_mgr_register_window (mgr, MODEST_WINDOW (window)); + modest_window_mgr_register_window (mgr, MODEST_WINDOW (window), NULL); } priv->draft_msg = draft; diff --git a/src/hildon2/modest-msg-view-window.c b/src/hildon2/modest-msg-view-window.c index 8f7c9e7..a05c6d4 100644 --- a/src/hildon2/modest-msg-view-window.c +++ b/src/hildon2/modest-msg-view-window.c @@ -1840,8 +1840,6 @@ message_reader (ModestMsgViewWindow *window, TnyHeader *header, GtkTreeRowReference *row_reference) { - gboolean already_showing = FALSE; - ModestWindow *msg_window = NULL; ModestWindowMgr *mgr; TnyAccount *account; TnyFolder *folder; @@ -1850,15 +1848,6 @@ message_reader (ModestMsgViewWindow *window, g_return_val_if_fail (row_reference != NULL, FALSE); mgr = modest_runtime_get_window_mgr (); - already_showing = modest_window_mgr_find_registered_header (mgr, header, &msg_window); - if (already_showing && (msg_window != MODEST_WINDOW (window))) { - gboolean retval; - if (msg_window) - gtk_window_present (GTK_WINDOW (msg_window)); - g_signal_emit_by_name (G_OBJECT (window), "delete-event", NULL, &retval); - return TRUE; - } - /* Msg download completed */ if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED)) { /* Ask the user if he wants to download the message if @@ -2643,12 +2632,9 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, found = modest_window_mgr_find_registered_header (mgr, header, &msg_win); if (found) { - if (msg_win) /* there is already a window for this uid; top it */ - gtk_window_present (GTK_WINDOW(msg_win)); - else - /* if it's found, but there is no msg_win, it's probably in the process of being created; - * thus, we don't do anything */ - g_warning ("window for is already being created"); + /* if it's found, but there is no msg_win, it's probably in the process of being created; + * thus, we don't do anything */ + g_warning ("window for is already being created"); } else { /* it's not found, so create a new window for it */ modest_window_mgr_register_header (mgr, header, attachment_uid); /* register the uid before building the window */ @@ -2658,7 +2644,7 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, msg_win = modest_msg_view_window_new_for_attachment (TNY_MSG (mime_part), account, attachment_uid); modest_window_set_zoom (MODEST_WINDOW (msg_win), modest_window_get_zoom (MODEST_WINDOW (window))); - modest_window_mgr_register_window (mgr, msg_win); + modest_window_mgr_register_window (mgr, msg_win, MODEST_WINDOW (window)); gtk_widget_show_all (GTK_WIDGET (msg_win)); } } diff --git a/src/hildon2/modest-platform.c b/src/hildon2/modest-platform.c index be10a10..17024a6 100644 --- a/src/hildon2/modest-platform.c +++ b/src/hildon2/modest-platform.c @@ -716,7 +716,7 @@ modest_platform_run_folder_name_dialog (GtkWindow *parent_window, gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), parent_window); gtk_widget_show_all (GTK_WIDGET(dialog)); result = gtk_dialog_run (GTK_DIALOG(dialog)); @@ -830,7 +830,7 @@ modest_platform_run_confirmation_dialog (GtkWindow *parent_window, dialog = hildon_note_new_confirmation (parent_window, message); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), parent_window); response = gtk_dialog_run (GTK_DIALOG (dialog)); @@ -853,7 +853,7 @@ modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window, button_cancel, GTK_RESPONSE_CANCEL, NULL); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), parent_window); response = gtk_dialog_run (GTK_DIALOG (dialog)); @@ -873,7 +873,7 @@ modest_platform_run_yes_no_dialog (GtkWindow *parent_window, _("mcen_bd_yes"), GTK_RESPONSE_YES, _("mcen_bd_no"), GTK_RESPONSE_NO, NULL); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), parent_window); response = gtk_dialog_run (GTK_DIALOG (dialog)); on_destroy_dialog (dialog); @@ -893,7 +893,7 @@ modest_platform_run_information_dialog (GtkWindow *parent_window, note = hildon_note_new_information (parent_window, message); if (block) modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (note)); + GTK_WINDOW (note), parent_window); if (block) { gtk_dialog_run (GTK_DIALOG (note)); @@ -1708,7 +1708,7 @@ modest_platform_run_certificate_confirmation_dialog (const gchar* server_name, (gpointer) certificate); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (note)); + GTK_WINDOW (note), GTK_WINDOW (main_win)); response = gtk_dialog_run(GTK_DIALOG(note)); on_destroy_dialog (note); @@ -1741,7 +1741,7 @@ modest_platform_run_alert_dialog (const gchar* prompt, GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_win), prompt)); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), GTK_WINDOW (main_win)); const int response = gtk_dialog_run (GTK_DIALOG (dialog)); retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK); diff --git a/src/maemo/easysetup/modest-easysetup-wizard-dialog.c b/src/maemo/easysetup/modest-easysetup-wizard-dialog.c index 9e61d43..17b98f8 100644 --- a/src/maemo/easysetup/modest-easysetup-wizard-dialog.c +++ b/src/maemo/easysetup/modest-easysetup-wizard-dialog.c @@ -908,7 +908,8 @@ on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data) modest_connection_specific_smtp_window_fill_with_connections (MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), priv->account_manager); /* Show the window */ - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (specific_window)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), + GTK_WINDOW (specific_window), GTK_WINDOW (self)); gtk_widget_show (specific_window); } @@ -1011,7 +1012,8 @@ show_advanced_edit(gpointer user_data) } modest_account_settings_dialog_load_settings (dialog, priv->settings); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), + GTK_WINDOW (dialog), GTK_WINDOW (self)); response = gtk_dialog_run (GTK_DIALOG (dialog)); diff --git a/src/maemo/modest-account-view-window.c b/src/maemo/modest-account-view-window.c index c72225e..0affe1b 100644 --- a/src/maemo/modest-account-view-window.c +++ b/src/maemo/modest-account-view-window.c @@ -343,6 +343,7 @@ on_edit_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) if (proto && MODEST_IS_ACCOUNT_PROTOCOL (proto)) { ModestAccountSettingsDialog *dialog = modest_account_protocol_get_account_settings_dialog (proto, account_name); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) self); gtk_widget_show (GTK_WIDGET (dialog)); } } @@ -386,7 +387,8 @@ on_new_button_clicked (GtkWidget *button, ModestAccountViewWindow *self) /* there is no such wizard yet */ wizard = GTK_DIALOG (modest_easysetup_wizard_dialog_new ()); modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), - GTK_WINDOW (wizard)); + GTK_WINDOW (wizard), + GTK_WINDOW (self)); /* if there is already another modal dialog, make it non-modal */ if (dialog) diff --git a/src/maemo/modest-address-book.c b/src/maemo/modest-address-book.c index b636c6e..61f9285 100644 --- a/src/maemo/modest-address-book.c +++ b/src/maemo/modest-address-book.c @@ -174,6 +174,7 @@ modest_address_book_select_addresses (ModestRecptEditor *recpt_editor) #if MODEST_ABOOK_API < 4 GtkWidget *contact_view = NULL; GtkWidget *contact_dialog; + GtkWidget *toplevel; #else /* MODEST_ABOOK_API < 4 */ OssoABookContactChooser *contact_chooser = NULL; #endif /* MODEST_ABOOK_API < 4 */ @@ -200,7 +201,8 @@ modest_address_book_select_addresses (ModestRecptEditor *recpt_editor) contact_dialog = osso_abook_select_dialog_new (OSSO_ABOOK_TREE_VIEW (contact_view)); gtk_window_set_title (GTK_WINDOW (contact_dialog), _("mcen_ti_select_recipients")); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (contact_dialog)); + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (recpt_editor)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (contact_dialog), (GtkWindow *) toplevel); gtk_widget_show (contact_dialog); diff --git a/src/maemo/modest-connection-specific-smtp-window.c b/src/maemo/modest-connection-specific-smtp-window.c index 3f98ded..b734983 100644 --- a/src/maemo/modest-connection-specific-smtp-window.c +++ b/src/maemo/modest-connection-specific-smtp-window.c @@ -267,7 +267,9 @@ on_button_edit (ModestConnectionSpecificSmtpWindow *self) server_settings = NULL; } - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (window)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), + GTK_WINDOW (window), + GTK_WINDOW (self)); gint response = gtk_dialog_run (GTK_DIALOG (window)); if (response == GTK_RESPONSE_OK) { diff --git a/src/maemo/modest-default-account-settings-dialog.c b/src/maemo/modest-default-account-settings-dialog.c index bdfb231..0e14a4d 100644 --- a/src/maemo/modest-default-account-settings-dialog.c +++ b/src/maemo/modest-default-account-settings-dialog.c @@ -507,7 +507,8 @@ on_button_signature (GtkButton *button, gpointer user_data) /* Show the window: */ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (priv->signature_dialog)); + GTK_WINDOW (priv->signature_dialog), + GTK_WINDOW (self)); response = gtk_dialog_run (GTK_DIALOG (priv->signature_dialog)); gtk_widget_hide (priv->signature_dialog); @@ -776,7 +777,8 @@ on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data) modest_connection_specific_smtp_window_fill_with_connections (smtp_win, priv->account_manager); /* Show the window: */ - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (smtp_win)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), + GTK_WINDOW (smtp_win), GTK_WINDOW (self)); gtk_widget_show (GTK_WIDGET (smtp_win)); priv->modified = TRUE; } diff --git a/src/maemo/modest-main-window.c b/src/maemo/modest-main-window.c index e252f7f..727682c 100644 --- a/src/maemo/modest-main-window.c +++ b/src/maemo/modest-main-window.c @@ -1721,7 +1721,7 @@ on_inner_widgets_key_pressed (GtkWidget *widget, return FALSE; if (MODEST_IS_HEADER_VIEW (widget)) { - if (event->keyval == GDK_Left) + if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left) gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view)); else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) { guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget)); @@ -1744,7 +1744,8 @@ on_inner_widgets_key_pressed (GtkWidget *widget, } } } - } else if (MODEST_IS_FOLDER_VIEW (widget) && (event->keyval == GDK_Right || event->keyval == GDK_Left)) { + } else if (MODEST_IS_FOLDER_VIEW (widget) && + (event->keyval == GDK_Right || event->keyval == GDK_KP_Right || event->keyval == GDK_Left || event->keyval == GDK_KP_Left)) { #if GTK_CHECK_VERSION(2, 8, 0) /* TODO: gtk_tree_view_get_visible_range() is only available in GTK+ 2.8 */ GtkTreePath *selected_path = NULL; GtkTreePath *start_path = NULL; diff --git a/src/maemo/modest-msg-edit-window.c b/src/maemo/modest-msg-edit-window.c index 511eb0c..65981b0 100644 --- a/src/maemo/modest-msg-edit-window.c +++ b/src/maemo/modest-msg-edit-window.c @@ -2160,7 +2160,8 @@ modest_msg_edit_window_insert_image (ModestMsgEditWindow *window) modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog)); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), + GTK_WINDOW (window)); response = gtk_dialog_run (GTK_DIALOG (dialog)); switch (response) { @@ -2274,7 +2275,7 @@ modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window) dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN); gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title")); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (window)); response = gtk_dialog_run (GTK_DIALOG (dialog)); switch (response) { @@ -2853,7 +2854,7 @@ modest_msg_edit_window_select_font (ModestMsgEditWindow *window) dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL); modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), - GTK_WINDOW(dialog)); + GTK_WINDOW(dialog), GTK_WINDOW (window)); /* First we get the currently selected font information */ wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE); @@ -2890,7 +2891,7 @@ modest_msg_edit_window_select_font (ModestMsgEditWindow *window) NULL); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), GTK_WINDOW (window)); gtk_widget_show_all (dialog); priv->font_dialog = dialog; response = gtk_dialog_run (GTK_DIALOG (dialog)); @@ -3545,7 +3546,7 @@ modest_msg_edit_window_set_draft (ModestMsgEditWindow *window, } priv->msg_uid = modest_tny_folder_get_header_unique_id (header); if (GTK_WIDGET_REALIZED (window)) - modest_window_mgr_register_window (mgr, MODEST_WINDOW (window)); + modest_window_mgr_register_window (mgr, MODEST_WINDOW (window), NULL); } priv->draft_msg = draft; diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index 4f1f139..af1f116 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -2653,7 +2653,7 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, msg_win = modest_msg_view_window_new_for_attachment (TNY_MSG (mime_part), account, attachment_uid); modest_window_set_zoom (MODEST_WINDOW (msg_win), modest_window_get_zoom (MODEST_WINDOW (window))); - modest_window_mgr_register_window (mgr, msg_win); + modest_window_mgr_register_window (mgr, msg_win, MODEST_WINDOW (window)); gtk_widget_show_all (GTK_WIDGET (msg_win)); } } diff --git a/src/maemo/modest-platform.c b/src/maemo/modest-platform.c index b438d0b..6c47d9d 100644 --- a/src/maemo/modest-platform.c +++ b/src/maemo/modest-platform.c @@ -716,7 +716,7 @@ modest_platform_run_folder_name_dialog (GtkWindow *parent_window, gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), GTK_WINDOW (parent_window)); gtk_widget_show_all (GTK_WIDGET(dialog)); result = gtk_dialog_run (GTK_DIALOG(dialog)); @@ -830,7 +830,7 @@ modest_platform_run_confirmation_dialog (GtkWindow *parent_window, dialog = hildon_note_new_confirmation (parent_window, message); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), GTK_WINDOW (parent_window)); response = gtk_dialog_run (GTK_DIALOG (dialog)); @@ -853,7 +853,7 @@ modest_platform_run_confirmation_dialog_with_buttons (GtkWindow *parent_window, button_cancel, GTK_RESPONSE_CANCEL, NULL); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), GTK_WINDOW (parent_window)); response = gtk_dialog_run (GTK_DIALOG (dialog)); @@ -873,7 +873,8 @@ modest_platform_run_yes_no_dialog (GtkWindow *parent_window, _("mcen_bd_yes"), GTK_RESPONSE_YES, _("mcen_bd_no"), GTK_RESPONSE_NO, NULL); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), + GTK_WINDOW (dialog), GTK_WINDOW (parent_window)); response = gtk_dialog_run (GTK_DIALOG (dialog)); on_destroy_dialog (dialog); @@ -893,7 +894,7 @@ modest_platform_run_information_dialog (GtkWindow *parent_window, note = hildon_note_new_information (parent_window, message); if (block) modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (note)); + GTK_WINDOW (note), GTK_WINDOW (parent_window)); if (block) { gtk_dialog_run (GTK_DIALOG (note)); @@ -1722,7 +1723,7 @@ modest_platform_run_certificate_confirmation_dialog (const gchar* server_name, (gpointer) certificate); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (note)); + GTK_WINDOW (note), (GtkWindow *) main_win); response = gtk_dialog_run(GTK_DIALOG(note)); on_destroy_dialog (note); @@ -1755,7 +1756,7 @@ modest_platform_run_alert_dialog (const gchar* prompt, GtkWidget *dialog = GTK_WIDGET (hildon_note_new_confirmation (GTK_WINDOW (main_win), prompt)); modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), (GtkWindow *) main_win); const int response = gtk_dialog_run (GTK_DIALOG (dialog)); retval = (response == GTK_RESPONSE_YES) || (response == GTK_RESPONSE_OK); diff --git a/src/modest-account-protocol.c b/src/modest-account-protocol.c index 066fe09..44b0e53 100644 --- a/src/modest-account-protocol.c +++ b/src/modest-account-protocol.c @@ -447,10 +447,6 @@ modest_account_protocol_get_account_settings_dialog (ModestAccountProtocol *self /* modest_account_settings_dialog_switch_to_user_info (dialog); */ /* modest_account_settings_dialog_check_allow_changes (dialog); */ - /* Set modal */ - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); - /* TODO: review this. When the dialog is closed, reconnect */ /* g_signal_connect (dialog, "response", */ /* G_CALLBACK (on_account_settings_dialog_response), */ diff --git a/src/modest-main.c b/src/modest-main.c index a42c16e..19cebd6 100644 --- a/src/modest-main.c +++ b/src/modest-main.c @@ -191,8 +191,6 @@ main (int argc, char *argv[]) goto cleanup; } - gtk_widget_show_all (GTK_WIDGET(main_win)); - /* Remove new mail notifications if exist */ modest_platform_remove_new_mail_notifications (FALSE); } diff --git a/src/modest-singletons.c b/src/modest-singletons.c index 1883f20..7be780a 100644 --- a/src/modest-singletons.c +++ b/src/modest-singletons.c @@ -31,6 +31,7 @@ #include "modest-runtime.h" #include "modest-defs.h" #include "modest-debug.h" +#include "widgets/modest-hildon1-window-mgr.h" #include /* 'private'/'protected' functions */ @@ -162,7 +163,7 @@ modest_singletons_init (ModestSingletons *obj) return; } - priv->window_mgr = modest_window_mgr_new (); + priv->window_mgr = modest_hildon1_window_mgr_new (); if (!priv->window_mgr) { g_printerr ("modest: cannot create modest window manager instance\n"); return; diff --git a/src/modest-tny-account-store.c b/src/modest-tny-account-store.c index 8d540c3..f1b221e 100644 --- a/src/modest-tny-account-store.c +++ b/src/modest-tny-account-store.c @@ -513,6 +513,7 @@ show_wrong_password_dialog (TnyAccount *account) if (proto && MODEST_IS_ACCOUNT_PROTOCOL (proto)) { ModestAccountSettingsDialog *dialog = modest_account_protocol_get_account_settings_dialog (proto, modest_account_name); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), NULL); gtk_widget_show (GTK_WIDGET (dialog)); } } diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index ef2b24c..945a469 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -199,22 +199,12 @@ gboolean modest_ui_actions_run_account_setup_wizard (ModestWindow *win) { gboolean result = FALSE; - GtkWindow *dialog, *wizard; + GtkWindow *wizard; gint dialog_response; - /* Show the easy-setup wizard: */ - dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr()); - if (dialog) { - /* old wizard is active already; - */ - gtk_window_present (GTK_WINDOW(dialog)); - return FALSE; - } - - /* there is no such wizard yet */ wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ()); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win); /* always present a main window in the background * we do it here, so we cannot end up with two wizards (as this @@ -230,10 +220,12 @@ modest_ui_actions_run_account_setup_wizard (ModestWindow *win) in order to get the widgets properly drawn (MainWindow main paned won't be in its right position and the dialog will be missplaced */ +#ifndef MODEST_TOOLKIT_HILDON2 gtk_widget_show_all (GTK_WIDGET (win)); gtk_widget_show_all (GTK_WIDGET (wizard)); gtk_window_present (GTK_WINDOW (win)); gtk_window_present (GTK_WINDOW (wizard)); +#endif dialog_response = gtk_dialog_run (GTK_DIALOG (wizard)); gtk_widget_destroy (GTK_WIDGET (wizard)); @@ -667,7 +659,7 @@ modest_ui_actions_on_accounts (GtkAction *action, GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ()); /* The accounts dialog must be modal */ - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win); modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win)); } } @@ -689,7 +681,7 @@ modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win) /* Show the window: */ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (specific_window)); + GTK_WINDOW (specific_window), (GtkWindow *) win); gtk_widget_show (specific_window); #endif /* !MODEST_TOOLKIT_GTK */ } @@ -761,7 +753,7 @@ modest_ui_actions_compose_msg(ModestWindow *win, allowed_size = MODEST_MAX_ATTACHMENT_SIZE; msg_win = modest_msg_edit_window_new (msg, account_name, FALSE); - modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win); + modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL); modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified); gtk_widget_show_all (GTK_WIDGET (msg_win)); @@ -982,7 +974,7 @@ open_msg_cb (ModestMailOperation *mail_op, /* Register and show new window */ if (win != NULL) { mgr = modest_runtime_get_window_mgr (); - modest_window_mgr_register_window (mgr, win); + modest_window_mgr_register_window (mgr, win, NULL); gtk_widget_show_all (GTK_WIDGET(win)); } @@ -1346,7 +1338,9 @@ open_msgs_from_headers (TnyList *headers, ModestWindow *win) window to the user */ if (found) { if (window) { +#ifndef MODEST_TOOLKIT_HILDON2 gtk_window_present (GTK_WINDOW (window)); +#endif } else { /* the header has been registered already, we don't do * anything but wait for the window to come up*/ @@ -1578,7 +1572,7 @@ reply_forward_cb (ModestMailOperation *mail_op, /* Create and register the windows */ msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE); mgr = modest_runtime_get_window_mgr (); - modest_window_mgr_register_window (mgr, msg_win); + modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window); if (rf_helper->parent_window != NULL) { gdouble parent_zoom; @@ -3567,7 +3561,7 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store, NULL); #endif /* !MODEST_TOOLKIT_GTK */ - modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL); gchar *server_name = modest_account_mgr_get_server_account_hostname ( modest_runtime_get_account_mgr(), server_account_name); @@ -4207,7 +4201,9 @@ modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle, if (active != fullscreen) { modest_window_mgr_set_fullscreen_mode (mgr, active); +#ifndef MODEST_TOOLKIT_HILDON2 gtk_window_present (GTK_WINDOW (window)); +#endif } } @@ -4224,7 +4220,9 @@ modest_ui_actions_on_change_fullscreen (GtkAction *action, fullscreen = modest_window_mgr_get_fullscreen_mode (mgr); modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen); +#ifndef MODEST_TOOLKIT_HILDON2 gtk_window_present (GTK_WINDOW (window)); +#endif } /* @@ -4242,7 +4240,7 @@ headers_action_show_details (TnyHeader *header, dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header); /* Run dialog */ - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) window); gtk_widget_show_all (dialog); g_signal_connect_swapped (dialog, "response", @@ -5496,7 +5494,7 @@ modest_ui_actions_on_move_to (GtkAction *action, /* Create and run the dialog */ dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view); modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view)); - modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog)); + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win); result = gtk_dialog_run (GTK_DIALOG(dialog)); g_object_ref (tree_view); gtk_widget_destroy (dialog); diff --git a/src/modest-utils.c b/src/modest-utils.c index 67a4b02..fb7089d 100644 --- a/src/modest-utils.c +++ b/src/modest-utils.c @@ -714,7 +714,7 @@ modest_utils_run_sort_dialog (GtkWindow *parent_window, if (dialog == NULL) return; modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), - GTK_WINDOW (dialog)); + GTK_WINDOW (dialog), parent_window); /* Fill sort keys */ switch (type) { diff --git a/src/widgets/Makefile.am b/src/widgets/Makefile.am index 6d85a60..f69e6ed 100644 --- a/src/widgets/Makefile.am +++ b/src/widgets/Makefile.am @@ -55,6 +55,8 @@ libmodest_widgets_la_SOURCES= \ modest-global-settings-dialog.h \ modest-gtkhtml-mime-part-view.c \ modest-gtkhtml-mime-part-view.h \ + modest-hildon1-window-mgr.c \ + modest-hildon1-window-mgr.h \ modest-hbox-cell-renderer.c \ modest-hbox-cell-renderer.h \ modest-vbox-cell-renderer.c \ diff --git a/src/widgets/modest-hildon1-window-mgr.c b/src/widgets/modest-hildon1-window-mgr.c new file mode 100644 index 0000000..c7bcac2 --- /dev/null +++ b/src/widgets/modest-hildon1-window-mgr.c @@ -0,0 +1,1020 @@ +/* Copyright (c) 2008, 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. + */ + +#include +#include "modest-hildon1-window-mgr.h" +#include "modest-msg-edit-window.h" +#include "modest-main-window.h" +#include "modest-conf.h" +#include "modest-defs.h" +#include "modest-signal-mgr.h" +#include "modest-runtime.h" +#include "modest-platform.h" +#include "modest-ui-actions.h" +#include "modest-debug.h" +#include "modest-tny-folder.h" + +/* 'private'/'protected' functions */ +static void modest_hildon1_window_mgr_class_init (ModestHildon1WindowMgrClass *klass); +static void modest_hildon1_window_mgr_instance_init (ModestHildon1WindowMgr *obj); +static void modest_hildon1_window_mgr_finalize (GObject *obj); + +static gboolean on_window_destroy (ModestWindow *window, + GdkEvent *event, + ModestHildon1WindowMgr *self); + +static gboolean on_modal_window_close (GtkWidget *widget, + GdkEvent *event, + gpointer user_data); + +static void on_modal_dialog_destroy (GtkObject *object, + gpointer user_data); + +static void on_modal_dialog_close (GtkDialog *dialog, + gint arg1, + gpointer user_data); + +static const gchar* get_show_toolbar_key (GType window_type, + gboolean fullscreen); + +static gboolean modest_hildon1_window_mgr_register_window (ModestWindowMgr *self, + ModestWindow *window, + ModestWindow *parent); +static void modest_hildon1_window_mgr_unregister_window (ModestWindowMgr *self, + ModestWindow *window); +static void modest_hildon1_window_mgr_set_fullscreen_mode (ModestWindowMgr *self, + gboolean on); +static gboolean modest_hildon1_window_mgr_get_fullscreen_mode (ModestWindowMgr *self); +static void modest_hildon1_window_mgr_show_toolbars (ModestWindowMgr *self, + GType window_type, + gboolean show_toolbars, + gboolean fullscreen); +static ModestWindow* modest_hildon1_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show); +static GtkWindow *modest_hildon1_window_mgr_get_modal (ModestWindowMgr *self); +static void modest_hildon1_window_mgr_set_modal (ModestWindowMgr *self, + GtkWindow *window, + GtkWindow *parent); +static gboolean modest_hildon1_window_mgr_find_registered_header (ModestWindowMgr *self, + TnyHeader *header, + ModestWindow **win); +static GList *modest_hildon1_window_mgr_get_window_list (ModestWindowMgr *self); + +typedef struct _ModestHildon1WindowMgrPrivate ModestHildon1WindowMgrPrivate; +struct _ModestHildon1WindowMgrPrivate { + GList *window_list; + GMutex *queue_lock; + GQueue *modal_windows; + + gboolean fullscreen_mode; + + GHashTable *destroy_handlers; + GHashTable *viewer_handlers; + GSList *window_state_uids; + + guint closing_time; + + GSList *modal_handler_uids; + ModestWindow *current_top; +}; +#define MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ + MODEST_TYPE_HILDON1_WINDOW_MGR, \ + ModestHildon1WindowMgrPrivate)) +/* globals */ +static GObjectClass *parent_class = NULL; + +GType +modest_hildon1_window_mgr_get_type (void) +{ + static GType my_type = 0; + if (!my_type) { + static const GTypeInfo my_info = { + sizeof(ModestHildon1WindowMgrClass), + NULL, /* base init */ + NULL, /* base finalize */ + (GClassInitFunc) modest_hildon1_window_mgr_class_init, + NULL, /* class finalize */ + NULL, /* class data */ + sizeof(ModestHildon1WindowMgr), + 1, /* n_preallocs */ + (GInstanceInitFunc) modest_hildon1_window_mgr_instance_init, + NULL + }; + my_type = g_type_register_static (MODEST_TYPE_WINDOW_MGR, + "ModestHildon1WindowMgr", + &my_info, 0); + } + return my_type; +} + +static void +modest_hildon1_window_mgr_class_init (ModestHildon1WindowMgrClass *klass) +{ + GObjectClass *gobject_class; + ModestWindowMgrClass *mgr_class; + + gobject_class = (GObjectClass*) klass; + mgr_class = (ModestWindowMgrClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + gobject_class->finalize = modest_hildon1_window_mgr_finalize; + mgr_class->register_window = modest_hildon1_window_mgr_register_window; + mgr_class->unregister_window = modest_hildon1_window_mgr_unregister_window; + mgr_class->set_fullscreen_mode = modest_hildon1_window_mgr_set_fullscreen_mode; + mgr_class->get_fullscreen_mode = modest_hildon1_window_mgr_get_fullscreen_mode; + mgr_class->show_toolbars = modest_hildon1_window_mgr_show_toolbars; + mgr_class->get_main_window = modest_hildon1_window_mgr_get_main_window; + mgr_class->get_modal = modest_hildon1_window_mgr_get_modal; + mgr_class->set_modal = modest_hildon1_window_mgr_set_modal; + mgr_class->find_registered_header = modest_hildon1_window_mgr_find_registered_header; + mgr_class->get_window_list = modest_hildon1_window_mgr_get_window_list; + + g_type_class_add_private (gobject_class, sizeof(ModestHildon1WindowMgrPrivate)); + +} + +static void +modest_hildon1_window_mgr_instance_init (ModestHildon1WindowMgr *obj) +{ + ModestHildon1WindowMgrPrivate *priv; + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE(obj); + priv->window_list = NULL; + priv->fullscreen_mode = FALSE; + priv->current_top = NULL; + priv->window_state_uids = NULL; + + priv->modal_windows = g_queue_new (); + priv->queue_lock = g_mutex_new (); + + /* Could not initialize it from gconf, singletons are not + ready yet */ + priv->destroy_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); + priv->viewer_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); + + priv->closing_time = 0; + + priv->modal_handler_uids = NULL; +} + +static void +modest_hildon1_window_mgr_finalize (GObject *obj) +{ + ModestHildon1WindowMgrPrivate *priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE(obj); + + modest_signal_mgr_disconnect_all_and_destroy (priv->window_state_uids); + priv->window_state_uids = NULL; + + if (priv->window_list) { + GList *iter = priv->window_list; + /* unregister pending windows */ + while (iter) { + ModestWindow *window = (ModestWindow *) iter->data; + iter = g_list_next (iter); + modest_window_mgr_unregister_window (MODEST_WINDOW_MGR (obj), window); + } + g_list_free (priv->window_list); + priv->window_list = NULL; + } + + /* Free the hash table with the handlers */ + if (priv->destroy_handlers) { + g_hash_table_destroy (priv->destroy_handlers); + priv->destroy_handlers = NULL; + } + + if (priv->viewer_handlers) { + g_hash_table_destroy (priv->viewer_handlers); + priv->viewer_handlers = NULL; + } + + modest_signal_mgr_disconnect_all_and_destroy (priv->modal_handler_uids); + priv->modal_handler_uids = NULL; + + if (priv->modal_windows) { + g_mutex_lock (priv->queue_lock); + g_queue_free (priv->modal_windows); + priv->modal_windows = NULL; + g_mutex_unlock (priv->queue_lock); + } + g_mutex_free (priv->queue_lock); + + /* Do not unref priv->main_window because it does not hold a + new reference */ + + + G_OBJECT_CLASS(parent_class)->finalize (obj); +} + +ModestWindowMgr* +modest_hildon1_window_mgr_new (void) +{ + return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_HILDON1_WINDOW_MGR, NULL)); +} + +void +modest_hildon1_window_mgr_close_all_windows (ModestWindowMgr *self) +{ + ModestHildon1WindowMgrPrivate *priv = NULL; + gboolean ret_value = FALSE; + ModestWindow *main_window; + + g_return_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self)); + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + /* If there is a main window then try to close it, and it will + close the others if needed */ + main_window = modest_window_mgr_get_main_window (self, FALSE); + if (main_window) { + g_signal_emit_by_name (main_window, "delete-event", NULL, &ret_value); + } else { + GList *wins = NULL, *next = NULL; + + /* delete-event handler actually removes window_list item, */ + wins = priv->window_list; + while (wins) { + next = g_list_next (wins); + g_signal_emit_by_name (G_OBJECT (wins->data), "delete-event", NULL, &ret_value); + wins = next; + } + } +} + +static gint +compare_msguids (ModestWindow *win, + const gchar *uid) +{ + const gchar *msg_uid; + + if ((!MODEST_IS_MSG_EDIT_WINDOW (win)) && (!MODEST_IS_MSG_VIEW_WINDOW (win))) + return 1; + + /* Get message uid from msg window */ + if (MODEST_IS_MSG_EDIT_WINDOW (win)) { + msg_uid = modest_msg_edit_window_get_message_uid (MODEST_MSG_EDIT_WINDOW (win)); + if (msg_uid && uid &&!strcmp (msg_uid, uid)) + return 0; + } else { + msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (win)); + } + + if (msg_uid && uid &&!strcmp (msg_uid, uid)) + return 0; + else + return 1; +} + +static gboolean +modest_hildon1_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header, + ModestWindow **win) +{ + ModestHildon1WindowMgrPrivate *priv = NULL; + gchar* uid = NULL; + gboolean has_header, has_window = FALSE; + GList *item = NULL; + + g_return_val_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self), FALSE); + g_return_val_if_fail (TNY_IS_HEADER(header), FALSE); + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + has_header = MODEST_WINDOW_MGR_CLASS (parent_class)->find_registered_header (self, header, win); + + uid = modest_tny_folder_get_header_unique_id (header); + + item = g_list_find_custom (priv->window_list, uid, (GCompareFunc) compare_msguids); + if (item) { + has_window = TRUE; + if (win) { + if ((!MODEST_IS_MSG_VIEW_WINDOW(item->data)) && + (!MODEST_IS_MSG_EDIT_WINDOW (item->data))) + g_debug ("not a valid window!"); + else { + g_debug ("found a window"); + *win = MODEST_WINDOW (item->data); + } + } + } + g_free (uid); + + return has_header || has_window; +} + +static GList * +modest_hildon1_window_mgr_get_window_list (ModestWindowMgr *self) +{ + ModestHildon1WindowMgrPrivate *priv; + + g_return_val_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self), NULL); + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + return g_list_copy (priv->window_list); +} + +static const gchar * +get_show_toolbar_key (GType window_type, + gboolean fullscreen) +{ + const gchar *key = NULL; + + if (window_type == MODEST_TYPE_MAIN_WINDOW) + key = (fullscreen) ? + MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN : + MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR; + else if (window_type == MODEST_TYPE_MSG_VIEW_WINDOW) + key = (fullscreen) ? + MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR_FULLSCREEN : + MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR; + else if (window_type == MODEST_TYPE_MSG_EDIT_WINDOW) + key = (fullscreen) ? + MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR_FULLSCREEN : + MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR; + else + g_return_val_if_reached (NULL); + + return key; +} + +#ifndef MODEST_TOOLKIT_GTK +static void +on_window_is_topmost (GObject *gobject, + GParamSpec *arg1, + gpointer user_data) +{ + ModestHildon1WindowMgr *self; + ModestHildon1WindowMgrPrivate *priv; + ModestWindow *win = (ModestWindow *) gobject; + + g_return_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (user_data)); + + self = MODEST_HILDON1_WINDOW_MGR (user_data); + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + if (hildon_window_get_is_topmost (HILDON_WINDOW (win))) + priv->current_top = win; +} + +#else +static gboolean +on_window_state_event (GtkWidget *widget, + GdkEventWindowState *event, + gpointer user_data) +{ + ModestHildon1WindowMgr *self; + ModestHildon1WindowMgrPrivate *priv; + + g_return_val_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (user_data), FALSE); + + self = MODEST_HILDON1_WINDOW_MGR (user_data); + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + MODEST_DEBUG_BLOCK ( + if (event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) + g_print ("GDK_WINDOW_STATE_WITHDRAWN\n"); + if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) + g_print ("GDK_WINDOW_STATE_ICONIFIED\n"); + if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) + g_print ("GDK_WINDOW_STATE_MAXIMIZED\n"); + if (event->changed_mask & GDK_WINDOW_STATE_STICKY) + g_print ("GDK_WINDOW_STATE_STICKY\n"); + if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) + g_print ("GDK_WINDOW_STATE_FULLSCREEN\n"); + if (event->changed_mask & GDK_WINDOW_STATE_ABOVE) + g_print ("GDK_WINDOW_STATE_ABOVE\n"); + if (event->changed_mask & GDK_WINDOW_STATE_BELOW) + g_print ("GDK_WINDOW_STATE_BELOW\n"); + ); + if (event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN || + event->changed_mask & GDK_WINDOW_STATE_ABOVE) { + priv->current_top = MODEST_WINDOW (widget); + } + + return FALSE; +} +#endif + +static gboolean +modest_hildon1_window_mgr_register_window (ModestWindowMgr *self, + ModestWindow *window, + ModestWindow *parent) +{ + GList *win; + ModestHildon1WindowMgrPrivate *priv; + gint *handler_id; + const gchar *key; + ModestWindow *main_window; + + g_return_val_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self), FALSE); + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + win = g_list_find (priv->window_list, window); + if (win) { + /* this is for the case we want to register the window and it was already + * registered. We leave silently. + */ + return FALSE; + } + + if (!MODEST_WINDOW_MGR_CLASS (parent_class)->register_window (self, window, parent)) + return FALSE; + + /* Add to list. Keep a reference to the window */ + g_object_ref (window); + priv->window_list = g_list_prepend (priv->window_list, window); + + /* Listen to window state changes. Unfortunately + window-state-event does not properly work for the Maemo + version, so we need to use is-topmost and the ifdef */ +#ifndef MODEST_TOOLKIT_GTK + priv->window_state_uids = + modest_signal_mgr_connect (priv->window_state_uids, + G_OBJECT (window), + "notify::is-topmost", + G_CALLBACK (on_window_is_topmost), + self); +#else + priv->window_state_uids = + modest_signal_mgr_connect (priv->window_state_uids, + G_OBJECT (window), + "window-state-event", + G_CALLBACK (on_window_state_event), + self); +#endif + /* Listen to object destruction */ + handler_id = g_malloc0 (sizeof (gint)); + *handler_id = g_signal_connect (window, "delete-event", G_CALLBACK (on_window_destroy), self); + g_hash_table_insert (priv->destroy_handlers, window, handler_id); + + main_window = modest_window_mgr_get_main_window (self, FALSE); + /* If there is a msg view window, let the main window listen the msg-changed signal */ + if (MODEST_IS_MSG_VIEW_WINDOW(window) && main_window) { + gulong *handler; + handler = g_malloc0 (sizeof (gulong)); + *handler = g_signal_connect (window, "msg-changed", + G_CALLBACK (modest_main_window_on_msg_view_window_msg_changed), + main_window); + g_hash_table_insert (priv->viewer_handlers, window, handler); + } + + /* Put into fullscreen if needed */ + if (priv->fullscreen_mode) + gtk_window_fullscreen (GTK_WINDOW (window)); + + /* Show/hide toolbar & fullscreen */ + key = get_show_toolbar_key (G_TYPE_FROM_INSTANCE (window), priv->fullscreen_mode); + modest_window_show_toolbar (window, modest_conf_get_bool (modest_runtime_get_conf (), key, NULL)); + + return TRUE; +} + +static void +cancel_window_operations (ModestWindow *window) +{ + GSList* pending_ops = NULL; + + /* cancel open and receive operations */ + pending_ops = modest_mail_operation_queue_get_by_source (modest_runtime_get_mail_operation_queue (), + G_OBJECT (window)); + while (pending_ops != NULL) { + ModestMailOperationTypeOperation type; + GSList* tmp_list = NULL; + + type = modest_mail_operation_get_type_operation (MODEST_MAIL_OPERATION (pending_ops->data)); + if (type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || type == MODEST_MAIL_OPERATION_TYPE_OPEN) { + modest_mail_operation_cancel (pending_ops->data); + } + g_object_unref (G_OBJECT (pending_ops->data)); + tmp_list = pending_ops; + pending_ops = g_slist_next (pending_ops); + g_slist_free_1 (tmp_list); + } +} + + + +static gboolean +on_window_destroy (ModestWindow *window, + GdkEvent *event, + ModestHildon1WindowMgr *self) +{ + gint dialog_response = GTK_RESPONSE_NONE; + gboolean no_propagate = FALSE; + + /* Specific stuff first */ + if (MODEST_IS_MAIN_WINDOW (window)) { + ModestHildon1WindowMgrPrivate *priv; + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + /* If more than one window already opened */ + if (g_list_length (priv->window_list) > 1) { + + /* Present the window if it's not visible now */ + if (!gtk_window_has_toplevel_focus (GTK_WINDOW (window))) { + gtk_window_present (GTK_WINDOW (window)); + priv->current_top = window; + } + /* Create the confirmation dialog MSG-NOT308 */ + dialog_response = modest_platform_run_confirmation_dialog ( + GTK_WINDOW (window), _("emev_nc_close_windows")); + + /* If the user wants to close all the windows */ + if ((dialog_response == GTK_RESPONSE_OK) + || (dialog_response == GTK_RESPONSE_ACCEPT) + || (dialog_response == GTK_RESPONSE_YES)) { + GList *iter = priv->window_list; + do { + if (iter->data != window) { + GList *tmp = iter->next; + on_window_destroy (MODEST_WINDOW (iter->data), + event, + self); + iter = tmp; + } else { + iter = g_list_next (iter); + } + } while (iter); + } else { + return TRUE; + } + } + + /* Do not unregister it, just hide */ + gtk_widget_hide_all (GTK_WIDGET (window)); + + /* Cancel pending operations */ + cancel_window_operations (window); + + /* Fake the window system, make it think that there is no window */ + if (modest_window_mgr_num_windows (MODEST_WINDOW_MGR (self)) == 0) + g_signal_emit_by_name (self, "window-list-empty"); + + no_propagate = TRUE; + } + else { + if (MODEST_IS_MSG_EDIT_WINDOW (window)) { + gboolean sent = FALSE; + gint response = GTK_RESPONSE_ACCEPT; + sent = modest_msg_edit_window_get_sent (MODEST_MSG_EDIT_WINDOW (window)); + /* Save currently edited message to Drafts if it was not sent */ + if (!sent && modest_msg_edit_window_is_modified (MODEST_MSG_EDIT_WINDOW (window))) { + + /* Raise the window if it's minimized */ + if (!gtk_window_has_toplevel_focus (GTK_WINDOW (window))) + gtk_window_present (GTK_WINDOW (window)); + + response = + modest_platform_run_confirmation_dialog (GTK_WINDOW (window), + _("mcen_nc_no_email_message_modified_save_changes")); + /* Save to drafts */ + if (response == GTK_RESPONSE_OK) + if (!modest_ui_actions_on_save_to_drafts (NULL, MODEST_MSG_EDIT_WINDOW (window))) + return TRUE; + } + } + /* Unregister window */ + modest_window_mgr_unregister_window (MODEST_WINDOW_MGR (self), window); + no_propagate = TRUE; + } + + return no_propagate; +} + +static void +disconnect_msg_changed (gpointer key, + gpointer value, + gpointer user_data) +{ + guint handler_id; + handler_id = GPOINTER_TO_UINT(value); + + if (key && G_IS_OBJECT(key)) + g_signal_handler_disconnect (G_OBJECT (key), handler_id); +} + +static void +modest_hildon1_window_mgr_unregister_window (ModestWindowMgr *self, + ModestWindow *window) +{ + GList *win; + ModestHildon1WindowMgrPrivate *priv; + gulong *tmp, handler_id; + + g_return_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self)); + g_return_if_fail (MODEST_IS_WINDOW (window)); + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + win = g_list_find (priv->window_list, window); + if (!win) { + g_warning ("Trying to unregister a window that has not being registered yet"); + return; + } + + /* If it's the main window unset it */ + if (MODEST_IS_MAIN_WINDOW (window)) { + modest_window_mgr_set_main_window (self, NULL); + + /* Disconnect all emissions of msg-changed */ + if (priv->viewer_handlers) { + g_hash_table_foreach (priv->viewer_handlers, + disconnect_msg_changed, + NULL); + g_hash_table_destroy (priv->viewer_handlers); + priv->viewer_handlers = NULL; + } + } + + /* Remove the viewer window handler from the hash table. The + HashTable could not exist if the main window was closed + when there were other windows remaining */ + if (MODEST_IS_MSG_VIEW_WINDOW (window) && priv->viewer_handlers) { + tmp = (gulong *) g_hash_table_lookup (priv->viewer_handlers, window); + /* If the viewer was created without a main window + (for example when opening a message through D-Bus + the viewer handlers was not registered */ + if (tmp) { + g_signal_handler_disconnect (window, *tmp); + g_hash_table_remove (priv->viewer_handlers, window); + } + } + + /* Remove from list & hash table */ + priv->window_list = g_list_remove_link (priv->window_list, win); + tmp = g_hash_table_lookup (priv->destroy_handlers, window); + handler_id = *tmp; + + g_hash_table_remove (priv->destroy_handlers, window); + + /* cancel open and receive operations */ + cancel_window_operations (window); + + /* Check if it's the topmost window, and remove the window from the stack. + * This is needed for the cases there's no other topmost window that will + * replace it in topmost handler. + */ + if (window == priv->current_top) + priv->current_top = NULL; + + /* Disconnect the "window-state-event" handler, we won't need it anymore */ + if (priv->window_state_uids) { +#ifndef MODEST_TOOLKIT_GTK + priv->window_state_uids = + modest_signal_mgr_disconnect (priv->window_state_uids, + G_OBJECT (window), + "notify::is-topmost"); +#else + priv->window_state_uids = + modest_signal_mgr_disconnect (priv->window_state_uids, + G_OBJECT (window), + "window-state-event"); +#endif + } + + /* Disconnect the "delete-event" handler, we won't need it anymore */ + g_signal_handler_disconnect (window, handler_id); + + /* Destroy the window */ + g_object_unref (win->data); + g_list_free (win); + + MODEST_WINDOW_MGR_CLASS (parent_class)->unregister_window (self, window); + + /* If there are no more windows registered emit the signal */ + if (modest_window_mgr_num_windows (self) == 0) + g_signal_emit_by_name (self, "window-list-empty"); +} + + + +static void +modest_hildon1_window_mgr_set_fullscreen_mode (ModestWindowMgr *self, + gboolean on) +{ + ModestHildon1WindowMgrPrivate *priv; + GList *win = NULL; + ModestConf *conf; + + g_return_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self)); + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + /* If there is no change do nothing */ + if (priv->fullscreen_mode == on) + return; + + priv->fullscreen_mode = on; + + conf = modest_runtime_get_conf (); + + /* Update windows */ + win = priv->window_list; + while (win) { + gboolean show; + const gchar *key = NULL; + + /* Getting this from gconf everytime is not that + expensive, we'll do it just a few times */ + key = get_show_toolbar_key (G_TYPE_FROM_INSTANCE (win->data), on); + show = modest_conf_get_bool (conf, key, NULL); + + /* Set fullscreen/unfullscreen */ + if (on) + gtk_window_fullscreen (GTK_WINDOW (win->data)); + else + gtk_window_unfullscreen (GTK_WINDOW (win->data)); + + /* Show/Hide toolbar */ + modest_window_show_toolbar (MODEST_WINDOW (win->data), show); + + win = g_list_next (win); + } +} + +static gboolean +modest_hildon1_window_mgr_get_fullscreen_mode (ModestWindowMgr *self) +{ + ModestHildon1WindowMgrPrivate *priv; + + g_return_val_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self), FALSE); + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + return priv->fullscreen_mode; +} + +static void +modest_hildon1_window_mgr_show_toolbars (ModestWindowMgr *self, + GType window_type, + gboolean show_toolbars, + gboolean fullscreen) +{ + ModestHildon1WindowMgrPrivate *priv; + ModestConf *conf; + const gchar *key = NULL; + + g_return_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self)); + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + conf = modest_runtime_get_conf (); + + /* If nothing changes then return */ + key = get_show_toolbar_key (window_type, fullscreen); + conf = modest_runtime_get_conf (); + if (modest_conf_get_bool (conf, key, NULL) == show_toolbars) + return; + + /* Save in conf */ + modest_conf_set_bool (conf, key, show_toolbars, NULL); + + /* Apply now if the view mode is the right one */ + if ((fullscreen && priv->fullscreen_mode) || + (!fullscreen && !priv->fullscreen_mode)) { + + GList *win = priv->window_list; + + while (win) { + if (G_TYPE_FROM_INSTANCE (win->data) == window_type) + modest_window_show_toolbar (MODEST_WINDOW (win->data), + show_toolbars); + win = g_list_next (win); + } + } +} + +static ModestWindow* +modest_hildon1_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show) +{ + ModestHildon1WindowMgrPrivate *priv; + ModestWindow *result; + + g_return_val_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self), NULL); + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + result = MODEST_WINDOW_MGR_CLASS (parent_class)->get_main_window (self, FALSE); + /* create the main window, if it hasn't been created yet */ + if (!result && show) { + /* modest_window_mgr_register_window will set priv->main_window */ + result = modest_main_window_new (); + modest_window_mgr_register_window (self, result, NULL); + gtk_widget_show_all (GTK_WIDGET (result)); + gtk_window_present (GTK_WINDOW (result)); + MODEST_DEBUG_BLOCK( + g_debug ("%s: created main window: %p\n", __FUNCTION__, result); + ); + } + + return result; +} + + +static GtkWindow * +modest_hildon1_window_mgr_get_modal (ModestWindowMgr *self) +{ + ModestHildon1WindowMgrPrivate *priv; + + g_return_val_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self), NULL); + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + return g_queue_peek_head (priv->modal_windows); +} + + +static void +modest_hildon1_window_mgr_set_modal (ModestWindowMgr *self, + GtkWindow *window, + GtkWindow *parent) +{ + GtkWindow *old_modal; + ModestHildon1WindowMgrPrivate *priv; + + g_return_if_fail (MODEST_IS_HILDON1_WINDOW_MGR (self)); + g_return_if_fail (GTK_IS_WINDOW (window)); + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + g_mutex_lock (priv->queue_lock); + old_modal = g_queue_peek_head (priv->modal_windows); + g_mutex_unlock (priv->queue_lock); + + if (!old_modal) { + /* make us transient wrt the main window then */ + if (priv->current_top && ((GtkWindow *) priv->current_top != window)) { + gtk_window_set_transient_for (window, GTK_WINDOW(priv->current_top)); + } else { + ModestWindow *main_win = modest_window_mgr_get_main_window (self, FALSE); + if (GTK_WINDOW(main_win) != window) /* they should not be the same */ + gtk_window_set_transient_for (window, GTK_WINDOW(main_win)); + } + gtk_window_set_modal (window, TRUE); + } else { + /* un-modalize the old one; the one on top should be the + * modal one */ + gtk_window_set_transient_for (window, GTK_WINDOW(old_modal)); + gtk_window_set_modal (window, TRUE); + } + + /* this will be the new modal window */ + g_mutex_lock (priv->queue_lock); + g_queue_push_head (priv->modal_windows, window); + g_mutex_unlock (priv->queue_lock); + + if (GTK_IS_DIALOG (window)) { + /* Note that response is not always enough because it + could be captured and removed easily by dialogs but + works for most of situations */ + priv->modal_handler_uids = + modest_signal_mgr_connect (priv->modal_handler_uids, + G_OBJECT (window), + "response", + G_CALLBACK (on_modal_dialog_close), + self); + /* We need this as well because dialogs are often + destroyed with gtk_widget_destroy and this one will + prevent response from happening */ + priv->modal_handler_uids = + modest_signal_mgr_connect (priv->modal_handler_uids, + G_OBJECT (window), + "destroy", + G_CALLBACK (on_modal_dialog_destroy), + self); + } else { + priv->modal_handler_uids = + modest_signal_mgr_connect (priv->modal_handler_uids, + G_OBJECT (window), + "delete-event", + G_CALLBACK (on_modal_window_close), + self); + } + /* Destroy width parent */ + gtk_window_set_destroy_with_parent (window, TRUE); +} + + + +static gboolean +idle_top_modal (gpointer data) +{ + ModestWindowMgr *self = MODEST_WINDOW_MGR (data); + ModestHildon1WindowMgrPrivate *priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + GtkWindow *topmost; + + /* Get the top modal */ + g_mutex_lock (priv->queue_lock); + topmost = (GtkWindow *) g_queue_peek_head (priv->modal_windows); + g_mutex_unlock (priv->queue_lock); + + /* Show it */ + if (topmost) { + gdk_threads_enter (); + gtk_window_present (topmost); + /* It seems that the window looses modality if some + other is shown on top of it after set_transient_for + and set_parent */ + gtk_window_set_modal (topmost, TRUE); + gdk_threads_leave (); + } + + return FALSE; +} + +static void +remove_modal_from_queue (GtkWidget *widget, + ModestWindowMgr *self) +{ + ModestHildon1WindowMgrPrivate *priv; + GList *item = NULL; + + priv = MODEST_HILDON1_WINDOW_MGR_GET_PRIVATE (self); + + /* Remove from queue. We don't use remove, because we want to + exit if the widget does not belong to the queue */ + g_mutex_lock (priv->queue_lock); + item = g_queue_find (priv->modal_windows, widget); + if (!item) { + g_warning ("Trying to remove a modal window that is not registered"); + g_mutex_unlock (priv->queue_lock); + return; + } + g_queue_unlink (priv->modal_windows, item); + g_mutex_unlock (priv->queue_lock); + + /* Disconnect handler */ + priv->modal_handler_uids = + modest_signal_mgr_disconnect (priv->modal_handler_uids, + G_OBJECT (widget), + GTK_IS_DIALOG (widget) ? + "response" : + "delete-event"); + if (GTK_IS_DIALOG (widget)) + priv->modal_handler_uids = + modest_signal_mgr_disconnect (priv->modal_handler_uids, + G_OBJECT (widget), + "destroy"); + + /* Schedule the next one for being shown */ + g_idle_add (idle_top_modal, self); +} + +static gboolean +on_modal_window_close (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); + + /* Remove modal window from queue */ + remove_modal_from_queue (widget, self); + + /* Continue */ + return FALSE; +} + +static void +on_modal_dialog_close (GtkDialog *dialog, + gint arg1, + gpointer user_data) +{ + ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); + + /* Remove modal window from queue. Note that if "destroy" + signal was invoked before the response the window could be + already deleted */ + remove_modal_from_queue (GTK_WIDGET (dialog), self); +} + +static void +on_modal_dialog_destroy (GtkObject *object, + gpointer user_data) +{ + ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); + + /* Remove modal window from queue */ + remove_modal_from_queue (GTK_WIDGET (object), self); +} + diff --git a/src/widgets/modest-hildon1-window-mgr.h b/src/widgets/modest-hildon1-window-mgr.h new file mode 100644 index 0000000..b7dcbdd --- /dev/null +++ b/src/widgets/modest-hildon1-window-mgr.h @@ -0,0 +1,69 @@ +/* Copyright (c) 2008, 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_HILDON1_WINDOW_MGR_H__ +#define __MODEST_HILDON1_WINDOW_MGR_H__ + +#include +#include "widgets/modest-window-mgr.h" +#include "widgets/modest-msg-view-window.h" + +G_BEGIN_DECLS + +/* convenience macros */ +#define MODEST_TYPE_HILDON1_WINDOW_MGR (modest_hildon1_window_mgr_get_type()) +#define MODEST_HILDON1_WINDOW_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_HILDON1_WINDOW_MGR,ModestHildon1WindowMgr)) +#define MODEST_HILDON1_WINDOW_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_HILDON1_WINDOW_MGR,ModestHildon1WindowMgrClass)) +#define MODEST_IS_HILDON1_WINDOW_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_HILDON1_WINDOW_MGR)) +#define MODEST_IS_HILDON1_WINDOW_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_HILDON1_WINDOW_MGR)) +#define MODEST_HILDON1_WINDOW_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_HILDON1_WINDOW_MGR,ModestHildon1WindowMgrClass)) + +typedef struct _ModestHildon1WindowMgr ModestHildon1WindowMgr; +typedef struct _ModestHildon1WindowMgrClass ModestHildon1WindowMgrClass; + +struct _ModestHildon1WindowMgr { + ModestWindowMgr parent; +}; + +struct _ModestHildon1WindowMgrClass { + ModestWindowMgrClass parent_class; + +}; + + +/* member functions */ +GType modest_hildon1_window_mgr_get_type (void) G_GNUC_CONST; + +/* typical parameter-less _new function */ +ModestWindowMgr* modest_hildon1_window_mgr_new (void); + +G_END_DECLS + +#endif /* __MODEST_HILDON1_WINDOW_MGR_H__ */ + diff --git a/src/widgets/modest-window-mgr.c b/src/widgets/modest-window-mgr.c index fb88abf..da7aa86 100644 --- a/src/widgets/modest-window-mgr.c +++ b/src/widgets/modest-window-mgr.c @@ -44,23 +44,28 @@ static void modest_window_mgr_class_init (ModestWindowMgrClass *klass); static void modest_window_mgr_init (ModestWindowMgr *obj); static void modest_window_mgr_finalize (GObject *obj); -static gboolean on_window_destroy (ModestWindow *window, - GdkEvent *event, - ModestWindowMgr *self); - -static gboolean on_modal_window_close (GtkWidget *widget, - GdkEvent *event, - gpointer user_data); - -static void on_modal_dialog_destroy (GtkObject *object, - gpointer user_data); - -static void on_modal_dialog_close (GtkDialog *dialog, - gint arg1, - gpointer user_data); - -static const gchar* get_show_toolbar_key (GType window_type, - gboolean fullscreen); +static gboolean modest_window_mgr_register_window_default (ModestWindowMgr *self, + ModestWindow *window, + ModestWindow *parent); +static void modest_window_mgr_unregister_window_default (ModestWindowMgr *self, + ModestWindow *window); +static void modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self, + gboolean on); +static gboolean modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self); +static void modest_window_mgr_show_toolbars_default (ModestWindowMgr *self, + GType window_type, + gboolean show_toolbars, + gboolean fullscreen); +static ModestWindow* modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show); +static GtkWindow *modest_window_mgr_get_modal_default (ModestWindowMgr *self); +static void modest_window_mgr_set_modal_default (ModestWindowMgr *self, + GtkWindow *window, + GtkWindow *parent); +static void modest_window_mgr_close_all_windows_default (ModestWindowMgr *self); +static gboolean modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, + TnyHeader *header, + ModestWindow **win); +static GList *modest_window_mgr_get_window_list_default (ModestWindowMgr *self); /* list my signals */ enum { @@ -70,32 +75,21 @@ enum { typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate; struct _ModestWindowMgrPrivate { - GList *window_list; guint banner_counter; ModestWindow *main_window; - GMutex *queue_lock; - GQueue *modal_windows; - - gboolean fullscreen_mode; - GSList *windows_that_prevent_hibernation; GSList *preregistered_uids; - GHashTable *destroy_handlers; - GHashTable *viewer_handlers; - GSList *window_state_uids; guint closing_time; - GSList *modal_handler_uids; GtkWidget *cached_view; GtkWidget *cached_editor; guint idle_load_view_id; guint idle_load_editor_id; - - ModestWindow *current_top; }; + #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ MODEST_TYPE_WINDOW_MGR, \ ModestWindowMgrPrivate)) @@ -133,10 +127,24 @@ static void modest_window_mgr_class_init (ModestWindowMgrClass *klass) { GObjectClass *gobject_class; + ModestWindowMgrClass *mgr_class; + gobject_class = (GObjectClass*) klass; + mgr_class = (ModestWindowMgrClass *) klass; parent_class = g_type_class_peek_parent (klass); gobject_class->finalize = modest_window_mgr_finalize; + mgr_class->register_window = modest_window_mgr_register_window_default; + mgr_class->unregister_window = modest_window_mgr_unregister_window_default; + mgr_class->set_fullscreen_mode = modest_window_mgr_set_fullscreen_mode_default; + mgr_class->get_fullscreen_mode = modest_window_mgr_get_fullscreen_mode_default; + mgr_class->show_toolbars = modest_window_mgr_show_toolbars_default; + mgr_class->get_main_window = modest_window_mgr_get_main_window_default; + mgr_class->get_modal = modest_window_mgr_get_modal_default; + mgr_class->set_modal = modest_window_mgr_set_modal_default; + mgr_class->close_all_windows = modest_window_mgr_close_all_windows_default; + mgr_class->find_registered_header = modest_window_mgr_find_registered_header_default; + mgr_class->get_window_list = modest_window_mgr_get_window_list_default; g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate)); @@ -200,26 +208,13 @@ modest_window_mgr_init (ModestWindowMgr *obj) ModestWindowMgrPrivate *priv; priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj); - priv->window_list = NULL; priv->banner_counter = 0; priv->main_window = NULL; - priv->fullscreen_mode = FALSE; - priv->current_top = NULL; - priv->window_state_uids = NULL; - priv->modal_windows = g_queue_new (); - priv->queue_lock = g_mutex_new (); - priv->preregistered_uids = NULL; - /* Could not initialize it from gconf, singletons are not - ready yet */ - priv->destroy_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); - priv->viewer_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); - priv->closing_time = 0; - priv->modal_handler_uids = NULL; priv->cached_view = NULL; priv->cached_editor = NULL; } @@ -248,51 +243,9 @@ modest_window_mgr_finalize (GObject *obj) priv->cached_editor = NULL; } - modest_signal_mgr_disconnect_all_and_destroy (priv->window_state_uids); - priv->window_state_uids = NULL; - - if (priv->window_list) { - GList *iter = priv->window_list; - /* unregister pending windows */ - while (iter) { - ModestWindow *window = (ModestWindow *) iter->data; - iter = g_list_next (iter); - modest_window_mgr_unregister_window (MODEST_WINDOW_MGR (obj), window); - } - g_list_free (priv->window_list); - priv->window_list = NULL; - } - g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL); g_slist_free (priv->preregistered_uids); - - /* Free the hash table with the handlers */ - if (priv->destroy_handlers) { - g_hash_table_destroy (priv->destroy_handlers); - priv->destroy_handlers = NULL; - } - - if (priv->viewer_handlers) { - g_hash_table_destroy (priv->viewer_handlers); - priv->viewer_handlers = NULL; - } - - modest_signal_mgr_disconnect_all_and_destroy (priv->modal_handler_uids); - priv->modal_handler_uids = NULL; - - if (priv->modal_windows) { - g_mutex_lock (priv->queue_lock); - g_queue_free (priv->modal_windows); - priv->modal_windows = NULL; - g_mutex_unlock (priv->queue_lock); - } - g_mutex_free (priv->queue_lock); - - /* Do not unref priv->main_window because it does not hold a - new reference */ - - G_OBJECT_CLASS(parent_class)->finalize (obj); } @@ -432,65 +385,33 @@ modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win) return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM); } -static gint -compare_msguids (ModestWindow *win, - const gchar *uid) +void +modest_window_mgr_close_all_windows (ModestWindowMgr *self) { - const gchar *msg_uid; - - if ((!MODEST_IS_MSG_EDIT_WINDOW (win)) && (!MODEST_IS_MSG_VIEW_WINDOW (win))) - return 1; - - /* Get message uid from msg window */ - if (MODEST_IS_MSG_EDIT_WINDOW (win)) { - msg_uid = modest_msg_edit_window_get_message_uid (MODEST_MSG_EDIT_WINDOW (win)); - if (msg_uid && uid &&!strcmp (msg_uid, uid)) - return 0; - } else { - msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (win)); - } - - if (msg_uid && uid &&!strcmp (msg_uid, uid)) - return 0; - else - return 1; + MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self); } -void -modest_window_mgr_close_all_windows (ModestWindowMgr *self) +static void +modest_window_mgr_close_all_windows_default (ModestWindowMgr *self) { - ModestWindowMgrPrivate *priv = NULL; - gboolean ret_value = FALSE; - - g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - - /* If there is a main window then try to close it, and it will - close the others if needed */ - if (priv->main_window) { - g_signal_emit_by_name (priv->main_window, "delete-event", NULL, &ret_value); - } else { - GList *wins = NULL, *next = NULL; - - /* delete-event handler actually removes window_list item, */ - wins = priv->window_list; - while (wins) { - next = g_list_next (wins); - g_signal_emit_by_name (G_OBJECT (wins->data), "delete-event", NULL, &ret_value); - wins = next; - } - } + return ; } gboolean modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header, - ModestWindow **win) + ModestWindow **win) +{ + return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win); +} + +static gboolean +modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header, + ModestWindow **win) { ModestWindowMgrPrivate *priv = NULL; gchar* uid = NULL; - gboolean has_header, has_window = FALSE; - GList *item = NULL; + gboolean has_header = FALSE; g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE); g_return_val_if_fail (TNY_IS_HEADER(header), FALSE); @@ -503,135 +424,48 @@ modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *head *win = NULL; has_header = has_uid (priv->preregistered_uids, uid); - - item = g_list_find_custom (priv->window_list, uid, (GCompareFunc) compare_msguids); - if (item) { - has_window = TRUE; - if (win) { - if ((!MODEST_IS_MSG_VIEW_WINDOW(item->data)) && - (!MODEST_IS_MSG_EDIT_WINDOW (item->data))) - g_debug ("not a valid window!"); - else { - g_debug ("found a window"); - *win = MODEST_WINDOW (item->data); - } - } - } - g_free (uid); - - return has_header || has_window; + + return has_header; } -static const gchar * -get_show_toolbar_key (GType window_type, - gboolean fullscreen) +GList * +modest_window_mgr_get_window_list (ModestWindowMgr *self) { - const gchar *key = NULL; - - if (window_type == MODEST_TYPE_MAIN_WINDOW) - key = (fullscreen) ? - MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN : - MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR; - else if (window_type == MODEST_TYPE_MSG_VIEW_WINDOW) - key = (fullscreen) ? - MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR_FULLSCREEN : - MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR; - else if (window_type == MODEST_TYPE_MSG_EDIT_WINDOW) - key = (fullscreen) ? - MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR_FULLSCREEN : - MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR; - else - g_return_val_if_reached (NULL); - - return key; + return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self); } -#ifndef MODEST_TOOLKIT_GTK -static void -on_window_is_topmost (GObject *gobject, - GParamSpec *arg1, - gpointer user_data) +static GList * +modest_window_mgr_get_window_list_default (ModestWindowMgr *self) { - ModestWindowMgr *self; - ModestWindowMgrPrivate *priv; - ModestWindow *win = (ModestWindow *) gobject; - - g_return_if_fail (MODEST_IS_WINDOW_MGR (user_data)); - - self = MODEST_WINDOW_MGR (user_data); - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - - if (hildon_window_get_is_topmost (HILDON_WINDOW (win))) - priv->current_top = win; + return NULL; } -#else -static gboolean -on_window_state_event (GtkWidget *widget, - GdkEventWindowState *event, - gpointer user_data) +gboolean +modest_window_mgr_register_window (ModestWindowMgr *self, + ModestWindow *window, + ModestWindow *parent) { - ModestWindowMgr *self; - ModestWindowMgrPrivate *priv; - - g_return_val_if_fail (MODEST_IS_WINDOW_MGR (user_data), FALSE); - - self = MODEST_WINDOW_MGR (user_data); - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - - MODEST_DEBUG_BLOCK ( - if (event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) - g_print ("GDK_WINDOW_STATE_WITHDRAWN\n"); - if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) - g_print ("GDK_WINDOW_STATE_ICONIFIED\n"); - if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) - g_print ("GDK_WINDOW_STATE_MAXIMIZED\n"); - if (event->changed_mask & GDK_WINDOW_STATE_STICKY) - g_print ("GDK_WINDOW_STATE_STICKY\n"); - if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) - g_print ("GDK_WINDOW_STATE_FULLSCREEN\n"); - if (event->changed_mask & GDK_WINDOW_STATE_ABOVE) - g_print ("GDK_WINDOW_STATE_ABOVE\n"); - if (event->changed_mask & GDK_WINDOW_STATE_BELOW) - g_print ("GDK_WINDOW_STATE_BELOW\n"); - ); - if (event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN || - event->changed_mask & GDK_WINDOW_STATE_ABOVE) { - priv->current_top = MODEST_WINDOW (widget); - } - - return FALSE; + return MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent); } -#endif -void -modest_window_mgr_register_window (ModestWindowMgr *self, - ModestWindow *window) +static gboolean +modest_window_mgr_register_window_default (ModestWindowMgr *self, + ModestWindow *window, + ModestWindow *parent) { - GList *win; ModestWindowMgrPrivate *priv; - gint *handler_id; - const gchar *key; - g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); - g_return_if_fail (GTK_IS_WINDOW (window)); + g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE); + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - win = g_list_find (priv->window_list, window); - if (win) { - /* this is for the case we want to register the window and it was already - * registered. We leave silently. - */ - return; - } - /* Check that it's not a second main window */ if (MODEST_IS_MAIN_WINDOW (window)) { if (priv->main_window) { g_warning ("%s: trying to register a second main window", __FUNCTION__); - return; + return FALSE; } else { priv->main_window = window; load_new_view (self); @@ -664,273 +498,36 @@ modest_window_mgr_register_window (ModestWindowMgr *self, modest_msg_edit_window_get_message_uid (MODEST_MSG_EDIT_WINDOW (window))); } - - /* Add to list. Keep a reference to the window */ - g_object_ref (window); - priv->window_list = g_list_prepend (priv->window_list, window); - - /* Listen to window state changes. Unfortunately - window-state-event does not properly work for the Maemo - version, so we need to use is-topmost and the ifdef */ -#ifndef MODEST_TOOLKIT_GTK - priv->window_state_uids = - modest_signal_mgr_connect (priv->window_state_uids, - G_OBJECT (window), - "notify::is-topmost", - G_CALLBACK (on_window_is_topmost), - self); -#else - priv->window_state_uids = - modest_signal_mgr_connect (priv->window_state_uids, - G_OBJECT (window), - "window-state-event", - G_CALLBACK (on_window_state_event), - self); -#endif - /* Listen to object destruction */ - handler_id = g_malloc0 (sizeof (gint)); - *handler_id = g_signal_connect (window, "delete-event", G_CALLBACK (on_window_destroy), self); - g_hash_table_insert (priv->destroy_handlers, window, handler_id); - - /* If there is a msg view window, let the main window listen the msg-changed signal */ - if (MODEST_IS_MSG_VIEW_WINDOW(window) && priv->main_window) { - gulong *handler; - handler = g_malloc0 (sizeof (gulong)); - *handler = g_signal_connect (window, "msg-changed", - G_CALLBACK (modest_main_window_on_msg_view_window_msg_changed), - priv->main_window); - g_hash_table_insert (priv->viewer_handlers, window, handler); - } - - /* Put into fullscreen if needed */ - if (priv->fullscreen_mode) - gtk_window_fullscreen (GTK_WINDOW (window)); - - /* Show/hide toolbar & fullscreen */ - key = get_show_toolbar_key (G_TYPE_FROM_INSTANCE (window), priv->fullscreen_mode); - modest_window_show_toolbar (window, modest_conf_get_bool (modest_runtime_get_conf (), key, NULL)); -} - -static void -cancel_window_operations (ModestWindow *window) -{ - GSList* pending_ops = NULL; - - /* cancel open and receive operations */ - pending_ops = modest_mail_operation_queue_get_by_source (modest_runtime_get_mail_operation_queue (), - G_OBJECT (window)); - while (pending_ops != NULL) { - ModestMailOperationTypeOperation type; - GSList* tmp_list = NULL; - - type = modest_mail_operation_get_type_operation (MODEST_MAIL_OPERATION (pending_ops->data)); - if (type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || type == MODEST_MAIL_OPERATION_TYPE_OPEN) { - modest_mail_operation_cancel (pending_ops->data); - } - g_object_unref (G_OBJECT (pending_ops->data)); - tmp_list = pending_ops; - pending_ops = g_slist_next (pending_ops); - g_slist_free_1 (tmp_list); - } -} - - - -static gboolean -on_window_destroy (ModestWindow *window, - GdkEvent *event, - ModestWindowMgr *self) -{ - gint dialog_response = GTK_RESPONSE_NONE; - gboolean no_propagate = FALSE; - - /* Specific stuff first */ - if (MODEST_IS_MAIN_WINDOW (window)) { - ModestWindowMgrPrivate *priv; - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - - /* If more than one window already opened */ - if (g_list_length (priv->window_list) > 1) { - - /* Present the window if it's not visible now */ - if (!gtk_window_has_toplevel_focus (GTK_WINDOW (window))) { - gtk_window_present (GTK_WINDOW (window)); - priv->current_top = window; - } - /* Create the confirmation dialog MSG-NOT308 */ - dialog_response = modest_platform_run_confirmation_dialog ( - GTK_WINDOW (window), _("emev_nc_close_windows")); - - /* If the user wants to close all the windows */ - if ((dialog_response == GTK_RESPONSE_OK) - || (dialog_response == GTK_RESPONSE_ACCEPT) - || (dialog_response == GTK_RESPONSE_YES)) { - GList *iter = priv->window_list; - do { - if (iter->data != window) { - GList *tmp = iter->next; - on_window_destroy (MODEST_WINDOW (iter->data), - event, - self); - iter = tmp; - } else { - iter = g_list_next (iter); - } - } while (iter); - } else { - return TRUE; - } - } - - /* Do not unregister it, just hide */ - gtk_widget_hide_all (GTK_WIDGET (window)); - - /* Cancel pending operations */ - cancel_window_operations (window); - - /* Fake the window system, make it think that there is no window */ - if (modest_window_mgr_num_windows (self) == 0) - g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0); - - no_propagate = TRUE; - } - else { - if (MODEST_IS_MSG_EDIT_WINDOW (window)) { - gboolean sent = FALSE; - gint response = GTK_RESPONSE_ACCEPT; - sent = modest_msg_edit_window_get_sent (MODEST_MSG_EDIT_WINDOW (window)); - /* Save currently edited message to Drafts if it was not sent */ - if (!sent && modest_msg_edit_window_is_modified (MODEST_MSG_EDIT_WINDOW (window))) { - - /* Raise the window if it's minimized */ - if (!gtk_window_has_toplevel_focus (GTK_WINDOW (window))) - gtk_window_present (GTK_WINDOW (window)); - - response = - modest_platform_run_confirmation_dialog (GTK_WINDOW (window), - _("mcen_nc_no_email_message_modified_save_changes")); - /* Save to drafts */ - if (response == GTK_RESPONSE_OK) - if (!modest_ui_actions_on_save_to_drafts (NULL, MODEST_MSG_EDIT_WINDOW (window))) - return TRUE; - } - } - /* Unregister window */ - modest_window_mgr_unregister_window (self, window); - no_propagate = TRUE; - } - - return no_propagate; -} -static void -disconnect_msg_changed (gpointer key, - gpointer value, - gpointer user_data) -{ - guint handler_id; - handler_id = GPOINTER_TO_UINT(value); - - if (key && G_IS_OBJECT(key)) - g_signal_handler_disconnect (G_OBJECT (key), handler_id); + return TRUE; } void modest_window_mgr_unregister_window (ModestWindowMgr *self, ModestWindow *window) { - GList *win; + MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window); +} + +static void +modest_window_mgr_unregister_window_default (ModestWindowMgr *self, + ModestWindow *window) +{ ModestWindowMgrPrivate *priv; - gulong *tmp, handler_id; g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); g_return_if_fail (MODEST_IS_WINDOW (window)); priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - win = g_list_find (priv->window_list, window); - if (!win) { - g_warning ("Trying to unregister a window that has not being registered yet"); - return; - } - - /* If it's the main window unset it */ - if (priv->main_window == window) { - priv->main_window = NULL; - - /* Disconnect all emissions of msg-changed */ - if (priv->viewer_handlers) { - g_hash_table_foreach (priv->viewer_handlers, - disconnect_msg_changed, - NULL); - g_hash_table_destroy (priv->viewer_handlers); - priv->viewer_handlers = NULL; - } - } - - /* Remove the viewer window handler from the hash table. The - HashTable could not exist if the main window was closed - when there were other windows remaining */ - if (MODEST_IS_MSG_VIEW_WINDOW (window) && priv->viewer_handlers) { - tmp = (gulong *) g_hash_table_lookup (priv->viewer_handlers, window); - /* If the viewer was created without a main window - (for example when opening a message through D-Bus - the viewer handlers was not registered */ - if (tmp) { - g_signal_handler_disconnect (window, *tmp); - g_hash_table_remove (priv->viewer_handlers, window); - } - } - /* Save state */ modest_window_save_state (window); - /* Remove from list & hash table */ - priv->window_list = g_list_remove_link (priv->window_list, win); - tmp = g_hash_table_lookup (priv->destroy_handlers, window); - handler_id = *tmp; - - g_hash_table_remove (priv->destroy_handlers, window); - - /* cancel open and receive operations */ - cancel_window_operations (window); - - /* Check if it's the topmost window, and remove the window from the stack. - * This is needed for the cases there's no other topmost window that will - * replace it in topmost handler. - */ - if (window == priv->current_top) - priv->current_top = NULL; - - /* Disconnect the "window-state-event" handler, we won't need it anymore */ - if (priv->window_state_uids) { -#ifndef MODEST_TOOLKIT_GTK - priv->window_state_uids = - modest_signal_mgr_disconnect (priv->window_state_uids, - G_OBJECT (window), - "notify::is-topmost"); -#else - priv->window_state_uids = - modest_signal_mgr_disconnect (priv->window_state_uids, - G_OBJECT (window), - "window-state-event"); -#endif - } - - /* Disconnect the "delete-event" handler, we won't need it anymore */ - g_signal_handler_disconnect (window, handler_id); - /* Disconnect all the window signals */ modest_window_disconnect_signals (window); /* Destroy the window */ - g_object_unref (win->data); - gtk_widget_destroy (win->data); - g_list_free (win); - - /* If there are no more windows registered emit the signal */ - if (modest_window_mgr_num_windows (self) == 0) - g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0); + gtk_widget_destroy (GTK_WIDGET (window)); } @@ -939,56 +536,26 @@ void modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self, gboolean on) { - ModestWindowMgrPrivate *priv; - GList *win = NULL; - ModestConf *conf; - - g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); - - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - - /* If there is no change do nothing */ - if (priv->fullscreen_mode == on) - return; - - priv->fullscreen_mode = on; - - conf = modest_runtime_get_conf (); - - /* Update windows */ - win = priv->window_list; - while (win) { - gboolean show; - const gchar *key = NULL; - - /* Getting this from gconf everytime is not that - expensive, we'll do it just a few times */ - key = get_show_toolbar_key (G_TYPE_FROM_INSTANCE (win->data), on); - show = modest_conf_get_bool (conf, key, NULL); - - /* Set fullscreen/unfullscreen */ - if (on) - gtk_window_fullscreen (GTK_WINDOW (win->data)); - else - gtk_window_unfullscreen (GTK_WINDOW (win->data)); - - /* Show/Hide toolbar */ - modest_window_show_toolbar (MODEST_WINDOW (win->data), show); + MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on); +} - win = g_list_next (win); - } +static void +modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self, + gboolean on) +{ + return; } gboolean modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self) { - ModestWindowMgrPrivate *priv; - - g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE); - - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self); +} - return priv->fullscreen_mode; +static gboolean +modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self) +{ + return FALSE; } void @@ -997,57 +564,49 @@ modest_window_mgr_show_toolbars (ModestWindowMgr *self, gboolean show_toolbars, gboolean fullscreen) { - ModestWindowMgrPrivate *priv; - ModestConf *conf; - const gchar *key = NULL; + return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen); +} +static void +modest_window_mgr_show_toolbars_default (ModestWindowMgr *self, + GType window_type, + gboolean show_toolbars, + gboolean fullscreen) +{ + return; +} + +void +modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win) +{ + ModestWindowMgrPrivate *priv; + g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - conf = modest_runtime_get_conf (); - - /* If nothing changes then return */ - key = get_show_toolbar_key (window_type, fullscreen); - conf = modest_runtime_get_conf (); - if (modest_conf_get_bool (conf, key, NULL) == show_toolbars) - return; - - /* Save in conf */ - modest_conf_set_bool (conf, key, show_toolbars, NULL); - - /* Apply now if the view mode is the right one */ - if ((fullscreen && priv->fullscreen_mode) || - (!fullscreen && !priv->fullscreen_mode)) { - - GList *win = priv->window_list; - - while (win) { - if (G_TYPE_FROM_INSTANCE (win->data) == window_type) - modest_window_show_toolbar (MODEST_WINDOW (win->data), - show_toolbars); - win = g_list_next (win); - } - } + priv->main_window = win; } ModestWindow* -modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean create) +modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show) +{ + return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show); +} + +static ModestWindow* +modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show) { ModestWindowMgrPrivate *priv; g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL); + priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - - /* create the main window, if it hasn't been created yet */ - if (!priv->main_window && create) { - /* modest_window_mgr_register_window will set priv->main_window */ - modest_window_mgr_register_window (self, modest_main_window_new ()); - MODEST_DEBUG_BLOCK( - g_debug ("%s: created main window: %p\n", __FUNCTION__, priv->main_window); - ); - } - - return priv->main_window; + if (priv->main_window) + return priv->main_window; + + if (show) + return modest_main_window_new (); + else return NULL; } @@ -1066,81 +625,30 @@ modest_window_mgr_main_window_exists (ModestWindowMgr *self) GtkWindow * modest_window_mgr_get_modal (ModestWindowMgr *self) { - ModestWindowMgrPrivate *priv; - - g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL); - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self); +} - return g_queue_peek_head (priv->modal_windows); +static GtkWindow * +modest_window_mgr_get_modal_default (ModestWindowMgr *self) +{ + return NULL; } void modest_window_mgr_set_modal (ModestWindowMgr *self, - GtkWindow *window) + GtkWindow *window, + GtkWindow *parent) { - GtkWindow *old_modal; - ModestWindowMgrPrivate *priv; - - g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); - g_return_if_fail (GTK_IS_WINDOW (window)); - - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - g_mutex_lock (priv->queue_lock); - old_modal = g_queue_peek_head (priv->modal_windows); - g_mutex_unlock (priv->queue_lock); - - if (!old_modal) { - /* make us transient wrt the main window then */ - if (priv->current_top && ((GtkWindow *) priv->current_top != window)) { - gtk_window_set_transient_for (window, GTK_WINDOW(priv->current_top)); - } else { - ModestWindow *main_win = modest_window_mgr_get_main_window (self, FALSE); - if (GTK_WINDOW(main_win) != window) /* they should not be the same */ - gtk_window_set_transient_for (window, GTK_WINDOW(main_win)); - } - gtk_window_set_modal (window, TRUE); - } else { - /* un-modalize the old one; the one on top should be the - * modal one */ - gtk_window_set_transient_for (window, GTK_WINDOW(old_modal)); - gtk_window_set_modal (window, TRUE); - } + MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent); +} - /* this will be the new modal window */ - g_mutex_lock (priv->queue_lock); - g_queue_push_head (priv->modal_windows, window); - g_mutex_unlock (priv->queue_lock); - - if (GTK_IS_DIALOG (window)) { - /* Note that response is not always enough because it - could be captured and removed easily by dialogs but - works for most of situations */ - priv->modal_handler_uids = - modest_signal_mgr_connect (priv->modal_handler_uids, - G_OBJECT (window), - "response", - G_CALLBACK (on_modal_dialog_close), - self); - /* We need this as well because dialogs are often - destroyed with gtk_widget_destroy and this one will - prevent response from happening */ - priv->modal_handler_uids = - modest_signal_mgr_connect (priv->modal_handler_uids, - G_OBJECT (window), - "destroy", - G_CALLBACK (on_modal_dialog_destroy), - self); - } else { - priv->modal_handler_uids = - modest_signal_mgr_connect (priv->modal_handler_uids, - G_OBJECT (window), - "delete-event", - G_CALLBACK (on_modal_window_close), - self); - } - /* Destroy width parent */ - gtk_window_set_destroy_with_parent (window, TRUE); +static void +modest_window_mgr_set_modal_default (ModestWindowMgr *self, + GtkWindow *window, + GtkWindow *parent) +{ + return; } @@ -1203,123 +711,24 @@ modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self) void modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self) { + GList *window_list; + GList *node; g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); - ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - /* Iterate over all windows */ - GList *win = priv->window_list; - while (win) { - ModestWindow *window = MODEST_WINDOW (win->data); + window_list = modest_window_mgr_get_window_list (self); + node = window_list; + while (node) { + ModestWindow *window = MODEST_WINDOW (node->data); if (window) { /* This calls the vfunc, * so each window can do its own thing: */ modest_window_save_state (window); } - win = g_list_next (win); - } -} - -static gboolean -idle_top_modal (gpointer data) -{ - ModestWindowMgr *self = MODEST_WINDOW_MGR (data); - ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - GtkWindow *topmost; - - /* Get the top modal */ - g_mutex_lock (priv->queue_lock); - topmost = (GtkWindow *) g_queue_peek_head (priv->modal_windows); - g_mutex_unlock (priv->queue_lock); - - /* Show it */ - if (topmost) { - gdk_threads_enter (); - gtk_window_present (topmost); - /* It seems that the window looses modality if some - other is shown on top of it after set_transient_for - and set_parent */ - gtk_window_set_modal (topmost, TRUE); - gdk_threads_leave (); - } - - return FALSE; -} - -static void -remove_modal_from_queue (GtkWidget *widget, - ModestWindowMgr *self) -{ - ModestWindowMgrPrivate *priv; - GList *item = NULL; - - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - - /* Remove from queue. We don't use remove, because we want to - exit if the widget does not belong to the queue */ - g_mutex_lock (priv->queue_lock); - item = g_queue_find (priv->modal_windows, widget); - if (!item) { - g_warning ("Trying to remove a modal window that is not registered"); - g_mutex_unlock (priv->queue_lock); - return; + node = g_list_next (node); } - g_queue_unlink (priv->modal_windows, item); - g_mutex_unlock (priv->queue_lock); - - /* Disconnect handler */ - priv->modal_handler_uids = - modest_signal_mgr_disconnect (priv->modal_handler_uids, - G_OBJECT (widget), - GTK_IS_DIALOG (widget) ? - "response" : - "delete-event"); - if (GTK_IS_DIALOG (widget)) - priv->modal_handler_uids = - modest_signal_mgr_disconnect (priv->modal_handler_uids, - G_OBJECT (widget), - "destroy"); - - /* Schedule the next one for being shown */ - g_idle_add (idle_top_modal, self); -} - -static gboolean -on_modal_window_close (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); - - /* Remove modal window from queue */ - remove_modal_from_queue (widget, self); - - /* Continue */ - return FALSE; -} - -static void -on_modal_dialog_close (GtkDialog *dialog, - gint arg1, - gpointer user_data) -{ - ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); - - /* Remove modal window from queue. Note that if "destroy" - signal was invoked before the response the window could be - already deleted */ - remove_modal_from_queue (GTK_WIDGET (dialog), self); -} - -static void -on_modal_dialog_destroy (GtkObject *object, - gpointer user_data) -{ - ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data); - - /* Remove modal window from queue */ - remove_modal_from_queue (GTK_WIDGET (object), self); + g_list_free (window_list); } gint @@ -1327,13 +736,18 @@ modest_window_mgr_num_windows (ModestWindowMgr *self) { ModestWindowMgrPrivate *priv; gint num_windows = 0; + GList *window_list; g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1); priv = MODEST_WINDOW_MGR_GET_PRIVATE(self); + + window_list = modest_window_mgr_get_window_list (self); - if (priv->window_list) - num_windows = g_list_length (priv->window_list); + if (window_list) { + num_windows = g_list_length (window_list); + g_list_free (window_list); + } /* Do not take into account the main window if it was hidden */ if (priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window)) diff --git a/src/widgets/modest-window-mgr.h b/src/widgets/modest-window-mgr.h index a8e7411..93cffb9 100644 --- a/src/widgets/modest-window-mgr.h +++ b/src/widgets/modest-window-mgr.h @@ -38,7 +38,7 @@ G_BEGIN_DECLS /* convenience macros */ #define MODEST_TYPE_WINDOW_MGR (modest_window_mgr_get_type()) #define MODEST_WINDOW_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_WINDOW_MGR,ModestWindowMgr)) -#define MODEST_WINDOW_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_WINDOW_MGR,GObject)) +#define MODEST_WINDOW_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_WINDOW_MGR,ModestWindowMgrClass)) #define MODEST_IS_WINDOW_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_WINDOW_MGR)) #define MODEST_IS_WINDOW_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_WINDOW_MGR)) #define MODEST_WINDOW_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_WINDOW_MGR,ModestWindowMgrClass)) @@ -53,6 +53,32 @@ struct _ModestWindowMgr { struct _ModestWindowMgrClass { GObjectClass parent_class; + /* Virtuals */ + gboolean (*register_window) (ModestWindowMgr *self, + ModestWindow *window, + ModestWindow *parent); + void (*unregister_window) (ModestWindowMgr *self, + ModestWindow *window); + void (*set_fullscreen_mode) (ModestWindowMgr *self, + gboolean on); + gboolean (*get_fullscreen_mode) (ModestWindowMgr *self); + void (*show_toolbars) (ModestWindowMgr *self, + GType window_type, + gboolean show_toolbars, + gboolean fullscreen); + ModestWindow * (*get_main_window) (ModestWindowMgr *self, + gboolean show); + void (*close_all_windows) (ModestWindowMgr *self); + GtkWindow * (*get_modal) (ModestWindowMgr *self); + void (*set_modal) (ModestWindowMgr *self, + GtkWindow *window, + GtkWindow *parent); + gboolean (*find_registered_header) (ModestWindowMgr *self, + TnyHeader *header, + ModestWindow **win); + GList * (*get_window_list) (ModestWindowMgr *self); + + /* Signals */ void (*window_list_empty) (ModestWindowMgr *self); }; @@ -73,8 +99,9 @@ ModestWindowMgr* modest_window_mgr_new (void); * Registers a new window in the window manager. The window manager * will keep a reference. **/ -void modest_window_mgr_register_window (ModestWindowMgr *self, - ModestWindow *window); +gboolean modest_window_mgr_register_window (ModestWindowMgr *self, + ModestWindow *window, + ModestWindow *parent); /** * modest_window_mgr_unregister_window: @@ -145,7 +172,7 @@ void modest_window_mgr_show_toolbars (ModestWindowMgr *self, /** * modest_window_mgr_get_main_window: * @self: a #ModestWindowMgr - * @create: if TRUE, create the main window if it was not yet existing + * @show: if TRUE, create the main window and show it if it was not existing. * * get the main window, and depending on @create, create one if it does not exist yet * @@ -153,7 +180,14 @@ void modest_window_mgr_show_toolbars (ModestWindowMgr *self, * did not yet exist **/ ModestWindow* modest_window_mgr_get_main_window (ModestWindowMgr *self, - gboolean create); + gboolean show); + +/** + * modest_window_mgr_set_main_window: + * @self: a #ModestWindowMgr + * @main_win: a #ModestMainWindow + */ +void modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *main_win); /** @@ -187,7 +221,8 @@ GtkWindow* modest_window_mgr_get_modal (ModestWindowMgr *self); * **/ void modest_window_mgr_set_modal (ModestWindowMgr *self, - GtkWindow *window); + GtkWindow *window, + GtkWindow *parent); /** * modest_window_mgr_prevent_hibernation_while_window_is_shown: @@ -246,6 +281,15 @@ modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win); gboolean modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header, ModestWindow **win); +/** + * modest_window_mgr_get_window_list: + * @self: a #ModestWindowMgr + * + * get the list of windows registered in window mgr. + * + * Returns: a #GList, that caller should free + */ +GList *modest_window_mgr_get_window_list (ModestWindowMgr *self); /** * modest_window_mgr_close_all_windows diff --git a/src/widgets/modest-window.c b/src/widgets/modest-window.c index acf9d90..c25d5b9 100644 --- a/src/widgets/modest-window.c +++ b/src/widgets/modest-window.c @@ -89,7 +89,11 @@ modest_window_get_type (void) NULL }; #ifndef MODEST_TOOLKIT_GTK +#ifdef MODEST_TOOLKIT_HILDON2 + parent_type = HILDON_TYPE_STACKABLE_WINDOW; +#else parent_type = HILDON_TYPE_WINDOW; +#endif #else parent_type = GTK_TYPE_WINDOW; #endif diff --git a/src/widgets/modest-window.h b/src/widgets/modest-window.h index cd159d4..0c8b874 100644 --- a/src/widgets/modest-window.h +++ b/src/widgets/modest-window.h @@ -53,10 +53,19 @@ typedef GtkWindowClass ModestWindowParentClass; #if MODEST_HILDON_API == 0 #include #else +#ifdef MODEST_TOOLKIT_HILDON2 +#include +#else #include +#endif #endif /*MODEST_HILDON_API == 0*/ +#ifdef MODEST_TOOLKIT_HILDON2 +typedef HildonStackableWindow ModestWindowParent; +typedef HildonStackableWindowClass ModestWindowParentClass; +#else typedef HildonWindow ModestWindowParent; typedef HildonWindowClass ModestWindowParentClass; +#endif #ifndef GTK_STOCK_FULLSCREEN #define GTK_STOCK_FULLSCREEN "" -- 1.7.9.5