2007-08-13 Murray Cumming <murrayc@murrayc.com>
[modest] / src / maemo / modest-main-window.c
index 9bb6f3f..6fba596 100644 (file)
@@ -63,6 +63,7 @@
 #include "modest-ui-dimming-manager.h"
 #include "maemo/modest-osso-state-saving.h"
 #include "modest-text-utils.h"
+#include "modest-signal-mgr.h"
 
 #ifdef MODEST_HAVE_HILDON0_WIDGETS
 #include <hildon-widgets/hildon-program.h>
@@ -109,7 +110,8 @@ static void on_queue_changed   (ModestMailOperationQueue *queue,
 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
 
 static void account_number_changed            (TnyAccountStore *account_store, 
-                                              const gchar *account_name,
+/*                                            const gchar *account_name,  */
+                                              TnyAccount *account,
                                               gpointer user_data);
 
 static gboolean on_inner_widgets_key_pressed  (GtkWidget *widget,
@@ -161,6 +163,10 @@ modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
                                                TnyFolderStore *folder_store, 
                                                gboolean selected,
                                                ModestMainWindow *main_window);
+                                               
+static void
+set_at_least_one_account_visible(ModestMainWindow *self);
+
 
 /* list my signals */
 enum {
@@ -210,9 +216,9 @@ struct _ModestMainWindowPrivate {
        guint progress_bar_timeout;
 
        /* Signal handler UIDs */
-       gint queue_changed_handler_uid; 
        GList *queue_err_signals;
-
+       GSList *sighandlers;
+       
        ModestConfNotificationId notification_id;
 };
 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
@@ -336,7 +342,7 @@ modest_main_window_init (ModestMainWindow *obj)
        priv->optimized_view  = FALSE;
        priv->send_receive_in_progress  = FALSE;
        priv->progress_bar_timeout = 0;
-       priv->queue_changed_handler_uid = 0;
+       priv->sighandlers = NULL;
 }
 
 static void
@@ -346,6 +352,12 @@ modest_main_window_finalize (GObject *obj)
 
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
 
+       if (priv->notification_id) {
+               modest_conf_forget_namespace (modest_runtime_get_conf (),
+                                             MODEST_CONF_NAMESPACE,
+                                             priv->notification_id);
+       }
+       
        /* Sanity check: shouldn't be needed, the window mgr should
           call this function before */
        modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
@@ -361,12 +373,6 @@ modest_main_window_finalize (GObject *obj)
                priv->progress_bar_timeout = 0;
        }
 
-       if (priv->notification_id) {
-               modest_conf_forget_namespace (modest_runtime_get_conf (),
-                                             MODEST_CONF_NAMESPACE,
-                                             priv->notification_id);
-       }
-
        G_OBJECT_CLASS(parent_class)->finalize (obj);
 }
 
@@ -399,8 +405,6 @@ modest_main_window_get_child_widget (ModestMainWindow *self,
 static void
 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
 {
-       printf ("DEBUGDEBUG: %s\n", __FUNCTION__);
-       
        ModestConf *conf;
        ModestMainWindowPrivate *priv;
 
@@ -642,15 +646,11 @@ _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
 static void
 modest_main_window_disconnect_signals (ModestWindow *self)
 {      
-       ModestMainWindowPrivate *priv;
-       
+       ModestMainWindowPrivate *priv;  
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
 
-       /* Disconnect signal handlers */
-       if (g_signal_handler_is_connected (modest_runtime_get_mail_operation_queue (),
-                                          priv->queue_changed_handler_uid))
-               g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (),
-                                            priv->queue_changed_handler_uid);
+       modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
+       priv->sighandlers = NULL;       
 }
 
 static void
@@ -664,76 +664,71 @@ connect_signals (ModestMainWindow *self)
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
 
        /* folder view */
-       g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
-                         G_CALLBACK(on_inner_widgets_key_pressed), self);
-       g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
-                         G_CALLBACK(modest_main_window_on_folder_selection_changed), self);
-       g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
-                         G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
-       g_signal_connect (G_OBJECT (priv->folder_view), "focus-in-event", 
-                         G_CALLBACK (on_folder_view_focus_in), self);
+       
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
+                                                      G_OBJECT(priv->folder_view), "key-press-event",
+                                                      G_CALLBACK(on_inner_widgets_key_pressed), self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), "folder_selection_changed",
+                                                      G_CALLBACK(modest_main_window_on_folder_selection_changed), self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), "folder-display-name-changed",
+                                                      G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view), "focus-in-event", 
+                                                      G_CALLBACK (on_folder_view_focus_in), self);
 
        /* Folder view CSM */
        menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
        gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
-       g_signal_connect (G_OBJECT(priv->folder_view), "tap-and-hold",
-                         G_CALLBACK(_folder_view_csm_menu_activated),
-                         self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
+                                                      G_CALLBACK(_folder_view_csm_menu_activated),
+                                                      self);
        /* header view */
