* Fixes a memory read error when closing the windows due to delayed dimming rules...
[modest] / src / maemo / modest-main-window.c
index 0f1379a..4bfc990 100644 (file)
@@ -389,6 +389,16 @@ modest_main_window_finalize (GObject *obj)
           call this function before */
        modest_main_window_disconnect_signals (MODEST_WINDOW (obj));    
        modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
+
+       if (priv->empty_view) {
+               g_object_unref (priv->empty_view);
+               priv->empty_view = NULL;
+       }
+       
+       if (priv->header_view) {
+               g_object_unref (priv->header_view);
+               priv->header_view = NULL;
+       }
        
        g_slist_free (priv->progress_widgets);
 
@@ -1051,13 +1061,6 @@ connect_signals (ModestMainWindow *self)
                                           "account_changed", 
                                           G_CALLBACK (on_account_changed),
                                           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);
 }
 
 static void 
@@ -1098,10 +1101,17 @@ on_hildon_program_is_topmost_notify(GObject *self,
        }       
 }
 
+typedef struct
+{
+       GtkWidget *folder_win;
+       gulong handler_id;
+} ShowHelper;
+
 static void
 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
 {
-       GtkWidget *folder_win = (GtkWidget *) user_data;
+       ShowHelper *helper = (ShowHelper *) user_data;
+       GtkWidget *folder_win = helper->folder_win;
        ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
        
        priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
@@ -1145,6 +1155,12 @@ modest_main_window_on_show (GtkWidget *self, gpointer user_data)
                modest_account_mgr_free_account_names (accounts);
                update_menus (MODEST_MAIN_WINDOW (self));
        }
+
+       /* Never call this function again (NOTE that it could happen
+          as we hide the main window instead of closing it while
+          there are operations ongoing) and free the helper */
+       g_signal_handler_disconnect (self, helper->handler_id);
+       g_slice_free (ShowHelper, helper);
 }
 
 static void 
@@ -1175,6 +1191,7 @@ modest_main_window_new (void)
        ModestConf *conf = NULL;
        GtkAction *action = NULL;
        GdkPixbuf *window_icon;
+       ShowHelper *helper;
        
        self  = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
        priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
@@ -1267,6 +1284,7 @@ modest_main_window_new (void)
        /* header view */
        priv->header_view =
                MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
+       g_object_ref (priv->header_view);
        if (!priv->header_view)
                g_printerr ("modest: cannot instantiate header view\n");
        modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
@@ -1282,6 +1300,7 @@ modest_main_window_new (void)
        /* Empty view */ 
        priv->empty_view = create_empty_view ();
        gtk_widget_show (priv->empty_view);
+       g_object_ref (priv->empty_view);
                 
        /* Create scrolled windows */
        folder_win = gtk_scrolled_window_new (NULL, NULL);
@@ -1313,9 +1332,14 @@ modest_main_window_new (void)
        g_signal_connect (G_OBJECT(app), "notify::is-topmost",
                G_CALLBACK (on_hildon_program_is_topmost_notify), self);
 
