Bug 792781 - 'Go to Folder' incorrectly unrefs CamelFolder twice
[evolution.git] / src / modules / mail / e-mail-shell-view-actions.c
blob0c1fe14f8f7f3ef97ebdbb2eec1d479a7f045d89
1 /*
2 * e-mail-shell-view-actions.c
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 #include "evolution-config.h"
23 #include "e-mail-shell-view-private.h"
25 static void
26 mail_shell_view_folder_created_cb (EMailFolderCreateDialog *dialog,
27 CamelStore *store,
28 const gchar *folder_name,
29 GWeakRef *folder_tree_weak_ref)
31 EMFolderTree *folder_tree;
33 folder_tree = g_weak_ref_get (folder_tree_weak_ref);
35 if (folder_tree != NULL) {
36 gchar *folder_uri;
38 /* Select the newly created folder. */
39 folder_uri = e_mail_folder_uri_build (store, folder_name);
40 em_folder_tree_set_selected (folder_tree, folder_uri, FALSE);
41 g_free (folder_uri);
43 g_object_unref (folder_tree);
47 static void
48 action_mail_account_disable_cb (GtkAction *action,
49 EMailShellView *mail_shell_view)
51 EMailShellSidebar *mail_shell_sidebar;
52 EShellView *shell_view;
53 EShellWindow *shell_window;
54 EShellBackend *shell_backend;
55 EMailBackend *backend;
56 EMailSession *session;
57 EMailAccountStore *account_store;
58 EMFolderTree *folder_tree;
59 CamelStore *store;
61 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
63 shell_view = E_SHELL_VIEW (mail_shell_view);
64 shell_backend = e_shell_view_get_shell_backend (shell_view);
65 shell_window = e_shell_view_get_shell_window (shell_view);
67 backend = E_MAIL_BACKEND (shell_backend);
68 session = e_mail_backend_get_session (backend);
69 account_store = e_mail_ui_session_get_account_store (
70 E_MAIL_UI_SESSION (session));
72 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
73 store = em_folder_tree_ref_selected_store (folder_tree);
74 g_return_if_fail (store != NULL);
76 e_mail_account_store_disable_service (
77 account_store,
78 GTK_WINDOW (shell_window),
79 CAMEL_SERVICE (store));
81 e_shell_view_update_actions (shell_view);
83 g_object_unref (store);
86 static void
87 action_mail_account_properties_cb (GtkAction *action,
88 EMailShellView *mail_shell_view)
90 EMailShellSidebar *mail_shell_sidebar;
91 EShell *shell;
92 EShellView *shell_view;
93 EShellWindow *shell_window;
94 EShellBackend *shell_backend;
95 ESourceRegistry *registry;
96 ESource *source;
97 EMFolderTree *folder_tree;
98 CamelService *service;
99 CamelStore *store;
100 const gchar *uid;
102 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
104 shell_view = E_SHELL_VIEW (mail_shell_view);
105 shell_backend = e_shell_view_get_shell_backend (shell_view);
106 shell_window = e_shell_view_get_shell_window (shell_view);
107 shell = e_shell_backend_get_shell (shell_backend);
109 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
110 store = em_folder_tree_ref_selected_store (folder_tree);
111 g_return_if_fail (store != NULL);
113 service = CAMEL_SERVICE (store);
114 uid = camel_service_get_uid (service);
115 registry = e_shell_get_registry (shell);
116 source = e_source_registry_ref_source (registry, uid);
117 g_return_if_fail (source != NULL);
119 e_mail_shell_backend_edit_account (
120 E_MAIL_SHELL_BACKEND (shell_backend),
121 GTK_WINDOW (shell_window), source);
123 g_object_unref (source);
124 g_object_unref (store);
127 static void
128 account_refresh_folder_info_received_cb (GObject *source,
129 GAsyncResult *result,
130 gpointer user_data)
132 CamelStore *store;
133 CamelFolderInfo *info;
134 EActivity *activity;
135 GError *error = NULL;
137 store = CAMEL_STORE (source);
138 activity = E_ACTIVITY (user_data);
140 info = camel_store_get_folder_info_finish (store, result, &error);
142 /* Provider takes care of notifications of new/removed
143 * folders, thus it's enough to free the returned list. */
144 camel_folder_info_free (info);
146 if (e_activity_handle_cancellation (activity, error)) {
147 g_error_free (error);
149 } else if (error != NULL) {
150 g_warning ("%s: %s", G_STRFUNC, error->message);
151 g_error_free (error);
154 g_clear_object (&activity);
157 static void
158 action_mail_account_refresh_cb (GtkAction *action,
159 EMailShellView *mail_shell_view)
161 EMailShellContent *mail_shell_content;
162 EMailShellSidebar *mail_shell_sidebar;
163 EMFolderTree *folder_tree;
164 EMailView *mail_view;
165 EActivity *activity;
166 ESourceRegistry *registry;
167 ESource *source;
168 EShell *shell;
169 CamelStore *store;
170 GCancellable *cancellable;
172 mail_shell_content = mail_shell_view->priv->mail_shell_content;
173 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
175 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
176 store = em_folder_tree_ref_selected_store (folder_tree);
177 g_return_if_fail (store != NULL);
179 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
180 activity = e_mail_reader_new_activity (E_MAIL_READER (mail_view));
181 cancellable = e_activity_get_cancellable (activity);
183 shell = e_shell_backend_get_shell (e_shell_view_get_shell_backend (E_SHELL_VIEW (mail_shell_view)));
184 registry = e_shell_get_registry (shell);
185 source = e_source_registry_ref_source (registry, camel_service_get_uid (CAMEL_SERVICE (store)));
186 g_return_if_fail (source != NULL);
188 e_shell_allow_auth_prompt_for (shell, source);
190 camel_store_get_folder_info (
191 store, NULL,
192 CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_REFRESH,
193 G_PRIORITY_DEFAULT, cancellable,
194 account_refresh_folder_info_received_cb, activity);
196 g_clear_object (&source);
197 g_clear_object (&store);
200 static void
201 action_mail_create_search_folder_cb (GtkAction *action,
202 EMailShellView *mail_shell_view)
204 EMailShellContent *mail_shell_content;
205 EMailReader *reader;
206 EShellView *shell_view;
207 EShellBackend *shell_backend;
208 EShellSearchbar *searchbar;
209 EFilterRule *search_rule;
210 EMVFolderRule *vfolder_rule;
211 EMailBackend *backend;
212 EMailSession *session;
213 EMailView *mail_view;
214 CamelFolder *folder;
215 const gchar *search_text;
216 gchar *folder_uri;
217 gchar *rule_name;
219 shell_view = E_SHELL_VIEW (mail_shell_view);
220 shell_backend = e_shell_view_get_shell_backend (shell_view);
222 mail_shell_content = mail_shell_view->priv->mail_shell_content;
223 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
224 searchbar = e_mail_shell_content_get_searchbar (mail_shell_content);
226 search_rule = e_shell_view_get_search_rule (shell_view);
227 g_return_if_fail (search_rule != NULL);
229 search_text = e_shell_searchbar_get_search_text (searchbar);
230 if (search_text == NULL || *search_text == '\0')
231 search_text = "''";
233 backend = E_MAIL_BACKEND (shell_backend);
234 session = e_mail_backend_get_session (backend);
236 search_rule = vfolder_clone_rule (session, search_rule);
237 g_return_if_fail (search_rule != NULL);
239 rule_name = g_strdup_printf ("%s %s", search_rule->name, search_text);
240 e_filter_rule_set_source (search_rule, E_FILTER_SOURCE_INCOMING);
241 e_filter_rule_set_name (search_rule, rule_name);
242 g_free (rule_name);
244 reader = E_MAIL_READER (mail_view);
245 folder = e_mail_reader_ref_folder (reader);
246 folder_uri = e_mail_folder_uri_from_folder (folder);
248 vfolder_rule = EM_VFOLDER_RULE (search_rule);
249 em_vfolder_rule_add_source (vfolder_rule, folder_uri);
250 vfolder_gui_add_rule (vfolder_rule);
252 g_clear_object (&folder);
253 g_free (folder_uri);
256 static void
257 action_mail_attachment_bar_cb (GtkAction *action,
258 EMailShellView *mail_shell_view)
260 EMailDisplay *mail_display;
261 EAttachmentView *attachment_view;
263 g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
265 mail_display = e_mail_reader_get_mail_display (E_MAIL_READER (mail_shell_view->priv->mail_shell_content));
266 attachment_view = e_mail_display_get_attachment_view (mail_display);
267 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
268 EAttachmentStore *store;
269 guint num_attachments;
271 store = e_attachment_bar_get_store (E_ATTACHMENT_BAR (attachment_view));
272 num_attachments = e_attachment_store_get_num_attachments (store);
273 gtk_widget_set_visible (GTK_WIDGET (attachment_view), num_attachments > 0);
274 } else {
275 gtk_widget_hide (GTK_WIDGET (attachment_view));
279 static void
280 action_mail_to_do_bar_cb (GtkAction *action,
281 EShellView *shell_view)
283 EShellContent *shell_content;
284 GtkWidget *to_do_pane;
286 g_return_if_fail (E_IS_MAIL_SHELL_VIEW (shell_view));
288 shell_content = e_shell_view_get_shell_content (shell_view);
289 to_do_pane = e_mail_shell_content_get_to_do_pane (E_MAIL_SHELL_CONTENT (shell_content));
291 gtk_widget_set_visible (to_do_pane, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
294 static void
295 action_mail_download_finished_cb (CamelStore *store,
296 GAsyncResult *result,
297 EActivity *activity)
299 EAlertSink *alert_sink;
300 GError *error = NULL;
302 alert_sink = e_activity_get_alert_sink (activity);
304 e_mail_store_prepare_for_offline_finish (store, result, &error);
306 if (e_activity_handle_cancellation (activity, error)) {
307 g_error_free (error);
309 } else if (error != NULL) {
310 e_alert_submit (
311 alert_sink, "mail:prepare-for-offline",
312 error->message, NULL);
313 g_error_free (error);
316 g_object_unref (activity);
319 static void
320 action_mail_download_cb (GtkAction *action,
321 EMailShellView *mail_shell_view)
323 EMailShellContent *mail_shell_content;
324 EMailView *mail_view;
325 EMailReader *reader;
326 EMailBackend *backend;
327 EMailSession *session;
328 GList *list, *link;
330 mail_shell_content = mail_shell_view->priv->mail_shell_content;
331 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
333 reader = E_MAIL_READER (mail_view);
334 backend = e_mail_reader_get_backend (reader);
335 session = e_mail_backend_get_session (backend);
337 list = camel_session_list_services (CAMEL_SESSION (session));
339 for (link = list; link != NULL; link = g_list_next (link)) {
340 EActivity *activity;
341 CamelService *service;
342 GCancellable *cancellable;
344 service = CAMEL_SERVICE (link->data);
346 if (!CAMEL_IS_STORE (service))
347 continue;
349 activity = e_mail_reader_new_activity (reader);
350 cancellable = e_activity_get_cancellable (activity);
352 e_mail_store_prepare_for_offline (
353 CAMEL_STORE (service), G_PRIORITY_DEFAULT,
354 cancellable, (GAsyncReadyCallback)
355 action_mail_download_finished_cb, activity);
358 g_list_free_full (list, (GDestroyNotify) g_object_unref);
361 static void
362 action_mail_flush_outbox_cb (GtkAction *action,
363 EMailShellView *mail_shell_view)
365 EShellBackend *shell_backend;
366 EShellView *shell_view;
367 EMailBackend *backend;
368 EMailSession *session;
370 shell_view = E_SHELL_VIEW (mail_shell_view);
371 shell_backend = e_shell_view_get_shell_backend (shell_view);
373 backend = E_MAIL_BACKEND (shell_backend);
374 session = e_mail_backend_get_session (backend);
376 mail_send_immediately (session);
379 static void
380 action_mail_folder_copy_cb (GtkAction *action,
381 EMailShellView *mail_shell_view)
383 EMailShellSidebar *mail_shell_sidebar;
384 EShellContent *shell_content;
385 EShellWindow *shell_window;
386 EShellView *shell_view;
387 EMFolderTree *folder_tree;
388 EMailSession *session;
389 gchar *selected_uri;
391 shell_view = E_SHELL_VIEW (mail_shell_view);
392 shell_window = e_shell_view_get_shell_window (shell_view);
393 shell_content = e_shell_view_get_shell_content (shell_view);
395 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
396 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
397 selected_uri = em_folder_tree_get_selected_uri (folder_tree);
398 session = em_folder_tree_get_session (folder_tree);
399 g_return_if_fail (selected_uri != NULL);
401 em_folder_utils_copy_folder (
402 GTK_WINDOW (shell_window),
403 session,
404 E_ALERT_SINK (shell_content),
405 selected_uri, FALSE);
407 g_free (selected_uri);
410 static void
411 action_mail_folder_delete_cb (GtkAction *action,
412 EMailShellView *mail_shell_view)
414 EMailShellContent *mail_shell_content;
415 EMailShellSidebar *mail_shell_sidebar;
416 EMailView *mail_view;
417 EMFolderTree *folder_tree;
418 CamelStore *selected_store = NULL;
419 gchar *selected_folder_name = NULL;
421 mail_shell_content = mail_shell_view->priv->mail_shell_content;
422 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
424 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
425 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
427 em_folder_tree_get_selected (
428 folder_tree, &selected_store, &selected_folder_name);
429 g_return_if_fail (CAMEL_IS_STORE (selected_store));
430 g_return_if_fail (selected_folder_name != NULL);
432 e_mail_reader_delete_folder_name (
433 E_MAIL_READER (mail_view),
434 selected_store, selected_folder_name);
436 g_object_unref (selected_store);
437 g_free (selected_folder_name);
440 static void
441 action_mail_folder_expunge_cb (GtkAction *action,
442 EMailShellView *mail_shell_view)
444 EMailShellContent *mail_shell_content;
445 EMailShellSidebar *mail_shell_sidebar;
446 EMailView *mail_view;
447 EMFolderTree *folder_tree;
448 CamelStore *selected_store = NULL;
449 gchar *selected_folder_name = NULL;
451 /* This handles both the "folder-expunge" and "account-expunge"
452 * actions. */
454 mail_shell_content = mail_shell_view->priv->mail_shell_content;
455 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
457 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
458 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
460 /* Get the folder from the folder tree, not the message list.
461 * This correctly handles the use case of right-clicking on
462 * the "Trash" folder and selecting "Empty Trash" without
463 * actually selecting the folder. In that case the message
464 * list would not contain the correct folder to expunge. */
465 em_folder_tree_get_selected (
466 folder_tree, &selected_store, &selected_folder_name);
467 g_return_if_fail (CAMEL_IS_STORE (selected_store));
468 g_return_if_fail (selected_folder_name != NULL);
470 e_mail_reader_expunge_folder_name (
471 E_MAIL_READER (mail_view),
472 selected_store, selected_folder_name);
474 g_object_unref (selected_store);
475 g_free (selected_folder_name);
478 static void
479 action_mail_folder_empty_junk_cb (GtkAction *action,
480 EMailShellView *mail_shell_view)
482 EMailShellContent *mail_shell_content;
483 EMailShellSidebar *mail_shell_sidebar;
484 EMailView *mail_view;
485 EMFolderTree *folder_tree;
486 CamelStore *selected_store = NULL;
487 gchar *selected_folder_name = NULL;
489 mail_shell_content = mail_shell_view->priv->mail_shell_content;
490 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
492 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
493 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
495 /* Get the folder from the folder tree, not the message list.
496 * This correctly handles the use case of right-clicking on
497 * the "Junk" folder and selecting "Empty Junk" without
498 * actually selecting the folder. In that case the message
499 * list would not contain the correct folder. */
500 em_folder_tree_get_selected (folder_tree, &selected_store, &selected_folder_name);
501 g_return_if_fail (CAMEL_IS_STORE (selected_store));
502 g_return_if_fail (selected_folder_name != NULL);
504 e_mail_reader_empty_junk_folder_name (E_MAIL_READER (mail_view), selected_store, selected_folder_name);
506 g_object_unref (selected_store);
507 g_free (selected_folder_name);
510 typedef struct _AsyncContext {
511 EActivity *activity;
512 EMailShellView *mail_shell_view;
513 gboolean can_subfolders;
514 GQueue folder_names;
515 } AsyncContext;
517 static void
518 async_context_free (AsyncContext *context)
520 if (context->activity != NULL)
521 g_object_unref (context->activity);
523 if (context->mail_shell_view != NULL)
524 g_object_unref (context->mail_shell_view);
526 /* This should be empty already, unless an error occurred... */
527 while (!g_queue_is_empty (&context->folder_names))
528 g_free (g_queue_pop_head (&context->folder_names));
530 g_slice_free (AsyncContext, context);
533 static void
534 mark_all_read_thread (GSimpleAsyncResult *simple,
535 GObject *object,
536 GCancellable *cancellable)
538 AsyncContext *context;
539 CamelStore *store;
540 CamelFolder *folder;
541 GPtrArray *uids;
542 gint ii;
543 GError *error = NULL;
545 context = g_simple_async_result_get_op_res_gpointer (simple);
546 store = CAMEL_STORE (object);
548 while (!g_queue_is_empty (&context->folder_names) && !error) {
549 gchar *folder_name;
551 folder_name = g_queue_pop_head (&context->folder_names);
552 folder = camel_store_get_folder_sync (
553 store, folder_name, 0, cancellable, &error);
554 g_free (folder_name);
556 if (folder == NULL)
557 break;
559 camel_folder_freeze (folder);
561 uids = camel_folder_get_uids (folder);
563 for (ii = 0; ii < uids->len; ii++)
564 camel_folder_set_message_flags (
565 folder, uids->pdata[ii],
566 CAMEL_MESSAGE_SEEN,
567 CAMEL_MESSAGE_SEEN);
569 camel_folder_thaw (folder);
571 /* Save changes to the server immediately. */
572 camel_folder_synchronize_sync (folder, FALSE, cancellable, &error);
574 camel_folder_free_uids (folder, uids);
575 g_object_unref (folder);
578 if (error != NULL)
579 g_simple_async_result_take_error (simple, error);
582 static void
583 mark_all_read_done_cb (GObject *source,
584 GAsyncResult *result,
585 gpointer user_data)
587 GSimpleAsyncResult *simple;
588 AsyncContext *context;
589 GError *local_error = NULL;
591 g_return_if_fail (
592 g_simple_async_result_is_valid (
593 result, source, mark_all_read_thread));
595 simple = G_SIMPLE_ASYNC_RESULT (result);
596 context = g_simple_async_result_get_op_res_gpointer (simple);
598 if (g_simple_async_result_propagate_error (simple, &local_error) &&
599 local_error &&
600 !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
601 EAlertSink *alert_sink;
603 alert_sink = e_activity_get_alert_sink (context->activity);
605 e_alert_submit (
606 alert_sink, "mail:mark-all-read",
607 local_error->message, NULL);
610 g_clear_error (&local_error);
612 e_activity_set_state (context->activity, E_ACTIVITY_COMPLETED);
615 static void
616 mark_all_read_collect_folder_names (GQueue *folder_names,
617 CamelFolderInfo *folder_info)
619 while (folder_info != NULL) {
620 if (folder_info->child != NULL)
621 mark_all_read_collect_folder_names (
622 folder_names, folder_info->child);
624 g_queue_push_tail (
625 folder_names, g_strdup (folder_info->full_name));
627 folder_info = folder_info->next;
631 enum {
632 MARK_ALL_READ_CANCEL,
633 MARK_ALL_READ_CURRENT_ONLY,
634 MARK_ALL_READ_WITH_SUBFOLDERS
637 static gint
638 mark_all_read_prompt_user (EMailShellView *mail_shell_view,
639 gboolean with_subfolders)
641 EShellView *shell_view;
642 EShellWindow *shell_window;
643 GtkWindow *parent;
645 shell_view = E_SHELL_VIEW (mail_shell_view);
646 shell_window = e_shell_view_get_shell_window (shell_view);
647 parent = GTK_WINDOW (shell_window);
649 if (with_subfolders) {
650 switch (e_alert_run_dialog_for_args (parent,
651 "mail:ask-mark-all-read-sub", NULL)) {
652 case GTK_RESPONSE_YES:
653 return MARK_ALL_READ_WITH_SUBFOLDERS;
654 case GTK_RESPONSE_NO:
655 return MARK_ALL_READ_CURRENT_ONLY;
656 default:
657 break;
659 } else if (e_util_prompt_user (parent,
660 "org.gnome.evolution.mail",
661 "prompt-on-mark-all-read",
662 "mail:ask-mark-all-read", NULL))
663 return MARK_ALL_READ_CURRENT_ONLY;
665 return MARK_ALL_READ_CANCEL;
668 static void
669 mark_all_read_got_folder_info (GObject *source,
670 GAsyncResult *result,
671 gpointer user_data)
673 CamelStore *store = CAMEL_STORE (source);
674 AsyncContext *context = user_data;
675 EAlertSink *alert_sink;
676 GCancellable *cancellable;
677 GSimpleAsyncResult *simple;
678 CamelFolderInfo *folder_info;
679 gint response;
680 GError *error = NULL;
682 alert_sink = e_activity_get_alert_sink (context->activity);
683 cancellable = e_activity_get_cancellable (context->activity);
685 folder_info = camel_store_get_folder_info_finish (
686 store, result, &error);
688 if (e_activity_handle_cancellation (context->activity, error)) {
689 g_warn_if_fail (folder_info == NULL);
690 async_context_free (context);
691 g_error_free (error);
692 return;
694 } else if (error != NULL) {
695 g_warn_if_fail (folder_info == NULL);
696 e_alert_submit (
697 alert_sink, "mail:mark-all-read",
698 error->message, NULL);
699 async_context_free (context);
700 g_error_free (error);
701 return;
704 if (!folder_info) {
705 /* Otherwise the operation is stuck and the Evolution cannot be quit */
706 g_warn_if_fail (folder_info != NULL);
707 e_activity_set_state (context->activity, E_ACTIVITY_COMPLETED);
708 async_context_free (context);
709 return;
712 response = mark_all_read_prompt_user (
713 context->mail_shell_view,
714 context->can_subfolders && folder_info->child != NULL);
716 if (response == MARK_ALL_READ_CURRENT_ONLY)
717 g_queue_push_tail (
718 &context->folder_names,
719 g_strdup (folder_info->full_name));
721 if (response == MARK_ALL_READ_WITH_SUBFOLDERS)
722 mark_all_read_collect_folder_names (
723 &context->folder_names, folder_info);
725 camel_folder_info_free (folder_info);
727 if (g_queue_is_empty (&context->folder_names)) {
728 e_activity_set_state (context->activity, E_ACTIVITY_COMPLETED);
729 async_context_free (context);
730 return;
733 simple = g_simple_async_result_new (
734 source, mark_all_read_done_cb,
735 context, mark_all_read_thread);
737 g_simple_async_result_set_op_res_gpointer (
738 simple, context, (GDestroyNotify) async_context_free);
740 g_simple_async_result_run_in_thread (
741 simple, mark_all_read_thread,
742 G_PRIORITY_DEFAULT, cancellable);
744 g_object_unref (simple);
747 static void
748 e_mail_shell_view_actions_mark_all_read (EMailShellView *mail_shell_view,
749 CamelStore *store,
750 const gchar *folder_name,
751 gboolean can_subfolders)
753 EShellView *shell_view;
754 EShellBackend *shell_backend;
755 EShellContent *shell_content;
756 EAlertSink *alert_sink;
757 GCancellable *cancellable;
758 AsyncContext *context;
760 g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
761 g_return_if_fail (CAMEL_IS_STORE (store));
762 g_return_if_fail (folder_name != NULL);
764 shell_view = E_SHELL_VIEW (mail_shell_view);
765 shell_backend = e_shell_view_get_shell_backend (shell_view);
766 shell_content = e_shell_view_get_shell_content (shell_view);
768 context = g_slice_new0 (AsyncContext);
769 context->mail_shell_view = g_object_ref (mail_shell_view);
770 context->can_subfolders = can_subfolders;
771 context->activity = e_activity_new ();
772 g_queue_init (&context->folder_names);
774 alert_sink = E_ALERT_SINK (shell_content);
775 e_activity_set_alert_sink (context->activity, alert_sink);
777 cancellable = camel_operation_new ();
778 e_activity_set_cancellable (context->activity, cancellable);
780 camel_operation_push_message (
781 cancellable, _("Marking messages as read..."));
783 e_shell_backend_add_activity (shell_backend, context->activity);
785 camel_store_get_folder_info (
786 store, folder_name,
787 can_subfolders ? CAMEL_STORE_FOLDER_INFO_RECURSIVE : 0,
788 G_PRIORITY_DEFAULT, cancellable,
789 mark_all_read_got_folder_info, context);
791 g_object_unref (cancellable);
794 static void
795 action_mail_folder_mark_all_as_read_cb (GtkAction *action,
796 EMailShellView *mail_shell_view)
798 EMailShellContent *mail_shell_content;
799 EMailReader *reader;
800 EMailView *mail_view;
801 CamelFolder *folder;
803 mail_shell_content = mail_shell_view->priv->mail_shell_content;
804 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
806 reader = E_MAIL_READER (mail_view);
808 folder = e_mail_reader_ref_folder (reader);
809 g_return_if_fail (folder != NULL);
811 if (camel_folder_get_folder_summary (folder) != NULL &&
812 camel_folder_summary_get_unread_count (camel_folder_get_folder_summary (folder)) == 0) {
813 g_object_unref (folder);
814 return;
817 e_mail_shell_view_actions_mark_all_read (
818 mail_shell_view,
819 camel_folder_get_parent_store (folder),
820 camel_folder_get_full_name (folder),
821 FALSE);
823 g_object_unref (folder);
826 static void
827 action_mail_popup_folder_mark_all_as_read_cb (GtkAction *action,
828 EMailShellView *mail_shell_view)
830 EMailShellSidebar *mail_shell_sidebar;
831 EMFolderTree *folder_tree;
832 CamelStore *store = NULL;
833 gchar *folder_name = NULL;
835 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
836 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
837 em_folder_tree_get_selected (folder_tree, &store, &folder_name);
839 /* This action should only be activatable if a folder is selected. */
840 g_return_if_fail (store != NULL && folder_name != NULL);
842 e_mail_shell_view_actions_mark_all_read (
843 mail_shell_view, store, folder_name, TRUE);
845 g_object_unref (store);
846 g_free (folder_name);
849 static void
850 action_mail_folder_move_cb (GtkAction *action,
851 EMailShellView *mail_shell_view)
853 EMailShellSidebar *mail_shell_sidebar;
854 EShellContent *shell_content;
855 EShellWindow *shell_window;
856 EShellView *shell_view;
857 EMFolderTree *folder_tree;
858 EMailSession *session;
859 gchar *selected_uri;
861 shell_view = E_SHELL_VIEW (mail_shell_view);
862 shell_window = e_shell_view_get_shell_window (shell_view);
863 shell_content = e_shell_view_get_shell_content (shell_view);
865 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
866 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
867 selected_uri = em_folder_tree_get_selected_uri (folder_tree);
868 session = em_folder_tree_get_session (folder_tree);
869 g_return_if_fail (selected_uri != NULL);
871 em_folder_utils_copy_folder (
872 GTK_WINDOW (shell_window),
873 session,
874 E_ALERT_SINK (shell_content),
875 selected_uri, TRUE);
877 g_free (selected_uri);
880 static void
881 action_mail_folder_new_cb (GtkAction *action,
882 EMailShellView *mail_shell_view)
884 EShellView *shell_view;
885 EShellWindow *shell_window;
886 EMailSession *session;
887 EMailShellSidebar *mail_shell_sidebar;
888 EMFolderTree *folder_tree;
889 GtkWidget *dialog;
890 CamelStore *store = NULL;
891 gchar *folder_name = NULL;
893 shell_view = E_SHELL_VIEW (mail_shell_view);
894 shell_window = e_shell_view_get_shell_window (shell_view);
896 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
897 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
899 session = em_folder_tree_get_session (folder_tree);
901 dialog = e_mail_folder_create_dialog_new (
902 GTK_WINDOW (shell_window),
903 E_MAIL_UI_SESSION (session));
905 g_signal_connect_data (
906 dialog, "folder-created",
907 G_CALLBACK (mail_shell_view_folder_created_cb),
908 e_weak_ref_new (folder_tree),
909 (GClosureNotify) e_weak_ref_free, 0);
911 if (em_folder_tree_get_selected (folder_tree, &store, &folder_name)) {
912 em_folder_selector_set_selected (
913 EM_FOLDER_SELECTOR (dialog), store, folder_name);
914 g_object_unref (store);
915 g_free (folder_name);
918 gtk_widget_show (GTK_WIDGET (dialog));
921 static void
922 action_mail_folder_properties_cb (GtkAction *action,
923 EMailShellView *mail_shell_view)
925 EMailShellSidebar *mail_shell_sidebar;
926 EShellView *shell_view;
927 EShellWindow *shell_window;
928 EShellContent *shell_content;
929 EMFolderTree *folder_tree;
930 CamelStore *store;
931 gchar *folder_name;
933 shell_view = E_SHELL_VIEW (mail_shell_view);
934 shell_window = e_shell_view_get_shell_window (shell_view);
935 shell_content = e_shell_view_get_shell_content (shell_view);
937 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
938 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
940 if (!em_folder_tree_get_selected (folder_tree, &store, &folder_name))
941 g_return_if_reached ();
943 em_folder_properties_show (
944 store, folder_name,
945 E_ALERT_SINK (shell_content),
946 GTK_WINDOW (shell_window));
948 g_object_unref (store);
949 g_free (folder_name);
952 static void
953 action_mail_folder_refresh_cb (GtkAction *action,
954 EMailShellView *mail_shell_view)
956 EMailShellContent *mail_shell_content;
957 EMailShellSidebar *mail_shell_sidebar;
958 EMailView *mail_view;
959 EMFolderTree *folder_tree;
960 CamelStore *selected_store = NULL;
961 gchar *selected_folder_name = NULL;
963 mail_shell_content = mail_shell_view->priv->mail_shell_content;
964 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
966 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
967 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
969 em_folder_tree_get_selected (
970 folder_tree, &selected_store, &selected_folder_name);
971 g_return_if_fail (CAMEL_IS_STORE (selected_store));
972 g_return_if_fail (selected_folder_name != NULL);
974 e_mail_reader_refresh_folder_name (
975 E_MAIL_READER (mail_view),
976 selected_store, selected_folder_name);
978 g_object_unref (selected_store);
979 g_free (selected_folder_name);
982 static void
983 action_mail_folder_rename_cb (GtkAction *action,
984 EMailShellView *mail_shell_view)
986 EMailShellSidebar *mail_shell_sidebar;
987 EMFolderTree *folder_tree;
989 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
990 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
992 em_folder_tree_edit_selected (folder_tree);
995 static void
996 action_mail_folder_select_thread_cb (GtkAction *action,
997 EMailShellView *mail_shell_view)
999 EMailShellContent *mail_shell_content;
1000 GtkWidget *message_list;
1001 EMailReader *reader;
1002 EMailView *mail_view;
1004 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1005 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1007 reader = E_MAIL_READER (mail_view);
1008 message_list = e_mail_reader_get_message_list (reader);
1010 message_list_select_thread (MESSAGE_LIST (message_list));
1013 static void
1014 action_mail_folder_select_subthread_cb (GtkAction *action,
1015 EMailShellView *mail_shell_view)
1017 EMailShellContent *mail_shell_content;
1018 GtkWidget *message_list;
1019 EMailReader *reader;
1020 EMailView *mail_view;
1022 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1023 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1025 reader = E_MAIL_READER (mail_view);
1026 message_list = e_mail_reader_get_message_list (reader);
1028 message_list_select_subthread (MESSAGE_LIST (message_list));
1031 static gboolean
1032 ask_can_unsubscribe_folder (GtkWindow *parent,
1033 EMailSession *session,
1034 CamelStore *store,
1035 const gchar *folder_name)
1037 CamelFolder *folder;
1038 gchar *full_display_name;
1039 gboolean res;
1041 g_return_val_if_fail (E_IS_MAIL_SESSION (session), FALSE);
1042 g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
1043 g_return_val_if_fail (folder_name != NULL, FALSE);
1045 folder = mail_folder_cache_ref_folder (e_mail_session_get_folder_cache (session), store, folder_name);
1046 g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
1048 full_display_name = e_mail_folder_to_full_display_name (folder, NULL);
1050 res = GTK_RESPONSE_YES == e_alert_run_dialog_for_args (parent,
1051 "mail:ask-unsubscribe-folder", full_display_name ? full_display_name : folder_name, NULL);
1053 g_clear_object (&folder);
1054 g_free (full_display_name);
1056 return res;
1059 static void
1060 action_mail_folder_unsubscribe_cb (GtkAction *action,
1061 EMailShellView *mail_shell_view)
1063 EMailShellContent *mail_shell_content;
1064 EMailShellSidebar *mail_shell_sidebar;
1065 EMailView *mail_view;
1066 EMFolderTree *folder_tree;
1067 EShellWindow *shell_window;
1068 EMailSession *session;
1069 CamelStore *selected_store = NULL;
1070 gchar *selected_folder_name = NULL;
1072 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1073 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1075 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
1076 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
1078 em_folder_tree_get_selected (
1079 folder_tree, &selected_store, &selected_folder_name);
1080 g_return_if_fail (CAMEL_IS_STORE (selected_store));
1081 g_return_if_fail (selected_folder_name != NULL);
1083 shell_window = e_shell_view_get_shell_window (E_SHELL_VIEW (mail_shell_view));
1084 session = em_folder_tree_get_session (folder_tree);
1086 if (ask_can_unsubscribe_folder (GTK_WINDOW (shell_window), session, selected_store, selected_folder_name))
1087 e_mail_reader_unsubscribe_folder_name (
1088 E_MAIL_READER (mail_view),
1089 selected_store, selected_folder_name);
1091 g_object_unref (selected_store);
1092 g_free (selected_folder_name);
1095 static void
1096 action_mail_global_expunge_cb (GtkAction *action,
1097 EMailShellView *mail_shell_view)
1099 EShellBackend *shell_backend;
1100 EShellWindow *shell_window;
1101 EShellView *shell_view;
1102 EMailBackend *backend;
1103 EMailSession *session;
1105 shell_view = E_SHELL_VIEW (mail_shell_view);
1106 shell_window = e_shell_view_get_shell_window (shell_view);
1107 shell_backend = e_shell_view_get_shell_backend (shell_view);
1109 backend = E_MAIL_BACKEND (shell_backend);
1110 session = e_mail_backend_get_session (backend);
1112 em_utils_empty_trash (
1113 GTK_WIDGET (shell_window), session);
1116 static void
1117 action_mail_goto_folder_cb (GtkAction *action,
1118 EMailShellView *mail_shell_view)
1120 CamelFolder *folder;
1121 EMailReader *reader;
1122 EMailView *mail_view;
1123 EMFolderSelector *selector;
1124 EMFolderTree *folder_tree;
1125 EMFolderTreeModel *model;
1126 GtkWidget *dialog;
1127 GtkWindow *window;
1128 const gchar *uri;
1130 mail_view = e_mail_shell_content_get_mail_view (mail_shell_view->priv->mail_shell_content);
1131 reader = E_MAIL_READER (mail_view);
1133 folder = e_mail_reader_ref_folder (reader);
1134 window = e_mail_reader_get_window (reader);
1136 model = em_folder_tree_model_get_default ();
1138 dialog = em_folder_selector_new (window, model);
1140 gtk_window_set_title (GTK_WINDOW (dialog), _("Go to Folder"));
1142 selector = EM_FOLDER_SELECTOR (dialog);
1143 em_folder_selector_set_can_create (selector, FALSE);
1144 em_folder_selector_set_default_button_label (selector, _("_Select"));
1146 folder_tree = em_folder_selector_get_folder_tree (selector);
1147 gtk_tree_view_expand_all (GTK_TREE_VIEW (folder_tree));
1149 if (folder) {
1150 gchar *uri = e_mail_folder_uri_from_folder (folder);
1152 if (uri) {
1153 em_folder_tree_set_selected (folder_tree, uri, FALSE);
1154 g_free (uri);
1158 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
1159 uri = em_folder_selector_get_selected_uri (selector);
1161 if (uri != NULL) {
1162 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_view->priv->mail_shell_sidebar);
1163 em_folder_tree_set_selected (folder_tree, uri, FALSE);
1167 gtk_widget_destroy (dialog);
1169 g_clear_object (&folder);
1172 static void
1173 action_mail_label_cb (GtkToggleAction *action,
1174 EMailShellView *mail_shell_view)
1176 EMailShellContent *mail_shell_content;
1177 EMailReader *reader;
1178 EMailView *mail_view;
1179 CamelFolder *folder;
1180 GPtrArray *uids;
1181 const gchar *tag;
1182 gint ii;
1184 tag = g_object_get_data (G_OBJECT (action), "tag");
1185 g_return_if_fail (tag != NULL);
1187 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1188 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1190 reader = E_MAIL_READER (mail_view);
1191 folder = e_mail_reader_ref_folder (reader);
1192 uids = e_mail_reader_get_selected_uids (reader);
1194 camel_folder_freeze (folder);
1195 for (ii = 0; ii < uids->len; ii++) {
1196 if (gtk_toggle_action_get_active (action))
1197 camel_folder_set_message_user_flag (
1198 folder, uids->pdata[ii], tag, TRUE);
1199 else {
1200 camel_folder_set_message_user_flag (
1201 folder, uids->pdata[ii], tag, FALSE);
1202 camel_folder_set_message_user_tag (
1203 folder, uids->pdata[ii], "label", NULL);
1206 camel_folder_thaw (folder);
1208 g_clear_object (&folder);
1209 g_ptr_array_unref (uids);
1212 static void
1213 action_mail_label_new_cb (GtkAction *action,
1214 EMailShellView *mail_shell_view)
1216 EShellView *shell_view;
1217 EShellWindow *shell_window;
1218 EShellBackend *shell_backend;
1219 EMailShellContent *mail_shell_content;
1220 EMailLabelDialog *label_dialog;
1221 EMailLabelListStore *label_store;
1222 EMailBackend *backend;
1223 EMailSession *session;
1224 EMailReader *reader;
1225 EMailView *mail_view;
1226 CamelFolder *folder;
1227 GtkTreeModel *model;
1228 GtkTreeIter iter;
1229 GtkWidget *dialog;
1230 GPtrArray *uids;
1231 GdkColor label_color;
1232 const gchar *label_name;
1233 gchar *label_tag;
1234 gint n_children;
1235 guint ii;
1237 shell_view = E_SHELL_VIEW (mail_shell_view);
1238 shell_window = e_shell_view_get_shell_window (shell_view);
1239 shell_backend = e_shell_view_get_shell_backend (shell_view);
1241 dialog = e_mail_label_dialog_new (GTK_WINDOW (shell_window));
1243 gtk_window_set_title (GTK_WINDOW (dialog), _("Add Label"));
1245 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
1246 goto exit;
1248 backend = E_MAIL_BACKEND (shell_backend);
1249 session = e_mail_backend_get_session (backend);
1250 label_store = e_mail_ui_session_get_label_store (
1251 E_MAIL_UI_SESSION (session));
1253 label_dialog = E_MAIL_LABEL_DIALOG (dialog);
1254 label_name = e_mail_label_dialog_get_label_name (label_dialog);
1255 e_mail_label_dialog_get_label_color (label_dialog, &label_color);
1257 e_mail_label_list_store_set (
1258 label_store, NULL, label_name, &label_color);
1260 /* XXX This is awkward. We've added a new label to the list store
1261 * but we don't have the new label's tag nor an iterator to use
1262 * to fetch it. We know the label was appended to the store,
1263 * so we have to dig it out manually. EMailLabelListStore API
1264 * probably needs some rethinking. */
1265 model = GTK_TREE_MODEL (label_store);
1266 n_children = gtk_tree_model_iter_n_children (model, NULL);
1267 gtk_tree_model_iter_nth_child (model, &iter, NULL, n_children - 1);
1268 label_tag = e_mail_label_list_store_get_tag (label_store, &iter);
1270 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1271 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1273 reader = E_MAIL_READER (mail_view);
1274 folder = e_mail_reader_ref_folder (reader);
1275 uids = e_mail_reader_get_selected_uids (reader);
1277 for (ii = 0; ii < uids->len; ii++)
1278 camel_folder_set_message_user_flag (
1279 folder, uids->pdata[ii], label_tag, TRUE);
1281 g_clear_object (&folder);
1282 g_ptr_array_unref (uids);
1284 g_free (label_tag);
1286 exit:
1287 gtk_widget_destroy (dialog);
1290 static void
1291 action_mail_label_none_cb (GtkAction *action,
1292 EMailShellView *mail_shell_view)
1294 EShellView *shell_view;
1295 EShellBackend *shell_backend;
1296 EMailBackend *backend;
1297 EMailSession *session;
1298 EMailShellContent *mail_shell_content;
1299 EMailLabelListStore *label_store;
1300 EMailReader *reader;
1301 EMailView *mail_view;
1302 CamelFolder *folder;
1303 GtkTreeIter iter;
1304 GPtrArray *uids;
1305 gboolean valid;
1306 guint ii;
1308 shell_view = E_SHELL_VIEW (mail_shell_view);
1309 shell_backend = e_shell_view_get_shell_backend (shell_view);
1311 backend = E_MAIL_BACKEND (shell_backend);
1312 session = e_mail_backend_get_session (backend);
1313 label_store = e_mail_ui_session_get_label_store (
1314 E_MAIL_UI_SESSION (session));
1316 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1317 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1319 reader = E_MAIL_READER (mail_view);
1320 folder = e_mail_reader_ref_folder (reader);
1321 uids = e_mail_reader_get_selected_uids (reader);
1323 valid = gtk_tree_model_get_iter_first (
1324 GTK_TREE_MODEL (label_store), &iter);
1326 while (valid) {
1327 gchar *tag;
1329 tag = e_mail_label_list_store_get_tag (label_store, &iter);
1331 for (ii = 0; ii < uids->len; ii++) {
1332 camel_folder_set_message_user_flag (
1333 folder, uids->pdata[ii], tag, FALSE);
1334 camel_folder_set_message_user_tag (
1335 folder, uids->pdata[ii], "label", NULL);
1338 g_free (tag);
1340 valid = gtk_tree_model_iter_next (
1341 GTK_TREE_MODEL (label_store), &iter);
1344 g_clear_object (&folder);
1345 g_ptr_array_unref (uids);
1348 static void
1349 action_mail_send_receive_cb (GtkAction *action,
1350 EMailShellView *mail_shell_view)
1352 EShellView *shell_view;
1353 EShellWindow *shell_window;
1354 EShellBackend *shell_backend;
1355 EMailBackend *backend;
1356 EMailSession *session;
1358 shell_view = E_SHELL_VIEW (mail_shell_view);
1359 shell_window = e_shell_view_get_shell_window (shell_view);
1360 shell_backend = e_shell_view_get_shell_backend (shell_view);
1362 backend = E_MAIL_BACKEND (shell_backend);
1363 session = e_mail_backend_get_session (backend);
1365 mail_send_receive (GTK_WINDOW (shell_window), session);
1368 static void
1369 action_mail_send_receive_receive_all_cb (GtkAction *action,
1370 EMailShellView *mail_shell_view)
1372 EShellView *shell_view;
1373 EShellWindow *shell_window;
1374 EShellBackend *shell_backend;
1375 EMailBackend *backend;
1376 EMailSession *session;
1378 shell_view = E_SHELL_VIEW (mail_shell_view);
1379 shell_window = e_shell_view_get_shell_window (shell_view);
1380 shell_backend = e_shell_view_get_shell_backend (shell_view);
1382 backend = E_MAIL_BACKEND (shell_backend);
1383 session = e_mail_backend_get_session (backend);
1385 mail_receive (GTK_WINDOW (shell_window), session);
1388 static void
1389 action_mail_send_receive_send_all_cb (GtkAction *action,
1390 EMailShellView *mail_shell_view)
1392 EShellView *shell_view;
1393 EShellBackend *shell_backend;
1394 EMailBackend *backend;
1395 EMailSession *session;
1397 shell_view = E_SHELL_VIEW (mail_shell_view);
1398 shell_backend = e_shell_view_get_shell_backend (shell_view);
1400 backend = E_MAIL_BACKEND (shell_backend);
1401 session = e_mail_backend_get_session (backend);
1403 mail_send_immediately (session);
1406 static void
1407 mail_shell_view_magic_spacebar (EMailShellView *mail_shell_view,
1408 gboolean move_forward)
1410 EMailShellContent *mail_shell_content;
1411 EMailShellSidebar *mail_shell_sidebar;
1412 EMFolderTree *folder_tree;
1413 EMailReader *reader;
1414 EMailView *mail_view;
1415 GtkWidget *message_list;
1416 EMailDisplay *display;
1417 GSettings *settings;
1418 gboolean magic_spacebar;
1420 /* This implements the so-called "Magic Backspace". */
1421 g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
1423 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1424 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1426 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
1427 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
1429 reader = E_MAIL_READER (mail_view);
1430 display = e_mail_reader_get_mail_display (reader);
1431 message_list = e_mail_reader_get_message_list (reader);
1433 settings = e_util_ref_settings ("org.gnome.evolution.mail");
1434 magic_spacebar = g_settings_get_boolean (settings, "magic-spacebar");
1435 g_object_unref (settings);
1437 if (!e_mail_display_process_magic_spacebar (display, move_forward)) {
1438 guint32 direction = move_forward ? MESSAGE_LIST_SELECT_NEXT : MESSAGE_LIST_SELECT_PREVIOUS;
1440 if (!magic_spacebar)
1441 return;
1443 if (message_list_select (MESSAGE_LIST (message_list),
1444 direction | MESSAGE_LIST_SELECT_WRAP |
1445 MESSAGE_LIST_SELECT_INCLUDE_COLLAPSED,
1446 0, CAMEL_MESSAGE_SEEN))
1447 return;
1449 em_folder_tree_select_next_path (folder_tree, TRUE);
1451 gtk_widget_grab_focus (message_list);
1455 static void
1456 action_mail_smart_backward_cb (GtkAction *action,
1457 EMailShellView *mail_shell_view)
1459 mail_shell_view_magic_spacebar (mail_shell_view, FALSE);
1462 static void
1463 action_mail_smart_forward_cb (GtkAction *action,
1464 EMailShellView *mail_shell_view)
1466 mail_shell_view_magic_spacebar (mail_shell_view, TRUE);
1469 static void
1470 action_mail_stop_cb (GtkAction *action,
1471 EMailShellView *mail_shell_view)
1473 EShellView *shell_view;
1474 EShellBackend *shell_backend;
1476 shell_view = E_SHELL_VIEW (mail_shell_view);
1477 shell_backend = e_shell_view_get_shell_backend (shell_view);
1479 e_shell_backend_cancel_all (shell_backend);
1482 static void
1483 action_mail_threads_collapse_all_cb (GtkAction *action,
1484 EMailShellView *mail_shell_view)
1486 EMailShellContent *mail_shell_content;
1487 GtkWidget *message_list;
1488 EMailReader *reader;
1489 EMailView *mail_view;
1491 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1492 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1494 reader = E_MAIL_READER (mail_view);
1495 message_list = e_mail_reader_get_message_list (reader);
1497 message_list_set_threaded_collapse_all (MESSAGE_LIST (message_list));
1500 static void
1501 action_mail_threads_expand_all_cb (GtkAction *action,
1502 EMailShellView *mail_shell_view)
1504 EMailShellContent *mail_shell_content;
1505 GtkWidget *message_list;
1506 EMailReader *reader;
1507 EMailView *mail_view;
1509 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1510 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1512 reader = E_MAIL_READER (mail_view);
1513 message_list = e_mail_reader_get_message_list (reader);
1515 message_list_set_threaded_expand_all (MESSAGE_LIST (message_list));
1518 static void
1519 action_mail_tools_filters_cb (GtkAction *action,
1520 EMailShellView *mail_shell_view)
1522 EShellBackend *shell_backend;
1523 EShellContent *shell_content;
1524 EShellWindow *shell_window;
1525 EShellView *shell_view;
1526 EMailBackend *backend;
1527 EMailSession *session;
1529 shell_view = E_SHELL_VIEW (mail_shell_view);
1530 shell_window = e_shell_view_get_shell_window (shell_view);
1531 shell_backend = e_shell_view_get_shell_backend (shell_view);
1532 shell_content = e_shell_view_get_shell_content (shell_view);
1534 backend = E_MAIL_BACKEND (shell_backend);
1535 session = e_mail_backend_get_session (backend);
1537 em_utils_edit_filters (
1538 session,
1539 E_ALERT_SINK (shell_content),
1540 GTK_WINDOW (shell_window));
1543 static void
1544 action_mail_tools_search_folders_cb (GtkAction *action,
1545 EMailShellView *mail_shell_view)
1547 EShellView *shell_view;
1548 EShellWindow *shell_window;
1549 EShellBackend *shell_backend;
1551 shell_view = E_SHELL_VIEW (mail_shell_view);
1552 shell_window = e_shell_view_get_shell_window (shell_view);
1553 shell_backend = e_shell_view_get_shell_backend (shell_view);
1555 vfolder_edit (
1556 E_MAIL_BACKEND (shell_backend),
1557 GTK_WINDOW (shell_window));
1560 static void
1561 action_mail_tools_subscriptions_cb (GtkAction *action,
1562 EMailShellView *mail_shell_view)
1564 EMailShellSidebar *mail_shell_sidebar;
1565 EShellWindow *shell_window;
1566 EShellView *shell_view;
1567 EMailSession *session;
1568 EMFolderTree *folder_tree;
1569 GtkWidget *dialog;
1570 CamelStore *store;
1572 shell_view = E_SHELL_VIEW (mail_shell_view);
1573 shell_window = e_shell_view_get_shell_window (shell_view);
1575 mail_shell_sidebar = mail_shell_view->priv->mail_shell_sidebar;
1576 folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
1577 session = em_folder_tree_get_session (folder_tree);
1579 /* The subscription editor's initial store can be NULL. */
1580 store = em_folder_tree_ref_selected_store (folder_tree);
1582 dialog = em_subscription_editor_new (
1583 GTK_WINDOW (shell_window), session, store);
1585 if (store != NULL)
1586 g_object_unref (store);
1588 gtk_dialog_run (GTK_DIALOG (dialog));
1589 gtk_widget_destroy (dialog);
1592 static void
1593 action_mail_view_cb (GtkRadioAction *action,
1594 GtkRadioAction *current,
1595 EMailShellView *mail_shell_view)
1597 EMailShellContent *mail_shell_content;
1598 GtkOrientation orientation;
1599 EMailView *mail_view;
1601 mail_shell_content = mail_shell_view->priv->mail_shell_content;
1602 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
1604 switch (gtk_radio_action_get_current_value (action)) {
1605 case 0:
1606 orientation = GTK_ORIENTATION_VERTICAL;
1607 break;
1608 case 1:
1609 orientation = GTK_ORIENTATION_HORIZONTAL;
1610 break;
1611 default:
1612 g_return_if_reached ();
1615 e_mail_view_set_orientation (mail_view, orientation);
1618 static GtkActionEntry mail_entries[] = {
1620 { "mail-account-disable",
1621 NULL,
1622 N_("_Disable Account"),
1623 NULL,
1624 N_("Disable this account"),
1625 G_CALLBACK (action_mail_account_disable_cb) },
1627 { "mail-account-expunge",
1628 NULL,
1629 N_("_Empty Trash"),
1630 NULL,
1631 N_("Permanently remove all the deleted messages from all folders"),
1632 G_CALLBACK (action_mail_folder_expunge_cb) },
1634 { "mail-account-empty-junk",
1635 NULL,
1636 N_("Empty _Junk"),
1637 NULL,
1638 N_("Delete all Junk messages from all folders"),
1639 G_CALLBACK (action_mail_folder_empty_junk_cb) },
1641 { "mail-account-properties",
1642 "document-properties",
1643 N_("_Properties"),
1644 NULL,
1645 N_("Edit properties of this account"),
1646 G_CALLBACK (action_mail_account_properties_cb) },
1648 { "mail-account-refresh",
1649 "view-refresh",
1650 N_("_Refresh"),
1651 NULL,
1652 N_("Refresh list of folders of this account"),
1653 G_CALLBACK (action_mail_account_refresh_cb) },
1655 { "mail-download",
1656 NULL,
1657 N_("_Download Messages for Offline Usage"),
1658 NULL,
1659 N_("Download messages of accounts and folders marked for offline usage"),
1660 G_CALLBACK (action_mail_download_cb) },
1662 { "mail-flush-outbox",
1663 "mail-send",
1664 N_("Fl_ush Outbox"),
1665 NULL,
1666 NULL, /* XXX Add a tooltip! */
1667 G_CALLBACK (action_mail_flush_outbox_cb) },
1669 { "mail-folder-copy",
1670 "folder-copy",
1671 N_("_Copy Folder To..."),
1672 NULL,
1673 N_("Copy the selected folder into another folder"),
1674 G_CALLBACK (action_mail_folder_copy_cb) },
1676 { "mail-folder-delete",
1677 "edit-delete",
1678 N_("_Delete"),
1679 NULL,
1680 N_("Permanently remove this folder"),
1681 G_CALLBACK (action_mail_folder_delete_cb) },
1683 { "mail-folder-expunge",
1684 NULL,
1685 N_("E_xpunge"),
1686 "<Control>e",
1687 N_("Permanently remove all deleted messages from this folder"),
1688 G_CALLBACK (action_mail_folder_expunge_cb) },
1690 { "mail-folder-mark-all-as-read",
1691 "mail-mark-read",
1692 N_("Mar_k All Messages as Read"),
1693 "<Control>slash",
1694 N_("Mark all messages in the folder as read"),
1695 G_CALLBACK (action_mail_folder_mark_all_as_read_cb) },
1697 { "mail-folder-move",
1698 "folder-move",
1699 N_("_Move Folder To..."),
1700 NULL,
1701 N_("Move the selected folder into another folder"),
1702 G_CALLBACK (action_mail_folder_move_cb) },
1704 { "mail-folder-new",
1705 "folder-new",
1706 /* Translators: An action caption to create a new mail folder */
1707 N_("_New..."),
1708 NULL,
1709 N_("Create a new folder for storing mail"),
1710 G_CALLBACK (action_mail_folder_new_cb) },
1712 { "mail-folder-properties",
1713 "document-properties",
1714 N_("_Properties"),
1715 NULL,
1716 N_("Change the properties of this folder"),
1717 G_CALLBACK (action_mail_folder_properties_cb) },
1719 { "mail-folder-refresh",
1720 "view-refresh",
1721 N_("_Refresh"),
1722 "F5",
1723 N_("Refresh the folder"),
1724 G_CALLBACK (action_mail_folder_refresh_cb) },
1726 { "mail-folder-rename",
1727 NULL,
1728 N_("_Rename..."),
1729 "F2",
1730 N_("Change the name of this folder"),
1731 G_CALLBACK (action_mail_folder_rename_cb) },
1733 { "mail-folder-select-thread",
1734 NULL,
1735 N_("Select Message _Thread"),
1736 "<Control>h",
1737 N_("Select all messages in the same thread as the selected message"),
1738 G_CALLBACK (action_mail_folder_select_thread_cb) },
1740 { "mail-folder-select-subthread",
1741 NULL,
1742 N_("Select Message S_ubthread"),
1743 "<Shift><Control>h",
1744 N_("Select all replies to the currently selected message"),
1745 G_CALLBACK (action_mail_folder_select_subthread_cb) },
1747 { "mail-folder-unsubscribe",
1748 NULL,
1749 N_("_Unsubscribe"),
1750 NULL,
1751 N_("Unsubscribe from the selected folder"),
1752 G_CALLBACK (action_mail_folder_unsubscribe_cb) },
1754 { "mail-global-expunge",
1755 NULL,
1756 N_("Empty _Trash"),
1757 NULL,
1758 N_("Permanently remove all the deleted messages from all accounts"),
1759 G_CALLBACK (action_mail_global_expunge_cb) },
1761 { "mail-goto-folder",
1762 NULL,
1763 N_("Go to _Folder"),
1764 "<Control>g",
1765 N_("Opens a dialog to select a folder to go to"),
1766 G_CALLBACK (action_mail_goto_folder_cb) },
1768 { "mail-label-new",
1769 NULL,
1770 N_("_New Label"),
1771 NULL,
1772 NULL, /* XXX Add a tooltip! */
1773 G_CALLBACK (action_mail_label_new_cb) },
1775 { "mail-label-none",
1776 NULL,
1777 /* Translators: "None" is used in the message label context menu.
1778 * It removes all labels from the selected messages. */
1779 N_("N_one"),
1780 "0",
1781 NULL, /* XXX Add a tooltip! */
1782 G_CALLBACK (action_mail_label_none_cb) },
1784 /* This is the same as "mail-tools-subscriptions" but only
1785 * appears in the sidebar context menu when right-clicking
1786 * on a store that supports folder subscriptions. No need
1787 * for a special callback because Folder->Subscriptions...
1788 * already tries to open the "Folder Subscriptions" dialog
1789 * according to the highlighted item in the sidebar, which
1790 * is exactly the behavior we want here. */
1791 { "mail-manage-subscriptions",
1792 NULL,
1793 N_("_Manage Subscriptions"),
1794 NULL,
1795 N_("Subscribe or unsubscribe to folders on remote servers"),
1796 G_CALLBACK (action_mail_tools_subscriptions_cb) },
1798 { "mail-popup-folder-mark-all-as-read",
1799 "mail-mark-read",
1800 N_("Mar_k All Messages as Read"),
1801 NULL,
1802 N_("Mark all messages in the folder as read"),
1803 G_CALLBACK (action_mail_popup_folder_mark_all_as_read_cb) },
1805 { "mail-send-receive",
1806 "mail-send-receive",
1807 N_("Send / _Receive"),
1808 "F12",
1809 N_("Send queued items and retrieve new items"),
1810 G_CALLBACK (action_mail_send_receive_cb) },
1812 { "mail-send-receive-receive-all",
1813 NULL,
1814 N_("R_eceive All"),
1815 NULL,
1816 N_("Receive new items from all accounts"),
1817 G_CALLBACK (action_mail_send_receive_receive_all_cb) },
1819 { "mail-send-receive-send-all",
1820 "mail-send",
1821 N_("_Send All"),
1822 NULL,
1823 N_("Send queued items in all accounts"),
1824 G_CALLBACK (action_mail_send_receive_send_all_cb) },
1826 { "mail-send-receive-submenu",
1827 "mail-send-receive",
1828 N_("Send / _Receive"),
1829 NULL,
1830 NULL,
1831 NULL },
1833 { "mail-smart-backward",
1834 NULL,
1835 NULL, /* No menu item; key press only */
1836 NULL,
1837 NULL,
1838 G_CALLBACK (action_mail_smart_backward_cb) },
1840 { "mail-smart-forward",
1841 NULL,
1842 NULL, /* No menu item; key press only */
1843 NULL,
1844 NULL,
1845 G_CALLBACK (action_mail_smart_forward_cb) },
1847 { "mail-stop",
1848 "process-stop",
1849 N_("Cancel"),
1850 NULL,
1851 N_("Cancel the current mail operation"),
1852 G_CALLBACK (action_mail_stop_cb) },
1854 { "mail-threads-collapse-all",
1855 NULL,
1856 N_("Collapse All _Threads"),
1857 "<Shift><Control>b",
1858 N_("Collapse all message threads"),
1859 G_CALLBACK (action_mail_threads_collapse_all_cb) },
1861 { "mail-threads-expand-all",
1862 NULL,
1863 N_("E_xpand All Threads"),
1864 NULL,
1865 N_("Expand all message threads"),
1866 G_CALLBACK (action_mail_threads_expand_all_cb) },
1868 { "mail-tools-filters",
1869 NULL,
1870 N_("_Message Filters"),
1871 NULL,
1872 N_("Create or edit rules for filtering new mail"),
1873 G_CALLBACK (action_mail_tools_filters_cb) },
1875 { "mail-tools-subscriptions",
1876 NULL,
1877 N_("_Subscriptions..."),
1878 NULL,
1879 N_("Subscribe or unsubscribe to folders on remote servers"),
1880 G_CALLBACK (action_mail_tools_subscriptions_cb) },
1882 /*** Menus ***/
1884 { "mail-folder-menu",
1885 NULL,
1886 N_("F_older"),
1887 NULL,
1888 NULL,
1889 NULL },
1891 { "mail-label-menu",
1892 NULL,
1893 N_("_Label"),
1894 NULL,
1895 NULL,
1896 NULL },
1898 { "mail-preview-menu",
1899 NULL,
1900 N_("_Preview"),
1901 NULL,
1902 NULL,
1903 NULL }
1906 static GtkActionEntry search_folder_entries[] = {
1908 { "mail-create-search-folder",
1909 NULL,
1910 N_("C_reate Search Folder From Search..."),
1911 NULL,
1912 NULL, /* XXX Add a tooltip! */
1913 G_CALLBACK (action_mail_create_search_folder_cb) },
1915 { "mail-tools-search-folders",
1916 NULL,
1917 N_("Search F_olders"),
1918 NULL,
1919 N_("Create or edit search folder definitions"),
1920 G_CALLBACK (action_mail_tools_search_folders_cb) },
1923 static EPopupActionEntry mail_popup_entries[] = {
1925 { "mail-popup-account-disable",
1926 NULL,
1927 "mail-account-disable" },
1929 { "mail-popup-account-expunge",
1930 NULL,
1931 "mail-account-expunge" },
1933 { "mail-popup-account-empty-junk",
1934 NULL,
1935 "mail-account-empty-junk" },
1937 { "mail-popup-account-refresh",
1938 NULL,
1939 "mail-account-refresh" },
1941 { "mail-popup-account-properties",
1942 NULL,
1943 "mail-account-properties" },
1945 { "mail-popup-flush-outbox",
1946 NULL,
1947 "mail-flush-outbox" },
1949 { "mail-popup-folder-copy",
1950 NULL,
1951 "mail-folder-copy" },
1953 { "mail-popup-folder-delete",
1954 NULL,
1955 "mail-folder-delete" },
1957 { "mail-popup-folder-move",
1958 NULL,
1959 "mail-folder-move" },
1961 { "mail-popup-folder-new",
1962 N_("_New Folder..."),
1963 "mail-folder-new" },
1965 { "mail-popup-folder-properties",
1966 NULL,
1967 "mail-folder-properties" },
1969 { "mail-popup-folder-refresh",
1970 NULL,
1971 "mail-folder-refresh" },
1973 { "mail-popup-folder-rename",
1974 NULL,
1975 "mail-folder-rename" },
1977 { "mail-popup-folder-unsubscribe",
1978 NULL,
1979 "mail-folder-unsubscribe" },
1981 { "mail-popup-manage-subscriptions",
1982 NULL,
1983 "mail-manage-subscriptions" }
1986 static GtkToggleActionEntry mail_toggle_entries[] = {
1988 { "mail-preview",
1989 NULL,
1990 N_("Show Message _Preview"),
1991 "<Control>m",
1992 N_("Show message preview pane"),
1993 NULL, /* Handled by property bindings */
1994 TRUE },
1996 { "mail-attachment-bar",
1997 NULL,
1998 N_("Show _Attachment Bar"),
1999 NULL,
2000 N_("Show Attachment Bar below the message preview pane when the message has attachments"),
2001 G_CALLBACK (action_mail_attachment_bar_cb),
2002 TRUE },
2004 { "mail-show-deleted",
2005 NULL,
2006 N_("Show _Deleted Messages"),
2007 NULL,
2008 N_("Show deleted messages with a line through them"),
2009 NULL, /* Handled by property bindings */
2010 FALSE },
2012 { "mail-show-junk",
2013 NULL,
2014 N_("Show _Junk Messages"),
2015 NULL,
2016 N_("Show junk messages with a red line through them"),
2017 NULL, /* Handled by property bindings */
2018 FALSE },
2020 { "mail-threads-group-by",
2021 NULL,
2022 N_("_Group By Threads"),
2023 "<Control>t",
2024 N_("Threaded message list"),
2025 NULL, /* Handled by property bindings */
2026 FALSE },
2028 { "mail-to-do-bar",
2029 NULL,
2030 N_("Show To _Do Bar"),
2031 NULL,
2032 N_("Show To Do bar with appointments and tasks"),
2033 G_CALLBACK (action_mail_to_do_bar_cb),
2034 TRUE },
2036 { "mail-vfolder-unmatched-enable",
2037 NULL,
2038 N_("_Unmatched Folder Enabled"),
2039 NULL,
2040 N_("Toggles whether Unmatched search folder is enabled"),
2041 NULL }
2044 static GtkRadioActionEntry mail_view_entries[] = {
2046 /* This action represents the initial active mail view.
2047 * It should not be visible in the UI, nor should it be
2048 * possible to switch to it from another shell view. */
2049 { "mail-view-initial",
2050 NULL,
2051 NULL,
2052 NULL,
2053 NULL,
2054 -1 },
2056 { "mail-view-classic",
2057 NULL,
2058 N_("_Classic View"),
2059 NULL,
2060 N_("Show message preview below the message list"),
2061 0 },
2063 { "mail-view-vertical",
2064 NULL,
2065 N_("_Vertical View"),
2066 NULL,
2067 N_("Show message preview alongside the message list"),
2071 static GtkRadioActionEntry mail_filter_entries[] = {
2073 { "mail-filter-all-messages",
2074 NULL,
2075 N_("All Messages"),
2076 NULL,
2077 NULL, /* XXX Add a tooltip! */
2078 MAIL_FILTER_ALL_MESSAGES },
2080 { "mail-filter-important-messages",
2081 "emblem-important",
2082 N_("Important Messages"),
2083 NULL,
2084 NULL, /* XXX Add a tooltip! */
2085 MAIL_FILTER_IMPORTANT_MESSAGES },
2087 { "mail-filter-last-5-days-messages",
2088 NULL,
2089 N_("Last 5 Days’ Messages"),
2090 NULL,
2091 NULL, /* XXX Add a tooltip! */
2092 MAIL_FILTER_LAST_5_DAYS_MESSAGES },
2094 { "mail-filter-messages-not-junk",
2095 "mail-mark-notjunk",
2096 N_("Messages Not Junk"),
2097 NULL,
2098 NULL, /* XXX Add a tooltip! */
2099 MAIL_FILTER_MESSAGES_NOT_JUNK },
2101 { "mail-filter-messages-with-attachments",
2102 "mail-attachment",
2103 N_("Messages with Attachments"),
2104 NULL,
2105 NULL, /* XXX Add a tooltip! */
2106 MAIL_FILTER_MESSAGES_WITH_ATTACHMENTS },
2108 { "mail-filter-messages-with-notes",
2109 "evolution-memos",
2110 N_("Messages with Notes"),
2111 NULL,
2112 NULL, /* XXX Add a tooltip! */
2113 MAIL_FILTER_MESSAGES_WITH_NOTES },
2115 { "mail-filter-no-label",
2116 NULL,
2117 N_("No Label"),
2118 NULL,
2119 NULL, /* XXX Add a tooltip! */
2120 MAIL_FILTER_NO_LABEL },
2122 { "mail-filter-read-messages",
2123 "mail-read",
2124 N_("Read Messages"),
2125 NULL,
2126 NULL, /* XXX Add a tooltip! */
2127 MAIL_FILTER_READ_MESSAGES },
2129 { "mail-filter-unread-messages",
2130 "mail-unread",
2131 N_("Unread Messages"),
2132 NULL,
2133 NULL, /* XXX Add a tooltip! */
2134 MAIL_FILTER_UNREAD_MESSAGES },
2136 { "mail-filter-message-thread",
2137 NULL,
2138 N_("Message Thread"),
2139 NULL,
2140 NULL, /* XXX Add a tooltip! */
2141 MAIL_FILTER_MESSAGE_THREAD }
2145 static GtkRadioActionEntry mail_search_entries[] = {
2147 { "mail-search-advanced-hidden",
2148 NULL,
2149 N_("Advanced Search"),
2150 NULL,
2151 NULL,
2152 MAIL_SEARCH_ADVANCED },
2154 { "mail-search-body-contains",
2155 NULL,
2156 N_("Body contains"),
2157 NULL,
2158 NULL, /* XXX Add a tooltip! */
2159 MAIL_SEARCH_BODY_CONTAINS },
2161 { "mail-search-free-form-expr",
2162 NULL,
2163 N_("Free form expression"),
2164 NULL,
2165 NULL, /* XXX Add a tooltip! */
2166 MAIL_SEARCH_FREE_FORM_EXPR },
2168 { "mail-search-message-contains",
2169 NULL,
2170 N_("Message contains"),
2171 NULL,
2172 NULL, /* XXX Add a tooltip! */
2173 MAIL_SEARCH_MESSAGE_CONTAINS },
2175 { "mail-search-recipients-contain",
2176 NULL,
2177 N_("Recipients contain"),
2178 NULL,
2179 NULL, /* XXX Add a tooltip! */
2180 MAIL_SEARCH_RECIPIENTS_CONTAIN },
2182 { "mail-search-sender-contains",
2183 NULL,
2184 N_("Sender contains"),
2185 NULL,
2186 NULL, /* XXX Add a tooltip! */
2187 MAIL_SEARCH_SENDER_CONTAINS },
2189 { "mail-search-subject-contains",
2190 NULL,
2191 N_("Subject contains"),
2192 NULL,
2193 NULL, /* XXX Add a tooltip! */
2194 MAIL_SEARCH_SUBJECT_CONTAINS },
2196 { "mail-search-subject-or-addresses-contain",
2197 NULL,
2198 N_("Subject or Addresses contain"),
2199 NULL,
2200 NULL, /* XXX Add a tooltip! */
2201 MAIL_SEARCH_SUBJECT_OR_ADDRESSES_CONTAIN }
2204 static GtkRadioActionEntry mail_scope_entries[] = {
2206 { "mail-scope-all-accounts",
2207 NULL,
2208 N_("All Accounts"),
2209 NULL,
2210 NULL, /* XXX Add a tooltip! */
2211 MAIL_SCOPE_ALL_ACCOUNTS },
2213 { "mail-scope-current-account",
2214 NULL,
2215 N_("Current Account"),
2216 NULL,
2217 NULL, /* XXX Add a tooltip! */
2218 MAIL_SCOPE_CURRENT_ACCOUNT },
2220 { "mail-scope-current-folder",
2221 NULL,
2222 N_("Current Folder"),
2223 NULL,
2224 NULL, /* XXX Add a tooltip! */
2225 MAIL_SCOPE_CURRENT_FOLDER }
2228 void
2229 e_mail_shell_view_actions_init (EMailShellView *mail_shell_view)
2231 EMailShellContent *mail_shell_content;
2232 EShellView *shell_view;
2233 EShellWindow *shell_window;
2234 EShellBackend *shell_backend;
2235 EShell *shell;
2236 EShellSearchbar *searchbar;
2237 EActionComboBox *combo_box;
2238 EMailView *mail_view;
2239 GtkActionGroup *action_group;
2240 GtkAction *action;
2241 GSettings *settings;
2243 g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
2245 shell_view = E_SHELL_VIEW (mail_shell_view);
2246 shell_window = e_shell_view_get_shell_window (shell_view);
2247 shell_backend = e_shell_view_get_shell_backend (shell_view);
2248 shell = e_shell_window_get_shell (shell_window);
2250 mail_shell_content = mail_shell_view->priv->mail_shell_content;
2251 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
2252 searchbar = e_mail_shell_content_get_searchbar (mail_shell_content);
2254 /* Mail Actions */
2255 action_group = ACTION_GROUP (MAIL);
2256 gtk_action_group_add_actions (
2257 action_group, mail_entries,
2258 G_N_ELEMENTS (mail_entries), mail_shell_view);
2259 gtk_action_group_add_toggle_actions (
2260 action_group, mail_toggle_entries,
2261 G_N_ELEMENTS (mail_toggle_entries), mail_shell_view);
2262 gtk_action_group_add_radio_actions (
2263 action_group, mail_view_entries,
2264 G_N_ELEMENTS (mail_view_entries), -1,
2265 G_CALLBACK (action_mail_view_cb), mail_shell_view);
2266 gtk_action_group_add_radio_actions (
2267 action_group, mail_search_entries,
2268 G_N_ELEMENTS (mail_search_entries),
2269 -1, NULL, NULL);
2270 gtk_action_group_add_radio_actions (
2271 action_group, mail_scope_entries,
2272 G_N_ELEMENTS (mail_scope_entries),
2273 MAIL_SCOPE_CURRENT_FOLDER, NULL, NULL);
2274 e_action_group_add_popup_actions (
2275 action_group, mail_popup_entries,
2276 G_N_ELEMENTS (mail_popup_entries));
2278 /* Search Folder Actions */
2279 action_group = ACTION_GROUP (SEARCH_FOLDERS);
2280 gtk_action_group_add_actions (
2281 action_group, search_folder_entries,
2282 G_N_ELEMENTS (search_folder_entries), mail_shell_view);
2284 action = ACTION (MAIL_SCOPE_ALL_ACCOUNTS);
2285 combo_box = e_shell_searchbar_get_scope_combo_box (searchbar);
2286 e_action_combo_box_set_action (combo_box, GTK_RADIO_ACTION (action));
2287 e_shell_searchbar_set_scope_visible (searchbar, TRUE);
2289 /* Advanced Search Action */
2290 action = ACTION (MAIL_SEARCH_ADVANCED_HIDDEN);
2291 gtk_action_set_visible (action, FALSE);
2292 e_shell_searchbar_set_search_option (
2293 searchbar, GTK_RADIO_ACTION (action));
2295 g_object_set (ACTION (MAIL_SEND_RECEIVE), "is-important", TRUE, NULL);
2297 /* Bind GObject properties for GSettings keys. */
2299 settings = e_util_ref_settings ("org.gnome.evolution.mail");
2301 g_settings_bind (
2302 settings, "show-deleted",
2303 ACTION (MAIL_SHOW_DELETED), "active",
2304 G_SETTINGS_BIND_DEFAULT);
2306 g_settings_bind (
2307 settings, "show-junk",
2308 ACTION (MAIL_SHOW_JUNK), "active",
2309 G_SETTINGS_BIND_DEFAULT);
2311 g_settings_bind (
2312 settings, "layout",
2313 ACTION (MAIL_VIEW_VERTICAL), "current-value",
2314 G_SETTINGS_BIND_DEFAULT);
2316 g_settings_bind (
2317 settings, "enable-unmatched",
2318 ACTION (MAIL_VFOLDER_UNMATCHED_ENABLE), "active",
2319 G_SETTINGS_BIND_DEFAULT);
2321 g_settings_bind (
2322 settings, "show-attachment-bar",
2323 ACTION (MAIL_ATTACHMENT_BAR), "active",
2324 G_SETTINGS_BIND_DEFAULT);
2326 if (e_shell_window_is_main_instance (shell_window)) {
2327 g_settings_bind (
2328 settings, "show-to-do-bar",
2329 ACTION (MAIL_TO_DO_BAR), "active",
2330 G_SETTINGS_BIND_DEFAULT);
2331 } else {
2332 g_settings_bind (
2333 settings, "show-to-do-bar-sub",
2334 ACTION (MAIL_TO_DO_BAR), "active",
2335 G_SETTINGS_BIND_DEFAULT);
2338 g_object_unref (settings);
2340 /* Fine tuning. */
2342 e_binding_bind_property (
2343 ACTION (MAIL_THREADS_GROUP_BY), "active",
2344 ACTION (MAIL_FOLDER_SELECT_THREAD), "sensitive",
2345 G_BINDING_SYNC_CREATE);
2347 e_binding_bind_property (
2348 ACTION (MAIL_THREADS_GROUP_BY), "active",
2349 ACTION (MAIL_FOLDER_SELECT_SUBTHREAD), "sensitive",
2350 G_BINDING_SYNC_CREATE);
2352 e_binding_bind_property (
2353 ACTION (MAIL_THREADS_GROUP_BY), "active",
2354 ACTION (MAIL_THREADS_COLLAPSE_ALL), "sensitive",
2355 G_BINDING_SYNC_CREATE);
2357 e_binding_bind_property (
2358 ACTION (MAIL_THREADS_GROUP_BY), "active",
2359 ACTION (MAIL_THREADS_EXPAND_ALL), "sensitive",
2360 G_BINDING_SYNC_CREATE);
2362 e_binding_bind_property (
2363 ACTION (MAIL_PREVIEW), "active",
2364 mail_view, "preview-visible",
2365 G_BINDING_BIDIRECTIONAL |
2366 G_BINDING_SYNC_CREATE);
2368 e_binding_bind_property (
2369 ACTION (MAIL_THREADS_GROUP_BY), "active",
2370 mail_shell_content, "group-by-threads",
2371 G_BINDING_BIDIRECTIONAL |
2372 G_BINDING_SYNC_CREATE);
2374 e_binding_bind_property (
2375 ACTION (MAIL_PREVIEW), "active",
2376 ACTION (MAIL_VIEW_CLASSIC), "sensitive",
2377 G_BINDING_SYNC_CREATE);
2379 e_binding_bind_property (
2380 ACTION (MAIL_PREVIEW), "active",
2381 ACTION (MAIL_VIEW_VERTICAL), "sensitive",
2382 G_BINDING_SYNC_CREATE);
2384 e_binding_bind_property (
2385 ACTION (MAIL_SHOW_DELETED), "active",
2386 mail_view, "show-deleted",
2387 G_BINDING_BIDIRECTIONAL |
2388 G_BINDING_SYNC_CREATE);
2390 e_binding_bind_property (
2391 ACTION (MAIL_SHOW_JUNK), "active",
2392 mail_view, "show-junk",
2393 G_BINDING_BIDIRECTIONAL |
2394 G_BINDING_SYNC_CREATE);
2396 e_binding_bind_property (
2397 shell_backend, "busy",
2398 ACTION (MAIL_STOP), "sensitive",
2399 G_BINDING_SYNC_CREATE);
2401 /* Keep the sensitivity of "Create Search Folder from Search"
2402 * in sync with "Save Search" so that its only selectable when
2403 * showing search results. */
2404 e_binding_bind_property (
2405 ACTION (SEARCH_SAVE), "sensitive",
2406 ACTION (MAIL_CREATE_SEARCH_FOLDER), "sensitive",
2407 G_BINDING_SYNC_CREATE);
2409 e_binding_bind_property (
2410 shell, "online",
2411 ACTION (MAIL_DOWNLOAD), "sensitive",
2412 G_BINDING_SYNC_CREATE);
2415 /* Helper for e_mail_shell_view_update_popup_labels() */
2416 static void
2417 mail_shell_view_update_label_action (GtkToggleAction *action,
2418 EMailReader *reader,
2419 GPtrArray *uids,
2420 const gchar *label_tag)
2422 CamelFolder *folder;
2423 gboolean exists = FALSE;
2424 gboolean not_exists = FALSE;
2425 gboolean sensitive;
2426 guint ii;
2428 folder = e_mail_reader_ref_folder (reader);
2430 /* Figure out the proper label action state for the selected
2431 * messages. If all the selected messages have the given label,
2432 * make the toggle action active. If all the selected message
2433 * DO NOT have the given label, make the toggle action inactive.
2434 * If some do and some don't, make the action insensitive. */
2436 for (ii = 0; ii < uids->len && (!exists || !not_exists); ii++) {
2437 const gchar *old_label;
2438 gchar *new_label;
2440 /* Check for new-style labels. */
2441 if (camel_folder_get_message_user_flag (
2442 folder, uids->pdata[ii], label_tag)) {
2443 exists = TRUE;
2444 continue;
2447 /* Check for old-style labels. */
2448 old_label = camel_folder_get_message_user_tag (
2449 folder, uids->pdata[ii], "label");
2450 if (old_label == NULL) {
2451 not_exists = TRUE;
2452 continue;
2455 /* Convert old-style labels ("<name>") to "$Label<name>". */
2456 new_label = g_alloca (strlen (old_label) + 10);
2457 g_stpcpy (g_stpcpy (new_label, "$Label"), old_label);
2459 if (strcmp (new_label, label_tag) == 0)
2460 exists = TRUE;
2461 else
2462 not_exists = TRUE;
2465 sensitive = !(exists && not_exists);
2466 gtk_toggle_action_set_active (action, exists);
2467 gtk_action_set_sensitive (GTK_ACTION (action), sensitive);
2469 g_clear_object (&folder);
2472 void
2473 e_mail_shell_view_update_popup_labels (EMailShellView *mail_shell_view)
2475 EShellView *shell_view;
2476 EShellWindow *shell_window;
2477 EShellBackend *shell_backend;
2478 EMailShellContent *mail_shell_content;
2479 EMailLabelListStore *label_store;
2480 EMailBackend *backend;
2481 EMailSession *session;
2482 EMailReader *reader;
2483 EMailView *mail_view;
2484 GtkUIManager *ui_manager;
2485 GtkActionGroup *action_group;
2486 GtkTreeIter iter;
2487 GPtrArray *uids;
2488 const gchar *path;
2489 gboolean valid;
2490 guint merge_id;
2491 gint ii = 0;
2493 g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
2495 shell_view = E_SHELL_VIEW (mail_shell_view);
2496 shell_window = e_shell_view_get_shell_window (shell_view);
2497 shell_backend = e_shell_view_get_shell_backend (shell_view);
2498 ui_manager = e_shell_window_get_ui_manager (shell_window);
2500 g_return_if_fail (ui_manager != NULL);
2501 g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
2503 backend = E_MAIL_BACKEND (shell_backend);
2504 session = e_mail_backend_get_session (backend);
2505 label_store = e_mail_ui_session_get_label_store (
2506 E_MAIL_UI_SESSION (session));
2508 action_group = ACTION_GROUP (MAIL_LABEL);
2509 merge_id = mail_shell_view->priv->label_merge_id;
2510 path = "/mail-message-popup/mail-label-menu/mail-label-actions";
2512 /* Unmerge the previous menu items. */
2513 gtk_ui_manager_remove_ui (ui_manager, merge_id);
2514 e_action_group_remove_all_actions (action_group);
2515 gtk_ui_manager_ensure_update (ui_manager);
2517 mail_shell_content = mail_shell_view->priv->mail_shell_content;
2518 mail_view = e_mail_shell_content_get_mail_view (mail_shell_content);
2520 reader = E_MAIL_READER (mail_view);
2521 uids = e_mail_reader_get_selected_uids (reader);
2523 valid = gtk_tree_model_get_iter_first (
2524 GTK_TREE_MODEL (label_store), &iter);
2526 while (valid) {
2527 EMailLabelAction *label_action;
2528 GtkAction *action;
2529 gchar *action_name;
2530 gchar *stock_id;
2531 gchar *label;
2532 gchar *tag;
2534 label = e_mail_label_list_store_get_name (
2535 label_store, &iter);
2536 stock_id = e_mail_label_list_store_get_stock_id (
2537 label_store, &iter);
2538 tag = e_mail_label_list_store_get_tag (
2539 label_store, &iter);
2540 action_name = g_strdup_printf ("mail-label-%d", ii);
2542 /* XXX Add a tooltip! */
2543 label_action = e_mail_label_action_new (
2544 action_name, label, NULL, stock_id);
2546 g_object_set_data_full (
2547 G_OBJECT (label_action), "tag",
2548 tag, (GDestroyNotify) g_free);
2550 /* Configure the action before we connect to signals. */
2551 mail_shell_view_update_label_action (
2552 GTK_TOGGLE_ACTION (label_action),
2553 reader, uids, tag);
2555 g_signal_connect (
2556 label_action, "toggled",
2557 G_CALLBACK (action_mail_label_cb), mail_shell_view);
2559 /* The action group takes ownership of the action. */
2560 action = GTK_ACTION (label_action);
2562 if (ii + 1 < 10) {
2563 gchar accel[5];
2565 accel[0] = '1' + ii;
2566 accel[1] = '\0';
2568 gtk_action_group_add_action_with_accel (action_group, action, accel);
2569 } else {
2570 gtk_action_group_add_action (action_group, action);
2572 g_object_unref (label_action);
2574 gtk_ui_manager_add_ui (
2575 ui_manager, merge_id, path, action_name,
2576 action_name, GTK_UI_MANAGER_AUTO, FALSE);
2578 g_free (label);
2579 g_free (stock_id);
2580 g_free (action_name);
2582 valid = gtk_tree_model_iter_next (
2583 GTK_TREE_MODEL (label_store), &iter);
2584 ii++;
2587 g_ptr_array_unref (uids);
2590 void
2591 e_mail_shell_view_update_search_filter (EMailShellView *mail_shell_view)
2593 EMailShellContent *mail_shell_content;
2594 EShellView *shell_view;
2595 EShellWindow *shell_window;
2596 EShellBackend *shell_backend;
2597 EShellSearchbar *searchbar;
2598 EMailLabelListStore *label_store;
2599 EMailBackend *backend;
2600 EMailSession *session;
2601 EActionComboBox *combo_box;
2602 GtkActionGroup *action_group;
2603 GtkRadioAction *radio_action;
2604 GtkTreeIter iter;
2605 GList *list;
2606 GSList *group;
2607 gboolean valid;
2608 gint ii = 0;
2610 g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view));
2612 shell_view = E_SHELL_VIEW (mail_shell_view);
2613 shell_window = e_shell_view_get_shell_window (shell_view);
2614 shell_backend = e_shell_view_get_shell_backend (shell_view);
2616 backend = E_MAIL_BACKEND (shell_backend);
2617 session = e_mail_backend_get_session (backend);
2618 label_store = e_mail_ui_session_get_label_store (
2619 E_MAIL_UI_SESSION (session));
2621 action_group = ACTION_GROUP (MAIL_FILTER);
2622 e_action_group_remove_all_actions (action_group);
2624 /* Add the standard filter actions. No callback is needed
2625 * because changes in the EActionComboBox are detected and
2626 * handled by EShellSearchbar. */
2627 gtk_action_group_add_radio_actions (
2628 action_group, mail_filter_entries,
2629 G_N_ELEMENTS (mail_filter_entries),
2630 MAIL_FILTER_ALL_MESSAGES, NULL, NULL);
2632 /* Retrieve the radio group from an action we just added. */
2633 list = gtk_action_group_list_actions (action_group);
2634 radio_action = GTK_RADIO_ACTION (list->data);
2635 group = gtk_radio_action_get_group (radio_action);
2636 g_list_free (list);
2638 valid = gtk_tree_model_get_iter_first (
2639 GTK_TREE_MODEL (label_store), &iter);
2641 while (valid) {
2642 GtkAction *action;
2643 gchar *action_name;
2644 gchar *stock_id;
2645 gchar *label;
2647 label = e_mail_label_list_store_get_name (
2648 label_store, &iter);
2649 stock_id = e_mail_label_list_store_get_stock_id (
2650 label_store, &iter);
2652 action_name = g_strdup_printf ("mail-filter-label-%d", ii);
2653 radio_action = gtk_radio_action_new (
2654 action_name, label, NULL, stock_id, ii);
2655 g_free (action_name);
2657 gtk_radio_action_set_group (radio_action, group);
2658 group = gtk_radio_action_get_group (radio_action);
2660 /* The action group takes ownership of the action. */
2661 action = GTK_ACTION (radio_action);
2662 gtk_action_group_add_action (action_group, action);
2663 g_object_unref (radio_action);
2665 g_free (label);
2666 g_free (stock_id);
2668 valid = gtk_tree_model_iter_next (
2669 GTK_TREE_MODEL (label_store), &iter);
2670 ii++;
2673 mail_shell_content = mail_shell_view->priv->mail_shell_content;
2674 searchbar = e_mail_shell_content_get_searchbar (mail_shell_content);
2675 combo_box = e_shell_searchbar_get_filter_combo_box (searchbar);
2677 e_shell_view_block_execute_search (shell_view);
2679 /* Use any action in the group; doesn't matter which. */
2680 e_action_combo_box_set_action (combo_box, radio_action);
2682 ii = MAIL_FILTER_MESSAGES_NOT_JUNK;
2683 e_action_combo_box_add_separator_after (combo_box, ii);
2685 ii = MAIL_FILTER_READ_MESSAGES;
2686 e_action_combo_box_add_separator_after (combo_box, ii);
2688 e_shell_view_unblock_execute_search (shell_view);