-       g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
-                         G_CALLBACK(modest_ui_actions_on_header_selected), self);
-       g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
-                         G_CALLBACK(modest_ui_actions_on_header_activated), self);
-       g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
-                         G_CALLBACK(modest_ui_actions_on_item_not_found), self);
-       g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
-                         G_CALLBACK(on_inner_widgets_key_pressed), self);
-       g_signal_connect (G_OBJECT(priv->header_view), "msg_count_changed",
-                         G_CALLBACK(_on_msg_count_changed), self);
-       g_signal_connect (G_OBJECT (priv->header_view), "focus-in-event",
-                         G_CALLBACK (on_header_view_focus_in), self);
-
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
+                                                      G_CALLBACK(modest_ui_actions_on_header_selected), self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
+                                                      G_CALLBACK(modest_ui_actions_on_header_activated), self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
+                                                      G_CALLBACK(modest_ui_actions_on_item_not_found), self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
+                                                      G_CALLBACK(on_inner_widgets_key_pressed), self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
+                                                      G_CALLBACK(_on_msg_count_changed), self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
+                                                      G_CALLBACK (on_header_view_focus_in), self);
+       
        /* Header view CSM */
        menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
        gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
-       g_signal_connect (G_OBJECT(priv->header_view), "tap-and-hold",
-                         G_CALLBACK(_header_view_csm_menu_activated),
-                         self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
+                                                      G_CALLBACK(_header_view_csm_menu_activated),
+                                                      self);
        
        /* window */
-       g_signal_connect (G_OBJECT (self), "window-state-event",
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
                          G_CALLBACK (modest_main_window_window_state_event),
                          NULL);
        
        /* Mail Operation Queue */
-       priv->queue_changed_handler_uid = 
-               g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
-                                 "queue-changed", G_CALLBACK (on_queue_changed), self);
-
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_mail_operation_queue ()),
+                                                      "queue-changed", G_CALLBACK (on_queue_changed), self);
+       
        /* Track changes in the device name */
        priv->notification_id =  modest_conf_listen_to_namespace (modest_runtime_get_conf (), 
                                                                  MODEST_CONF_NAMESPACE);
-       g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
-                         "key_changed", G_CALLBACK (on_configuration_key_changed), 
-                         self);
-
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(modest_runtime_get_conf ()),
+                                                      "key_changed", G_CALLBACK (on_configuration_key_changed), 
+                                                      self);
+       
        /* Track account changes. We need to refresh the toolbar */
-       g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
-                         "account_inserted", G_CALLBACK (account_number_changed),
-                         self);
-       g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
-                         "account_removed", G_CALLBACK (account_number_changed),
-                         self);
-
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store ()),
+                                                      "account_inserted", G_CALLBACK (account_number_changed),
+                                                      self);
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store ()),
+                                                      "account_removed", G_CALLBACK (account_number_changed),
+                                                      self);
        /* Account store */
-       g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), 
-                         "password_requested",
-                         G_CALLBACK (modest_ui_actions_on_password_requested), self);
-                         
-/*     /\* Device *\/ */
-/*     g_signal_connect (G_OBJECT(modest_runtime_get_account_store()),  */
-/*                       "connecting-finished", */
-/*                       G_CALLBACK(on_account_store_connecting_finished), self); */
+       priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store()), 
+                                                      "password_requested",
+                                                      G_CALLBACK (modest_ui_actions_on_password_requested), self);
 }
 
 #if 0
