diff options
author | Milan Crha <mcrha@redhat.com> | 2013-05-04 00:11:37 +0800 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2013-05-04 00:11:37 +0800 |
commit | 7770e7c36560adb9ce3d4714e369ebcd46274b85 (patch) | |
tree | 2bb0b336e71f15a22369c3234014afe2ebb40b6f /plugins | |
parent | 5dfeb54af9639bc3a1df5e4262ec384d2abf5a9d (diff) | |
download | gsoc2013-evolution-7770e7c36560adb9ce3d4714e369ebcd46274b85.tar.gz gsoc2013-evolution-7770e7c36560adb9ce3d4714e369ebcd46274b85.tar.zst gsoc2013-evolution-7770e7c36560adb9ce3d4714e369ebcd46274b85.zip |
Merge [mark-all-read] plugin into core code
During fixes on bug #602428, rather than do everything twice,
I merged the plugin into the core code, thus it should be easier
to maintain as well.
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/mark-all-read/Makefile.am | 31 | ||||
-rw-r--r-- | plugins/mark-all-read/mark-all-read.c | 602 | ||||
-rw-r--r-- | plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml | 21 |
3 files changed, 0 insertions, 654 deletions
diff --git a/plugins/mark-all-read/Makefile.am b/plugins/mark-all-read/Makefile.am deleted file mode 100644 index 2ed1397664..0000000000 --- a/plugins/mark-all-read/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -@EVO_PLUGIN_RULE@ - -plugin_DATA = org-gnome-mark-all-read.eplug - -plugin_LTLIBRARIES = liborg-gnome-mark-all-read.la - -liborg_gnome_mark_all_read_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) - -liborg_gnome_mark_all_read_la_SOURCES = mark-all-read.c - -liborg_gnome_mark_all_read_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_mark_all_read_la_LIBADD = \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/shell/libeshell.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) - -EXTRA_DIST = org-gnome-mark-all-read.eplug.xml - -BUILT_SOURCES = $(plugin_DATA) -CLEANFILES = $(BUILT_SOURCES) - --include $(top_srcdir)/git.mk diff --git a/plugins/mark-all-read/mark-all-read.c b/plugins/mark-all-read/mark-all-read.c deleted file mode 100644 index d04553d0bb..0000000000 --- a/plugins/mark-all-read/mark-all-read.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Chenthill Palanisamy <pchenthill@novell.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> - -#include <libemail-engine/e-mail-folder-utils.h> - -#include <mail/em-folder-tree.h> -#include <mail/em-utils.h> - -#include <shell/e-shell-sidebar.h> -#include <shell/e-shell-view.h> -#include <shell/e-shell-window.h> - -#define PRIMARY_TEXT \ - N_("Also mark messages in subfolders?") -#define SECONDARY_TEXT \ - N_("Do you want to mark messages as read in the current folder " \ - "only, or in the current folder as well as all subfolders?") - -typedef struct _AsyncContext AsyncContext; - -struct _AsyncContext { - EActivity *activity; - GQueue folder_names; -}; - -enum { - MARK_ALL_READ_CANCEL, - MARK_ALL_READ_CURRENT_FOLDER, - MARK_ALL_READ_WITH_SUBFOLDERS -}; - -gboolean e_plugin_ui_init (GtkUIManager *ui_manager, - EShellView *shell_view); -gint e_plugin_lib_enable (EPlugin *ep, - gint enable); - -static void -async_context_free (AsyncContext *context) -{ - if (context->activity != NULL) - g_object_unref (context->activity); - - /* This should be empty already, but just to be sure... */ - while (!g_queue_is_empty (&context->folder_names)) - g_free (g_queue_pop_head (&context->folder_names)); - - g_slice_free (AsyncContext, context); -} - -gint -e_plugin_lib_enable (EPlugin *ep, - gint enable) -{ - return 0; -} - -static void -button_clicked_cb (GtkButton *button, - GtkDialog *dialog) -{ - gpointer response; - - response = g_object_get_data (G_OBJECT (button), "response"); - gtk_dialog_response (dialog, GPOINTER_TO_INT (response)); -} - -static gint -prompt_user (gboolean has_subfolders) -{ - GtkWidget *container; - GtkWidget *dialog; - GtkWidget *grid; - GtkWidget *widget; - GtkWidget *vbox; - gchar *markup; - gint response, ret; - - if (!has_subfolders) { - EShell *shell; - GtkWindow *parent; - - shell = e_shell_get_default (); - parent = e_shell_get_active_window (shell); - - return em_utils_prompt_user ( - parent, "prompt-on-mark-all-read", "mail:ask-mark-all-read", NULL) ? - MARK_ALL_READ_CURRENT_FOLDER : MARK_ALL_READ_CANCEL; - } - - dialog = gtk_dialog_new (); - widget = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); - gtk_widget_hide (widget); - gtk_window_set_title (GTK_WINDOW (dialog), ""); - gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); - vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); - - /* Grid */ - widget = gtk_grid_new (); - gtk_grid_set_row_spacing (GTK_GRID (widget), 12); - gtk_grid_set_column_spacing (GTK_GRID (widget), 12); - gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - - grid = widget; - - /* Question Icon */ - widget = gtk_image_new_from_stock ( - GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); - gtk_widget_set_valign (widget, GTK_ALIGN_START); - gtk_grid_attach (GTK_GRID (grid), widget, 0, 0, 1, 3); - gtk_widget_show (widget); - - /* Primary Text */ - markup = g_markup_printf_escaped ( - "<big><b>%s</b></big>", gettext (PRIMARY_TEXT)); - widget = gtk_label_new (markup); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0); - gtk_grid_attach (GTK_GRID (grid), widget, 1, 0, 1, 1); - gtk_widget_show (widget); - g_free (markup); - - /* Secondary Text */ - widget = gtk_label_new (gettext (SECONDARY_TEXT)); - gtk_widget_set_vexpand (widget, TRUE); - gtk_widget_set_valign (widget, GTK_ALIGN_START); - gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0); - gtk_grid_attach (GTK_GRID (grid), widget, 1, 1, 1, 1); - gtk_widget_show (widget); - - /* Action Area */ - widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_widget_set_halign (widget, GTK_ALIGN_END); - gtk_grid_attach (GTK_GRID (grid), widget, 1, 2, 1, 1); - gtk_widget_show (widget); - - container = widget; - - /* Cancel button */ - widget = gtk_button_new_from_stock (GTK_STOCK_CANCEL); - g_object_set_data ( - G_OBJECT (widget), "response", - GINT_TO_POINTER (GTK_RESPONSE_CANCEL)); - g_signal_connect ( - widget, "clicked", - G_CALLBACK (button_clicked_cb), dialog); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - /* To Translators: It's a response button caption on a question - * "Do you want to mark messages as read in the current folder - * only, or in the current folder as well as all subfolders?" */ - widget = gtk_button_new_with_mnemonic ( - _("In Current Folder and _Subfolders")); - g_object_set_data ( - G_OBJECT (widget), "response", - GINT_TO_POINTER (GTK_RESPONSE_YES)); - g_signal_connect ( - widget, "clicked", - G_CALLBACK (button_clicked_cb), dialog); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - /* To Translators: It's a response button caption on a question - * "Do you want to mark messages as read in the current folder - * only, or in the current folder as well as all subfolders?" */ - widget = gtk_button_new_with_mnemonic ( - _("In Current _Folder Only")); - g_object_set_data ( - G_OBJECT (widget), "response", - GINT_TO_POINTER (GTK_RESPONSE_NO)); - g_signal_connect ( - widget, "clicked", - G_CALLBACK (button_clicked_cb), dialog); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - - if (response == GTK_RESPONSE_YES) - ret = MARK_ALL_READ_WITH_SUBFOLDERS; - else if (response == GTK_RESPONSE_NO) - ret = MARK_ALL_READ_CURRENT_FOLDER; - else - ret = MARK_ALL_READ_CANCEL; - - return ret; -} - -static gboolean -scan_folder_tree_for_unread_helper (GtkTreeModel *model, - GtkTreeIter *iter, - GtkTreePath *path, - gboolean is_first_node, - gint initial_depth, - gint *relative_depth) -{ - /* This is based on gtk_tree_model_foreach(). Unfortunately - * that function insists on traversing the entire tree model. */ - - do { - GtkTreeIter child; - gboolean folder_has_unread; - gboolean is_draft = FALSE; - gboolean is_store = FALSE; - gboolean is_trash; - gboolean is_virtual; - guint unread = 0; - guint folder_flags = 0; - guint folder_type; - - gtk_tree_model_get ( - model, iter, - COL_UINT_FLAGS, &folder_flags, - COL_UINT_UNREAD, &unread, - COL_BOOL_IS_STORE, &is_store, - COL_BOOL_IS_DRAFT, &is_draft, -1); - - folder_type = (folder_flags & CAMEL_FOLDER_TYPE_MASK); - is_virtual = ((folder_flags & CAMEL_FOLDER_VIRTUAL) != 0); - is_trash = (folder_type == CAMEL_FOLDER_TYPE_TRASH); - - folder_has_unread = - !is_store && !is_draft && - (!is_virtual || !is_trash) && - unread > 0 && unread != ~((guint) 0); - - if (folder_has_unread) { - gint current_depth; - - current_depth = gtk_tree_path_get_depth (path); - *relative_depth = current_depth - initial_depth + 1; - - /* If we find unread messages in a child of the - * selected folder, short-circuit the recursion. */ - if (*relative_depth > 1) - return TRUE; - } - - if (gtk_tree_model_iter_children (model, &child, iter)) { - gtk_tree_path_down (path); - - if (scan_folder_tree_for_unread_helper ( - model, &child, path, FALSE, - initial_depth, relative_depth)) - return TRUE; - - gtk_tree_path_up (path); - } - - /* do not check sibling nodes of the selected folder */ - if (is_first_node) - break; - - gtk_tree_path_next (path); - - } while (gtk_tree_model_iter_next (model, iter)); - - return FALSE; -} - -static gint -scan_folder_tree_for_unread (const gchar *folder_uri) -{ - GtkTreeRowReference *reference; - EMFolderTreeModel *model; - gint relative_depth = 0; - - /* Traverses the selected folder and its children and returns - * the relative depth of the furthest child folder containing - * unread mail. Except, we abort the traversal as soon as we - * find a child folder with unread messages. So the possible - * return values are: - * - * Depth = 0: No unread mail found. - * Depth = 1: Unread mail only in selected folder. - * Depth = 2: Unread mail in one of the child folders. - */ - - if (folder_uri == NULL) - return 0; - - model = em_folder_tree_model_get_default (); - reference = em_folder_tree_model_lookup_uri (model, folder_uri); - - if (gtk_tree_row_reference_valid (reference)) { - GtkTreePath *path; - GtkTreeIter iter; - - path = gtk_tree_row_reference_get_path (reference); - gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path); - - scan_folder_tree_for_unread_helper ( - GTK_TREE_MODEL (model), &iter, path, TRUE, - gtk_tree_path_get_depth (path), &relative_depth); - - gtk_tree_path_free (path); - } - - return relative_depth; -} - -static void -collect_folder_names (GQueue *folder_names, - CamelFolderInfo *folder_info) -{ - while (folder_info != NULL) { - if (folder_info->child != NULL) - collect_folder_names ( - folder_names, folder_info->child); - - g_queue_push_tail ( - folder_names, g_strdup (folder_info->full_name)); - - folder_info = folder_info->next; - } -} - -static void -mar_got_folder (CamelStore *store, - GAsyncResult *result, - AsyncContext *context) -{ - EAlertSink *alert_sink; - GCancellable *cancellable; - CamelFolder *folder; - gchar *folder_name; - GError *error = NULL; - GPtrArray *uids; - gint ii; - - alert_sink = e_activity_get_alert_sink (context->activity); - cancellable = e_activity_get_cancellable (context->activity); - - folder = camel_store_get_folder_finish (store, result, &error); - - if (e_activity_handle_cancellation (context->activity, error)) { - g_warn_if_fail (folder == NULL); - async_context_free (context); - g_error_free (error); - return; - - } else if (error != NULL) { - g_warn_if_fail (folder == NULL); - e_alert_submit ( - alert_sink, "mail:folder-open", - error->message, NULL); - async_context_free (context); - g_error_free (error); - return; - } - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - - camel_folder_freeze (folder); - - uids = camel_folder_get_uids (folder); - - for (ii = 0; ii < uids->len; ii++) - camel_folder_set_message_flags ( - folder, uids->pdata[ii], - CAMEL_MESSAGE_SEEN, - CAMEL_MESSAGE_SEEN); - - camel_folder_free_uids (folder, uids); - - camel_folder_thaw (folder); - g_object_unref (folder); - - /* If the folder name queue is empty, we're done. */ - if (g_queue_is_empty (&context->folder_names)) { - e_activity_set_state (context->activity, E_ACTIVITY_COMPLETED); - async_context_free (context); - return; - } - - folder_name = g_queue_pop_head (&context->folder_names); - - camel_store_get_folder ( - store, folder_name, 0, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) mar_got_folder, context); - - g_free (folder_name); -} - -static void -mar_got_folder_info (CamelStore *store, - GAsyncResult *result, - AsyncContext *context) -{ - EAlertSink *alert_sink; - GCancellable *cancellable; - CamelFolderInfo *folder_info; - gchar *folder_name; - gint response; - GError *error = NULL; - - alert_sink = e_activity_get_alert_sink (context->activity); - cancellable = e_activity_get_cancellable (context->activity); - - folder_info = camel_store_get_folder_info_finish ( - store, result, &error); - - if (e_activity_handle_cancellation (context->activity, error)) { - g_warn_if_fail (folder_info == NULL); - async_context_free (context); - g_error_free (error); - return; - - /* XXX This EAlert primary text isn't technically correct since - * we're just collecting folder tree info and haven't actually - * opened any folders yet, but the user doesn't need to know. */ - } else if (error != NULL) { - g_warn_if_fail (folder_info == NULL); - e_alert_submit ( - alert_sink, "mail:folder-open", - error->message, NULL); - async_context_free (context); - g_error_free (error); - return; - } - - g_return_if_fail (folder_info != NULL); - - response = prompt_user (folder_info->child != NULL); - - if (response == MARK_ALL_READ_CURRENT_FOLDER) - g_queue_push_tail ( - &context->folder_names, - g_strdup (folder_info->full_name)); - - if (response == MARK_ALL_READ_WITH_SUBFOLDERS) - collect_folder_names (&context->folder_names, folder_info); - - camel_store_free_folder_info (store, folder_info); - - /* If the user cancelled, we're done. */ - if (g_queue_is_empty (&context->folder_names)) { - e_activity_set_state (context->activity, E_ACTIVITY_COMPLETED); - async_context_free (context); - return; - } - - folder_name = g_queue_pop_head (&context->folder_names); - - camel_store_get_folder ( - store, folder_name, 0, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) mar_got_folder, context); - - g_free (folder_name); -} - -static void -action_mail_mark_read_recursive_cb (GtkAction *action, - EShellView *shell_view) -{ - EAlertSink *alert_sink; - GCancellable *cancellable; - EShellBackend *shell_backend; - EShellContent *shell_content; - EShellSidebar *shell_sidebar; - EMFolderTree *folder_tree; - AsyncContext *context; - CamelStore *store; - gchar *folder_name; - - shell_backend = e_shell_view_get_shell_backend (shell_view); - shell_content = e_shell_view_get_shell_content (shell_view); - shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); - - g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL); - - /* This action should only be activatable if a folder is selected. */ - if (!em_folder_tree_get_selected (folder_tree, &store, &folder_name)) - g_return_if_reached (); - - g_object_unref (folder_tree); - - /* Open the selected folder asynchronously. */ - - context = g_slice_new0 (AsyncContext); - context->activity = e_activity_new (); - g_queue_init (&context->folder_names); - - alert_sink = E_ALERT_SINK (shell_content); - e_activity_set_alert_sink (context->activity, alert_sink); - - cancellable = camel_operation_new (); - e_activity_set_cancellable (context->activity, cancellable); - - e_shell_backend_add_activity (shell_backend, context->activity); - - camel_store_get_folder_info ( - store, folder_name, - CAMEL_STORE_FOLDER_INFO_FAST | - CAMEL_STORE_FOLDER_INFO_RECURSIVE, - G_PRIORITY_DEFAULT, cancellable, - (GAsyncReadyCallback) mar_got_folder_info, context); - - g_object_unref (cancellable); - - g_object_unref (store); - g_free (folder_name); -} - -static GtkActionEntry entries[] = { - - { "mail-mark-read-recursive", - "mail-mark-read", - N_("Mark Me_ssages as Read"), - NULL, - NULL, /* XXX Add a tooltip! */ - G_CALLBACK (action_mail_mark_read_recursive_cb) } -}; - -static void -update_actions_cb (EShellView *shell_view, - gpointer user_data) -{ - GtkActionGroup *action_group; - EShellSidebar *shell_sidebar; - EShellWindow *shell_window; - EMFolderTree *folder_tree; - GtkAction *action; - gchar *folder_uri; - gboolean visible; - - g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); - - shell_window = e_shell_view_get_shell_window (shell_view); - action_group = e_shell_window_get_action_group (shell_window, "mail"); - - action = gtk_action_group_get_action (action_group, entries[0].name); - g_return_if_fail (action != NULL); - - shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); - g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL); - folder_uri = em_folder_tree_get_selected_uri (folder_tree); - - visible = em_folder_tree_get_selected (folder_tree, NULL, NULL) - && scan_folder_tree_for_unread (folder_uri) > 0; - gtk_action_set_visible (action, visible); - - g_object_unref (folder_tree); - g_free (folder_uri); -} - -gboolean -e_plugin_ui_init (GtkUIManager *ui_manager, - EShellView *shell_view) -{ - EShellWindow *shell_window; - GtkActionGroup *action_group; - - shell_window = e_shell_view_get_shell_window (shell_view); - action_group = e_shell_window_get_action_group (shell_window, "mail"); - - /* Add actions to the "mail" action group. */ - gtk_action_group_add_actions ( - action_group, entries, - G_N_ELEMENTS (entries), shell_view); - - g_signal_connect ( - shell_view, "update-actions", - G_CALLBACK (update_actions_cb), NULL); - - return TRUE; -} diff --git a/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml b/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml deleted file mode 100644 index a254e1e4db..0000000000 --- a/plugins/mark-all-read/org-gnome-mark-all-read.eplug.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0"?> -<e-plugin-list> - <e-plugin id="org.gnome.evolution.mail.folder.mark_all_read" - type="shlib" - domain="@GETTEXT_PACKAGE@" - _name="Mark All Read" - location="@PLUGINDIR@/liborg-gnome-mark-all-read@SOEXT@"> - <author name="Chenthill Palanisamy" email="pchenthill@novell.com"/> - <_description>Mark all messages in a folder as read.</_description> - - <hook class="org.gnome.evolution.ui:1.0"> - <ui-manager id="org.gnome.evolution.mail"> - <popup name="mail-folder-popup"> - <placeholder name="mail-folder-popup-actions"> - <menuitem action="mail-mark-read-recursive"/> - </placeholder> - </popup> - </ui-manager> - </hook> - </e-plugin> -</e-plugin-list> |