* let the dbus-invoked msgs use the same uids as other messages,
[modest] / src / widgets / modest-window-mgr.c
index c49b026..d66cc14 100644 (file)
@@ -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 */
 
@@ -232,9 +239,13 @@ 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 (!has_uid (priv->preregistered_uids, 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);
 }
@@ -251,8 +262,19 @@ 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))
+       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))
+                       g_debug ("BUG: uid %s NOT removed", uid);
+               else
+                       g_debug ("uid %s removed", uid);
+       }
 
        g_free (uid);
 }
@@ -283,7 +305,7 @@ modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *head
 {
        ModestWindowMgrPrivate *priv;
        gchar* uid;
-       gboolean retval = FALSE;
+       gboolean has_header, has_window = FALSE;
        GList *item = NULL;
 
        g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
@@ -293,24 +315,29 @@ modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *head
 
        uid = modest_tny_folder_get_header_unique_id (header);
        
-       /* first, look for the window */
-       /* note, the UID cannot be in both the window list and the preregistered uid list */
-       if (priv->window_list) {
-               item = g_list_find_custom (priv->window_list, 
-                                          uid, (GCompareFunc) compare_msguids);
-               if (item) 
-                       retval = TRUE;
-               if (win)
-                       *win = item ? MODEST_WINDOW(item->data) : NULL;
-       }
+       if (win)
+               *win = NULL;
        
+       g_debug ("windows in list: %d", g_list_length (priv->window_list));
+       g_debug ("headers in list: %d", g_slist_length (priv->preregistered_uids));
 
-       /* IF It's not in the window list. maybe it's in our uid list... */
-       retval = retval || has_uid (priv->preregistered_uids, uid);
+       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))
+                               g_debug ("not a valid window!");
+                       else {
+                               g_debug ("found a window");
+                               *win = MODEST_WINDOW (item->data);
+                       }
+               }
+       }
 
        g_free (uid);
-
-       return retval;
+       return has_header || has_window;
 }
 
 
@@ -335,7 +362,7 @@ modest_window_mgr_register_window (ModestWindowMgr *self,
                g_warning ("Trying to register an already registered window");
                return;
        }
-
+       
        /* Check that it's not a second main window */
        if (MODEST_IS_MAIN_WINDOW (window)) {
                if (priv->main_window) {
@@ -348,6 +375,14 @@ modest_window_mgr_register_window (ModestWindowMgr *self,
 
        /* remove from the list of pre-registered uids */
        if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
+               const gchar *uid = modest_msg_view_window_get_message_uid
+                       (MODEST_MSG_VIEW_WINDOW (window));
+
+               g_debug ("registering window for %s", uid);
+                               
+               if (!has_uid (priv->preregistered_uids, uid)) 
+                       g_debug ("weird: no uid for window (%s)", uid);
+
                priv->preregistered_uids = 
                        remove_uid (priv->preregistered_uids,
                                    modest_msg_view_window_get_message_uid
@@ -361,9 +396,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 +492,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 +524,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 +544,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 */
@@ -496,7 +561,9 @@ modest_window_mgr_unregister_window (ModestWindowMgr *self,
                                      priv->show_toolbars, NULL);
 
                /* Quit main loop */
-               gtk_main_quit ();
+               /* FIXME: do we ever need to do this here? */
+               if (gtk_main_level() > 0)
+                       gtk_main_quit ();
        }
 }