From e88463756e12926277a032f2db233bd90b4694b0 Mon Sep 17 00:00:00 2001 From: Sergio Villar Senin Date: Fri, 6 Jul 2007 19:38:21 +0000 Subject: [PATCH] * Added msg-changed signal to the viewer window, to notify about the change in the message that it is shown * Fixes NB#62532, only prevent the message currently being shown from deleting pmo-trunk-r2621 --- src/maemo/modest-main-window.c | 31 +++++++++++++++++++++- src/maemo/modest-msg-view-window.c | 25 +++++++++++++++--- src/modest-mail-operation.c | 8 +----- src/widgets/modest-header-view-priv.h | 2 ++ src/widgets/modest-header-view.c | 43 +++++++++++++++++++++++++----- src/widgets/modest-main-window.h | 16 ++++++----- src/widgets/modest-msg-view-window.h | 7 +++-- src/widgets/modest-window-mgr.c | 47 +++++++++++++++++++++++++++++---- 8 files changed, 147 insertions(+), 32 deletions(-) diff --git a/src/maemo/modest-main-window.c b/src/maemo/modest-main-window.c index d413712..2aec465 100644 --- a/src/maemo/modest-main-window.c +++ b/src/maemo/modest-main-window.c @@ -37,7 +37,7 @@ #include "modest-hildon-includes.h" #include "modest-defs.h" #include - +#include "widgets/modest-header-view-priv.h" #include "widgets/modest-main-window.h" #include "widgets/modest-msg-edit-window.h" #include "widgets/modest-account-view-window.h" @@ -2198,3 +2198,32 @@ modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view, modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window); } + +gboolean +modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window, + GtkTreeModel *model, + GtkTreeRowReference *row_reference, + ModestMainWindow *self) +{ + ModestMainWindowPrivate *priv = NULL; + GtkTreeModel *header_model = NULL; + GtkTreePath *path = NULL; + + g_return_val_if_fail (MODEST_MSG_VIEW_WINDOW (view_window), FALSE); + g_return_val_if_fail (MODEST_MAIN_WINDOW (self), FALSE); + g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE); + + priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self); + header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view)); + + /* Do nothing if we changed the folder in the main view */ + if (header_model != model) + return FALSE; + + /* Select the message in the header view */ + path = gtk_tree_row_reference_get_path (row_reference); + _modest_header_view_select_from_path (MODEST_HEADER_VIEW (priv->header_view), path); + gtk_tree_path_free (path); + + return TRUE; +} diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index b8ff9aa..5db7724 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -33,6 +33,7 @@ #include #include #include +#include "modest-marshal.h" #include "modest-platform.h" #include #include @@ -107,8 +108,7 @@ static void update_window_title (ModestMsgViewWindow *window); /* list my signals */ enum { - /* MY_SIGNAL_1, */ - /* MY_SIGNAL_2, */ + MSG_CHANGED_SIGNAL, LAST_SIGNAL }; @@ -166,7 +166,7 @@ struct _ModestMsgViewWindowPrivate { static GtkWindowClass *parent_class = NULL; /* uncomment the following if you have defined any signals */ -/* static guint signals[LAST_SIGNAL] = {0}; */ +static guint signals[LAST_SIGNAL] = {0}; GType modest_msg_view_window_get_type (void) @@ -229,6 +229,15 @@ modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass) g_type_class_add_private (gobject_class, sizeof(ModestMsgViewWindowPrivate)); modest_window_class->save_state_func = save_state; + + signals[MSG_CHANGED_SIGNAL] = + g_signal_new ("msg-changed", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestMsgViewWindowClass, msg_changed), + NULL, NULL, + modest_marshal_VOID__POINTER_POINTER, + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); } static void @@ -1255,6 +1264,16 @@ view_msg_cb (ModestMailOperation *mail_op, update_window_title (MODEST_MSG_VIEW_WINDOW (self)); modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view)); + /* Set the new message uid of the window */ + if (priv->msg_uid) { + g_free (priv->msg_uid); + priv->msg_uid = modest_tny_folder_get_header_unique_id (header); + } + + /* Notify the observers */ + g_signal_emit (G_OBJECT (self), signals[MSG_CHANGED_SIGNAL], + 0, priv->header_model, priv->row_reference); + /* Free new references */ g_object_unref (self); } diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 8f4cb07..9dfcaf8 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -1380,7 +1380,7 @@ transfer_folder_status_cb (GObject *obj, g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER); helper = (XFerMsgAsyncHelper *) user_data; - g_return_if_fail (helper != NULL); + g_return_if_fail (helper != NULL); self = helper->mail_op; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); @@ -2179,7 +2179,6 @@ on_refresh_folder (TnyFolder *folder, } priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; - out: /* Call user defined callback, if it exists */ if (helper->user_callback) { @@ -2277,11 +2276,6 @@ modest_mail_operation_notify_end (ModestMailOperation *self) priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - if (!priv) { - g_warning ("BUG: %s: priv == NULL", __FUNCTION__); - return; - } - /* Set the account back to not busy */ if (priv->account_name) { modest_account_mgr_set_account_busy (modest_runtime_get_account_mgr(), diff --git a/src/widgets/modest-header-view-priv.h b/src/widgets/modest-header-view-priv.h index 226c42d..2716aca 100644 --- a/src/widgets/modest-header-view-priv.h +++ b/src/widgets/modest-header-view-priv.h @@ -60,6 +60,8 @@ void _modest_header_view_sender_receiver_cell_data (GtkTreeViewColumn *column, void _modest_header_view_compact_header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data); +void _modest_header_view_select_from_path (ModestHeaderView *self, GtkTreePath *path); + typedef enum _ModestHeaderViewCompactHeaderMode { MODEST_HEADER_VIEW_COMPACT_HEADER_MODE_IN = 0, MODEST_HEADER_VIEW_COMPACT_HEADER_MODE_OUT = 1, diff --git a/src/widgets/modest-header-view.c b/src/widgets/modest-header-view.c index 097c2e6..ba3ebe9 100644 --- a/src/widgets/modest-header-view.c +++ b/src/widgets/modest-header-view.c @@ -71,7 +71,7 @@ static gboolean filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data); -static void on_selection_changed (GtkTreeSelection *sel, +static void on_selection_changed (GtkTreeSelection *sel, gpointer user_data); static void setup_drag_and_drop (GtkTreeView *self); @@ -104,13 +104,13 @@ struct _ModestHeaderViewPrivate { ModestEmailClipboard *clipboard; /* Filter tree model */ - gchar **hidding_ids; - guint n_selected; + gchar **hidding_ids; + guint n_selected; gint sort_colid[2][TNY_FOLDER_TYPE_NUM]; gint sort_type[2][TNY_FOLDER_TYPE_NUM]; - + gulong selection_changed_handler; }; typedef struct _HeadersCountChangedHelper HeadersCountChangedHelper; @@ -342,7 +342,6 @@ modest_header_view_set_columns (ModestHeaderView *self, const GList *columns, Tn selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(self)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); -/* sortable = gtk_tree_view_get_model (GTK_TREE_VIEW (self)); */ tree_filter = gtk_tree_view_get_model (GTK_TREE_VIEW (self)); sortable = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER(tree_filter)); @@ -498,6 +497,7 @@ modest_header_view_init (ModestHeaderView *obj) priv->clipboard = modest_runtime_get_email_clipboard (); priv->hidding_ids = NULL; priv->n_selected = 0; + priv->selection_changed_handler = 0; /* Sort parameters */ for (j=0; j < 2; j++) { @@ -537,6 +537,11 @@ modest_header_view_finalize (GObject *obj) self = MODEST_HEADER_VIEW(obj); priv = MODEST_HEADER_VIEW_GET_PRIVATE(self); + if (priv->selection_changed_handler) { + g_signal_handler_disconnect (self, priv->selection_changed_handler); + priv->selection_changed_handler = 0; + } + g_mutex_lock (priv->observers_lock); if (priv->monitor) { tny_folder_monitor_stop (priv->monitor); @@ -578,8 +583,9 @@ modest_header_view_new (TnyFolder *folder, ModestHeaderViewStyle style) TRUE); /* alternating row colors */ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self)); - g_signal_connect (sel, "changed", - G_CALLBACK(on_selection_changed), self); + priv->selection_changed_handler = + g_signal_connect_after (sel, "changed", + G_CALLBACK(on_selection_changed), self); g_signal_connect (self, "row-activated", G_CALLBACK (on_header_row_activated), NULL); @@ -1648,3 +1654,26 @@ modest_header_view_refilter (ModestHeaderView *header_view) if (GTK_IS_TREE_MODEL_FILTER (model)) gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model)); } + +/** + * Protected method, selects a row pointed by path + **/ +void +_modest_header_view_select_from_path (ModestHeaderView *self, + GtkTreePath *path) +{ + GtkTreeSelection *selection = NULL; + ModestHeaderViewPrivate *priv; + + g_return_if_fail (MODEST_HEADER_VIEW (self)); + g_return_if_fail (path != NULL); + + priv = MODEST_HEADER_VIEW_GET_PRIVATE (self); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self)); + + /* Unselect previous selection */ + gtk_tree_selection_unselect_all (selection); + + /* Select new path*/ + gtk_tree_selection_select_path (selection, path); +} diff --git a/src/widgets/modest-main-window.h b/src/widgets/modest-main-window.h index 1730bbe..710a41d 100644 --- a/src/widgets/modest-main-window.h +++ b/src/widgets/modest-main-window.h @@ -36,7 +36,7 @@ #include #include #include - +#include G_BEGIN_DECLS @@ -196,8 +196,7 @@ ModestMainWindowContentsStyle modest_main_window_get_contents_style (ModestMainW * Returns: TRUE if send$receive operaton is in * progress, FALSE otherwise. **/ -gboolean -modest_main_window_send_receive_in_progress (ModestMainWindow *self); +gboolean modest_main_window_send_receive_in_progress (ModestMainWindow *self); /** * modest_main_window_notify_send_receive_initied: @@ -205,8 +204,7 @@ modest_main_window_send_receive_in_progress (ModestMainWindow *self); * * Notifies main window that send/receive operaiton was just started. **/ -void -modest_main_window_notify_send_receive_initied (ModestMainWindow *self); +void modest_main_window_notify_send_receive_initied (ModestMainWindow *self); /** * modest_main_window_notify_send_receive_completed: @@ -214,9 +212,13 @@ modest_main_window_notify_send_receive_initied (ModestMainWindow *self); * * Notifies main window that send/receive operaiton was completed. **/ -void -modest_main_window_notify_send_receive_completed (ModestMainWindow *self); +void modest_main_window_notify_send_receive_completed (ModestMainWindow *self); + +gboolean modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window, + GtkTreeModel *model, + GtkTreeRowReference *row_reference, + ModestMainWindow *self); G_END_DECLS diff --git a/src/widgets/modest-msg-view-window.h b/src/widgets/modest-msg-view-window.h index 65b97cd..d2c9f0b 100644 --- a/src/widgets/modest-msg-view-window.h +++ b/src/widgets/modest-msg-view-window.h @@ -51,8 +51,11 @@ typedef struct { typedef struct { ModestWindowClass parent_class; - /* insert signal callback declarations, eg. */ - /* void (* my_event) (ModestEditMsgWindow* obj); */ + + void (*msg_changed) (ModestMsgViewWindow *self, + GtkTreeModel *model, + GtkTreeRowReference *row_reference, + gpointer user_data); } ModestMsgViewWindowClass; /** diff --git a/src/widgets/modest-window-mgr.c b/src/widgets/modest-window-mgr.c index ca27a2c..d7adb5a 100644 --- a/src/widgets/modest-window-mgr.c +++ b/src/widgets/modest-window-mgr.c @@ -67,6 +67,7 @@ struct _ModestWindowMgrPrivate { GSList *windows_that_prevent_hibernation; GSList *preregistered_uids; GHashTable *destroy_handlers; + GHashTable *viewer_handlers; }; #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ MODEST_TYPE_WINDOW_MGR, \ @@ -129,7 +130,8 @@ modest_window_mgr_init (ModestWindowMgr *obj) ready yet */ priv->show_toolbars = FALSE; priv->show_toolbars_fullscreen = FALSE; - priv->destroy_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); + 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); } static void @@ -159,6 +161,11 @@ modest_window_mgr_finalize (GObject *obj) priv->destroy_handlers = NULL; } + if (priv->viewer_handlers) { + g_hash_table_destroy (priv->viewer_handlers); + priv->viewer_handlers = NULL; + } + /* Do not unref priv->main_window because it does not hold a new reference */ @@ -361,9 +368,18 @@ modest_window_mgr_register_window (ModestWindowMgr *self, /* Listen to object destruction */ handler_id = g_malloc0 (sizeof (gint)); *handler_id = g_signal_connect (window, "delete-event", G_CALLBACK (on_window_destroy), self); -/* *handler_id = g_signal_connect (window, "destroy", 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)); @@ -448,6 +464,18 @@ on_window_destroy (ModestWindow *window, return FALSE; } +static void +disconnect_msg_changed (gpointer key, + gpointer value, + gpointer user_data) +{ + gulong *handler_id; + + handler_id = (gulong *) value; + g_signal_handler_disconnect (G_OBJECT (key), *handler_id); +} + + void modest_window_mgr_unregister_window (ModestWindowMgr *self, ModestWindow *window) @@ -468,9 +496,17 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self, } /* If it's the main window unset it */ - if (priv->main_window == window) + if (priv->main_window == window) { priv->main_window = NULL; + /* Disconnect all emissions of msg-changed */ + g_hash_table_foreach (priv->viewer_handlers, + disconnect_msg_changed, + NULL); + g_hash_table_destroy (priv->viewer_handlers); + priv->viewer_handlers = NULL; + } + /* Save state */ modest_window_save_state (window); @@ -480,9 +516,10 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self, handler_id = *tmp; g_hash_table_remove (priv->destroy_handlers, window); - /* Remove the reference to the window. Disconnect also the - delete-event handler, we won't need it anymore */ + /* Disconnect the "delete-event" handler, we won't need it anymore */ g_signal_handler_disconnect (window, handler_id); + + /* Destroy the window */ gtk_widget_destroy (win->data); /* If there are no more windows registered then exit program */ -- 1.7.9.5