-       g_signal_connect (G_OBJECT(self), "show",
-                         G_CALLBACK (modest_main_window_on_show), folder_win);
-               
+       /* Connect to "show" action. We delay the creation of some
+          elements until that moment */
+       helper = g_slice_new0 (ShowHelper);
+       helper->folder_win = folder_win;
+       helper->handler_id = g_signal_connect (G_OBJECT(self), "show",
+                                              G_CALLBACK (modest_main_window_on_show), 
+                                              helper);
+       
        /* Set window icon */
        window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
        if (window_icon) {
@@ -1766,6 +1790,75 @@ create_device_name_visual_string (const gchar *device_name,
        return label;
 }
 
+typedef struct
+{
+       GtkWidget *count_label;
+       GtkWidget *msg_count_label;
+       GtkWidget *size_label;
+       gchar *color_markup;
+} DetailsWidgets;
+
+static gchar *
+create_uint_label (const gchar *markup,
+                  const gchar *name,
+                  guint count)
+{
+       return g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", markup, name, count);
+}
+
+static gchar *
+create_gchar_label (const gchar *markup,
+                   const gchar *name,
+                   gchar *count)
+{
+       return g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", markup, name, count);
+}
+
+static void
+update_folder_stats_status_cb (ModestFolderStats stats,
+                              gpointer user_data)
+{
+       DetailsWidgets *widgets = (DetailsWidgets *) user_data;
+       gchar *label, *tmp;
+
+       label = create_uint_label (widgets->color_markup, _("mcen_fi_rootfolder_folders"), stats.folders);
+       gtk_label_set_markup (GTK_LABEL (widgets->count_label), label);
+       g_free (label);
+
+       label = create_uint_label (widgets->color_markup, _("mcen_fi_rootfolder_messages"), stats.msg_count);
+       gtk_label_set_markup (GTK_LABEL (widgets->msg_count_label), label);
+       g_free (label);
+
+       if (widgets->size_label) {
+               tmp = modest_text_utils_get_display_size (stats.local_size);
+               label = create_gchar_label (widgets->color_markup, _("mcen_fi_rootfolder_size"), tmp);
+               gtk_label_set_markup (GTK_LABEL (widgets->size_label), label);
+               g_free (label);
+               g_free (tmp);
+       }
+}
+
+static void
+update_folder_stats_cb (ModestFolderStats stats,
+                       gpointer user_data)
+{
+       DetailsWidgets *widgets = (DetailsWidgets *) user_data;
+
+       /* refresh data */
+       update_folder_stats_status_cb (stats, user_data);
+
+       /* frees. Note that the widgets could have been destroyed but
+          we still keep a reference */
+       g_free (widgets->color_markup);
+       if (widgets->count_label)
+               g_object_unref (widgets->count_label);
+       if (widgets->msg_count_label)
+               g_object_unref (widgets->msg_count_label);
+       if (widgets->size_label)
+       g_object_unref (widgets->size_label);
+       g_slice_free (DetailsWidgets, widgets);
+}
+
 static GtkWidget *
 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
 {
@@ -1775,10 +1868,13 @@ create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
        GtkWidget *label_w;
        gchar *label;
        gchar *gray_color_markup;
+       DetailsWidgets *widgets;
 
        vbox = gtk_vbox_new (FALSE, 0);
+       widgets = g_slice_new0 (DetailsWidgets);
 
        gray_color_markup = get_gray_color_markup (styled_widget);
+       widgets->color_markup = g_strdup (gray_color_markup);
 
        /* Account description: */
        if (modest_tny_account_is_virtual_local_folders (account)
@@ -1833,43 +1929,39 @@ create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
 
        /* Message count */
        TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
-       label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", 
-                                        gray_color_markup, _("mcen_fi_rootfolder_messages"), 
-                                        modest_tny_folder_store_get_message_count (folder_store));
+       label = create_uint_label (gray_color_markup, _("mcen_fi_rootfolder_messages"), 0);
        label_w = gtk_label_new (NULL);
        gtk_label_set_markup (GTK_LABEL (label_w), label);
        gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
        gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
        g_free (label);
 
+       widgets->msg_count_label = g_object_ref (label_w);
+
        /* Folder count */
-       label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d", 
-                                        gray_color_markup, 
-                                        _("mcen_fi_rootfolder_folders"), 
-                                        modest_tny_folder_store_get_folder_count (folder_store));
+       label = create_uint_label (gray_color_markup, _("mcen_fi_rootfolder_folders"), 0);
        label_w = gtk_label_new (NULL);
        gtk_label_set_markup (GTK_LABEL (label_w), label);
        gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
        gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
        g_free (label);
 
+       widgets->count_label = g_object_ref (label_w);
+
        /* Size / Date */
        if (modest_tny_account_is_virtual_local_folders (account)
                || modest_tny_account_is_memory_card_account (account)) {
 
-               gchar *size = modest_text_utils_get_display_size (
-                       modest_tny_folder_store_get_local_size (folder_store));
-               
-               label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s", 
-                                                gray_color_markup, _("mcen_fi_rootfolder_size"),
-                                                size);
-               g_free (size);
+               label = create_gchar_label (gray_color_markup, _("mcen_fi_rootfolder_size"), "0");
                
                label_w = gtk_label_new (NULL);
                gtk_label_set_markup (GTK_LABEL (label_w), label);
                gtk_label_set_ellipsize (GTK_LABEL (label_w),  PANGO_ELLIPSIZE_END);
                gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
                g_free (label);
+
+               widgets->size_label = g_object_ref (label_w);
+
        } else if (TNY_IS_ACCOUNT(folder_store)) {
                TnyAccount *account = TNY_ACCOUNT(folder_store);
                
@@ -1895,6 +1987,12 @@ create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
 
        g_free (gray_color_markup);
 
+       /* Refresh folder stats asynchronously */
+       modest_tny_folder_store_get_folder_stats (TNY_FOLDER_STORE (account),
+                                                 update_folder_stats_cb,
+                                                 update_folder_stats_status_cb,
+                                                 widgets);
+
        /* Set alignment */
        gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
 
@@ -2030,10 +2128,7 @@ modest_main_window_set_contents_style (ModestMainWindow *self,
           details widget */
        GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
        if (content) {
-               if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
-                       g_object_ref (content);
-               else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
-                       g_object_ref (priv->empty_view);
+               if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
                        gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
                }
                
@@ -2502,7 +2597,9 @@ set_account_visible(ModestMainWindow *self, const gchar *acc_name)
                modest_folder_view_set_account_id_of_visible_server_account 
                        (priv->folder_view,
                         modest_server_account_settings_get_account_name (store_settings));
+               modest_folder_view_select_first_inbox_or_local (priv->folder_view);
                modest_window_set_active_account (MODEST_WINDOW (self), account_name);
+
                action = gtk_action_group_get_action (priv->view_additions_group, account_name);
                if (action != NULL) {
                        if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
@@ -2513,9 +2610,6 @@ set_account_visible(ModestMainWindow *self, const gchar *acc_name)
                }
        }
        
-       modest_folder_view_select_first_inbox_or_local (priv->folder_view);
-
-
        /* Free */
        if (settings) {
                g_object_unref (store_settings);
@@ -2861,6 +2955,7 @@ on_window_hide (GObject    *gobject,
                                                         mail_op);
                        modest_mail_operation_sync_folder (mail_op, TNY_FOLDER (folder_store), FALSE);
                        g_object_unref (mail_op);
+                       g_object_unref (folder_store);
                }
        }
 }