@@ -1251,9 +1246,10 @@ compare_display_names (ModestAccountData *a,
 
 static void 
 account_number_changed (TnyAccountStore *account_store, 
-                       const gchar *account_name,
+/*                     const gchar *account_name, */
+                       TnyAccount *account,
                        gpointer user_data)
-{
+{      
        GSList *account_names, *iter, *accounts;
        ModestMainWindow *self;
        ModestMainWindowPrivate *priv;
@@ -1266,6 +1262,9 @@ account_number_changed (TnyAccountStore *account_store,
        GtkWidget *send_receive_button, *item;
        GtkAction *send_receive_all = NULL;
                
+       g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
+/*     g_return_if_fail (TNY_IS_ACCOUNT (account)); */
+
        self = MODEST_MAIN_WINDOW (user_data);
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
        parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
@@ -1515,6 +1514,11 @@ account_number_changed (TnyAccountStore *account_store,
        /* Frees */
        g_slist_free (accounts);
        g_free (default_account);
+
+
+       /* Make sure that at least one account is viewed if there are any 
+        * accounts, for instance when adding the first account: */
+       set_at_least_one_account_visible (self);
 }
 
 /* 
@@ -1795,6 +1799,11 @@ _on_msg_count_changed (ModestHeaderView *header_view,
        
        printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
 
+/*     Check header removed  (hide marked as DELETED headers) */
+       if (changed & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS) {
+               modest_header_view_refilter (MODEST_HEADER_VIEW(priv->header_view));
+       }
+
        /* Set contents style of headers view */
        if (folder_empty)  {
                modest_main_window_set_contents_style (main_window,
@@ -1997,19 +2006,6 @@ set_toolbar_mode (ModestMainWindow *self,
                
                if (cancel_action)
                        gtk_action_set_visible (cancel_action, FALSE);
-/*             if (priv->sort_toolitem) */
-/*                     gtk_widget_show (priv->sort_toolitem); */
-               
-/*             if (priv->refresh_toolitem) */
-/*                     gtk_widget_show (priv->refresh_toolitem); */
-                       
-/*             if (priv->progress_toolitem) */
-/*                     gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE); */
-/*             if (priv->progress_bar) */
-/*                     gtk_widget_hide (priv->progress_bar); */
-                       
-/*             if (priv->cancel_toolitem) */
-/*                     gtk_widget_hide (priv->cancel_toolitem); */
 
                /* Hide toolbar if optimized view is enabled */
                if (priv->optimized_view)
@@ -2029,20 +2025,6 @@ set_toolbar_mode (ModestMainWindow *self,
                if (priv->progress_bar)
                        gtk_widget_show (priv->progress_bar);
 
-/*             if (priv->sort_toolitem) */
-/*                     gtk_widget_hide (priv->sort_toolitem); */
-               
-/*             if (priv->refresh_toolitem) */
-/*                     gtk_widget_hide (priv->refresh_toolitem); */
-               
-/*             if (priv->progress_toolitem) */
-/*                     gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); */
-/*             if (priv->progress_bar) */
-/*                     gtk_widget_show (priv->progress_bar); */
-                       
-/*             if (priv->cancel_toolitem) */
-/*                     gtk_widget_show (priv->cancel_toolitem); */
-
                /* Show toolbar if it's hiden (optimized view ) */
                if (priv->optimized_view)
                        gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
@@ -2102,7 +2084,6 @@ on_queue_changed (ModestMailOperationQueue *queue,
        ModestToolBarModes mode;
        GSList *tmp;
        gboolean mode_changed = FALSE;
-/*     ModestMailOperationStatus status; */
 
        g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
@@ -2110,7 +2091,6 @@ on_queue_changed (ModestMailOperationQueue *queue,
        /* Get toolbar mode from operation id*/
        op_type = modest_mail_operation_get_type_operation (mail_op);
        switch (op_type) {
-/*     case MODEST_MAIL_OPERATION_TYPE_SEND: */
        case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
        case MODEST_MAIL_OPERATION_TYPE_OPEN:
                mode = TOOLBAR_MODE_TRANSFER;
@@ -2128,8 +2108,9 @@ on_queue_changed (ModestMailOperationQueue *queue,
        switch (type) {
        case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
                if (mode == TOOLBAR_MODE_TRANSFER) {
-                       if (mode_changed)
+                       if (mode_changed) {
                                set_toolbar_transfer_mode(self);                    
+                       }
                        while (tmp) {
                                modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
                                                                      mail_op);
@@ -2148,8 +2129,7 @@ on_queue_changed (ModestMailOperationQueue *queue,
                        
                        /* If no more operations are being observed, NORMAL mode is enabled again */
                        if (observers_empty (self)) {
-                               set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
-                               
+                               set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);                           
                        }
                }
 
@@ -2158,23 +2138,14 @@ on_queue_changed (ModestMailOperationQueue *queue,
 
 }
 
-static void 
-on_show_account_action_activated  (GtkAction *action,
-                                  gpointer user_data)
+static void
+set_account_visible(ModestMainWindow *self, const gchar *acc_name)
 {
-       ModestAccountData *acc_data;
-       ModestMainWindow *self;
-       ModestMainWindowPrivate *priv;
-       ModestAccountMgr *mgr;
-       const gchar *acc_name;
-
-       self = MODEST_MAIN_WINDOW (user_data);
-       priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
+       ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
 
        /* Get account data */
-       acc_name = gtk_action_get_name (action);
-       mgr = modest_runtime_get_account_mgr ();
-       acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
+       ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
+       ModestAccountData *acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
 
        /* Set the new visible & active account */
        if (acc_data && acc_data->store_account) { 
@@ -2190,6 +2161,41 @@ on_show_account_action_activated  (GtkAction *action,
                modest_account_mgr_free_account_data (mgr, acc_data);
 }
 
+/* Make sure that at least one account is "viewed": */
+static void
+set_at_least_one_account_visible(ModestMainWindow *self)
+{
+       ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
+       ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
+
+       if (!(priv->folder_view)) {
+               /* It is too early to do this. */
+               return; 
+       }
+       
+       const gchar *active_server_account_name = 
+               modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);        
+       if (!active_server_account_name ||
+               !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
+       {
+               gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
+               if (first_modest_name) {
+                       set_account_visible (self, first_modest_name);
+                       g_free (first_modest_name);
+               }
+       }
+}
+
+static void 
+on_show_account_action_activated  (GtkAction *action,
+                                  gpointer user_data)
+{
+       ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
+
+       const gchar *acc_name = gtk_action_get_name (action);
+       set_account_visible (self, acc_name);
+}
+
 static void
 refresh_account (const gchar *account_name)
 {
@@ -2362,8 +2368,8 @@ modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_win
        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 (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
+       g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
        g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
 
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
@@ -2381,3 +2387,4 @@ modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_win
 
        return TRUE;
 }
+