* Added msg-changed signal to the viewer window, to notify about the change in the...
authorSergio Villar Senin <svillar@igalia.com>
Fri, 6 Jul 2007 19:38:21 +0000 (19:38 +0000)
committerSergio Villar Senin <svillar@igalia.com>
Fri, 6 Jul 2007 19:38:21 +0000 (19:38 +0000)
* Fixes NB#62532, only prevent the message currently being shown from deleting

pmo-trunk-r2621

src/maemo/modest-main-window.c
src/maemo/modest-msg-view-window.c
src/modest-mail-operation.c
src/widgets/modest-header-view-priv.h
src/widgets/modest-header-view.c
src/widgets/modest-main-window.h
src/widgets/modest-msg-view-window.h
src/widgets/modest-window-mgr.c

index d413712..2aec465 100644 (file)
@@ -37,7 +37,7 @@
 #include "modest-hildon-includes.h"
 #include "modest-defs.h"
 #include <string.h>
 #include "modest-hildon-includes.h"
 #include "modest-defs.h"
 #include <string.h>
-
+#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"
 #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);
 
 }
        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;
+}
index b8ff9aa..5db7724 100644 (file)
@@ -33,6 +33,7 @@
 #include <tny-msg.h>
 #include <tny-mime-part.h>
 #include <tny-vfs-stream.h>
 #include <tny-msg.h>
 #include <tny-mime-part.h>
 #include <tny-vfs-stream.h>
+#include "modest-marshal.h"
 #include "modest-platform.h"
 #include <modest-maemo-utils.h>
 #include <modest-tny-msg.h>
 #include "modest-platform.h"
 #include <modest-maemo-utils.h>
 #include <modest-tny-msg.h>
@@ -107,8 +108,7 @@ static void update_window_title (ModestMsgViewWindow *window);
 
 /* list my signals */
 enum {
 
 /* list my signals */
 enum {
-       /* MY_SIGNAL_1, */
-       /* MY_SIGNAL_2, */
+       MSG_CHANGED_SIGNAL,
        LAST_SIGNAL
 };
 
        LAST_SIGNAL
 };
 
@@ -166,7 +166,7 @@ struct _ModestMsgViewWindowPrivate {
 static GtkWindowClass *parent_class = NULL;
 
 /* uncomment the following if you have defined any signals */
 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)
 
 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;
        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
 }
 
 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));
 
        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);
 }
        /* Free new references */
        g_object_unref (self);
 }
index 8f4cb07..9dfcaf8 100644 (file)
@@ -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 (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);
 
        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;
        }
 
        priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
-
  out:
        /* Call user defined callback, if it exists */
        if (helper->user_callback) {
  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);
 
 
        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(), 
        /* Set the account back to not busy */
        if (priv->account_name) {
                modest_account_mgr_set_account_busy (modest_runtime_get_account_mgr(), 
index 226c42d..2716aca 100644 (file)
@@ -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_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,
 typedef enum _ModestHeaderViewCompactHeaderMode {
        MODEST_HEADER_VIEW_COMPACT_HEADER_MODE_IN = 0,
        MODEST_HEADER_VIEW_COMPACT_HEADER_MODE_OUT = 1,
index 097c2e6..ba3ebe9 100644 (file)
@@ -71,7 +71,7 @@ static gboolean     filter_row             (GtkTreeModel *model,
                                            GtkTreeIter *iter,
                                            gpointer data);
 
                                            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);
                                             gpointer user_data);
 
 static void          setup_drag_and_drop    (GtkTreeView *self);
@@ -104,13 +104,13 @@ struct _ModestHeaderViewPrivate {
        ModestEmailClipboard *clipboard;
 
        /* Filter tree model */
        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];
 
 
        gint                  sort_colid[2][TNY_FOLDER_TYPE_NUM];
        gint                  sort_type[2][TNY_FOLDER_TYPE_NUM];
 
-
+       gulong                selection_changed_handler;
 };
 
 typedef struct _HeadersCountChangedHelper HeadersCountChangedHelper;
 };
 
 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);
 
        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));
 
        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->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++) {
 
        /* 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);
 
        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);
        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));
        
                                      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);
        
        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));
 }
        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);
+}
index 1730bbe..710a41d 100644 (file)
@@ -36,7 +36,7 @@
 #include <widgets/modest-header-view.h>
 #include <widgets/modest-folder-view.h>
 #include <widgets/modest-msg-view.h>
 #include <widgets/modest-header-view.h>
 #include <widgets/modest-folder-view.h>
 #include <widgets/modest-msg-view.h>
-
+#include <widgets/modest-msg-view-window.h>
 
 G_BEGIN_DECLS
 
 
 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.
  **/
  * 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:
 
 /**
  * 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. 
  **/
  * 
  * 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:
 
 /**
  * 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. 
  **/
  * 
  * 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
 
 
 G_END_DECLS
 
index 65b97cd..d2c9f0b 100644 (file)
@@ -51,8 +51,11 @@ typedef struct {
        
 typedef struct {
        ModestWindowClass parent_class;
        
 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;
 
 /**
 } ModestMsgViewWindowClass;
 
 /**
index ca27a2c..d7adb5a 100644 (file)
@@ -67,6 +67,7 @@ struct _ModestWindowMgrPrivate {
        GSList       *windows_that_prevent_hibernation;
        GSList       *preregistered_uids;
        GHashTable   *destroy_handlers;
        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, \
 };
 #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;
           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
 }
 
 static void
@@ -159,6 +161,11 @@ modest_window_mgr_finalize (GObject *obj)
                priv->destroy_handlers = NULL;
        }
 
                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 */
 
        /* 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);
        /* 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);
 
        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));
        /* 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;
 }
 
        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)
 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 it's the main window unset it */
-       if (priv->main_window == window)
+       if (priv->main_window == window) {
                priv->main_window = NULL;
 
                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);
 
        /* 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);
 
        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);
        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 */
        gtk_widget_destroy (win->data);
 
        /* If there are no more windows registered then exit program */