From: Javier Fernandez Garcia-Boente Date: Wed, 8 Aug 2007 09:37:32 +0000 (+0000) Subject: * Implement optimizations on DimmingRules management. X-Git-Tag: git_migration_finished~2616 X-Git-Url: http://git.maemo.org/git/?p=modest;a=commitdiff_plain;h=fd3801d4e2aa9fcdf8baa83a4fee2e7da4b7bb1b * Implement optimizations on DimmingRules management. * Copy/Cut/Paste dimming rules of Editor are not working fine; it does not take into account if something was selected or not. These changes on src/maemo/modest-msg-edit-window.c try to solve these problems, with no success at this moment. * Fixes: NB#64553 pmo-trunk-r2947 --- diff --git a/src/maemo/modest-msg-edit-window.c b/src/maemo/modest-msg-edit-window.c index 0830961..880c855 100644 --- a/src/maemo/modest-msg-edit-window.c +++ b/src/maemo/modest-msg-edit-window.c @@ -138,6 +138,7 @@ static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboa static void update_window_title (ModestMsgEditWindow *window); static void update_dimmed (ModestMsgEditWindow *window); static void update_paste_dimming (ModestMsgEditWindow *window); +static void update_copy_cut_dimming (ModestMsgEditWindow *window); static void update_select_all_dimming (ModestMsgEditWindow *window); static void update_zoom_dimming (ModestMsgEditWindow *window); @@ -2772,8 +2773,6 @@ modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard, ModestWindowPrivate *parent_priv; ModestMsgEditWindowPrivate *priv; GtkAction *action; - gboolean has_selection; - GtkWidget *focused; GList *selected_attachments = NULL; gint n_att_selected = 0; @@ -2782,13 +2781,6 @@ modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard, if (!GTK_WIDGET_VISIBLE (window)) return; - has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL); - focused = gtk_window_get_focus (GTK_WINDOW (window)); - - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu"); - gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused))); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu"); - gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused))); selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)); n_att_selected = g_list_length (selected_attachments); @@ -2797,6 +2789,7 @@ modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard, action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu"); gtk_action_set_sensitive (action, n_att_selected == 1); + update_copy_cut_dimming (window); update_paste_dimming (window); } @@ -3030,6 +3023,43 @@ modest_msg_edit_window_find_toolbar_close (GtkWidget *widget, static void +update_copy_cut_dimming (ModestMsgEditWindow *window) +{ + ModestWindowPrivate *parent_priv = NULL; + ModestMsgEditWindowPrivate *priv = NULL; + GtkClipboard *clipboard = NULL; + GtkAction *action = NULL; + gboolean has_selection = FALSE; + GtkWidget *focused = NULL; + gchar *selection = NULL; + guint i, j; + + priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); + parent_priv = MODEST_WINDOW_GET_PRIVATE (window); + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + focused = gtk_window_get_focus (GTK_WINDOW (window)); + + + if (GTK_IS_EDITABLE (focused)) { + gtk_editable_get_selection_bounds (GTK_EDITABLE (focused), + &i, &j); + + has_selection = i!= 0 && j != 0; + } + +/* has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL); */ +/* has_selection = selection != NULL; */ + + action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu"); + gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused))); + action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu"); + gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused))); + + if (selection != NULL) + g_free(selection); +} + +static void update_paste_dimming (ModestMsgEditWindow *window) { ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window); @@ -3103,6 +3133,7 @@ edit_menu_activated (GtkAction *action, ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata); update_select_all_dimming (window); + update_copy_cut_dimming (window); update_paste_dimming (window); } static void diff --git a/src/maemo/modest-progress-bar-widget.c b/src/maemo/modest-progress-bar-widget.c index b699351..161a4ad 100644 --- a/src/maemo/modest-progress-bar-widget.c +++ b/src/maemo/modest-progress-bar-widget.c @@ -237,14 +237,14 @@ modest_progress_bar_add_operation (ModestProgressObject *self, G_CALLBACK (on_progress_changed), me); /* Set curent operation */ -/* if (priv->current == NULL) { */ - priv->current = mail_op; - - priv->count = 0; - - /* Call progress_change handler to initialize progress message */ - modest_progress_bar_widget_set_undetermined_progress (MODEST_PROGRESS_BAR_WIDGET(self), mail_op); -/* } */ + if (priv->current == NULL) { + priv->current = mail_op; + + priv->count = 0; + + /* Call progress_change handler to initialize progress message */ + modest_progress_bar_widget_set_undetermined_progress (MODEST_PROGRESS_BAR_WIDGET(self), mail_op); + } /* Add operation to obserbable objects list */ priv->observables = g_slist_prepend (priv->observables, data); diff --git a/src/modest-dimming-rules-group.c b/src/modest-dimming-rules-group.c index af23b00..4d9e05a 100644 --- a/src/modest-dimming-rules-group.c +++ b/src/modest-dimming-rules-group.c @@ -31,6 +31,7 @@ #include "modest-dimming-rules-group-priv.h" #include "modest-dimming-rule.h" #include "modest-platform.h" +#include "modest-ui-dimming-rules.h" static void modest_dimming_rules_group_class_init (ModestDimmingRulesGroupClass *klass); static void modest_dimming_rules_group_init (ModestDimmingRulesGroup *obj); @@ -41,6 +42,7 @@ static void _insensitive_press_callback (GtkWidget *widget, gpointer user_data); typedef struct _ModestDimmingRulesGroupPrivate ModestDimmingRulesGroupPrivate; struct _ModestDimmingRulesGroupPrivate { + ModestWindow *window; gchar *name; gboolean notifications_enabled; GHashTable *rules_map; @@ -103,6 +105,8 @@ modest_dimming_rules_group_init (ModestDimmingRulesGroup *obj) priv = MODEST_DIMMING_RULES_GROUP_GET_PRIVATE(obj); priv->name = NULL; + priv->window = NULL; + priv->notifications_enabled = FALSE; priv->rules_map = g_hash_table_new_full ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal, (GDestroyNotify) g_free, @@ -177,6 +181,10 @@ modest_dimming_rules_group_add_rules (ModestDimmingRulesGroup *self, priv = MODEST_DIMMING_RULES_GROUP_GET_PRIVATE(self); + /* Set window to process dimming rules */ + priv->window = MODEST_WINDOW (user_data); + + /* Add dimming rules */ for (i=0; i < n_elements; i++) { entry = modest_dimming_entries[i]; @@ -193,7 +201,7 @@ modest_dimming_rules_group_add_rules (ModestDimmingRulesGroup *self, if (widget == NULL) continue; /* Create a new dimming rule */ - dim_rule = modest_dimming_rule_new (MODEST_WINDOW(user_data), + dim_rule = modest_dimming_rule_new (priv->window, (ModestDimmingCallback) entry.callback, entry.action_path); @@ -223,11 +231,20 @@ void modest_dimming_rules_group_execute (ModestDimmingRulesGroup *self) { ModestDimmingRulesGroupPrivate *priv; + DimmedState *state = NULL; g_return_if_fail (MODEST_IS_DIMMING_RULES_GROUP(self)); priv = MODEST_DIMMING_RULES_GROUP_GET_PRIVATE(self); + /* Init dimming rules init data */ + state = modest_ui_dimming_rules_define_dimming_state (priv->window); + modest_window_set_dimming_state (priv->window, state); + + /* execute group dimming rules */ g_hash_table_foreach (priv->rules_map, _execute_dimming_rule, NULL); + + /* Free dimming ruls init data */ + modest_window_set_dimming_state (priv->window, NULL); } diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 1345131..1ebd006 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -73,7 +73,7 @@ static void modest_mail_operation_finalize (GObject *obj); static void get_msg_cb (TnyFolder *folder, gboolean cancelled, TnyMsg *msg, - GError *err, + GError *rr, gpointer user_data); static void get_msg_status_cb (GObject *obj, @@ -1362,7 +1362,6 @@ update_account_thread (gpointer thr_user_data) goto out; /* Perform send (if operation was not cancelled) */ -/* priv->op_type = MODEST_MAIL_OPERATION_TYPE_SEND; */ priv->done = 0; priv->total = 0; if (priv->account != NULL) @@ -1371,9 +1370,7 @@ update_account_thread (gpointer thr_user_data) send_queue = modest_runtime_get_send_queue (info->transport_account); if (send_queue) { -/* timeout = g_timeout_add (250, idle_notify_progress, info->mail_op); */ modest_tny_send_queue_try_to_send (send_queue); -/* g_source_remove (timeout); */ } else { g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED, @@ -2593,6 +2590,8 @@ on_refresh_folder (TnyFolder *folder, if (error) { priv->error = g_error_copy (error); priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + printf("DEBUG: %s: Operation error:\n %s", __FUNCTION__, + error->message); goto out; } @@ -2602,11 +2601,12 @@ on_refresh_folder (TnyFolder *folder, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, _("Error trying to refresh the contents of %s"), tny_folder_get_name (folder)); + printf("DEBUG: %s: Operation cancelled.\n", __FUNCTION__); goto out; } priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; - out: + /* Call user defined callback, if it exists */ if (helper->user_callback) { @@ -2618,6 +2618,7 @@ on_refresh_folder (TnyFolder *folder, /* no gdk_threads_leave (), CHECKED */ } + out: /* Free */ g_slice_free (RefreshAsyncHelper, helper); diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index a1bf3f0..0debad3 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -4097,13 +4097,9 @@ modest_ui_actions_on_email_menu_activated (GtkAction *action, ModestWindow *window) { g_return_if_fail (MODEST_IS_WINDOW (window)); - - /* Init dimming rules init data */ /* Update dimmed */ modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules"); - - /* Free dimming ruls init data */ } void diff --git a/src/modest-ui-dimming-rules.c b/src/modest-ui-dimming-rules.c index c115653..c88ff13 100644 --- a/src/modest-ui-dimming-rules.c +++ b/src/modest-ui-dimming-rules.c @@ -50,8 +50,8 @@ static gboolean _invalid_attach_selected (ModestWindow *win, static gboolean _purged_attach_selected (ModestWindow *win, gboolean all, ModestDimmingRule *rule); static gboolean _clipboard_is_empty (ModestWindow *win); static gboolean _invalid_clipboard_selected (ModestWindow *win, ModestDimmingRule *rule); -static gboolean _already_opened_msg (ModestWindow *win, guint *n_messages); -static gboolean _selected_msg_marked_as (ModestMainWindow *win, TnyHeaderFlags mask, gboolean opposite, gboolean all); +/* static gboolean _already_opened_msg (ModestWindow *win, guint *n_messages); */ +/* static gboolean _selected_msg_marked_as (ModestMainWindow *win, TnyHeaderFlags mask, gboolean opposite, gboolean all); */ static gboolean _selected_folder_not_writeable (ModestMainWindow *win); static gboolean _selected_folder_is_snd_level (ModestMainWindow *win); static gboolean _selected_folder_is_any_of_type (ModestWindow *win, TnyFolderType types[], guint ntypes); @@ -64,11 +64,217 @@ static gboolean _msg_download_in_progress (ModestMsgViewWindow *win); static gboolean _msg_download_completed (ModestMainWindow *win); static gboolean _selected_msg_sent_in_progress (ModestWindow *win); static gboolean _sending_in_progress (ModestWindow *win); -static gboolean _message_is_marked_as_deleted (ModestMsgViewWindow *win); -static gboolean _selected_message_is_marked_as_deleted (ModestMainWindow *win); +/* static gboolean _message_is_marked_as_deleted (ModestMsgViewWindow *win); */ +/* static gboolean _selected_message_is_marked_as_deleted (ModestMainWindow *win); */ static gboolean _invalid_folder_for_purge (ModestWindow *win, ModestDimmingRule *rule); static gboolean _transfer_mode_enabled (ModestWindow *win); +static void fill_list_of_caches (gpointer key, gpointer value, gpointer userdata); + + +static DimmedState * +_define_main_window_dimming_state (ModestMainWindow *window) +{ + DimmedState *state = NULL; + GtkWidget *header_view = NULL; + TnyList *selected_headers = NULL; + TnyIterator *iter = NULL; + TnyHeader *header = NULL; + ModestCacheMgr *cache_mgr = NULL; + GHashTable *send_queue_cache = NULL; + ModestTnySendQueue *send_queue = NULL; + GSList *send_queues = NULL, *node = NULL; + ModestWindowMgr *mgr = NULL; + gboolean found = FALSE; + gchar *msg_uid = NULL; + TnyHeaderFlags flags; + + g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(window), NULL); + + /* Init state */ + state = g_slice_new0 (DimmedState); + state->n_selected = 0; + state->already_opened_msg = FALSE; + state->any_marked_as_deleted = FALSE; + state->all_marked_as_deleted = FALSE; + state->any_marked_as_seen = FALSE; + state->all_marked_as_seen = FALSE; + state->any_marked_as_cached = FALSE; + state->all_marked_as_cached = FALSE; + state->any_has_attachments = FALSE; + state->all_has_attachments = FALSE; + state->sent_in_progress = FALSE; + + /* Get header view and selected headers */ + header_view = modest_main_window_get_child_widget (window, MODEST_WIDGET_TYPE_HEADER_VIEW); + selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view)); + if (!selected_headers) + return state; + + /* Examine selected headers */ + iter = tny_list_create_iterator (selected_headers); + while (!tny_iterator_is_done (iter)) { + header = TNY_HEADER (tny_iterator_get_current (iter)); + flags = tny_header_get_flags (header); + + /* No selected */ + state->n_selected++; + + /* Already opened */ + mgr = modest_runtime_get_window_mgr (); + if (!state->already_opened_msg) + state->already_opened_msg = modest_window_mgr_find_registered_header (mgr, header, NULL); + + /* Mark as deleted */ + state->any_marked_as_deleted &= flags & TNY_HEADER_FLAG_DELETED; + if (!state->any_marked_as_deleted) + state->any_marked_as_deleted = flags & TNY_HEADER_FLAG_DELETED; + + /* Mark as seen */ + state->any_marked_as_seen &= flags & TNY_HEADER_FLAG_SEEN; + if (!state->any_marked_as_seen) + state->any_marked_as_seen = flags & TNY_HEADER_FLAG_SEEN; + + /* Mark as cached */ + state->any_marked_as_cached &= flags & TNY_HEADER_FLAG_CACHED; + if (!state->any_marked_as_cached) + state->any_marked_as_cached = flags & TNY_HEADER_FLAG_CACHED; + + /* Mark has_attachments */ + state->any_has_attachments &= flags & TNY_HEADER_FLAG_ATTACHMENTS; + if (!state->any_has_attachments) + state->any_has_attachments = flags & TNY_HEADER_FLAG_ATTACHMENTS; + + /* sent in progress */ + msg_uid = modest_tny_send_queue_get_msg_id (header); + if (!state->sent_in_progress) { + cache_mgr = modest_runtime_get_cache_mgr (); + send_queue_cache = modest_cache_mgr_get_cache (cache_mgr, + MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE); + + g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues); + + for (node = send_queues; node != NULL && !found; node = g_slist_next (node)) { + send_queue = MODEST_TNY_SEND_QUEUE (node->data); + + /* Check if msg uid is being processed inside send queue */ + found = modest_tny_send_queue_msg_is_being_sent (send_queue, msg_uid); + } + state->sent_in_progress = found; + } + + tny_iterator_next (iter); + g_object_unref (header); + } + + /* Free */ + g_free(msg_uid); + g_object_unref(selected_headers); + g_object_unref(iter); + g_slist_free (send_queues); + + return state; +} + +static DimmedState * +_define_msg_view_window_dimming_state (ModestMsgViewWindow *window) +{ + DimmedState *state = NULL; + TnyHeader *header = NULL; + ModestCacheMgr *cache_mgr = NULL; + GHashTable *send_queue_cache = NULL; + ModestTnySendQueue *send_queue = NULL; + GSList *send_queues = NULL, *node = NULL; + gboolean found = FALSE; + gchar *msg_uid = NULL; + TnyHeaderFlags flags; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(window), NULL); + + /* Init state */ + state = g_slice_new0 (DimmedState); + state->n_selected = 0; + state->already_opened_msg = FALSE; + state->any_marked_as_deleted = FALSE; + state->all_marked_as_deleted = FALSE; + state->any_marked_as_seen = FALSE; + state->all_marked_as_seen = FALSE; + state->any_marked_as_cached = FALSE; + state->all_marked_as_cached = FALSE; + state->any_has_attachments = FALSE; + state->all_has_attachments = FALSE; + state->sent_in_progress = FALSE; + + header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(window)); + g_return_val_if_fail (TNY_IS_HEADER(header), state); + flags = tny_header_get_flags (header); + + /* Selected */ + state->n_selected++; + + /* Mark as deleted */ + state->any_marked_as_deleted &= flags & TNY_HEADER_FLAG_DELETED; + if (!state->any_marked_as_deleted) + state->any_marked_as_deleted = flags & TNY_HEADER_FLAG_DELETED; + + /* Mark as seen */ + state->any_marked_as_seen &= flags & TNY_HEADER_FLAG_SEEN; + if (!state->any_marked_as_seen) + state->any_marked_as_seen = flags & TNY_HEADER_FLAG_SEEN; + + /* Mark as cached */ + state->any_marked_as_cached &= flags & TNY_HEADER_FLAG_CACHED; + if (!state->any_marked_as_cached) + state->any_marked_as_cached = flags & TNY_HEADER_FLAG_CACHED; + + /* Mark has_attachments */ + state->any_has_attachments &= flags & TNY_HEADER_FLAG_ATTACHMENTS; + if (!state->any_has_attachments) + state->any_has_attachments = flags & TNY_HEADER_FLAG_ATTACHMENTS; + + /* sent in progress */ + msg_uid = modest_tny_send_queue_get_msg_id (header); + if (!state->sent_in_progress) { + cache_mgr = modest_runtime_get_cache_mgr (); + send_queue_cache = modest_cache_mgr_get_cache (cache_mgr, + MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE); + + g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues); + + for (node = send_queues; node != NULL && !found; node = g_slist_next (node)) { + send_queue = MODEST_TNY_SEND_QUEUE (node->data); + + /* Check if msg uid is being processed inside send queue */ + found = modest_tny_send_queue_msg_is_being_sent (send_queue, msg_uid); + } + state->sent_in_progress = found; + } + + /* Free */ + g_free(msg_uid); + g_object_unref (header); + g_slist_free (send_queues); + + return state; +} + + +DimmedState * +modest_ui_dimming_rules_define_dimming_state (ModestWindow *window) +{ + DimmedState *state = NULL; + + g_return_val_if_fail (MODEST_IS_WINDOW(window), NULL); + + if (MODEST_IS_MAIN_WINDOW (window)) + state = _define_main_window_dimming_state (MODEST_MAIN_WINDOW(window)); + else if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + state = _define_msg_view_window_dimming_state (MODEST_MSG_VIEW_WINDOW(window)); + } + + return state; +} + gboolean modest_ui_dimming_rules_on_new_msg (ModestWindow *win, gpointer user_data) @@ -322,17 +528,19 @@ modest_ui_dimming_rules_on_open_msg (ModestWindow *win, gpointer user_data) { ModestDimmingRule *rule = NULL; gboolean dimmed = FALSE; + const DimmedState *state = NULL; g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE); g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE); rule = MODEST_DIMMING_RULE (user_data); - + state = modest_window_get_dimming_state (win); + /* Check dimmed rule */ if (!dimmed) { dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data); } if (!dimmed) { - dimmed = _selected_message_is_marked_as_deleted (MODEST_MAIN_WINDOW (win)); + dimmed = state->any_marked_as_deleted; if (dimmed) modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted")); } @@ -439,10 +647,12 @@ modest_ui_dimming_rules_on_delete_msg (ModestWindow *win, gpointer user_data) { ModestDimmingRule *rule = NULL; guint n_messages = 0; + const DimmedState *state = NULL; gboolean dimmed = FALSE; g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE); rule = MODEST_DIMMING_RULE (user_data); + state = modest_window_get_dimming_state (win); /* Check dimmed rule */ if (MODEST_IS_MAIN_WINDOW (win)) { @@ -455,24 +665,25 @@ modest_ui_dimming_rules_on_delete_msg (ModestWindow *win, gpointer user_data) dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data); } if (!dimmed) { - dimmed = _already_opened_msg (win, &n_messages); + dimmed = state->already_opened_msg; + n_messages = state->n_selected; if (dimmed) { gchar *num = g_strdup_printf ("%d", n_messages); gchar *message = g_strdup_printf(_("mcen_nc_unable_to_delete_n_messages"), num); -/* modest_dimming_rule_set_notification (rule, _("mcen_nc_unable_to_delete_n_messages")); */ modest_dimming_rule_set_notification (rule, message); g_free(message); g_free(num); } + } if (!dimmed) { - dimmed = _selected_message_is_marked_as_deleted (MODEST_MAIN_WINDOW (win)); + dimmed = state->any_marked_as_deleted; if (dimmed) { modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted")); } } if (!dimmed) { - dimmed = _selected_msg_sent_in_progress (win); + dimmed = state->sent_in_progress; if (dimmed) modest_dimming_rule_set_notification (rule, _CS("ckct_ib_unable_to_delete")); } @@ -484,7 +695,7 @@ modest_ui_dimming_rules_on_delete_msg (ModestWindow *win, gpointer user_data) modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading")); } if (!dimmed) { - dimmed = _message_is_marked_as_deleted (MODEST_MSG_VIEW_WINDOW (win)); + dimmed = state->any_marked_as_deleted; if (dimmed) modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted")); } @@ -572,11 +783,13 @@ modest_ui_dimming_rules_on_mark_as_read_msg (ModestWindow *win, gpointer user_da { ModestDimmingRule *rule = NULL; TnyHeaderFlags flags; + const DimmedState *state = NULL; gboolean dimmed = FALSE; g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE); g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE); rule = MODEST_DIMMING_RULE (user_data); + state = modest_window_get_dimming_state (win); flags = TNY_HEADER_FLAG_SEEN; @@ -585,7 +798,7 @@ modest_ui_dimming_rules_on_mark_as_read_msg (ModestWindow *win, gpointer user_da dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data); } if (!dimmed) { - dimmed = _selected_msg_marked_as (MODEST_MAIN_WINDOW(win), flags, FALSE, TRUE); + dimmed = state->all_marked_as_seen; if (dimmed) modest_dimming_rule_set_notification (rule, ""); } @@ -598,11 +811,13 @@ modest_ui_dimming_rules_on_mark_as_unread_msg (ModestWindow *win, gpointer user_ { ModestDimmingRule *rule = NULL; TnyHeaderFlags flags; + const DimmedState *state = NULL; gboolean dimmed = FALSE; g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE); g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE); rule = MODEST_DIMMING_RULE (user_data); + state = modest_window_get_dimming_state (win); flags = TNY_HEADER_FLAG_SEEN; @@ -610,7 +825,7 @@ modest_ui_dimming_rules_on_mark_as_unread_msg (ModestWindow *win, gpointer user_ if (!dimmed) dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data); if (!dimmed) { - dimmed = _selected_msg_marked_as (MODEST_MAIN_WINDOW(win), flags, TRUE, TRUE); + dimmed = !state->any_marked_as_seen; if (dimmed) modest_dimming_rule_set_notification (rule, ""); } @@ -640,22 +855,20 @@ gboolean modest_ui_dimming_rules_on_main_window_move_to (ModestWindow *win, gpointer user_data) { GtkWidget *folder_view = NULL; - GtkWidget *header_view = NULL; ModestDimmingRule *rule = NULL; guint n_messages = 0; + const DimmedState *state = NULL; gboolean dimmed = FALSE; g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE); g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE); rule = MODEST_DIMMING_RULE (user_data); + state = modest_window_get_dimming_state (win); /* Get the folder view */ folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win), MODEST_WIDGET_TYPE_FOLDER_VIEW); - /* Get header view */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win), - MODEST_WIDGET_TYPE_HEADER_VIEW); /* Check diming rules for folders transfer */ if (gtk_widget_is_focus (folder_view)) { @@ -682,7 +895,8 @@ modest_ui_dimming_rules_on_main_window_move_to (ModestWindow *win, gpointer user /* Check diming rules for messages transfer */ if (!dimmed) { - dimmed = _already_opened_msg (win, &n_messages); + dimmed = state->already_opened_msg; + n_messages = state->n_selected; if (dimmed) { gchar *message = g_strdup_printf(_("emev_bd_unabletomove_items"), n_messages); modest_dimming_rule_set_notification (rule, message); @@ -858,11 +1072,13 @@ gboolean modest_ui_dimming_rules_on_remove_attachments (ModestWindow *win, gpointer user_data) { ModestDimmingRule *rule = NULL; + const DimmedState *state = NULL; gboolean dimmed = FALSE; g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE); g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE); rule = MODEST_DIMMING_RULE (user_data); + state = modest_window_get_dimming_state (win); /* Check in main window if there's only one message selected */ if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) { @@ -883,7 +1099,7 @@ modest_ui_dimming_rules_on_remove_attachments (ModestWindow *win, gpointer user_ /* Check if the selected message in main window has attachments */ if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) { - dimmed = _selected_msg_marked_as (MODEST_MAIN_WINDOW(win), TNY_HEADER_FLAG_ATTACHMENTS, TRUE, FALSE); + dimmed = state->any_has_attachments; if (dimmed) modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments")); } @@ -1053,17 +1269,20 @@ modest_ui_dimming_rules_on_cancel_sending (ModestWindow *win, gpointer user_data ModestDimmingRule *rule = NULL; TnyFolderType types[1]; guint n_messages = 0; + const DimmedState *state = NULL; gboolean dimmed = FALSE; g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE); g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE); rule = MODEST_DIMMING_RULE (user_data); + state = modest_window_get_dimming_state (win); types[0] = TNY_FOLDER_TYPE_OUTBOX; /* Check dimmed rules */ if (!dimmed) { - dimmed = _already_opened_msg (win, &n_messages); + dimmed = state->already_opened_msg; + n_messages = state->n_selected; if (dimmed) modest_dimming_rule_set_notification (rule, _("mcen_ib_message_unableto_cancel_send")); } @@ -1124,39 +1343,6 @@ modest_ui_dimming_rules_on_add_to_contacts (ModestWindow *win, gpointer user_dat /* *********************** static utility functions ******************** */ -/* Returns whether the selected message is marked as deleted. */ -static gboolean -_message_is_marked_as_deleted (ModestMsgViewWindow *win) -{ - g_return_val_if_fail (win, FALSE); - g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE); - - TnyHeader* header = modest_msg_view_window_get_header (win); - if (!header) - return FALSE; - - return (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED); -} - - - -/* Returns whether the selected message is marked as deleted. - * @param win The main window, or NULL if you want this function - * to discover the main window itself, which is marginally less - * efficient. */ -static gboolean -_selected_message_is_marked_as_deleted (ModestMainWindow *win) -{ - gboolean result = FALSE; - TnyHeaderFlags flags; - - flags = TNY_HEADER_FLAG_DELETED; - - /* Check dimmed rule */ - result = _selected_msg_marked_as (win, flags, FALSE, FALSE); - - return result; -} static gboolean _selected_folder_not_writeable (ModestMainWindow *win) @@ -1496,8 +1682,12 @@ static gboolean _invalid_clipboard_selected (ModestWindow *win, ModestDimmingRule *rule) { + const DimmedState *state = NULL; gboolean result = FALSE; + g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE); + state = modest_window_get_dimming_state (win); + if (MODEST_IS_MSG_VIEW_WINDOW (win)) { GtkClipboard *clipboard = NULL; gchar *selection = NULL; @@ -1516,16 +1706,13 @@ _invalid_clipboard_selected (ModestWindow *win, if (result) modest_dimming_rule_set_notification (rule, ""); + + if (selection != NULL) + g_free(selection); } else if (MODEST_IS_MAIN_WINDOW (win)) { - GtkWidget *header_view = NULL; - - /* Get header view to check selected messages */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win), - MODEST_WIDGET_TYPE_HEADER_VIEW); - /* Check dimming */ - result = !modest_header_view_has_selected_headers (MODEST_HEADER_VIEW(header_view)); + result = state->n_selected == 0; if (result) modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected")); } @@ -1546,12 +1733,16 @@ _invalid_attach_selected (ModestWindow *win, TnyHeaderFlags flags; gboolean nested_attachments = FALSE; gboolean selected_messages = FALSE; + const DimmedState *state = NULL; gboolean result = FALSE; + g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE); + state = modest_window_get_dimming_state (win); + if (MODEST_IS_MAIN_WINDOW (win)) { flags = TNY_HEADER_FLAG_ATTACHMENTS; if (!result) - result = _selected_msg_marked_as (MODEST_MAIN_WINDOW (win), flags, TRUE, FALSE); + result = !state->any_has_attachments; } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) { @@ -1656,34 +1847,27 @@ _invalid_msg_selected (ModestMainWindow *win, gboolean unique, ModestDimmingRule *rule) { - GtkWidget *header_view = NULL; GtkWidget *folder_view = NULL; - gboolean selected_headers = FALSE; + const DimmedState *state = NULL; gboolean result = FALSE; g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE); g_return_val_if_fail (MODEST_IS_DIMMING_RULE (rule), FALSE); + state = modest_window_get_dimming_state (MODEST_WINDOW(win)); - /* Get header view to check selected messages */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win), - MODEST_WIDGET_TYPE_HEADER_VIEW); - /* Get folder view to check focus */ folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), MODEST_WIDGET_TYPE_FOLDER_VIEW); - /* Get selected headers */ - selected_headers = modest_header_view_has_selected_headers (MODEST_HEADER_VIEW(header_view)); - /* Check dimmed rule (TODO: check focus on widgets */ if (!result) { - result = ((!selected_headers) || + result = ((state->n_selected == 0 ) || (gtk_widget_is_focus (folder_view))); if (result) modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected")); } if (!result && unique) { - result = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW(header_view)) > 1; + result = state->n_selected > 1; if (result) modest_dimming_rule_set_notification (rule, _("mcen_ib_select_one_message")); } @@ -1691,136 +1875,6 @@ _invalid_msg_selected (ModestMainWindow *win, return result; } -static gboolean -_already_opened_msg (ModestWindow *win, - guint *n_messages) -{ - //ModestWindow *window = NULL; - ModestWindowMgr *mgr = NULL; - GtkWidget *header_view = NULL; - TnyList *selected_headers = NULL; - TnyIterator *iter = NULL; - TnyHeader *header = NULL; - gboolean found; - - g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE); - - /* Get header view to check selected messages */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win), - MODEST_WIDGET_TYPE_HEADER_VIEW); - - - /* Check no selection */ - if (!modest_header_view_has_selected_headers (MODEST_HEADER_VIEW(header_view))) - return FALSE; - - /* Get selected headers */ - selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view)); - if (selected_headers == NULL) - return FALSE; - - *n_messages = tny_list_get_length (selected_headers); - - /* Check dimmed rule (TODO: check focus on widgets */ - mgr = modest_runtime_get_window_mgr (); - iter = tny_list_create_iterator (selected_headers); - found = FALSE; - while (!tny_iterator_is_done (iter)) { - header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - found = modest_window_mgr_find_registered_header (mgr,header, NULL); - - g_object_unref (header); - } - - tny_iterator_next (iter); - - if (found) - break; - } - - /* free */ - if (selected_headers != NULL) - g_object_unref (selected_headers); - if (iter != NULL) - g_object_unref (iter); - - return found; -} - -/* Returns whether the selected message has these flags. - * @win: The main window, or NULL if you want this function - * to discover the main window itself. - */ -static gboolean -_selected_msg_marked_as (ModestMainWindow *win, - TnyHeaderFlags mask, - gboolean opposite, - gboolean all) -{ - ModestMainWindow *main_window = NULL; - GtkWidget *header_view = NULL; - TnyList *selected_headers = NULL; - TnyIterator *iter = NULL; - TnyHeader *header = NULL; - TnyHeaderFlags flags = 0; - gboolean result = TRUE; - - /* The caller can supply the main window if it knows it, - * to save time, or we can get it here: */ - if (win && MODEST_IS_MAIN_WINDOW (win)) - main_window = win; - else { - main_window = MODEST_MAIN_WINDOW ( - modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ())); - } - - /* TODO: Javi, what about if the main window does not - exist?. Adding some code to avoid CRITICALs */ - if (!main_window) - return FALSE; - - /* Get header view to check selected messages */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(main_window), - MODEST_WIDGET_TYPE_HEADER_VIEW); - - /* Check no selection */ - if (!modest_header_view_has_selected_headers (MODEST_HEADER_VIEW(header_view))) - return TRUE; - - /* Get selected headers */ - selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view)); - if (selected_headers == NULL) - return TRUE; - - /* Call the function for each header */ - iter = tny_list_create_iterator (selected_headers); - while (!tny_iterator_is_done (iter) && result) { - header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - flags = tny_header_get_flags (header); - if (opposite) - result = (flags & mask) == 0; - else - result = (flags & mask) != 0; - - g_object_unref (header); - } - - tny_iterator_next (iter); - } - - if (all) - result = result && tny_iterator_is_done (iter); - - /* free */ - if (selected_headers != NULL) - g_object_unref (selected_headers); - if (iter != NULL) - g_object_unref (iter); - - return result; -} static gboolean _msg_download_in_progress (ModestMsgViewWindow *win) @@ -1837,50 +1891,8 @@ _msg_download_in_progress (ModestMsgViewWindow *win) static gboolean _msg_download_completed (ModestMainWindow *win) { - GtkWidget *header_view = NULL; - TnyList *selected_headers = NULL; - TnyIterator *iter = NULL; - TnyHeader *header = NULL; - TnyHeaderFlags flags = 0; - gboolean result = FALSE; - - g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (win), FALSE); - - - /* Get header view to check selected messages */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win), - MODEST_WIDGET_TYPE_HEADER_VIEW); - - /* Check no selection */ - if (!modest_header_view_has_selected_headers (MODEST_HEADER_VIEW(header_view))) - return TRUE; - - /* Get selected headers */ - selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view)); - if (selected_headers == NULL) - return TRUE; - - /* Check dimmed rule */ - result = TRUE; - iter = tny_list_create_iterator (selected_headers); - while (!tny_iterator_is_done (iter) && result) { - header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - flags = tny_header_get_flags (header); - /* TODO: is this the right flag?, it seems that some - headers that have been previously downloaded do not - come with it */ - result = (flags & TNY_HEADER_FLAG_CACHED); - - g_object_unref (header); - } - - tny_iterator_next (iter); - } - - g_object_unref (iter); - - return result; + const DimmedState *state = modest_window_get_dimming_state (MODEST_WINDOW(win)); + return state->any_marked_as_cached; } static void @@ -1893,74 +1905,8 @@ fill_list_of_caches (gpointer key, gpointer value, gpointer userdata) static gboolean _selected_msg_sent_in_progress (ModestWindow *win) { - ModestCacheMgr *cache_mgr; - GHashTable *send_queue_cache; - GSList *send_queues = NULL, *node; - ModestTnySendQueue *send_queue = NULL; - GtkWidget *header_view = NULL; - TnyList *header_list = NULL; - TnyIterator *iter = NULL; - TnyHeader *header = NULL; - gboolean result = FALSE; - gchar *msg_uid = NULL; - - - if (MODEST_IS_MAIN_WINDOW(win)) { - - /* Get header view to check selected messages */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win), - MODEST_WIDGET_TYPE_HEADER_VIEW); - - /* Check no selection */ - if (!modest_header_view_has_selected_headers (MODEST_HEADER_VIEW(header_view))) - return FALSE; - - /* Get selected headers */ - header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view)); - - /* Get message header */ - if (!header_list) return FALSE; - iter = tny_list_create_iterator (header_list); - header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - /* Get message uid */ - msg_uid = modest_tny_send_queue_get_msg_id (header); - g_object_unref (header); - } - - } else if (MODEST_IS_MSG_VIEW_WINDOW(win)) { - - /* Get message header */ - header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win)); - if (header) { - /* Get message uid */ - msg_uid = modest_tny_send_queue_get_msg_id (header); - g_object_unref (header); - } - } - - /* Search on send queues cache */ - cache_mgr = modest_runtime_get_cache_mgr (); - send_queue_cache = modest_cache_mgr_get_cache (cache_mgr, - MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE); - - g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues); - - for (node = send_queues; node != NULL && !result; node = g_slist_next (node)) { - send_queue = MODEST_TNY_SEND_QUEUE (node->data); - - /* Check if msg uid is being processed inside send queue */ - result = modest_tny_send_queue_msg_is_being_sent (send_queue, msg_uid); - } - - - /* Free */ - g_free(msg_uid); - g_object_unref(header_list); - g_object_unref(iter); - g_slist_free (send_queues); - - return result; + const DimmedState *state = modest_window_get_dimming_state (win); + return state->sent_in_progress; } @@ -2070,3 +2016,4 @@ _transfer_mode_enabled (ModestWindow *win) return result; } + diff --git a/src/modest-ui-dimming-rules.h b/src/modest-ui-dimming-rules.h index 2b6b65c..32a69ad 100644 --- a/src/modest-ui-dimming-rules.h +++ b/src/modest-ui-dimming-rules.h @@ -36,6 +36,9 @@ G_BEGIN_DECLS +/* Window dimming state */ +DimmedState *modest_ui_dimming_rules_define_dimming_state (ModestWindow *window); + /* Menu & toolbar dimming rules */ gboolean modest_ui_dimming_rules_on_new_msg (ModestWindow *win, gpointer user_data); gboolean modest_ui_dimming_rules_on_new_folder (ModestWindow *win, gpointer user_data); diff --git a/src/widgets/modest-window-priv.h b/src/widgets/modest-window-priv.h index ccf9ab0..c845af6 100644 --- a/src/widgets/modest-window-priv.h +++ b/src/widgets/modest-window-priv.h @@ -39,12 +39,12 @@ G_BEGIN_DECLS typedef struct _ModestWindowPrivate ModestWindowPrivate; struct _ModestWindowPrivate { - GtkUIManager *ui_manager; + GtkUIManager *ui_manager; ModestUIDimmingManager *ui_dimming_manager; - GtkWidget *toolbar; - GtkWidget *menubar; - - gchar *active_account; + GtkWidget *toolbar; + GtkWidget *menubar; + DimmedState *dimming_state; + gchar *active_account; }; #define MODEST_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ diff --git a/src/widgets/modest-window.c b/src/widgets/modest-window.c index 91394bb..265fc04 100644 --- a/src/widgets/modest-window.c +++ b/src/widgets/modest-window.c @@ -208,6 +208,34 @@ modest_window_check_dimming_rules_group (ModestWindow *self, modest_ui_dimming_manager_process_dimming_rules_group (priv->ui_dimming_manager, group_name); } +void +modest_window_set_dimming_state (ModestWindow *window, + DimmedState *state) +{ + ModestWindowPrivate *priv; + + g_return_if_fail (MODEST_IS_WINDOW (window)); + priv = MODEST_WINDOW_GET_PRIVATE(window); + + /* Free previous */ + if (priv->dimming_state != NULL) + g_slice_free (DimmedState, priv->dimming_state); + + /* Set new state */ + priv->dimming_state = state; +} + +const DimmedState * +modest_window_get_dimming_state (ModestWindow *window) +{ + ModestWindowPrivate *priv; + + g_return_val_if_fail (MODEST_IS_WINDOW (window), NULL); + priv = MODEST_WINDOW_GET_PRIVATE(window); + + return priv->dimming_state; +} + GtkAction * modest_window_get_action (ModestWindow *window, const gchar *action_path) diff --git a/src/widgets/modest-window.h b/src/widgets/modest-window.h index be1c722..63bd1bd 100644 --- a/src/widgets/modest-window.h +++ b/src/widgets/modest-window.h @@ -40,7 +40,7 @@ G_BEGIN_DECLS #endif /*HAVE_CONFIG_H*/ #include - + /* * admittedly, the ifdefs for gtk and maemo are rather ugly; still * this way is probably the easiest to maintain @@ -66,6 +66,21 @@ typedef HildonWindowClass ModestWindowParentClass; #endif /*MODEST_PLATFORM_MAEMO */ +/* Dimmed state variables */ +typedef struct _DimmedState { + guint n_selected; + gboolean already_opened_msg; + gboolean any_marked_as_deleted; + gboolean all_marked_as_deleted; + gboolean any_marked_as_seen; + gboolean all_marked_as_seen; + gboolean any_marked_as_cached; + gboolean all_marked_as_cached; + gboolean any_has_attachments; + gboolean all_has_attachments; + gboolean sent_in_progress; +} DimmedState; + /* convenience macros */ #define MODEST_TYPE_WINDOW (modest_window_get_type()) #define MODEST_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_WINDOW,ModestWindow)) @@ -189,6 +204,31 @@ void modest_window_save_state (ModestWindow *window); /** + * modest_window_set_dimming_state: + * @window: a #ModestWindow instance object + * @state: the #DimmedState state at specific time + * + * Set basic dimming variables from selected headers at + * specific moment. + **/ +void +modest_window_set_dimming_state (ModestWindow *window, + DimmedState *state); + +/** + * modest_window_set_dimming_state: + * @window: a #ModestWindow instance object + * + * Set basic dimming variables from selected headers at + * specific moment. + * + * @Returns: a #DimmedState state saved previously. + **/ +const DimmedState * +modest_window_get_dimming_state (ModestWindow *window); + + +/** * modest_window_get_action: * @window: a #ModestWindow instance object * @action_path: the full path of required action.