X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmaemo%2Fmodest-main-window.c;h=69fc7d4f355a61eead653553ab8de4f8f177d5c6;hp=009d3254cc9c0104d2ca5591bfa7ce40d5da16f9;hb=4dc1719b3df5a026a74679d7ba6c7dc1fa05ae4d;hpb=119a9504f03dc6f35c5343331e64ba1750227766 diff --git a/src/maemo/modest-main-window.c b/src/maemo/modest-main-window.c index 009d325..69fc7d4 100644 --- a/src/maemo/modest-main-window.c +++ b/src/maemo/modest-main-window.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "modest-hildon-includes.h" #include "modest-defs.h" @@ -539,8 +538,9 @@ static gint compare_display_names (ModestAccountSettings *a, ModestAccountSettings *b) { - return strcmp (modest_account_settings_get_display_name (a), - modest_account_settings_get_display_name (b)); + return g_utf8_collate (modest_account_settings_get_display_name (a), + modest_account_settings_get_display_name (b)); + } /* We use this function to prevent the send&receive CSM to be shown @@ -701,7 +701,7 @@ update_menus (ModestMainWindow* self) /* Add ui from account data. We allow 2^9-1 account changes in a single execution because we're downcasting the guint to a guint8 in order to use a - GByteArray. It should be enough. */ + GByteArray. It should be enough :-) */ item_name = g_strconcat (account_name, "Menu", NULL); merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager); priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1); @@ -760,7 +760,8 @@ update_menus (ModestMainWindow* self) item = gtk_menu_item_new (); gtk_container_add (GTK_CONTAINER (item), label); - gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item)); + gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), + GTK_WIDGET (item)); g_signal_connect_data (G_OBJECT (item), "activate", G_CALLBACK (on_send_receive_csm_activated), @@ -1145,14 +1146,6 @@ modest_main_window_on_show (GtkWidget *self, gpointer user_data) gtk_widget_show_all(GTK_WIDGET(self)); modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self)); } else { - GSList *accounts; - GtkAction *send_receive_all; - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self); - accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE); - send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager, - "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu"); - gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0); - modest_account_mgr_free_account_names (accounts); update_menus (MODEST_MAIN_WINDOW (self)); } @@ -1370,7 +1363,9 @@ modest_main_window_set_style (ModestMainWindow *self, ModestWindowPrivate *parent_priv; GtkAction *action; gboolean active; - + GtkTreeSelection *sel; + GList *rows, *list; + g_return_if_fail (MODEST_IS_MAIN_WINDOW (self)); priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self); @@ -1392,6 +1387,11 @@ modest_main_window_set_style (ModestMainWindow *self, g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self); } + /* We need to store the selection because it's lost when the + widget is reparented */ + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->header_view)); + rows = gtk_tree_selection_get_selected_rows (sel, NULL); + priv->style = style; switch (style) { case MODEST_MAIN_WINDOW_STYLE_SIMPLE: @@ -1420,14 +1420,40 @@ modest_main_window_set_style (ModestMainWindow *self, break; default: + g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); + g_list_free (rows); g_return_if_reached (); } + /* Reselect the previously selected folders. We disable the + dimming rules execution during that time because there is + no need to work out it again and it could take a lot of + time if all the headers are selected */ + list = rows; + modest_window_disable_dimming (MODEST_WINDOW (self)); + while (list) { + gtk_tree_selection_select_path (sel, (GtkTreePath *) list->data); + list = g_list_next (list); + } + modest_window_enable_dimming (MODEST_WINDOW (self)); + + /* Free */ + g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); + g_list_free (rows); + /* Let header view grab the focus if it's being shown */ - if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS) + if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS) { gtk_widget_grab_focus (GTK_WIDGET (priv->header_view)); - else - gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget)); + } else { + if (priv->style == MODEST_MAIN_WINDOW_STYLE_SPLIT) + gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view)); + else + gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget)); + } + + /* Check dimming rules */ + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self)); + modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self)); /* Show changes */ gtk_widget_show_all (GTK_WIDGET (priv->main_vbox)); @@ -1718,8 +1744,45 @@ on_inner_widgets_key_pressed (GtkWidget *widget, } } } - } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right) + } else if (MODEST_IS_FOLDER_VIEW (widget) && (event->keyval == GDK_Right || event->keyval == GDK_Left)) { +#if GTK_CHECK_VERSION(2, 8, 0) /* TODO: gtk_tree_view_get_visible_range() is only available in GTK+ 2.8 */ + GtkTreePath *selected_path = NULL; + GtkTreePath *start_path = NULL; + GtkTreePath *end_path = NULL; + GList *selected; + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->header_view)); + selected = gtk_tree_selection_get_selected_rows (selection, NULL); + if (selected != NULL) { + selected_path = (GtkTreePath *) selected->data; + if (gtk_tree_view_get_visible_range (GTK_TREE_VIEW (priv->header_view), + &start_path, + &end_path)) { + + if ((gtk_tree_path_compare (start_path, selected_path) != -1) || + (gtk_tree_path_compare (end_path, selected_path) != 1)) { + + /* Scroll to first path */ + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->header_view), + selected_path, + NULL, + TRUE, + 0.5, + 0.0); + } + } + if (start_path) + gtk_tree_path_free (start_path); + if (end_path) + gtk_tree_path_free (end_path); + g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL); + g_list_free (selected); + } +#endif /* GTK_CHECK_VERSION */ + /* fix scroll */ gtk_widget_grab_focus (GTK_WIDGET (priv->header_view)); + } return FALSE; } @@ -1790,6 +1853,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 ("%s: %d", markup, name, count); +} + +static gchar * +create_gchar_label (const gchar *markup, + const gchar *name, + gchar *count) +{ + return g_markup_printf_escaped ("%s: %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) { @@ -1799,10 +1931,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) @@ -1857,43 +1992,39 @@ create_details_widget (GtkWidget *styled_widget, TnyAccount *account) /* Message count */ TnyFolderStore *folder_store = TNY_FOLDER_STORE (account); - label = g_markup_printf_escaped ("%s: %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 ("%s: %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 ("%s: %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); @@ -1919,6 +2050,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); @@ -2068,6 +2205,8 @@ modest_main_window_set_contents_style (ModestMainWindow *self, wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view)); modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget), TRUE); + if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) + gtk_widget_grab_focus (GTK_WIDGET (priv->header_view)); break; case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS: { @@ -2087,12 +2226,16 @@ modest_main_window_set_contents_style (ModestMainWindow *self, modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget), FALSE); } + if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) + gtk_widget_grab_focus (GTK_WIDGET (priv->details_widget)); break; } case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY: wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view)); modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget), FALSE); + if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) + gtk_widget_grab_focus (GTK_WIDGET (priv->empty_view)); break; default: g_return_if_reached (); @@ -2756,6 +2899,17 @@ modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_win return TRUE; } +static void +updating_banner_destroyed (gpointer data, + GObject *where_the_object_was) +{ + ModestMainWindowPrivate *priv = NULL; + + priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data); + + priv->updating_banner = NULL; +} + static gboolean show_updating_banner (gpointer user_data) { @@ -2770,6 +2924,13 @@ show_updating_banner (gpointer user_data) priv->updating_banner = modest_platform_animation_banner (GTK_WIDGET (user_data), NULL, _CS ("ckdg_pb_updating")); + + /* We need this because banners in Maemo could be + destroyed by dialogs so we need to properly update + our reference to it */ + g_object_weak_ref (G_OBJECT (priv->updating_banner), + updating_banner_destroyed, + user_data); gdk_threads_leave (); } @@ -2895,6 +3056,17 @@ on_window_destroy (GtkObject *widget, remove_banners (MODEST_MAIN_WINDOW (widget)); } +static void +retrieving_banner_destroyed (gpointer data, + GObject *where_the_object_was) +{ + ModestMainWindowPrivate *priv = NULL; + + priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data); + + priv->retrieving_banner = NULL; +} + static gboolean show_retrieving_banner (gpointer user_data) { @@ -2909,6 +3081,13 @@ show_retrieving_banner (gpointer user_data) priv->retrieving_banner = modest_platform_animation_banner (GTK_WIDGET (user_data), NULL, _("mcen_ib_getting_items")); + + /* We need this because banners in Maemo could be + destroyed by dialogs so we need to properly update + our reference to it */ + g_object_weak_ref (G_OBJECT (priv->retrieving_banner), + retrieving_banner_destroyed, + user_data); gdk_threads_leave (); }