X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fwidgets%2Fmodest-window-mgr.c;h=6c2f191932f7f983a09c4c89dd74eee078f8daf2;hp=33ec152a97ba56099b69eadeb5e8a8cdb7f3a4e1;hb=a4a4f2640022f8b27dc85bc1ef49ac88dbbcf3d3;hpb=94a4612a68cf9129d80418e40d177911297b76e7 diff --git a/src/widgets/modest-window-mgr.c b/src/widgets/modest-window-mgr.c index 33ec152..6c2f191 100644 --- a/src/widgets/modest-window-mgr.c +++ b/src/widgets/modest-window-mgr.c @@ -60,9 +60,8 @@ static const gchar* get_show_toolbar_key (GType window_type, /* list my signals */ enum { - /* MY_SIGNAL_1, */ - /* MY_SIGNAL_2, */ - LAST_SIGNAL + WINDOW_LIST_EMPTY_SIGNAL, + NUM_SIGNALS }; typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate; @@ -92,7 +91,7 @@ struct _ModestWindowMgrPrivate { static GObjectClass *parent_class = NULL; /* uncomment the following if you have defined any signals */ -/* static guint signals[LAST_SIGNAL] = {0}; */ +static guint signals[NUM_SIGNALS] = {0}; GType modest_window_mgr_get_type (void) @@ -128,6 +127,23 @@ modest_window_mgr_class_init (ModestWindowMgrClass *klass) gobject_class->finalize = modest_window_mgr_finalize; g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate)); + + + /** + * ModestWindowMgr::window-list-empty + * @self: the #ModestWindowMgr that emits the signal + * @user_data: user data set when the signal handler was connected + * + * Issued whenever the window list becomes empty + */ + signals[WINDOW_LIST_EMPTY_SIGNAL] = + g_signal_new ("window-list-empty", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestWindowMgrClass, window_list_empty), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -261,7 +277,7 @@ append_uid (GSList *list, const gchar *uid) void -modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header) +modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header, const gchar *alt_uid) { ModestWindowMgrPrivate *priv; gchar* uid; @@ -272,13 +288,15 @@ modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header) priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); uid = modest_tny_folder_get_header_unique_id (header); - + if (uid == NULL) + uid = g_strdup (alt_uid); + if (!has_uid (priv->preregistered_uids, uid)) { g_debug ("registering new uid %s", uid); priv->preregistered_uids = append_uid (priv->preregistered_uids, uid); } else g_debug ("already had uid %s", uid); - + g_free (uid); } @@ -293,13 +311,13 @@ modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header) priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); uid = modest_tny_folder_get_header_unique_id (header); - + if (!has_uid (priv->preregistered_uids, uid)) { g_debug ("trying to unregister non-existing uid %s", uid); priv->preregistered_uids = append_uid (priv->preregistered_uids, uid); } else g_debug ("unregistering uid %s", uid); - + if (has_uid (priv->preregistered_uids, uid)) { priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid); if (has_uid (priv->preregistered_uids, uid)) @@ -307,10 +325,63 @@ modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header) else g_debug ("uid %s removed", uid); } - + g_free (uid); } + +#define MODEST_WINDOW_HELP_ID_PARAM "help-id" + +void +modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const gchar* help_id) +{ + /* we don't need 'self', but for API consistency... */ + g_return_if_fail (self && MODEST_IS_WINDOW_MGR(self)); + + g_return_if_fail (win && GTK_IS_WINDOW(win)); + g_return_if_fail (help_id); + + g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM, + g_strdup(help_id), g_free); +} + + +const gchar* +modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win) +{ + const gchar* help_id = NULL; + + /* we don't need 'self', but for API consistency... */ + g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL); + + g_return_val_if_fail (win, NULL); + g_return_val_if_fail (GTK_IS_WINDOW(win), NULL); + + if (MODEST_IS_MAIN_WINDOW (win)) { + GtkWidget *folder_view; + TnyFolderStore *folder_store; + + /* Get selected folder */ + folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), + MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW); + folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); + + /* Switch help_id */ + if (folder_store && TNY_IS_FOLDER (folder_store)) { + help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store)); + if (!help_id) + g_warning ("%s: BUG: did not get a valid help_id", __FUNCTION__); + } + if (folder_store) + g_object_unref (folder_store); + } + + if (!help_id) + help_id = g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM); + + return help_id; +} + static gint compare_msguids (ModestWindow *win, const gchar *uid) @@ -335,14 +406,13 @@ compare_msguids (ModestWindow *win, return 1; } - void modest_window_mgr_close_all_windows (ModestWindowMgr *self) { ModestWindowMgrPrivate *priv = NULL; GList *wins = NULL; gboolean ret_value = FALSE; - + g_return_if_fail (MODEST_IS_WINDOW_MGR (self)); priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); @@ -375,9 +445,9 @@ modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *head if (win) *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; @@ -391,8 +461,8 @@ modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *head } } } - g_free (uid); + return has_header || has_window; } @@ -436,8 +506,9 @@ modest_window_mgr_register_window (ModestWindowMgr *self, win = g_list_find (priv->window_list, window); if (win) { - g_warning ("%s: trying to re-register a window", - __FUNCTION__); + /* this is for the case we want to register the window and it was already + * registered. We leave silently. + */ return; } @@ -456,17 +527,16 @@ modest_window_mgr_register_window (ModestWindowMgr *self, if (MODEST_IS_MSG_VIEW_WINDOW(window)) { const gchar *uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (window)); - + if (!has_uid (priv->preregistered_uids, uid)) g_debug ("weird: no uid for window (%s)", uid); g_debug ("registering window for %s", uid ? uid : ""); - + priv->preregistered_uids = remove_uid (priv->preregistered_uids, modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (window))); - } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) { const gchar *uid = modest_msg_edit_window_get_message_uid (MODEST_MSG_EDIT_WINDOW (window)); @@ -512,6 +582,8 @@ on_window_destroy (ModestWindow *window, GdkEvent *event, ModestWindowMgr *self) { + gint dialog_response = GTK_RESPONSE_NONE; + /* Specific stuff first */ if (MODEST_IS_MAIN_WINDOW (window)) { ModestWindowMgrPrivate *priv; @@ -520,21 +592,32 @@ on_window_destroy (ModestWindow *window, /* If more than one window already opened */ if (g_list_length (priv->window_list) > 1) { + /* 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 (modest_main_window_close_all (MODEST_MAIN_WINDOW (window))) { - 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); - } + 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; + } } } else { @@ -577,62 +660,6 @@ disconnect_msg_changed (gpointer key, g_signal_handler_disconnect (G_OBJECT (key), handler_id); } - - -/* interval before retrying to close the application */ -#define CLOSING_RETRY_INTERVAL 3000 -/* interval before cancel whatever is left in the queue, and closing anyway */ -#define MAX_WAIT_FOR_CLOSING 30 * 1000 - -static gboolean -on_quit_maybe (ModestWindowMgr *self) -{ - ModestWindowMgrPrivate *priv; - guint queue_num; - - priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); - - /* it seems, in the meantime some windows were - * created. in that case, stop 'on_quit_maybe' */ - if (priv->window_list) { - priv->closing_time = 0; - return FALSE; - } - - if (priv->closing_time >= MAX_WAIT_FOR_CLOSING) { - /* we waited long enough: cancel all remaining operations */ - g_debug ("%s: we waited long enough (%ds), cancelling queue and quiting", - __FUNCTION__, priv->closing_time/1000); - /* FIXME: below gives me a lot of: - * GLIB CRITICAL ** default - modest_mail_operation_cancel: - * assertion `priv->account' failed - * which means there is no account for the given operation - * so, we're not trying to be nice, we're just quiting. - */ - //modest_mail_operation_queue_cancel_all - // (modest_runtime_get_mail_operation_queue()); - } else { - - /* if there is anything left in our operation queue, - * wait another round - */ - queue_num = modest_mail_operation_queue_num_elements - (modest_runtime_get_mail_operation_queue()); - if (queue_num > 0) { - g_debug ("%s: waiting, there are still %d operation(s) queued", - __FUNCTION__, queue_num); - priv->closing_time += CLOSING_RETRY_INTERVAL; - return TRUE; - } - } - - /* so: no windows left, nothing in the queue: quit */ - priv->closing_time = 0; - gtk_main_quit (); - return FALSE; -} - - void modest_window_mgr_unregister_window (ModestWindowMgr *self, ModestWindow *window) @@ -671,8 +698,13 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self, 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); - g_signal_handler_disconnect (window, *tmp); - g_hash_table_remove (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 */ @@ -693,10 +725,9 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self, /* Destroy the window */ gtk_widget_destroy (win->data); - /* If there are no more windows registered then exit program */ + /* If there are no more windows registered emit the signal */ if (priv->window_list == NULL) - g_timeout_add (CLOSING_RETRY_INTERVAL, - (GSourceFunc)on_quit_maybe, self); + g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0); } @@ -797,7 +828,7 @@ modest_window_mgr_show_toolbars (ModestWindowMgr *self, } ModestWindow* -modest_window_mgr_get_main_window (ModestWindowMgr *self) +modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean create) { ModestWindowMgrPrivate *priv; @@ -805,7 +836,7 @@ modest_window_mgr_get_main_window (ModestWindowMgr *self) priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); /* create the main window, if it hasn't been created yet */ - if (!priv->main_window) { + 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 ()); g_debug ("%s: created main window: %p\n", __FUNCTION__, priv->main_window); @@ -815,6 +846,18 @@ modest_window_mgr_get_main_window (ModestWindowMgr *self) } +gboolean +modest_window_mgr_main_window_exists (ModestWindowMgr *self) +{ + ModestWindowMgrPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE); + priv = MODEST_WINDOW_MGR_GET_PRIVATE (self); + + return priv->main_window != NULL; +} + + GtkWindow * modest_window_mgr_get_modal (ModestWindowMgr *self) { @@ -1030,3 +1073,14 @@ on_modal_dialog_close (GtkDialog *dialog, remove_modal_from_queue (GTK_WIDGET (dialog), self); } +gint +modest_window_mgr_num_windows (ModestWindowMgr *self) +{ + ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(self); + gint num_windows = 0; + + if (priv->window_list) + num_windows = g_list_length (priv->window_list); + + return num_windows; +}