No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-reader.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-reader.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * e-mail-reader.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "e-mail-reader.h"
27
28 #include <glib/gi18n.h>
29 #include <gdk/gdkkeysyms.h>
30
31 #ifdef HAVE_XFREE
32 #include <X11/XF86keysym.h>
33 #endif
34
35 #include "e-util/e-charset.h"
36 #include "e-util/e-util.h"
37 #include "libevolution-utils/e-alert-dialog.h"
38 #include "shell/e-shell-utils.h"
39 #include "widgets/misc/e-popup-action.h"
40 #include "widgets/misc/e-menu-tool-action.h"
41
42 #include "libemail-utils/mail-mt.h"
43
44 #include "libemail-engine/mail-ops.h"
45 #include "libemail-engine/e-mail-utils.h"
46 #include "libemail-engine/e-mail-enumtypes.h"
47
48 #include "mail/e-mail-backend.h"
49 #include "mail/e-mail-browser.h"
50 #include "mail/e-mail-reader-utils.h"
51 #include "mail/e-mail-ui-session.h"
52 #include "mail/e-mail-view.h"
53 #include "mail/em-composer-utils.h"
54 #include "mail/em-event.h"
55 #include "mail/em-folder-selector.h"
56 #include "mail/em-folder-tree.h"
57 #include "mail/em-utils.h"
58 #include "mail/mail-autofilter.h"
59 #include "mail/mail-vfolder-ui.h"
60 #include "mail/message-list.h"
61
62 #include <em-format/e-mail-formatter.h>
63 #include <em-format/e-mail-parser.h>
64 #include <em-format/e-mail-part-utils.h>
65
66 #define E_MAIL_READER_GET_PRIVATE(obj) \
67 ((EMailReaderPrivate *) g_object_get_qdata \
68 (G_OBJECT (obj), quark_private))
69
70 #define d(x)
71
72 typedef struct _EMailReaderClosure EMailReaderClosure;
73 typedef struct _EMailReaderPrivate EMailReaderPrivate;
74
75 struct _EMailReaderClosure {
76 EMailReader *reader;
77 EActivity *activity;
78 gchar *message_uid;
79 };
80
81 struct _EMailReaderPrivate {
82
83 EMailForwardStyle forward_style;
84 EMailReplyStyle reply_style;
85
86 /* This timer runs when the user selects a single message. */
87 guint message_selected_timeout_id;
88
89 /* This allows message retrieval to be cancelled if another
90 * message is selected before the retrieval has completed. */
91 GCancellable *retrieving_message;
92
93 /* These flags work together to prevent message selection
94 * restoration after a folder switch from automatically
95 * marking the message as read. We only want that to
96 * happen when the -user- selects a message. */
97 guint folder_was_just_selected : 1;
98 guint restoring_message_selection : 1;
99 guint avoid_next_mark_as_seen : 1;
100
101 guint group_by_threads : 1;
102 };
103
104 enum {
105 CHANGED,
106 FOLDER_LOADED,
107 MESSAGE_LOADED,
108 MESSAGE_SEEN,
109 SHOW_SEARCH_BAR,
110 UPDATE_ACTIONS,
111 SHOW_FOLDER,
112 SHOW_PREVTAB,
113 SHOW_NEXTTAB,
114 CLOSE_TAB,
115 LAST_SIGNAL
116 };
117
118 /* Remembers the previously selected folder when transferring messages. */
119 static gchar *default_xfer_messages_uri;
120
121 static GQuark quark_private;
122 static guint signals[LAST_SIGNAL];
123
124 G_DEFINE_INTERFACE (EMailReader, e_mail_reader, G_TYPE_INITIALLY_UNOWNED)
125
126 static void
127 mail_reader_set_display_formatter_for_message (EMailReader *reader,
128 EMailDisplay *display,
129 const gchar *message_uid,
130 CamelMimeMessage *message,
131 CamelFolder *folder);
132
133 static void
134 mail_reader_closure_free (EMailReaderClosure *closure)
135 {
136 if (closure->reader != NULL)
137 g_object_unref (closure->reader);
138
139 if (closure->activity != NULL)
140 g_object_unref (closure->activity);
141
142 g_free (closure->message_uid);
143
144 g_slice_free (EMailReaderClosure, closure);
145 }
146
147 static void
148 mail_reader_private_free (EMailReaderPrivate *priv)
149 {
150 if (priv->message_selected_timeout_id > 0)
151 g_source_remove (priv->message_selected_timeout_id);
152
153 if (priv->retrieving_message != NULL) {
154 g_cancellable_cancel (priv->retrieving_message);
155 g_object_unref (priv->retrieving_message);
156 priv->retrieving_message = 0;
157 }
158
159 g_slice_free (EMailReaderPrivate, priv);
160 }
161
162 static void
163 action_mail_add_sender_cb (GtkAction *action,
164 EMailReader *reader)
165 {
166 EShell *shell;
167 EMailBackend *backend;
168 EShellBackend *shell_backend;
169 CamelMessageInfo *info = NULL;
170 CamelFolder *folder;
171 GPtrArray *uids;
172 const gchar *address;
173 const gchar *message_uid;
174
175 folder = e_mail_reader_get_folder (reader);
176 backend = e_mail_reader_get_backend (reader);
177
178 uids = e_mail_reader_get_selected_uids (reader);
179 g_return_if_fail (uids != NULL && uids->len == 1);
180 message_uid = g_ptr_array_index (uids, 0);
181
182 info = camel_folder_get_message_info (folder, message_uid);
183 if (info == NULL)
184 goto exit;
185
186 address = camel_message_info_from (info);
187 if (address == NULL || *address == '\0')
188 goto exit;
189
190 /* XXX EBookShellBackend should be listening for this
191 * event. Kind of kludgey, but works for now. */
192 shell_backend = E_SHELL_BACKEND (backend);
193 shell = e_shell_backend_get_shell (shell_backend);
194 e_shell_event (shell, "contact-quick-add-email", (gpointer) address);
195 emu_remove_from_mail_cache_1 (address);
196
197 exit:
198 if (info)
199 camel_folder_free_message_info (folder, info);
200 em_utils_uids_free (uids);
201 }
202
203 static void
204 action_add_to_address_book_cb (GtkAction *action,
205 EMailReader *reader)
206 {
207 EShell *shell;
208 EMailBackend *backend;
209 EShellBackend *shell_backend;
210 CamelInternetAddress *cia;
211 EWebView *web_view;
212 CamelURL *curl;
213 const gchar *uri;
214 gchar *email;
215
216 /* This action is defined in EMailDisplay. */
217
218 backend = e_mail_reader_get_backend (reader);
219
220 web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
221 if (!web_view)
222 return;
223
224 uri = e_web_view_get_selected_uri (web_view);
225 g_return_if_fail (uri != NULL);
226
227 curl = camel_url_new (uri, NULL);
228 g_return_if_fail (curl != NULL);
229
230 if (curl->path == NULL || *curl->path == '\0')
231 goto exit;
232
233 cia = camel_internet_address_new ();
234 if (camel_address_decode (CAMEL_ADDRESS (cia), curl->path) < 0) {
235 g_object_unref (cia);
236 goto exit;
237 }
238
239 email = camel_address_format (CAMEL_ADDRESS (cia));
240
241 /* XXX EBookShellBackend should be listening for this
242 * event. Kind of kludgey, but works for now. */
243 shell_backend = E_SHELL_BACKEND (backend);
244 shell = e_shell_backend_get_shell (shell_backend);
245 e_shell_event (shell, "contact-quick-add-email", email);
246 emu_remove_from_mail_cache_1 (curl->path);
247
248 g_object_unref (cia);
249 g_free (email);
250
251 exit:
252 camel_url_free (curl);
253 }
254
255 static void
256 attachment_load_finish (EAttachment *attachment,
257 GAsyncResult *result,
258 GFile *file)
259 {
260 EShell *shell;
261 GtkWindow *parent;
262
263 e_attachment_load_finish (attachment, result, NULL);
264
265 shell = e_shell_get_default ();
266 parent = e_shell_get_active_window (shell);
267
268 e_attachment_save_async (
269 attachment, file, (GAsyncReadyCallback)
270 e_attachment_save_handle_error, parent);
271
272 g_object_unref (file);
273 }
274
275 static void
276 action_mail_image_save_cb (GtkAction *action,
277 EMailReader *reader)
278 {
279 EMailDisplay *display;
280 EWebView *web_view;
281 EMailPartList *parts;
282 const gchar *image_src;
283 CamelMimePart *part;
284 EAttachment *attachment;
285 GFile *file;
286
287 display = e_mail_reader_get_mail_display (reader);
288 web_view = E_WEB_VIEW (display);
289
290 if (!E_IS_WEB_VIEW (web_view))
291 return;
292
293 image_src = e_web_view_get_cursor_image_src (web_view);
294 if (!image_src)
295 return;
296
297 parts = e_mail_display_get_parts_list (display);
298 g_return_if_fail (parts != NULL);
299 g_return_if_fail (parts->message != NULL);
300
301 if (g_str_has_prefix (image_src, "cid:")) {
302 part = camel_mime_message_get_part_by_content_id (
303 parts->message, image_src + 4);
304 g_return_if_fail (part != NULL);
305
306 g_object_ref (part);
307 } else {
308 CamelStream *image_stream;
309 CamelDataWrapper *dw;
310 CamelDataCache *cache;
311 const gchar *filename;
312 const gchar *user_cache_dir;
313
314 /* Open cache and find the file there */
315 user_cache_dir = e_get_user_cache_dir ();
316 cache = camel_data_cache_new (user_cache_dir, NULL);
317 image_stream = camel_data_cache_get (cache, "http", image_src, NULL);
318 if (!image_stream) {
319 g_object_unref (cache);
320 return;
321 }
322
323 filename = strrchr (image_src, '/');
324 if (filename && strchr (filename, '?'))
325 filename = NULL;
326 else if (filename)
327 filename = filename + 1;
328
329 part = camel_mime_part_new ();
330 if (filename)
331 camel_mime_part_set_filename (part, filename);
332
333 dw = camel_data_wrapper_new ();
334 camel_data_wrapper_set_mime_type (
335 dw, "application/octet-stream");
336 camel_data_wrapper_construct_from_stream_sync (
337 dw, image_stream, NULL, NULL);
338 camel_medium_set_content (CAMEL_MEDIUM (part), dw);
339 g_object_unref (dw);
340
341 camel_mime_part_set_encoding (
342 part, CAMEL_TRANSFER_ENCODING_BASE64);
343
344 g_object_unref (image_stream);
345 g_object_unref (cache);
346 }
347
348 file = e_shell_run_save_dialog (
349 e_shell_get_default (),
350 _("Save Image"), camel_mime_part_get_filename (part),
351 NULL, NULL, NULL);
352 if (file == NULL) {
353 g_object_unref (part);
354 return;
355 }
356
357 attachment = e_attachment_new ();
358 e_attachment_set_mime_part (attachment, part);
359
360 e_attachment_load_async (
361 attachment, (GAsyncReadyCallback)
362 attachment_load_finish, file);
363
364 g_object_unref (part);
365 }
366
367 static void
368 action_mail_charset_cb (GtkRadioAction *action,
369 GtkRadioAction *current,
370 EMailReader *reader)
371 {
372 EMailDisplay *display;
373 const gchar *charset;
374
375 if (action != current)
376 return;
377
378 display = e_mail_reader_get_mail_display (reader);
379 charset = g_object_get_data (G_OBJECT (action), "charset");
380
381 /* Charset for "Default" action will be NULL. */
382 e_mail_display_set_charset (display, charset);
383 }
384
385 static void
386 action_mail_check_for_junk_cb (GtkAction *action,
387 EMailReader *reader)
388 {
389 EMailBackend *backend;
390 EMailSession *session;
391 CamelFolder *folder;
392 GPtrArray *uids;
393
394 folder = e_mail_reader_get_folder (reader);
395 backend = e_mail_reader_get_backend (reader);
396 uids = e_mail_reader_get_selected_uids (reader);
397
398 session = e_mail_backend_get_session (backend);
399
400 mail_filter_folder (
401 session, folder, uids,
402 E_FILTER_SOURCE_JUNKTEST, FALSE);
403 }
404
405 static void
406 action_mail_copy_cb (GtkAction *action,
407 EMailReader *reader)
408 {
409 CamelFolder *folder;
410 EMailBackend *backend;
411 EMailSession *session;
412 EMFolderSelector *selector;
413 EMFolderTree *folder_tree;
414 EMFolderTreeModel *model;
415 GtkWidget *dialog;
416 GtkWindow *window;
417 GPtrArray *uids;
418 const gchar *uri;
419
420 backend = e_mail_reader_get_backend (reader);
421 session = e_mail_backend_get_session (backend);
422
423 folder = e_mail_reader_get_folder (reader);
424 window = e_mail_reader_get_window (reader);
425 uids = e_mail_reader_get_selected_uids (reader);
426
427 model = em_folder_tree_model_get_default ();
428
429 dialog = em_folder_selector_new (
430 window, model,
431 EM_FOLDER_SELECTOR_CAN_CREATE,
432 _("Copy to Folder"), NULL, _("C_opy"));
433
434 selector = EM_FOLDER_SELECTOR (dialog);
435 folder_tree = em_folder_selector_get_folder_tree (selector);
436
437 em_folder_tree_set_excluded (
438 folder_tree,
439 EMFT_EXCLUDE_NOSELECT |
440 EMFT_EXCLUDE_VIRTUAL |
441 EMFT_EXCLUDE_VTRASH);
442
443 if (default_xfer_messages_uri != NULL)
444 em_folder_tree_set_selected (
445 folder_tree, default_xfer_messages_uri, FALSE);
446
447 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
448 goto exit;
449
450 uri = em_folder_selector_get_selected_uri (selector);
451
452 g_free (default_xfer_messages_uri);
453 default_xfer_messages_uri = g_strdup (uri);
454
455 if (uri != NULL) {
456 mail_transfer_messages (
457 session, folder, uids,
458 FALSE, uri, 0, NULL, NULL);
459 uids = NULL;
460 }
461
462 exit:
463 if (uids != NULL)
464 em_utils_uids_free (uids);
465
466 gtk_widget_destroy (dialog);
467 }
468
469 static void
470 action_mail_delete_cb (GtkAction *action,
471 EMailReader *reader)
472 {
473 guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
474 guint32 set = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
475
476 if (!e_mail_reader_confirm_delete (reader))
477 return;
478
479 /* FIXME Verify all selected messages are deletable.
480 * But handle it by disabling this action. */
481
482 if (e_mail_reader_mark_selected (reader, mask, set) == 1)
483 e_mail_reader_select_next_message (reader, FALSE);
484 }
485
486 static void
487 action_mail_filter_on_mailing_list_cb (GtkAction *action,
488 EMailReader *reader)
489 {
490 e_mail_reader_create_filter_from_selected (reader, AUTO_MLIST);
491 }
492
493 static void
494 action_mail_filter_on_recipients_cb (GtkAction *action,
495 EMailReader *reader)
496 {
497 e_mail_reader_create_filter_from_selected (reader, AUTO_TO);
498 }
499
500 static void
501 action_mail_filter_on_sender_cb (GtkAction *action,
502 EMailReader *reader)
503 {
504 e_mail_reader_create_filter_from_selected (reader, AUTO_FROM);
505 }
506
507 static void
508 action_mail_filter_on_subject_cb (GtkAction *action,
509 EMailReader *reader)
510 {
511 e_mail_reader_create_filter_from_selected (reader, AUTO_SUBJECT);
512 }
513
514 static void
515 action_mail_filters_apply_cb (GtkAction *action,
516 EMailReader *reader)
517 {
518 EMailBackend *backend;
519 EMailSession *session;
520 CamelFolder *folder;
521 GPtrArray *uids;
522
523 folder = e_mail_reader_get_folder (reader);
524 backend = e_mail_reader_get_backend (reader);
525 uids = e_mail_reader_get_selected_uids (reader);
526
527 session = e_mail_backend_get_session (backend);
528
529 mail_filter_folder (
530 session, folder, uids,
531 E_FILTER_SOURCE_DEMAND, FALSE);
532 }
533
534 static void
535 action_mail_remove_attachments_cb (GtkAction *action,
536 EMailReader *reader)
537 {
538 e_mail_reader_remove_attachments (reader);
539 }
540
541 static void
542 action_mail_remove_duplicates_cb (GtkAction *action,
543 EMailReader *reader)
544 {
545 e_mail_reader_remove_duplicates (reader);
546 }
547
548 static void
549 action_mail_find_cb (GtkAction *action,
550 EMailReader *reader)
551 {
552 e_mail_reader_show_search_bar (reader);
553 }
554
555 static void
556 action_mail_flag_clear_cb (GtkAction *action,
557 EMailReader *reader)
558 {
559 EMailDisplay *display;
560 CamelFolder *folder;
561 GtkWindow *window;
562 GPtrArray *uids;
563
564 folder = e_mail_reader_get_folder (reader);
565 display = e_mail_reader_get_mail_display (reader);
566 uids = e_mail_reader_get_selected_uids (reader);
567 window = e_mail_reader_get_window (reader);
568
569 em_utils_flag_for_followup_clear (window, folder, uids);
570
571 e_mail_display_reload (display);
572 }
573
574 static void
575 action_mail_flag_completed_cb (GtkAction *action,
576 EMailReader *reader)
577 {
578 EMailDisplay *display;
579 CamelFolder *folder;
580 GtkWindow *window;
581 GPtrArray *uids;
582
583 folder = e_mail_reader_get_folder (reader);
584 display = e_mail_reader_get_mail_display (reader);
585 uids = e_mail_reader_get_selected_uids (reader);
586 window = e_mail_reader_get_window (reader);
587
588 em_utils_flag_for_followup_completed (window, folder, uids);
589
590 e_mail_display_reload (display);
591 }
592
593 static void
594 action_mail_flag_for_followup_cb (GtkAction *action,
595 EMailReader *reader)
596 {
597 CamelFolder *folder;
598 GPtrArray *uids;
599
600 folder = e_mail_reader_get_folder (reader);
601 uids = e_mail_reader_get_selected_uids (reader);
602
603 em_utils_flag_for_followup (reader, folder, uids);
604 }
605
606 static gboolean
607 get_close_browser_reader (EMailReader *reader)
608 {
609 GSettings *settings;
610 const gchar *key;
611 gchar *value;
612 gboolean close_it = FALSE;
613
614 /* only allow closing of a mail browser and nothing else */
615 if (!E_IS_MAIL_BROWSER (reader))
616 return FALSE;
617
618 settings = g_settings_new ("org.gnome.evolution.mail");
619
620 key = "prompt-on-reply-close-browser";
621 value = g_settings_get_string (settings, key);
622
623 if (value && g_str_equal (value, "always")) {
624 close_it = TRUE;
625 } else if (!value || !g_str_equal (value, "never")) {
626 GtkWidget *dialog;
627 GtkWindow *parent;
628 gint response;
629 EShell *shell;
630 EMailBackend *backend;
631 EShellBackend *shell_backend;
632
633 backend = e_mail_reader_get_backend (reader);
634
635 shell_backend = E_SHELL_BACKEND (backend);
636 shell = e_shell_backend_get_shell (shell_backend);
637
638 parent = e_shell_get_active_window (shell);
639 if (!parent)
640 parent = e_mail_reader_get_window (reader);
641
642 dialog = e_alert_dialog_new_for_args (
643 parent, "mail:ask-reply-close-browser", NULL);
644 response = gtk_dialog_run (GTK_DIALOG (dialog));
645 gtk_widget_destroy (dialog);
646
647 close_it = response == GTK_RESPONSE_YES || response == GTK_RESPONSE_OK;
648
649 if (response == GTK_RESPONSE_OK)
650 g_settings_set_string (settings, key, "always");
651 else if (response == GTK_RESPONSE_CANCEL)
652 g_settings_set_string (settings, key, "never");
653 }
654
655 g_free (value);
656 g_object_unref (settings);
657
658 return close_it;
659 }
660
661 static void
662 check_close_browser_reader (EMailReader *reader)
663 {
664 if (get_close_browser_reader (reader))
665 gtk_widget_destroy (GTK_WIDGET (reader));
666 }
667
668 static void
669 action_mail_forward_cb (GtkAction *action,
670 EMailReader *reader)
671 {
672 CamelFolder *folder;
673 GtkWindow *window;
674 GPtrArray *uids;
675 gboolean close_reader;
676
677 folder = e_mail_reader_get_folder (reader);
678 window = e_mail_reader_get_window (reader);
679 uids = e_mail_reader_get_selected_uids (reader);
680 g_return_if_fail (uids != NULL);
681 close_reader = get_close_browser_reader (reader);
682
683 /* XXX Either e_mail_reader_get_selected_uids()
684 * or MessageList should do this itself. */
685 g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
686
687 if (em_utils_ask_open_many (window, uids->len))
688 em_utils_forward_messages (
689 reader, folder, uids,
690 e_mail_reader_get_forward_style (reader),
691 close_reader ? GTK_WIDGET (reader) : NULL);
692
693 g_ptr_array_unref (uids);
694 }
695
696 static void
697 action_mail_forward_attached_cb (GtkAction *action,
698 EMailReader *reader)
699 {
700 CamelFolder *folder;
701 GtkWindow *window;
702 GPtrArray *uids;
703 gboolean close_reader;
704
705 folder = e_mail_reader_get_folder (reader);
706 window = e_mail_reader_get_window (reader);
707 uids = e_mail_reader_get_selected_uids (reader);
708 g_return_if_fail (uids != NULL);
709 close_reader = get_close_browser_reader (reader);
710
711 /* XXX Either e_mail_reader_get_selected_uids()
712 * or MessageList should do this itself. */
713 g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
714
715 if (em_utils_ask_open_many (window, uids->len))
716 em_utils_forward_messages (
717 reader, folder, uids,
718 E_MAIL_FORWARD_STYLE_ATTACHED,
719 close_reader ? GTK_WIDGET (reader) : NULL);
720
721 g_ptr_array_unref (uids);
722 }
723
724 static void
725 action_mail_forward_inline_cb (GtkAction *action,
726 EMailReader *reader)
727 {
728 CamelFolder *folder;
729 GtkWindow *window;
730 GPtrArray *uids;
731 gboolean close_reader;
732
733 folder = e_mail_reader_get_folder (reader);
734 window = e_mail_reader_get_window (reader);
735 uids = e_mail_reader_get_selected_uids (reader);
736 g_return_if_fail (uids != NULL);
737 close_reader = get_close_browser_reader (reader);
738
739 /* XXX Either e_mail_reader_get_selected_uids()
740 * or MessageList should do this itself. */
741 g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
742
743 if (em_utils_ask_open_many (window, uids->len))
744 em_utils_forward_messages (
745 reader, folder, uids,
746 E_MAIL_FORWARD_STYLE_INLINE,
747 close_reader ? GTK_WIDGET (reader) : NULL);
748
749 g_ptr_array_unref (uids);
750 }
751
752 static void
753 action_mail_forward_quoted_cb (GtkAction *action,
754 EMailReader *reader)
755 {
756 CamelFolder *folder;
757 GtkWindow *window;
758 GPtrArray *uids;
759 gboolean close_reader;
760
761 folder = e_mail_reader_get_folder (reader);
762 window = e_mail_reader_get_window (reader);
763 uids = e_mail_reader_get_selected_uids (reader);
764 g_return_if_fail (uids != NULL);
765 close_reader = get_close_browser_reader (reader);
766
767 /* XXX Either e_mail_reader_get_selected_uids()
768 * or MessageList should do this itself. */
769 g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
770
771 if (em_utils_ask_open_many (window, uids->len))
772 em_utils_forward_messages (
773 reader, folder, uids,
774 E_MAIL_FORWARD_STYLE_QUOTED,
775 close_reader ? GTK_WIDGET (reader) : NULL);
776
777 g_ptr_array_unref (uids);
778 }
779
780 static void
781 action_mail_load_images_cb (GtkAction *action,
782 EMailReader *reader)
783 {
784 EMailDisplay *display;
785
786 display = e_mail_reader_get_mail_display (reader);
787
788 e_mail_display_load_images (display);
789 }
790
791 static void
792 action_mail_mark_important_cb (GtkAction *action,
793 EMailReader *reader)
794 {
795 guint32 mask = CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_DELETED;
796 guint32 set = CAMEL_MESSAGE_FLAGGED;
797
798 e_mail_reader_mark_selected (reader, mask, set);
799 }
800
801 static gboolean
802 is_junk_folder_selected (EMailReader *reader)
803 {
804 CamelFolder *folder;
805
806 folder = e_mail_reader_get_folder (reader);
807
808 return folder && (folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
809 }
810
811 static void
812 action_mail_mark_junk_cb (GtkAction *action,
813 EMailReader *reader)
814 {
815 guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_JUNK |
816 CAMEL_MESSAGE_NOTJUNK | CAMEL_MESSAGE_JUNK_LEARN;
817 guint32 set = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_JUNK |
818 CAMEL_MESSAGE_JUNK_LEARN;
819
820 if (e_mail_reader_mark_selected (reader, mask, set) == 1 &&
821 !is_junk_folder_selected (reader))
822 e_mail_reader_select_next_message (reader, TRUE);
823 }
824
825 static void
826 action_mail_mark_notjunk_cb (GtkAction *action,
827 EMailReader *reader)
828 {
829 guint32 mask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK |
830 CAMEL_MESSAGE_JUNK_LEARN;
831 guint32 set = CAMEL_MESSAGE_NOTJUNK | CAMEL_MESSAGE_JUNK_LEARN;
832
833 if (e_mail_reader_mark_selected (reader, mask, set) == 1 &&
834 is_junk_folder_selected (reader))
835 e_mail_reader_select_next_message (reader, TRUE);
836 }
837
838 static void
839 action_mail_mark_read_cb (GtkAction *action,
840 EMailReader *reader)
841 {
842 guint32 mask = CAMEL_MESSAGE_SEEN;
843 guint32 set = CAMEL_MESSAGE_SEEN;
844
845 e_mail_reader_mark_selected (reader, mask, set);
846 }
847
848 static void
849 action_mail_mark_unimportant_cb (GtkAction *action,
850 EMailReader *reader)
851 {
852 guint32 mask = CAMEL_MESSAGE_FLAGGED;
853 guint32 set = 0;
854
855 e_mail_reader_mark_selected (reader, mask, set);
856 }
857
858 static void
859 action_mail_mark_unread_cb (GtkAction *action,
860 EMailReader *reader)
861 {
862 GtkWidget *message_list;
863 EMFolderTreeModel *model;
864 CamelFolder *folder;
865 guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
866 guint32 set = 0;
867 guint n_marked;
868
869 message_list = e_mail_reader_get_message_list (reader);
870
871 n_marked = e_mail_reader_mark_selected (reader, mask, set);
872
873 if (MESSAGE_LIST (message_list)->seen_id != 0) {
874 g_source_remove (MESSAGE_LIST (message_list)->seen_id);
875 MESSAGE_LIST (message_list)->seen_id = 0;
876 }
877
878 /* Notify the tree model that the user has marked messages as
879 * unread so it doesn't mistake the event as new mail arriving. */
880 model = em_folder_tree_model_get_default ();
881 folder = e_mail_reader_get_folder (reader);
882 em_folder_tree_model_user_marked_unread (model, folder, n_marked);
883 }
884
885 static void
886 action_mail_message_edit_cb (GtkAction *action,
887 EMailReader *reader)
888 {
889 EShell *shell;
890 EMailBackend *backend;
891 ESourceRegistry *registry;
892 CamelFolder *folder;
893 GPtrArray *uids;
894 gboolean replace;
895
896 folder = e_mail_reader_get_folder (reader);
897 uids = e_mail_reader_get_selected_uids (reader);
898 g_return_if_fail (uids != NULL);
899
900 backend = e_mail_reader_get_backend (reader);
901 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
902 registry = e_shell_get_registry (shell);
903
904 /* XXX Either e_mail_reader_get_selected_uids()
905 * or MessageList should do this itself. */
906 g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
907
908 replace = em_utils_folder_is_drafts (registry, folder);
909 em_utils_edit_messages (reader, folder, uids, replace);
910
911 g_ptr_array_unref (uids);
912 }
913
914 static void
915 action_mail_message_new_cb (GtkAction *action,
916 EMailReader *reader)
917 {
918 EShell *shell;
919 EMailBackend *backend;
920 EShellBackend *shell_backend;
921 CamelFolder *folder;
922
923 folder = e_mail_reader_get_folder (reader);
924 backend = e_mail_reader_get_backend (reader);
925
926 shell_backend = E_SHELL_BACKEND (backend);
927 shell = e_shell_backend_get_shell (shell_backend);
928
929 em_utils_compose_new_message (shell, folder);
930 }
931
932 static void
933 action_mail_message_open_cb (GtkAction *action,
934 EMailReader *reader)
935 {
936 e_mail_reader_open_selected_mail (reader);
937 }
938
939 static void
940 action_mail_move_cb (GtkAction *action,
941 EMailReader *reader)
942 {
943 CamelFolder *folder;
944 EMailBackend *backend;
945 EMailSession *session;
946 EMFolderSelector *selector;
947 EMFolderTree *folder_tree;
948 EMFolderTreeModel *model;
949 GtkWidget *dialog;
950 GtkWindow *window;
951 GPtrArray *uids;
952 const gchar *uri;
953
954 backend = e_mail_reader_get_backend (reader);
955 session = e_mail_backend_get_session (backend);
956
957 folder = e_mail_reader_get_folder (reader);
958 uids = e_mail_reader_get_selected_uids (reader);
959 window = e_mail_reader_get_window (reader);
960
961 model = em_folder_tree_model_get_default ();
962
963 dialog = em_folder_selector_new (
964 window, model,
965 EM_FOLDER_SELECTOR_CAN_CREATE,
966 _("Move to Folder"), NULL, _("_Move"));
967
968 selector = EM_FOLDER_SELECTOR (dialog);
969 folder_tree = em_folder_selector_get_folder_tree (selector);
970
971 em_folder_tree_set_excluded (
972 folder_tree,
973 EMFT_EXCLUDE_NOSELECT |
974 EMFT_EXCLUDE_VIRTUAL |
975 EMFT_EXCLUDE_VTRASH);
976
977 if (default_xfer_messages_uri != NULL)
978 em_folder_tree_set_selected (
979 folder_tree, default_xfer_messages_uri, FALSE);
980
981 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
982 goto exit;
983
984 uri = em_folder_selector_get_selected_uri (selector);
985
986 g_free (default_xfer_messages_uri);
987 default_xfer_messages_uri = g_strdup (uri);
988
989 if (uri != NULL) {
990 mail_transfer_messages (
991 session, folder, uids,
992 TRUE, uri, 0, NULL, NULL);
993 uids = NULL;
994 }
995
996 exit:
997 if (uids != NULL)
998 em_utils_uids_free (uids);
999
1000 gtk_widget_destroy (dialog);
1001 }
1002
1003 static void
1004 action_mail_folder_cb (GtkAction *action,
1005 EMailReader *reader)
1006 {
1007 g_signal_emit (reader, signals[SHOW_FOLDER], 0);
1008 }
1009
1010 static void
1011 action_mail_nexttab_cb (GtkAction *action,
1012 EMailReader *reader)
1013 {
1014 g_signal_emit (reader, signals[SHOW_NEXTTAB], 0);
1015 }
1016
1017 static void
1018 action_mail_prevtab_cb (GtkAction *action,
1019 EMailReader *reader)
1020 {
1021 g_signal_emit (reader, signals[SHOW_PREVTAB], 0);
1022 }
1023
1024 static void
1025 action_mail_closetab_cb (GtkAction *action,
1026 EMailReader *reader)
1027 {
1028 g_signal_emit (reader, signals[CLOSE_TAB], 0);
1029 }
1030
1031 static void
1032 action_mail_next_cb (GtkAction *action,
1033 EMailReader *reader)
1034 {
1035 GtkWidget *message_list;
1036 MessageListSelectDirection direction;
1037 guint32 flags, mask;
1038
1039 direction = MESSAGE_LIST_SELECT_NEXT;
1040 flags = 0;
1041 mask = 0;
1042
1043 message_list = e_mail_reader_get_message_list (reader);
1044
1045 message_list_select (
1046 MESSAGE_LIST (message_list), direction, flags, mask);
1047 }
1048
1049 static void
1050 action_mail_next_important_cb (GtkAction *action,
1051 EMailReader *reader)
1052 {
1053 GtkWidget *message_list;
1054 MessageListSelectDirection direction;
1055 guint32 flags, mask;
1056
1057 direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
1058 flags = CAMEL_MESSAGE_FLAGGED;
1059 mask = CAMEL_MESSAGE_FLAGGED;
1060
1061 message_list = e_mail_reader_get_message_list (reader);
1062
1063 message_list_select (
1064 MESSAGE_LIST (message_list), direction, flags, mask);
1065 }
1066
1067 static void
1068 action_mail_next_thread_cb (GtkAction *action,
1069 EMailReader *reader)
1070 {
1071 GtkWidget *message_list;
1072
1073 message_list = e_mail_reader_get_message_list (reader);
1074
1075 message_list_select_next_thread (MESSAGE_LIST (message_list));
1076 }
1077
1078 static void
1079 action_mail_next_unread_cb (GtkAction *action,
1080 EMailReader *reader)
1081 {
1082 GtkWidget *message_list;
1083 MessageListSelectDirection direction;
1084 guint32 flags, mask;
1085
1086 direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
1087 flags = 0;
1088 mask = CAMEL_MESSAGE_SEEN;
1089
1090 message_list = e_mail_reader_get_message_list (reader);
1091
1092 message_list_select (
1093 MESSAGE_LIST (message_list), direction, flags, mask);
1094 }
1095
1096 static void
1097 action_mail_previous_cb (GtkAction *action,
1098 EMailReader *reader)
1099 {
1100 GtkWidget *message_list;
1101 MessageListSelectDirection direction;
1102 guint32 flags, mask;
1103
1104 direction = MESSAGE_LIST_SELECT_PREVIOUS;
1105 flags = 0;
1106 mask = 0;
1107
1108 message_list = e_mail_reader_get_message_list (reader);
1109
1110 message_list_select (
1111 MESSAGE_LIST (message_list), direction, flags, mask);
1112 }
1113
1114 static void
1115 action_mail_previous_important_cb (GtkAction *action,
1116 EMailReader *reader)
1117 {
1118 GtkWidget *message_list;
1119 MessageListSelectDirection direction;
1120 guint32 flags, mask;
1121
1122 direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
1123 flags = CAMEL_MESSAGE_FLAGGED;
1124 mask = CAMEL_MESSAGE_FLAGGED;
1125
1126 message_list = e_mail_reader_get_message_list (reader);
1127
1128 message_list_select (
1129 MESSAGE_LIST (message_list), direction, flags, mask);
1130 }
1131
1132 static void
1133 action_mail_previous_thread_cb (GtkAction *action,
1134 EMailReader *reader)
1135 {
1136 GtkWidget *message_list;
1137
1138 message_list = e_mail_reader_get_message_list (reader);
1139
1140 message_list_select_prev_thread (MESSAGE_LIST (message_list));
1141 }
1142
1143 static void
1144 action_mail_previous_unread_cb (GtkAction *action,
1145 EMailReader *reader)
1146 {
1147 GtkWidget *message_list;
1148 MessageListSelectDirection direction;
1149 guint32 flags, mask;
1150
1151 direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
1152 flags = 0;
1153 mask = CAMEL_MESSAGE_SEEN;
1154
1155 message_list = e_mail_reader_get_message_list (reader);
1156
1157 message_list_select (
1158 MESSAGE_LIST (message_list), direction, flags, mask);
1159 }
1160
1161 static void
1162 action_mail_print_cb (GtkAction *action,
1163 EMailReader *reader)
1164 {
1165 GtkPrintOperationAction print_action;
1166
1167 print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
1168 e_mail_reader_print (reader, print_action);
1169 }
1170
1171 static void
1172 action_mail_print_preview_cb (GtkAction *action,
1173 EMailReader *reader)
1174 {
1175 GtkPrintOperationAction print_action;
1176
1177 print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
1178 e_mail_reader_print (reader, print_action);
1179 }
1180
1181 static void
1182 mail_reader_redirect_cb (CamelFolder *folder,
1183 GAsyncResult *result,
1184 EMailReaderClosure *closure)
1185 {
1186 EShell *shell;
1187 EMailBackend *backend;
1188 EAlertSink *alert_sink;
1189 CamelMimeMessage *message;
1190 GError *error = NULL;
1191
1192 alert_sink = e_activity_get_alert_sink (closure->activity);
1193
1194 message = camel_folder_get_message_finish (folder, result, &error);
1195
1196 if (e_activity_handle_cancellation (closure->activity, error)) {
1197 g_warn_if_fail (message == NULL);
1198 mail_reader_closure_free (closure);
1199 g_error_free (error);
1200 return;
1201
1202 } else if (error != NULL) {
1203 g_warn_if_fail (message == NULL);
1204 e_alert_submit (
1205 alert_sink, "mail:no-retrieve-message",
1206 error->message, NULL);
1207 mail_reader_closure_free (closure);
1208 g_error_free (error);
1209 return;
1210 }
1211
1212 g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1213
1214 backend = e_mail_reader_get_backend (closure->reader);
1215 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
1216
1217 em_utils_redirect_message (shell, message);
1218 check_close_browser_reader (closure->reader);
1219
1220 g_object_unref (message);
1221
1222 mail_reader_closure_free (closure);
1223 }
1224
1225 static void
1226 action_mail_redirect_cb (GtkAction *action,
1227 EMailReader *reader)
1228 {
1229 EActivity *activity;
1230 GCancellable *cancellable;
1231 EMailReaderClosure *closure;
1232 GtkWidget *message_list;
1233 CamelFolder *folder;
1234 const gchar *message_uid;
1235
1236 folder = e_mail_reader_get_folder (reader);
1237 message_list = e_mail_reader_get_message_list (reader);
1238
1239 message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1240 g_return_if_fail (message_uid != NULL);
1241
1242 /* Open the message asynchronously. */
1243
1244 activity = e_mail_reader_new_activity (reader);
1245 cancellable = e_activity_get_cancellable (activity);
1246
1247 closure = g_slice_new0 (EMailReaderClosure);
1248 closure->activity = activity;
1249 closure->reader = g_object_ref (reader);
1250
1251 camel_folder_get_message (
1252 folder, message_uid, G_PRIORITY_DEFAULT,
1253 cancellable, (GAsyncReadyCallback)
1254 mail_reader_redirect_cb, closure);
1255 }
1256
1257 static void
1258 action_mail_reply_all_check (CamelFolder *folder,
1259 GAsyncResult *result,
1260 EMailReaderClosure *closure)
1261 {
1262 EAlertSink *alert_sink;
1263 CamelMimeMessage *message;
1264 CamelInternetAddress *to, *cc;
1265 gint recip_count = 0;
1266 EMailReplyType type = E_MAIL_REPLY_TO_ALL;
1267 GError *error = NULL;
1268
1269 alert_sink = e_activity_get_alert_sink (closure->activity);
1270
1271 message = camel_folder_get_message_finish (folder, result, &error);
1272
1273 if (e_activity_handle_cancellation (closure->activity, error)) {
1274 g_warn_if_fail (message == NULL);
1275 mail_reader_closure_free (closure);
1276 g_error_free (error);
1277 return;
1278
1279 } else if (error != NULL) {
1280 g_warn_if_fail (message == NULL);
1281 e_alert_submit (
1282 alert_sink, "mail:no-retrieve-message",
1283 error->message, NULL);
1284 mail_reader_closure_free (closure);
1285 g_error_free (error);
1286 return;
1287 }
1288
1289 g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1290
1291 to = camel_mime_message_get_recipients (
1292 message, CAMEL_RECIPIENT_TYPE_TO);
1293 cc = camel_mime_message_get_recipients (
1294 message, CAMEL_RECIPIENT_TYPE_CC);
1295
1296 recip_count = camel_address_length (CAMEL_ADDRESS (to));
1297 recip_count += camel_address_length (CAMEL_ADDRESS (cc));
1298
1299 if (recip_count >= 15) {
1300 GtkWidget *dialog;
1301 GtkWidget *check;
1302 GtkWidget *container;
1303 gint response;
1304
1305 dialog = e_alert_dialog_new_for_args (
1306 e_mail_reader_get_window (closure->reader),
1307 "mail:ask-reply-many-recips", NULL);
1308
1309 container = e_alert_dialog_get_content_area (
1310 E_ALERT_DIALOG (dialog));
1311
1312 /* Check buttons */
1313 check = gtk_check_button_new_with_mnemonic (
1314 _("_Do not ask me again."));
1315 gtk_box_pack_start (
1316 GTK_BOX (container), check, FALSE, FALSE, 0);
1317 gtk_widget_show (check);
1318
1319 response = gtk_dialog_run (GTK_DIALOG (dialog));
1320
1321 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check))) {
1322 GSettings *settings;
1323
1324 settings = g_settings_new ("org.gnome.evolution.mail");
1325 g_settings_set_boolean (settings, "prompt-on-reply-many-recips", FALSE);
1326 g_object_unref (settings);
1327 }
1328
1329 gtk_widget_destroy (dialog);
1330
1331 switch (response) {
1332 case GTK_RESPONSE_NO:
1333 type = E_MAIL_REPLY_TO_SENDER;
1334 break;
1335 case GTK_RESPONSE_CANCEL:
1336 case GTK_RESPONSE_DELETE_EVENT:
1337 goto exit;
1338 default:
1339 break;
1340 }
1341 }
1342
1343 e_mail_reader_reply_to_message (closure->reader, message, type);
1344 check_close_browser_reader (closure->reader);
1345
1346 exit:
1347 g_object_unref (message);
1348
1349 mail_reader_closure_free (closure);
1350 }
1351
1352 static void
1353 action_mail_reply_all_cb (GtkAction *action,
1354 EMailReader *reader)
1355 {
1356 GSettings *settings;
1357 const gchar *key;
1358 guint32 state;
1359 gboolean ask;
1360
1361 state = e_mail_reader_check_state (reader);
1362
1363 settings = g_settings_new ("org.gnome.evolution.mail");
1364 key = "prompt-on-reply-many-recips";
1365 ask = g_settings_get_boolean (settings, key);
1366 g_object_unref (settings);
1367
1368 if (ask && !(state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
1369 EActivity *activity;
1370 GCancellable *cancellable;
1371 EMailReaderClosure *closure;
1372 CamelFolder *folder;
1373 GtkWidget *message_list;
1374 const gchar *message_uid;
1375
1376 folder = e_mail_reader_get_folder (reader);
1377 g_return_if_fail (CAMEL_IS_FOLDER (folder));
1378
1379 message_list = e_mail_reader_get_message_list (reader);
1380 message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1381 g_return_if_fail (message_uid != NULL);
1382
1383 activity = e_mail_reader_new_activity (reader);
1384 cancellable = e_activity_get_cancellable (activity);
1385
1386 closure = g_slice_new0 (EMailReaderClosure);
1387 closure->activity = activity;
1388 closure->reader = g_object_ref (reader);
1389
1390 camel_folder_get_message (
1391 folder, message_uid, G_PRIORITY_DEFAULT,
1392 cancellable, (GAsyncReadyCallback)
1393 action_mail_reply_all_check, closure);
1394
1395 return;
1396 }
1397
1398 e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_ALL);
1399 check_close_browser_reader (reader);
1400 }
1401
1402 static void
1403 action_mail_reply_group_cb (GtkAction *action,
1404 EMailReader *reader)
1405 {
1406 GSettings *settings;
1407 gboolean reply_list;
1408 guint32 state;
1409
1410 state = e_mail_reader_check_state (reader);
1411
1412 settings = g_settings_new ("org.gnome.evolution.mail");
1413 reply_list = g_settings_get_boolean (settings, "composer-group-reply-to-list");
1414 g_object_unref (settings);
1415
1416 if (reply_list && (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
1417 e_mail_reader_reply_to_message (
1418 reader, NULL, E_MAIL_REPLY_TO_LIST);
1419 check_close_browser_reader (reader);
1420 } else
1421 action_mail_reply_all_cb (action, reader);
1422 }
1423
1424 static void
1425 action_mail_reply_list_cb (GtkAction *action,
1426 EMailReader *reader)
1427 {
1428 e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_LIST);
1429 check_close_browser_reader (reader);
1430 }
1431
1432 static void
1433 action_mail_reply_sender_check (CamelFolder *folder,
1434 GAsyncResult *result,
1435 EMailReaderClosure *closure)
1436 {
1437 EAlertSink *alert_sink;
1438 CamelMimeMessage *message;
1439 EMailReplyType type = E_MAIL_REPLY_TO_SENDER;
1440 GSettings *settings;
1441 gboolean ask_ignore_list_reply_to;
1442 gboolean ask_list_reply_to;
1443 gboolean munged_list_message;
1444 gboolean active;
1445 GError *error = NULL;
1446
1447 alert_sink = e_activity_get_alert_sink (closure->activity);
1448
1449 message = camel_folder_get_message_finish (folder, result, &error);
1450
1451 if (e_activity_handle_cancellation (closure->activity, error)) {
1452 g_warn_if_fail (message == NULL);
1453 mail_reader_closure_free (closure);
1454 g_error_free (error);
1455 return;
1456
1457 } else if (error != NULL) {
1458 g_warn_if_fail (message == NULL);
1459 e_alert_submit (
1460 alert_sink, "mail:no-retrieve-message",
1461 error->message, NULL);
1462 mail_reader_closure_free (closure);
1463 g_error_free (error);
1464 return;
1465 }
1466
1467 g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1468
1469 settings = g_settings_new ("org.gnome.evolution.mail");
1470
1471 ask_ignore_list_reply_to = g_settings_get_boolean (
1472 settings, "composer-ignore-list-reply-to");
1473 ask_list_reply_to = g_settings_get_boolean (
1474 settings, "prompt-on-list-reply-to");
1475
1476 munged_list_message = em_utils_is_munged_list_message (message);
1477
1478 /* Don't do the "Are you sure you want to reply in private?" pop-up
1479 * if it's a Reply-To: munged list message... unless we're ignoring
1480 * munging. */
1481 if (ask_ignore_list_reply_to || !munged_list_message) {
1482 GtkWidget *dialog;
1483 GtkWidget *check;
1484 GtkWidget *container;
1485 gint response;
1486
1487 dialog = e_alert_dialog_new_for_args (
1488 e_mail_reader_get_window (closure->reader),
1489 "mail:ask-list-private-reply", NULL);
1490
1491 container = e_alert_dialog_get_content_area (
1492 E_ALERT_DIALOG (dialog));
1493
1494 /* Check buttons */
1495 check = gtk_check_button_new_with_mnemonic (
1496 _("_Do not ask me again."));
1497 gtk_box_pack_start (
1498 GTK_BOX (container), check, FALSE, FALSE, 0);
1499 gtk_widget_show (check);
1500
1501 response = gtk_dialog_run (GTK_DIALOG (dialog));
1502
1503 active = gtk_toggle_button_get_active (
1504 GTK_TOGGLE_BUTTON (check));
1505 if (active) {
1506 g_settings_set_boolean (
1507 settings, "prompt-on-private-list-reply", FALSE);
1508 }
1509
1510 gtk_widget_destroy (dialog);
1511
1512 if (response == GTK_RESPONSE_YES)
1513 type = E_MAIL_REPLY_TO_ALL;
1514 else if (response == GTK_RESPONSE_OK)
1515 type = E_MAIL_REPLY_TO_LIST;
1516 else if (response == GTK_RESPONSE_CANCEL ||
1517 response == GTK_RESPONSE_DELETE_EVENT) {
1518 goto exit;
1519 }
1520
1521 } else if (ask_list_reply_to) {
1522 GtkWidget *dialog;
1523 GtkWidget *container;
1524 GtkWidget *check_again;
1525 GtkWidget *check_always_ignore;
1526 gint response;
1527
1528 dialog = e_alert_dialog_new_for_args (
1529 e_mail_reader_get_window (closure->reader),
1530 "mail:ask-list-honour-reply-to", NULL);
1531
1532 container = e_alert_dialog_get_content_area (
1533 E_ALERT_DIALOG (dialog));
1534
1535 check_again = gtk_check_button_new_with_mnemonic (
1536 _("_Do not ask me again."));
1537 gtk_box_pack_start (
1538 GTK_BOX (container), check_again, FALSE, FALSE, 0);
1539 gtk_widget_show (check_again);
1540
1541 check_always_ignore = gtk_check_button_new_with_mnemonic (
1542 _("_Always ignore Reply-To: for mailing lists."));
1543 gtk_box_pack_start (
1544 GTK_BOX (container), check_always_ignore,
1545 FALSE, FALSE, 0);
1546 gtk_widget_show (check_always_ignore);
1547
1548 response = gtk_dialog_run (GTK_DIALOG (dialog));
1549
1550 active = gtk_toggle_button_get_active (
1551 GTK_TOGGLE_BUTTON (check_again));
1552 if (active) {
1553 g_settings_set_boolean (
1554 settings, "prompt-on-list-reply-to", FALSE);
1555 }
1556
1557 active = gtk_toggle_button_get_active (
1558 GTK_TOGGLE_BUTTON (check_always_ignore));
1559 g_settings_set_boolean (
1560 settings, "composer-ignore-list-reply-to", active);
1561
1562 gtk_widget_destroy (dialog);
1563
1564 switch (response) {
1565 case GTK_RESPONSE_NO:
1566 type = E_MAIL_REPLY_TO_FROM;
1567 break;
1568 case GTK_RESPONSE_OK:
1569 type = E_MAIL_REPLY_TO_LIST;
1570 break;
1571 case GTK_RESPONSE_CANCEL:
1572 case GTK_RESPONSE_DELETE_EVENT:
1573 goto exit;
1574 default:
1575 break;
1576 }
1577 }
1578
1579 e_mail_reader_reply_to_message (closure->reader, message, type);
1580 check_close_browser_reader (closure->reader);
1581
1582 exit:
1583 g_object_unref (settings);
1584 g_object_unref (message);
1585
1586 mail_reader_closure_free (closure);
1587 }
1588
1589 static void
1590 action_mail_reply_sender_cb (GtkAction *action,
1591 EMailReader *reader)
1592 {
1593 GSettings *settings;
1594 gboolean ask_list_reply_to;
1595 gboolean ask_private_list_reply;
1596 gboolean ask;
1597 guint32 state;
1598
1599 state = e_mail_reader_check_state (reader);
1600
1601 settings = g_settings_new ("org.gnome.evolution.mail");
1602 ask_list_reply_to = g_settings_get_boolean (
1603 settings, "prompt-on-list-reply-to");
1604 ask_private_list_reply = g_settings_get_boolean (
1605 settings, "prompt-on-private-list-reply");
1606 g_object_unref (settings);
1607
1608 ask = (ask_private_list_reply || ask_list_reply_to);
1609
1610 if (ask && (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
1611 EActivity *activity;
1612 GCancellable *cancellable;
1613 EMailReaderClosure *closure;
1614 CamelFolder *folder;
1615 GtkWidget *message_list;
1616 const gchar *message_uid;
1617
1618 folder = e_mail_reader_get_folder (reader);
1619 g_return_if_fail (CAMEL_IS_FOLDER (folder));
1620
1621 message_list = e_mail_reader_get_message_list (reader);
1622 message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1623 g_return_if_fail (message_uid != NULL);
1624
1625 activity = e_mail_reader_new_activity (reader);
1626 cancellable = e_activity_get_cancellable (activity);
1627
1628 closure = g_slice_new0 (EMailReaderClosure);
1629 closure->activity = activity;
1630 closure->reader = g_object_ref (reader);
1631
1632 camel_folder_get_message (
1633 folder, message_uid, G_PRIORITY_DEFAULT,
1634 cancellable, (GAsyncReadyCallback)
1635 action_mail_reply_sender_check, closure);
1636
1637 return;
1638 }
1639
1640 e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_SENDER);
1641 check_close_browser_reader (reader);
1642 }
1643
1644 static void
1645 action_mail_reply_recipient_cb (GtkAction *action,
1646 EMailReader *reader)
1647 {
1648 e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_RECIPIENT);
1649 check_close_browser_reader (reader);
1650 }
1651
1652 static void
1653 action_mail_save_as_cb (GtkAction *action,
1654 EMailReader *reader)
1655 {
1656 e_mail_reader_save_messages (reader);
1657 }
1658
1659 static void
1660 action_mail_search_folder_from_mailing_list_cb (GtkAction *action,
1661 EMailReader *reader)
1662 {
1663 e_mail_reader_create_vfolder_from_selected (reader, AUTO_MLIST);
1664 }
1665
1666 static void
1667 action_mail_search_folder_from_recipients_cb (GtkAction *action,
1668 EMailReader *reader)
1669 {
1670 e_mail_reader_create_vfolder_from_selected (reader, AUTO_TO);
1671 }
1672
1673 static void
1674 action_mail_search_folder_from_sender_cb (GtkAction *action,
1675 EMailReader *reader)
1676 {
1677 e_mail_reader_create_vfolder_from_selected (reader, AUTO_FROM);
1678 }
1679
1680 static void
1681 action_mail_search_folder_from_subject_cb (GtkAction *action,
1682 EMailReader *reader)
1683 {
1684 e_mail_reader_create_vfolder_from_selected (reader, AUTO_SUBJECT);
1685 }
1686
1687 static void
1688 action_mail_show_all_headers_cb (GtkToggleAction *action,
1689 EMailReader *reader)
1690 {
1691 EMailDisplay *display;
1692
1693 display = e_mail_reader_get_mail_display (reader);
1694
1695 /* mode change when viewing message source is ignored */
1696 if (e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_SOURCE ||
1697 e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_RAW)
1698 return;
1699
1700 if (gtk_toggle_action_get_active (action))
1701 e_mail_display_set_mode (display, E_MAIL_FORMATTER_MODE_ALL_HEADERS);
1702 else
1703 e_mail_display_set_mode (display, E_MAIL_FORMATTER_MODE_NORMAL);
1704 }
1705
1706 struct _source_retrieval_closure {
1707 EMailReader *browser;
1708 EActivity *activity;
1709 gchar *message_uid;
1710 };
1711
1712 static void
1713 mail_source_retrieved (GObject *object,
1714 GAsyncResult *result,
1715 gpointer user_data)
1716 {
1717 CamelMimeMessage *message;
1718 EMailDisplay *display;
1719 GError *error = NULL;
1720 struct _source_retrieval_closure *data;
1721
1722 data = user_data;
1723 display = e_mail_reader_get_mail_display (data->browser);
1724
1725 message = camel_folder_get_message_finish (
1726 CAMEL_FOLDER (object), result, &error);
1727
1728 /* Sanity check. */
1729 g_return_if_fail (
1730 ((message != NULL) && (error == NULL)) ||
1731 ((message == NULL) && (error != NULL)));
1732
1733 if (error != NULL) {
1734 gchar *status;
1735 status = g_strdup_printf (
1736 "%s<br>%s",
1737 _("Failed to retrieve message:"),
1738 error->message);
1739 e_mail_display_set_status (display, status);
1740 g_error_free (error);
1741 g_free (status);
1742 goto free_data;
1743 }
1744
1745 mail_reader_set_display_formatter_for_message (
1746 data->browser, display, data->message_uid,
1747 message, CAMEL_FOLDER (object));
1748
1749 free_data:
1750 e_activity_set_state (data->activity, E_ACTIVITY_COMPLETED);
1751 g_object_unref (data->browser);
1752 g_object_unref (data->activity);
1753 g_free (data->message_uid);
1754 g_free (data);
1755 }
1756
1757 static void
1758 action_mail_show_source_cb (GtkAction *action,
1759 EMailReader *reader)
1760 {
1761 EMailDisplay *display;
1762 EMailBackend *backend;
1763 GtkWidget *browser;
1764 CamelFolder *folder;
1765 GPtrArray *uids;
1766 const gchar *message_uid;
1767 gchar *string;
1768 EActivity *activity;
1769 GCancellable *cancellable;
1770 struct _source_retrieval_closure *closure;
1771
1772 backend = e_mail_reader_get_backend (reader);
1773 folder = e_mail_reader_get_folder (reader);
1774 uids = e_mail_reader_get_selected_uids (reader);
1775 g_return_if_fail (uids != NULL && uids->len == 1);
1776 message_uid = g_ptr_array_index (uids, 0);
1777
1778 browser = e_mail_browser_new (backend, NULL, NULL, E_MAIL_FORMATTER_MODE_SOURCE);
1779 e_mail_reader_set_folder (E_MAIL_READER (browser), folder);
1780 e_mail_reader_set_message (E_MAIL_READER (browser), message_uid);
1781 display = e_mail_reader_get_mail_display (E_MAIL_READER (browser));
1782
1783 string = g_strdup_printf (_("Retrieving message '%s'"), message_uid);
1784 e_mail_display_set_parts_list (display, NULL);
1785 e_mail_display_set_status (display, string);
1786 gtk_widget_show (browser);
1787
1788 activity = e_mail_reader_new_activity (reader);
1789 e_activity_set_text (activity, string);
1790 cancellable = e_activity_get_cancellable (activity);
1791 g_free (string);
1792
1793 closure = g_new0 (struct _source_retrieval_closure, 1);
1794 closure->browser = g_object_ref (E_MAIL_READER (browser));
1795 closure->activity = activity;
1796 closure->message_uid = g_strdup (message_uid);
1797 camel_folder_get_message (
1798 folder, message_uid, G_PRIORITY_DEFAULT,
1799 cancellable, mail_source_retrieved,
1800 closure);
1801
1802 em_utils_uids_free (uids);
1803 }
1804
1805 static void
1806 action_mail_toggle_important_cb (GtkAction *action,
1807 EMailReader *reader)
1808 {
1809 CamelFolder *folder;
1810 GPtrArray *uids;
1811 guint ii;
1812
1813 folder = e_mail_reader_get_folder (reader);
1814 uids = e_mail_reader_get_selected_uids (reader);
1815
1816 camel_folder_freeze (folder);
1817
1818 for (ii = 0; ii < uids->len; ii++) {
1819 guint32 flags;
1820
1821 flags = camel_folder_get_message_flags (
1822 folder, uids->pdata[ii]);
1823 flags ^= CAMEL_MESSAGE_FLAGGED;
1824 if (flags & CAMEL_MESSAGE_FLAGGED)
1825 flags &= ~CAMEL_MESSAGE_DELETED;
1826
1827 camel_folder_set_message_flags (
1828 folder, uids->pdata[ii], CAMEL_MESSAGE_FLAGGED |
1829 CAMEL_MESSAGE_DELETED, flags);
1830 }
1831
1832 camel_folder_thaw (folder);
1833
1834 em_utils_uids_free (uids);
1835 }
1836
1837 static void
1838 action_mail_undelete_cb (GtkAction *action,
1839 EMailReader *reader)
1840 {
1841 guint32 mask = CAMEL_MESSAGE_DELETED;
1842 guint32 set = 0;
1843
1844 e_mail_reader_mark_selected (reader, mask, set);
1845 }
1846
1847 static void
1848 action_mail_zoom_100_cb (GtkAction *action,
1849 EMailReader *reader)
1850 {
1851 EMailDisplay *display;
1852
1853 display = e_mail_reader_get_mail_display (reader);
1854
1855 webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (display), 1.0);
1856 }
1857
1858 static void
1859 action_mail_zoom_in_cb (GtkAction *action,
1860 EMailReader *reader)
1861 {
1862 EMailDisplay *display;
1863
1864 display = e_mail_reader_get_mail_display (reader);
1865
1866 webkit_web_view_zoom_in (WEBKIT_WEB_VIEW (display));
1867 }
1868
1869 static void
1870 action_mail_zoom_out_cb (GtkAction *action,
1871 EMailReader *reader)
1872 {
1873 EMailDisplay *display;
1874
1875 display = e_mail_reader_get_mail_display (reader);
1876
1877 webkit_web_view_zoom_out (WEBKIT_WEB_VIEW (display));
1878 }
1879
1880 static void
1881 action_search_folder_recipient_cb (GtkAction *action,
1882 EMailReader *reader)
1883 {
1884 EMailBackend *backend;
1885 EMailSession *session;
1886 EWebView *web_view;
1887 CamelFolder *folder;
1888 CamelURL *curl;
1889 const gchar *uri;
1890
1891 /* This action is defined in EMailDisplay. */
1892
1893 folder = e_mail_reader_get_folder (reader);
1894 web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
1895
1896 uri = e_web_view_get_selected_uri (web_view);
1897 g_return_if_fail (uri != NULL);
1898
1899 curl = camel_url_new (uri, NULL);
1900 g_return_if_fail (curl != NULL);
1901
1902 backend = e_mail_reader_get_backend (reader);
1903 session = e_mail_backend_get_session (backend);
1904
1905 if (curl->path != NULL && *curl->path != '\0') {
1906 CamelInternetAddress *inet_addr;
1907
1908 inet_addr = camel_internet_address_new ();
1909 camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
1910 vfolder_gui_add_from_address (
1911 session, inet_addr, AUTO_TO, folder);
1912 g_object_unref (inet_addr);
1913 }
1914
1915 camel_url_free (curl);
1916 }
1917
1918 static void
1919 action_search_folder_sender_cb (GtkAction *action,
1920 EMailReader *reader)
1921 {
1922 EMailBackend *backend;
1923 EMailSession *session;
1924 EWebView *web_view;
1925 CamelFolder *folder;
1926 CamelURL *curl;
1927 const gchar *uri;
1928
1929 /* This action is defined in EMailDisplay. */
1930
1931 folder = e_mail_reader_get_folder (reader);
1932 web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
1933
1934 uri = e_web_view_get_selected_uri (web_view);
1935 g_return_if_fail (uri != NULL);
1936
1937 curl = camel_url_new (uri, NULL);
1938 g_return_if_fail (curl != NULL);
1939
1940 backend = e_mail_reader_get_backend (reader);
1941 session = e_mail_backend_get_session (backend);
1942
1943 if (curl->path != NULL && *curl->path != '\0') {
1944 CamelInternetAddress *inet_addr;
1945
1946 inet_addr = camel_internet_address_new ();
1947 camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
1948 vfolder_gui_add_from_address (
1949 session, inet_addr, AUTO_FROM, folder);
1950 g_object_unref (inet_addr);
1951 }
1952
1953 camel_url_free (curl);
1954 }
1955
1956 static GtkActionEntry mail_reader_entries[] = {
1957
1958 { "mail-add-sender",
1959 NULL,
1960 N_("A_dd Sender to Address Book"),
1961 NULL,
1962 N_("Add sender to address book"),
1963 G_CALLBACK (action_mail_add_sender_cb) },
1964
1965 { "mail-check-for-junk",
1966 "mail-mark-junk",
1967 N_("Check for _Junk"),
1968 NULL,
1969 N_("Filter the selected messages for junk status"),
1970 G_CALLBACK (action_mail_check_for_junk_cb) },
1971
1972 { "mail-copy",
1973 "mail-copy",
1974 N_("_Copy to Folder..."),
1975 "<Shift><Control>y",
1976 N_("Copy selected messages to another folder"),
1977 G_CALLBACK (action_mail_copy_cb) },
1978
1979 { "mail-delete",
1980 "user-trash",
1981 N_("_Delete Message"),
1982 "<Control>d",
1983 N_("Mark the selected messages for deletion"),
1984 G_CALLBACK (action_mail_delete_cb) },
1985
1986 { "mail-filter-rule-for-mailing-list",
1987 NULL,
1988 N_("Create a Filter Rule for Mailing _List..."),
1989 NULL,
1990 N_("Create a rule to filter messages to this mailing list"),
1991 G_CALLBACK (action_mail_filter_on_mailing_list_cb) },
1992
1993 { "mail-filter-rule-for-recipients",
1994 NULL,
1995 N_("Create a Filter Rule for _Recipients..."),
1996 NULL,
1997 N_("Create a rule to filter messages to these recipients"),
1998 G_CALLBACK (action_mail_filter_on_recipients_cb) },
1999
2000 { "mail-filter-rule-for-sender",
2001 NULL,
2002 N_("Create a Filter Rule for Se_nder..."),
2003 NULL,
2004 N_("Create a rule to filter messages from this sender"),
2005 G_CALLBACK (action_mail_filter_on_sender_cb) },
2006
2007 { "mail-filter-rule-for-subject",
2008 NULL,
2009 N_("Create a Filter Rule for _Subject..."),
2010 NULL,
2011 N_("Create a rule to filter messages with this subject"),
2012 G_CALLBACK (action_mail_filter_on_subject_cb) },
2013
2014 { "mail-filters-apply",
2015 "stock_mail-filters-apply",
2016 N_("A_pply Filters"),
2017 "<Control>y",
2018 N_("Apply filter rules to the selected messages"),
2019 G_CALLBACK (action_mail_filters_apply_cb) },
2020
2021 { "mail-find",
2022 GTK_STOCK_FIND,
2023 N_("_Find in Message..."),
2024 "<Shift><Control>f",
2025 N_("Search for text in the body of the displayed message"),
2026 G_CALLBACK (action_mail_find_cb) },
2027
2028 { "mail-flag-clear",
2029 NULL,
2030 N_("_Clear Flag"),
2031 NULL,
2032 N_("Remove the follow-up flag from the selected messages"),
2033 G_CALLBACK (action_mail_flag_clear_cb) },
2034
2035 { "mail-flag-completed",
2036 NULL,
2037 N_("_Flag Completed"),
2038 NULL,
2039 N_("Set the follow-up flag to completed on the selected messages"),
2040 G_CALLBACK (action_mail_flag_completed_cb) },
2041
2042 { "mail-flag-for-followup",
2043 "stock_mail-flag-for-followup",
2044 N_("Follow _Up..."),
2045 "<Shift><Control>g",
2046 N_("Flag the selected messages for follow-up"),
2047 G_CALLBACK (action_mail_flag_for_followup_cb) },
2048
2049 { "mail-forward-attached",
2050 NULL,
2051 N_("_Attached"),
2052 NULL,
2053 N_("Forward the selected message to someone as an attachment"),
2054 G_CALLBACK (action_mail_forward_attached_cb) },
2055
2056 { "mail-forward-attached-full",
2057 NULL,
2058 N_("Forward As _Attached"),
2059 NULL,
2060 N_("Forward the selected message to someone as an attachment"),
2061 G_CALLBACK (action_mail_forward_attached_cb) },
2062
2063 { "mail-forward-inline",
2064 NULL,
2065 N_("_Inline"),
2066 NULL,
2067 N_("Forward the selected message in the body of a new message"),
2068 G_CALLBACK (action_mail_forward_inline_cb) },
2069
2070 { "mail-forward-inline-full",
2071 NULL,
2072 N_("Forward As _Inline"),
2073 NULL,
2074 N_("Forward the selected message in the body of a new message"),
2075 G_CALLBACK (action_mail_forward_inline_cb) },
2076
2077 { "mail-forward-quoted",
2078 NULL,
2079 N_("_Quoted"),
2080 NULL,
2081 N_("Forward the selected message quoted like a reply"),
2082 G_CALLBACK (action_mail_forward_quoted_cb) },
2083
2084 { "mail-forward-quoted-full",
2085 NULL,
2086 N_("Forward As _Quoted"),
2087 NULL,
2088 N_("Forward the selected message quoted like a reply"),
2089 G_CALLBACK (action_mail_forward_quoted_cb) },
2090
2091 { "mail-load-images",
2092 "image-x-generic",
2093 N_("_Load Images"),
2094 "<Control>i",
2095 N_("Force images in HTML mail to be loaded"),
2096 G_CALLBACK (action_mail_load_images_cb) },
2097
2098 { "mail-mark-important",
2099 "mail-mark-important",
2100 N_("_Important"),
2101 NULL,
2102 N_("Mark the selected messages as important"),
2103 G_CALLBACK (action_mail_mark_important_cb) },
2104
2105 { "mail-mark-junk",
2106 "mail-mark-junk",
2107 N_("_Junk"),
2108 "<Control>j",
2109 N_("Mark the selected messages as junk"),
2110 G_CALLBACK (action_mail_mark_junk_cb) },
2111
2112 { "mail-mark-notjunk",
2113 "mail-mark-notjunk",
2114 N_("_Not Junk"),
2115 "<Shift><Control>j",
2116 N_("Mark the selected messages as not being junk"),
2117 G_CALLBACK (action_mail_mark_notjunk_cb) },
2118
2119 { "mail-mark-read",
2120 "mail-mark-read",
2121 N_("_Read"),
2122 "<Control>k",
2123 N_("Mark the selected messages as having been read"),
2124 G_CALLBACK (action_mail_mark_read_cb) },
2125
2126 { "mail-mark-unimportant",
2127 NULL,
2128 N_("Uni_mportant"),
2129 NULL,
2130 N_("Mark the selected messages as unimportant"),
2131 G_CALLBACK (action_mail_mark_unimportant_cb) },
2132
2133 { "mail-mark-unread",
2134 "mail-mark-unread",
2135 N_("_Unread"),
2136 "<Shift><Control>k",
2137 N_("Mark the selected messages as not having been read"),
2138 G_CALLBACK (action_mail_mark_unread_cb) },
2139
2140 { "mail-message-edit",
2141 NULL,
2142 N_("_Edit as New Message..."),
2143 NULL,
2144 N_("Open the selected messages in the composer for editing"),
2145 G_CALLBACK (action_mail_message_edit_cb) },
2146
2147 { "mail-message-new",
2148 "mail-message-new",
2149 N_("Compose _New Message"),
2150 "<Shift><Control>m",
2151 N_("Open a window for composing a mail message"),
2152 G_CALLBACK (action_mail_message_new_cb) },
2153
2154 { "mail-message-open",
2155 NULL,
2156 N_("_Open in New Window"),
2157 "<Control>o",
2158 N_("Open the selected messages in a new window"),
2159 G_CALLBACK (action_mail_message_open_cb) },
2160
2161 { "mail-move",
2162 "mail-move",
2163 N_("_Move to Folder..."),
2164 "<Shift><Control>v",
2165 N_("Move selected messages to another folder"),
2166 G_CALLBACK (action_mail_move_cb) },
2167
2168 { "mail-goto-folder",
2169 NULL,
2170 N_("_Switch to Folder"),
2171 "<Control>Up",
2172 N_("Display the parent folder"),
2173 G_CALLBACK (action_mail_folder_cb) },
2174
2175 { "mail-goto-nexttab",
2176 NULL,
2177 N_("Switch to _next tab"),
2178 "<Shift><Control>Down",
2179 N_("Switch to the next tab"),
2180 G_CALLBACK (action_mail_nexttab_cb) },
2181
2182 { "mail-goto-prevtab",
2183 NULL,
2184 N_("Switch to _previous tab"),
2185 "<Shift><Control>Up",
2186 N_("Switch to the previous tab"),
2187 G_CALLBACK (action_mail_prevtab_cb) },
2188
2189 { "mail-close-tab",
2190 NULL,
2191 N_("Cl_ose current tab"),
2192 "<Shift><Control>w",
2193 N_("Close current tab"),
2194 G_CALLBACK (action_mail_closetab_cb) },
2195
2196 { "mail-next",
2197 GTK_STOCK_GO_FORWARD,
2198 N_("_Next Message"),
2199 "<Control>Page_Down",
2200 N_("Display the next message"),
2201 G_CALLBACK (action_mail_next_cb) },
2202
2203 { "mail-next-important",
2204 NULL,
2205 N_("Next _Important Message"),
2206 NULL,
2207 N_("Display the next important message"),
2208 G_CALLBACK (action_mail_next_important_cb) },
2209
2210 { "mail-next-thread",
2211 NULL,
2212 N_("Next _Thread"),
2213 NULL,
2214 N_("Display the next thread"),
2215 G_CALLBACK (action_mail_next_thread_cb) },
2216
2217 { "mail-next-unread",
2218 NULL,
2219 N_("Next _Unread Message"),
2220 "<Control>bracketright",
2221 N_("Display the next unread message"),
2222 G_CALLBACK (action_mail_next_unread_cb) },
2223
2224 { "mail-previous",
2225 GTK_STOCK_GO_BACK,
2226 N_("_Previous Message"),
2227 "<Control>Page_Up",
2228 N_("Display the previous message"),
2229 G_CALLBACK (action_mail_previous_cb) },
2230
2231 { "mail-previous-important",
2232 NULL,
2233 N_("Pr_evious Important Message"),
2234 NULL,
2235 N_("Display the previous important message"),
2236 G_CALLBACK (action_mail_previous_important_cb) },
2237
2238 { "mail-previous-thread",
2239 NULL,
2240 N_("Previous T_hread"),
2241 NULL,
2242 N_("Display the previous thread"),
2243 G_CALLBACK (action_mail_previous_thread_cb) },
2244
2245 { "mail-previous-unread",
2246 NULL,
2247 N_("P_revious Unread Message"),
2248 "<Control>bracketleft",
2249 N_("Display the previous unread message"),
2250 G_CALLBACK (action_mail_previous_unread_cb) },
2251
2252 { "mail-print",
2253 GTK_STOCK_PRINT,
2254 NULL,
2255 "<Control>p",
2256 N_("Print this message"),
2257 G_CALLBACK (action_mail_print_cb) },
2258
2259 { "mail-print-preview",
2260 GTK_STOCK_PRINT_PREVIEW,
2261 NULL,
2262 NULL,
2263 N_("Preview the message to be printed"),
2264 G_CALLBACK (action_mail_print_preview_cb) },
2265
2266 { "mail-redirect",
2267 NULL,
2268 N_("Re_direct"),
2269 NULL,
2270 N_("Redirect (bounce) the selected message to someone"),
2271 G_CALLBACK (action_mail_redirect_cb) },
2272
2273 { "mail-remove-attachments",
2274 GTK_STOCK_DELETE,
2275 N_("Remo_ve Attachments"),
2276 NULL,
2277 N_("Remove attachments"),
2278 G_CALLBACK (action_mail_remove_attachments_cb) },
2279
2280 { "mail-remove-duplicates",
2281 NULL,
2282 N_("Remove Du_plicate Messages"),
2283 NULL,
2284 N_("Checks selected messages for duplicates"),
2285 G_CALLBACK (action_mail_remove_duplicates_cb) },
2286
2287 { "mail-reply-all",
2288 NULL,
2289 N_("Reply to _All"),
2290 "<Shift><Control>r",
2291 N_("Compose a reply to all the recipients of the selected message"),
2292 G_CALLBACK (action_mail_reply_all_cb) },
2293
2294 { "mail-reply-list",
2295 NULL,
2296 N_("Reply to _List"),
2297 "<Control>l",
2298 N_("Compose a reply to the mailing list of the selected message"),
2299 G_CALLBACK (action_mail_reply_list_cb) },
2300
2301 { "mail-reply-sender",
2302 "mail-reply-sender",
2303 N_("_Reply to Sender"),
2304 "<Control>r",
2305 N_("Compose a reply to the sender of the selected message"),
2306 G_CALLBACK (action_mail_reply_sender_cb) },
2307
2308 { "mail-save-as",
2309 GTK_STOCK_SAVE_AS,
2310 N_("_Save as mbox..."),
2311 "<Control>s",
2312 N_("Save selected messages as an mbox file"),
2313 G_CALLBACK (action_mail_save_as_cb) },
2314
2315 { "mail-show-source",
2316 NULL,
2317 N_("_Message Source"),
2318 "<Control>u",
2319 N_("Show the raw email source of the message"),
2320 G_CALLBACK (action_mail_show_source_cb) },
2321
2322 { "mail-toggle-important",
2323 NULL,
2324 NULL, /* No menu item; key press only */
2325 NULL,
2326 NULL,
2327 G_CALLBACK (action_mail_toggle_important_cb) },
2328
2329 { "mail-undelete",
2330 NULL,
2331 N_("_Undelete Message"),
2332 "<Shift><Control>d",
2333 N_("Undelete the selected messages"),
2334 G_CALLBACK (action_mail_undelete_cb) },
2335
2336 { "mail-zoom-100",
2337 GTK_STOCK_ZOOM_100,
2338 N_("_Normal Size"),
2339 "<Control>0",
2340 N_("Reset the text to its original size"),
2341 G_CALLBACK (action_mail_zoom_100_cb) },
2342
2343 { "mail-zoom-in",
2344 GTK_STOCK_ZOOM_IN,
2345 N_("_Zoom In"),
2346 "<Control>plus",
2347 N_("Increase the text size"),
2348 G_CALLBACK (action_mail_zoom_in_cb) },
2349
2350 { "mail-zoom-out",
2351 GTK_STOCK_ZOOM_OUT,
2352 N_("Zoom _Out"),
2353 "<Control>minus",
2354 N_("Decrease the text size"),
2355 G_CALLBACK (action_mail_zoom_out_cb) },
2356
2357 /*** Menus ***/
2358
2359 { "mail-create-menu",
2360 NULL,
2361 N_("Cre_ate"),
2362 NULL,
2363 NULL,
2364 NULL },
2365
2366 { "mail-encoding-menu",
2367 NULL,
2368 N_("Ch_aracter Encoding"),
2369 NULL,
2370 NULL,
2371 NULL },
2372
2373 { "mail-forward-as-menu",
2374 NULL,
2375 N_("F_orward As"),
2376 NULL,
2377 NULL,
2378 NULL },
2379
2380 { "mail-reply-group-menu",
2381 NULL,
2382 N_("_Group Reply"),
2383 NULL,
2384 NULL,
2385 NULL },
2386
2387 { "mail-goto-menu",
2388 GTK_STOCK_JUMP_TO,
2389 N_("_Go To"),
2390 NULL,
2391 NULL,
2392 NULL },
2393
2394 { "mail-mark-as-menu",
2395 NULL,
2396 N_("Mar_k As"),
2397 NULL,
2398 NULL,
2399 NULL },
2400
2401 { "mail-message-menu",
2402 NULL,
2403 N_("_Message"),
2404 NULL,
2405 NULL,
2406 NULL },
2407
2408 { "mail-zoom-menu",
2409 NULL,
2410 N_("_Zoom"),
2411 NULL,
2412 NULL,
2413 NULL }
2414 };
2415
2416 static GtkActionEntry mail_reader_search_folder_entries[] = {
2417
2418 { "mail-search-folder-from-mailing-list",
2419 NULL,
2420 N_("Create a Search Folder from Mailing _List..."),
2421 NULL,
2422 N_("Create a search folder for this mailing list"),
2423 G_CALLBACK (action_mail_search_folder_from_mailing_list_cb) },
2424
2425 { "mail-search-folder-from-recipients",
2426 NULL,
2427 N_("Create a Search Folder from Recipien_ts..."),
2428 NULL,
2429 N_("Create a search folder for these recipients"),
2430 G_CALLBACK (action_mail_search_folder_from_recipients_cb) },
2431
2432 { "mail-search-folder-from-sender",
2433 NULL,
2434 N_("Create a Search Folder from Sen_der..."),
2435 NULL,
2436 N_("Create a search folder for this sender"),
2437 G_CALLBACK (action_mail_search_folder_from_sender_cb) },
2438
2439 { "mail-search-folder-from-subject",
2440 NULL,
2441 N_("Create a Search Folder from S_ubject..."),
2442 NULL,
2443 N_("Create a search folder for this subject"),
2444 G_CALLBACK (action_mail_search_folder_from_subject_cb) },
2445 };
2446
2447 static EPopupActionEntry mail_reader_popup_entries[] = {
2448
2449 { "mail-popup-copy",
2450 NULL,
2451 "mail-copy" },
2452
2453 { "mail-popup-delete",
2454 NULL,
2455 "mail-delete" },
2456
2457 { "mail-popup-flag-clear",
2458 NULL,
2459 "mail-flag-clear" },
2460
2461 { "mail-popup-flag-completed",
2462 NULL,
2463 "mail-flag-completed" },
2464
2465 { "mail-popup-flag-for-followup",
2466 N_("Mark for Follo_w Up..."),
2467 "mail-flag-for-followup" },
2468
2469 { "mail-popup-forward",
2470 NULL,
2471 "mail-forward" },
2472
2473 { "mail-popup-mark-important",
2474 N_("Mark as _Important"),
2475 "mail-mark-important" },
2476
2477 { "mail-popup-mark-junk",
2478 N_("Mark as _Junk"),
2479 "mail-mark-junk" },
2480
2481 { "mail-popup-mark-notjunk",
2482 N_("Mark as _Not Junk"),
2483 "mail-mark-notjunk" },
2484
2485 { "mail-popup-mark-read",
2486 N_("Mar_k as Read"),
2487 "mail-mark-read" },
2488
2489 { "mail-popup-mark-unimportant",
2490 N_("Mark as Uni_mportant"),
2491 "mail-mark-unimportant" },
2492
2493 { "mail-popup-mark-unread",
2494 N_("Mark as _Unread"),
2495 "mail-mark-unread" },
2496
2497 { "mail-popup-message-edit",
2498 NULL,
2499 "mail-message-edit" },
2500
2501 { "mail-popup-move",
2502 NULL,
2503 "mail-move" },
2504
2505 { "mail-popup-print",
2506 NULL,
2507 "mail-print" },
2508
2509 { "mail-popup-remove-attachments",
2510 NULL,
2511 "mail-remove-attachments" },
2512
2513 { "mail-popup-remove-duplicates",
2514 NULL,
2515 "mail-remove-duplicates" },
2516
2517 { "mail-popup-reply-all",
2518 NULL,
2519 "mail-reply-all" },
2520
2521 { "mail-popup-reply-sender",
2522 NULL,
2523 "mail-reply-sender" },
2524
2525 { "mail-popup-save-as",
2526 NULL,
2527 "mail-save-as" },
2528
2529 { "mail-popup-undelete",
2530 NULL,
2531 "mail-undelete" }
2532 };
2533
2534 static GtkToggleActionEntry mail_reader_toggle_entries[] = {
2535
2536 { "mail-caret-mode",
2537 NULL,
2538 N_("_Caret Mode"),
2539 "F7",
2540 N_("Show a blinking cursor in the body of displayed messages"),
2541 NULL, /* No callback required */
2542 FALSE },
2543
2544 { "mail-show-all-headers",
2545 NULL,
2546 N_("All Message _Headers"),
2547 NULL,
2548 N_("Show messages with all email headers"),
2549 G_CALLBACK (action_mail_show_all_headers_cb),
2550 FALSE }
2551 };
2552
2553 static void
2554 mail_reader_double_click_cb (EMailReader *reader,
2555 gint row,
2556 ETreePath path,
2557 gint col,
2558 GdkEvent *event)
2559 {
2560 GtkAction *action;
2561
2562 /* Ignore double clicks on columns that handle their own state. */
2563 if (MESSAGE_LIST_COLUMN_IS_ACTIVE (col))
2564 return;
2565
2566 action = e_mail_reader_get_action (reader, "mail-message-open");
2567 gtk_action_activate (action);
2568 }
2569
2570 static gboolean
2571 mail_reader_key_press_event_cb (EMailReader *reader,
2572 GdkEventKey *event)
2573 {
2574 GtkAction *action;
2575 const gchar *action_name;
2576
2577 if ((event->state & GDK_CONTROL_MASK) != 0)
2578 goto ctrl;
2579
2580 /* <keyval> alone */
2581 switch (event->keyval) {
2582 case GDK_KEY_Delete:
2583 case GDK_KEY_KP_Delete:
2584 action_name = "mail-delete";
2585 break;
2586
2587 case GDK_KEY_Return:
2588 case GDK_KEY_KP_Enter:
2589 case GDK_KEY_ISO_Enter:
2590 action_name = "mail-message-open";
2591 break;
2592
2593 case GDK_KEY_period:
2594 case GDK_KEY_bracketright:
2595 action_name = "mail-next-unread";
2596 break;
2597
2598 case GDK_KEY_comma:
2599 case GDK_KEY_bracketleft:
2600 action_name = "mail-previous-unread";
2601 break;
2602
2603 #ifdef HAVE_XFREE
2604 case XF86XK_Reply:
2605 action_name = "mail-reply-all";
2606 break;
2607
2608 case XF86XK_MailForward:
2609 action_name = "mail-forward";
2610 break;
2611 #endif
2612
2613 case GDK_KEY_exclam:
2614 action_name = "mail-toggle-important";
2615 break;
2616
2617 default:
2618 return FALSE;
2619 }
2620
2621 goto exit;
2622
2623 ctrl:
2624
2625 /* Ctrl + <keyval> */
2626 switch (event->keyval) {
2627 case GDK_KEY_period:
2628 action_name = "mail-next-unread";
2629 break;
2630
2631 case GDK_KEY_comma:
2632 action_name = "mail-previous-unread";
2633 break;
2634
2635 default:
2636 return FALSE;
2637 }
2638
2639 exit:
2640 action = e_mail_reader_get_action (reader, action_name);
2641 gtk_action_activate (action);
2642
2643 return TRUE;
2644 }
2645
2646 static gint
2647 mail_reader_key_press_cb (EMailReader *reader,
2648 gint row,
2649 ETreePath path,
2650 gint col,
2651 GdkEvent *event)
2652 {
2653 return mail_reader_key_press_event_cb (reader, &event->key);
2654 }
2655
2656 static gboolean
2657 mail_reader_message_seen_cb (EMailReaderClosure *closure)
2658 {
2659 EMailReader *reader;
2660 GtkWidget *message_list;
2661 EMailPartList *parts;
2662 EMailDisplay *display;
2663 CamelMimeMessage *message;
2664 const gchar *current_uid;
2665 const gchar *message_uid;
2666 gboolean uid_is_current = TRUE;
2667
2668 reader = closure->reader;
2669 message_uid = closure->message_uid;
2670
2671 display = e_mail_reader_get_mail_display (reader);
2672 parts = e_mail_display_get_parts_list (display);
2673 message_list = e_mail_reader_get_message_list (reader);
2674
2675 if (e_tree_is_dragging (E_TREE (message_list)))
2676 return FALSE;
2677
2678 current_uid = MESSAGE_LIST (message_list)->cursor_uid;
2679 uid_is_current &= (g_strcmp0 (current_uid, message_uid) == 0);
2680
2681 if (parts)
2682 message = parts->message;
2683 else
2684 message = NULL;
2685
2686 if (uid_is_current && message != NULL)
2687 g_signal_emit (
2688 reader, signals[MESSAGE_SEEN], 0,
2689 message_uid, message);
2690
2691 return FALSE;
2692 }
2693
2694 static gboolean
2695 schedule_timeout_mark_seen (EMailReader *reader)
2696 {
2697 EShell *shell;
2698 EMailBackend *backend;
2699 EShellBackend *shell_backend;
2700 EShellSettings *shell_settings;
2701 MessageList *message_list;
2702 gboolean schedule_timeout;
2703 gint timeout_interval;
2704 const gchar *message_uid;
2705 backend = e_mail_reader_get_backend (reader);
2706 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2707 shell_backend = E_SHELL_BACKEND (backend);
2708 shell = e_shell_backend_get_shell (shell_backend);
2709 shell_settings = e_shell_get_shell_settings (shell);
2710
2711 message_uid = message_list->cursor_uid;
2712 if (message_uid == NULL ||
2713 e_tree_is_dragging (E_TREE (message_list)))
2714 return FALSE;
2715
2716 schedule_timeout =
2717 (message_uid != NULL) &&
2718 e_shell_settings_get_boolean (
2719 shell_settings, "mail-mark-seen");
2720 timeout_interval =
2721 e_shell_settings_get_int (
2722 shell_settings, "mail-mark-seen-timeout");
2723
2724 if (message_list->seen_id > 0) {
2725 g_source_remove (message_list->seen_id);
2726 message_list->seen_id = 0;
2727 }
2728
2729 if (schedule_timeout) {
2730 EMailReaderClosure *timeout_closure;
2731
2732 timeout_closure = g_slice_new0 (EMailReaderClosure);
2733 timeout_closure->reader = g_object_ref (reader);
2734 timeout_closure->message_uid = g_strdup (message_uid);
2735
2736 MESSAGE_LIST (message_list)->seen_id = g_timeout_add_full (
2737 G_PRIORITY_DEFAULT, timeout_interval,
2738 (GSourceFunc) mail_reader_message_seen_cb,
2739 timeout_closure, (GDestroyNotify)
2740 mail_reader_closure_free);
2741 }
2742
2743 return schedule_timeout;
2744 }
2745
2746 static gboolean
2747 discard_timeout_mark_seen_cb (EMailReader *reader)
2748 {
2749 MessageList *message_list;
2750
2751 g_return_val_if_fail (reader != NULL, FALSE);
2752
2753 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2754 g_return_val_if_fail (message_list != NULL, FALSE);
2755
2756 if (message_list->seen_id > 0) {
2757 g_source_remove (message_list->seen_id);
2758 message_list->seen_id = 0;
2759 }
2760
2761 return FALSE;
2762 }
2763
2764 static void
2765 mail_reader_message_loaded_cb (CamelFolder *folder,
2766 GAsyncResult *result,
2767 EMailReaderClosure *closure)
2768 {
2769 EMailReader *reader;
2770 EMailReaderPrivate *priv;
2771 CamelMimeMessage *message = NULL;
2772 GtkWidget *message_list;
2773 const gchar *message_uid;
2774 GError *error = NULL;
2775
2776 reader = closure->reader;
2777 message_uid = closure->message_uid;
2778
2779 priv = E_MAIL_READER_GET_PRIVATE (reader);
2780
2781 /* If the private struct is NULL, the EMailReader was destroyed
2782 * while we were loading the message and we're likely holding the
2783 * last reference. Nothing to do but drop the reference. */
2784 if (priv == NULL) {
2785 mail_reader_closure_free (closure);
2786 return;
2787 }
2788
2789 message = camel_folder_get_message_finish (folder, result, &error);
2790
2791 /* If the user picked a different message in the time it took
2792 * to fetch this message, then don't bother rendering it. */
2793 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
2794 g_clear_error (&error);
2795 goto exit;
2796 }
2797
2798 message_list = e_mail_reader_get_message_list (reader);
2799
2800 if (!message_list) {
2801 /* for cases where message fetching took so long that
2802 * user closed the message window before this was called */
2803 goto exit;
2804 }
2805
2806 if (message != NULL)
2807 g_signal_emit (
2808 reader, signals[MESSAGE_LOADED], 0,
2809 message_uid, message);
2810
2811 exit:
2812 priv->restoring_message_selection = FALSE;
2813 if (error) {
2814 EPreviewPane *preview_pane;
2815 EWebView *web_view;
2816
2817 preview_pane = e_mail_reader_get_preview_pane (reader);
2818 web_view = e_preview_pane_get_web_view (preview_pane);
2819
2820 e_alert_submit (
2821 E_ALERT_SINK (web_view),
2822 "mail:no-retrieve-message",
2823 error->message, NULL);
2824 }
2825
2826 g_clear_error (&error);
2827
2828 mail_reader_closure_free (closure);
2829
2830 if (message)
2831 g_object_unref (message);
2832 }
2833
2834 static gboolean
2835 mail_reader_message_selected_timeout_cb (EMailReader *reader)
2836 {
2837 EMailReaderPrivate *priv;
2838 EMailDisplay *display;
2839 GtkWidget *message_list;
2840 CamelFolder *folder;
2841 const gchar *cursor_uid;
2842 const gchar *format_uid;
2843 EMailPartList *parts;
2844
2845 priv = E_MAIL_READER_GET_PRIVATE (reader);
2846
2847 folder = e_mail_reader_get_folder (reader);
2848
2849 message_list = e_mail_reader_get_message_list (reader);
2850 display = e_mail_reader_get_mail_display (reader);
2851 parts = e_mail_display_get_parts_list (display);
2852
2853 cursor_uid = MESSAGE_LIST (message_list)->cursor_uid;
2854 format_uid = parts ? parts->message_uid : NULL;
2855
2856 if (MESSAGE_LIST (message_list)->last_sel_single) {
2857 GtkWidget *widget;
2858 gboolean display_visible;
2859 gboolean selected_uid_changed;
2860
2861 /* Decide whether to download the full message now. */
2862 widget = GTK_WIDGET (display);
2863 display_visible = gtk_widget_get_mapped (widget);
2864
2865 selected_uid_changed = (g_strcmp0 (cursor_uid, format_uid) != 0);
2866
2867 if (display_visible && selected_uid_changed) {
2868 EMailReaderClosure *closure;
2869 GCancellable *cancellable;
2870 EActivity *activity;
2871 gchar *string;
2872
2873 string = g_strdup_printf (_("Retrieving message '%s'"), cursor_uid);
2874 e_mail_display_set_parts_list (display, NULL);
2875 e_mail_display_set_status (display, string);
2876 g_free (string);
2877
2878 activity = e_mail_reader_new_activity (reader);
2879 e_activity_set_text (activity, _("Retrieving message"));
2880 cancellable = e_activity_get_cancellable (activity);
2881
2882 closure = g_slice_new0 (EMailReaderClosure);
2883 closure->activity = activity;
2884 closure->reader = g_object_ref (reader);
2885 closure->message_uid = g_strdup (cursor_uid);
2886
2887 camel_folder_get_message (
2888 folder, cursor_uid, G_PRIORITY_DEFAULT,
2889 cancellable, (GAsyncReadyCallback)
2890 mail_reader_message_loaded_cb, closure);
2891
2892 if (priv->retrieving_message != NULL)
2893 g_object_unref (priv->retrieving_message);
2894 priv->retrieving_message = g_object_ref (cancellable);
2895 }
2896 } else {
2897 e_mail_display_set_parts_list (display, NULL);
2898 priv->restoring_message_selection = FALSE;
2899 }
2900
2901 priv->message_selected_timeout_id = 0;
2902
2903 return FALSE;
2904 }
2905
2906 static void
2907 mail_reader_message_selected_cb (EMailReader *reader,
2908 const gchar *message_uid)
2909 {
2910 EMailReaderPrivate *priv;
2911 MessageList *message_list;
2912
2913 priv = E_MAIL_READER_GET_PRIVATE (reader);
2914
2915 /* Cancel the previous message retrieval activity. */
2916 g_cancellable_cancel (priv->retrieving_message);
2917
2918 /* Cancel the seen timer. */
2919 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2920 if (message_list && message_list->seen_id) {
2921 g_source_remove (message_list->seen_id);
2922 message_list->seen_id = 0;
2923 }
2924
2925 /* Cancel the message selected timer. */
2926 if (priv->message_selected_timeout_id > 0) {
2927 g_source_remove (priv->message_selected_timeout_id);
2928 priv->message_selected_timeout_id = 0;
2929 }
2930
2931 /* If a folder was just selected then we are now automatically
2932 * restoring the previous message selection. We behave slightly
2933 * differently than if the user had selected the message. */
2934 priv->restoring_message_selection = priv->folder_was_just_selected;
2935 priv->folder_was_just_selected = FALSE;
2936
2937 if (message_list_selected_count (message_list) != 1) {
2938 EMailDisplay *display = e_mail_reader_get_mail_display (reader);
2939
2940 e_mail_display_set_parts_list (display, NULL);
2941 e_web_view_clear (E_WEB_VIEW (display));
2942 } else if (priv->restoring_message_selection) {
2943 /* Skip the timeout if we're restoring the previous message
2944 * selection. The timeout is there for when we're scrolling
2945 * rapidly through the message list. */
2946 mail_reader_message_selected_timeout_cb (reader);
2947 } else {
2948 priv->message_selected_timeout_id = g_timeout_add (
2949 100, (GSourceFunc)
2950 mail_reader_message_selected_timeout_cb, reader);
2951 }
2952
2953 e_mail_reader_changed (reader);
2954 }
2955
2956 static void
2957 mail_reader_message_cursor_change_cb (EMailReader *reader)
2958 {
2959 MessageList *message_list;
2960 EMailReaderPrivate *priv;
2961
2962 g_return_if_fail (reader != NULL);
2963
2964 priv = E_MAIL_READER_GET_PRIVATE (reader);
2965 g_return_if_fail (priv != NULL);
2966
2967 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2968 g_return_if_fail (message_list != NULL);
2969
2970 if (message_list->seen_id == 0 &&
2971 E_IS_MAIL_VIEW (reader) &&
2972 e_mail_view_get_preview_visible (E_MAIL_VIEW (reader)) &&
2973 !priv->avoid_next_mark_as_seen)
2974 schedule_timeout_mark_seen (reader);
2975 }
2976
2977 static void
2978 mail_reader_emit_folder_loaded (EMailReader *reader)
2979 {
2980 EMailReaderPrivate *priv;
2981 MessageList *message_list;
2982
2983 priv = E_MAIL_READER_GET_PRIVATE (reader);
2984 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
2985
2986 if (priv && (message_list_count (message_list) <= 0 ||
2987 message_list_selected_count (message_list) <= 0))
2988 priv->avoid_next_mark_as_seen = FALSE;
2989
2990 g_signal_emit (reader, signals[FOLDER_LOADED], 0);
2991 }
2992
2993 static EAlertSink *
2994 mail_reader_get_alert_sink (EMailReader *reader)
2995 {
2996 EPreviewPane *preview_pane;
2997
2998 preview_pane = e_mail_reader_get_preview_pane (reader);
2999
3000 return E_ALERT_SINK (preview_pane);
3001 }
3002
3003 static GPtrArray *
3004 mail_reader_get_selected_uids (EMailReader *reader)
3005 {
3006 GtkWidget *message_list;
3007
3008 message_list = e_mail_reader_get_message_list (reader);
3009
3010 return message_list_get_selected (MESSAGE_LIST (message_list));
3011 }
3012
3013 static CamelFolder *
3014 mail_reader_get_folder (EMailReader *reader)
3015 {
3016 GtkWidget *message_list;
3017
3018 message_list = e_mail_reader_get_message_list (reader);
3019
3020 return MESSAGE_LIST (message_list)->folder;
3021 }
3022
3023 static gboolean
3024 mail_reader_get_enable_show_folder (EMailReader *reader)
3025 {
3026 return FALSE;
3027 }
3028
3029 static void
3030 mail_reader_set_folder (EMailReader *reader,
3031 CamelFolder *folder)
3032 {
3033 EMailReaderPrivate *priv;
3034 EMailDisplay *display;
3035 CamelFolder *previous_folder;
3036 ESourceRegistry *registry;
3037 GtkWidget *message_list;
3038 EMailBackend *backend;
3039 EShell *shell;
3040 gboolean outgoing;
3041 gboolean sync_folder;
3042
3043 priv = E_MAIL_READER_GET_PRIVATE (reader);
3044
3045 backend = e_mail_reader_get_backend (reader);
3046 display = e_mail_reader_get_mail_display (reader);
3047 message_list = e_mail_reader_get_message_list (reader);
3048
3049 previous_folder = e_mail_reader_get_folder (reader);
3050
3051 backend = e_mail_reader_get_backend (reader);
3052 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
3053 registry = e_shell_get_registry (shell);
3054
3055 /* Only synchronize the real folder if we're online. */
3056 sync_folder =
3057 (previous_folder != NULL) &&
3058 (CAMEL_IS_VEE_FOLDER (previous_folder) ||
3059 e_shell_get_online (shell));
3060 if (sync_folder)
3061 mail_sync_folder (previous_folder, NULL, NULL);
3062
3063 /* Skip the rest if we're already viewing the folder. */
3064 if (folder == previous_folder)
3065 return;
3066
3067 outgoing = folder != NULL && (
3068 em_utils_folder_is_drafts (registry, folder) ||
3069 em_utils_folder_is_outbox (registry, folder) ||
3070 em_utils_folder_is_sent (registry, folder));
3071
3072 e_web_view_clear (E_WEB_VIEW (display));
3073
3074 priv->folder_was_just_selected = (folder != NULL);
3075
3076 /* this is to make sure any post-poned changes in Search Folders
3077 * will be propagated on folder selection */
3078 if (folder && CAMEL_IS_VEE_FOLDER (folder))
3079 mail_sync_folder (folder, NULL, NULL);
3080
3081 message_list_set_folder (
3082 MESSAGE_LIST (message_list), folder, outgoing);
3083
3084 mail_reader_emit_folder_loaded (reader);
3085 }
3086
3087 static void
3088 mail_reader_set_message (EMailReader *reader,
3089 const gchar *message_uid)
3090 {
3091 GtkWidget *message_list;
3092
3093 message_list = e_mail_reader_get_message_list (reader);
3094
3095 message_list_select_uid (
3096 MESSAGE_LIST (message_list), message_uid, FALSE);
3097 }
3098
3099 static void
3100 mail_reader_folder_loaded (EMailReader *reader)
3101 {
3102 guint32 state;
3103
3104 state = e_mail_reader_check_state (reader);
3105 e_mail_reader_update_actions (reader, state);
3106 }
3107
3108 struct format_parser_async_closure_ {
3109 struct _formatter_weak_ref_closure *weak_ref_closure;
3110 EMailDisplay *display;
3111 EActivity *activity;
3112 };
3113
3114 static void
3115 set_mail_display_part_list (GObject *object,
3116 GAsyncResult *result,
3117 gpointer user_data)
3118 {
3119 EMailPartList *part_list;
3120 EMailReader *reader;
3121 EMailDisplay *display;
3122
3123 reader = E_MAIL_READER (object);
3124 display = e_mail_reader_get_mail_display (reader);
3125
3126 part_list = e_mail_reader_parse_message_finish (reader, result);
3127
3128 e_mail_display_set_parts_list (display, part_list);
3129 e_mail_display_load (display, NULL);
3130
3131 /* Remove the reference added when parts list was created,
3132 * so that only owners are EMailDisplays */
3133 g_object_unref (part_list);
3134 }
3135
3136 static void
3137 mail_reader_set_display_formatter_for_message (EMailReader *reader,
3138 EMailDisplay *display,
3139 const gchar *message_uid,
3140 CamelMimeMessage *message,
3141 CamelFolder *folder)
3142 {
3143 CamelObjectBag *registry;
3144 EMailPartList *parts;
3145 EMailReaderPrivate *priv;
3146 gchar *mail_uri;
3147
3148 priv = E_MAIL_READER_GET_PRIVATE (reader);
3149 mail_uri = e_mail_part_build_uri (folder, message_uid, NULL, NULL);
3150 registry = e_mail_part_list_get_registry ();
3151 parts = camel_object_bag_peek (registry, mail_uri);
3152 g_free (mail_uri);
3153
3154 if (parts == NULL) {
3155
3156 e_mail_reader_parse_message (
3157 reader, folder, message_uid, message,
3158 priv->retrieving_message,
3159 set_mail_display_part_list, NULL);
3160
3161 } else {
3162 e_mail_display_set_parts_list (display, parts);
3163 e_mail_display_load (display, NULL);
3164 g_object_unref (parts);
3165 }
3166 }
3167
3168 static void
3169 mail_reader_message_loaded (EMailReader *reader,
3170 const gchar *message_uid,
3171 CamelMimeMessage *message)
3172 {
3173 EMailReaderPrivate *priv;
3174 GtkWidget *message_list;
3175 EMailBackend *backend;
3176 CamelFolder *folder;
3177 EMailDisplay *display;
3178 EShellBackend *shell_backend;
3179 EShell *shell;
3180 EMEvent *event;
3181 EMEventTargetMessage *target;
3182 GError *error = NULL;
3183
3184 priv = E_MAIL_READER_GET_PRIVATE (reader);
3185
3186 folder = e_mail_reader_get_folder (reader);
3187 backend = e_mail_reader_get_backend (reader);
3188 display = e_mail_reader_get_mail_display (reader);
3189 message_list = e_mail_reader_get_message_list (reader);
3190
3191 shell_backend = E_SHELL_BACKEND (backend);
3192 shell = e_shell_backend_get_shell (shell_backend);
3193
3194 /** @Event: message.reading
3195 * @Title: Viewing a message
3196 * @Target: EMEventTargetMessage
3197 *
3198 * message.reading is emitted whenever a user views a message.
3199 */
3200 event = em_event_peek ();
3201 target = em_event_target_new_message (
3202 event, folder, message, message_uid, 0, NULL);
3203 e_event_emit (
3204 (EEvent *) event, "message.reading",
3205 (EEventTarget *) target);
3206
3207 mail_reader_set_display_formatter_for_message (
3208 reader, display, message_uid, message, folder);
3209
3210 /* Reset the shell view icon. */
3211 e_shell_event (shell, "mail-icon", (gpointer) "evolution-mail");
3212
3213 if (MESSAGE_LIST (message_list)->seen_id > 0) {
3214 g_source_remove (MESSAGE_LIST (message_list)->seen_id);
3215 MESSAGE_LIST (message_list)->seen_id = 0;
3216 }
3217
3218 /* Determine whether to mark the message as read. */
3219 if (message != NULL &&
3220 !priv->restoring_message_selection &&
3221 !priv->avoid_next_mark_as_seen &&
3222 schedule_timeout_mark_seen (reader)) {
3223 g_clear_error (&error);
3224 } else if (error != NULL) {
3225 e_alert_submit (
3226 E_ALERT_SINK (display),
3227 "mail:no-retrieve-message",
3228 error->message, NULL);
3229 g_error_free (error);
3230 }
3231
3232 priv->avoid_next_mark_as_seen = FALSE;
3233 }
3234
3235 static void
3236 mail_reader_message_seen (EMailReader *reader,
3237 const gchar *message_uid,
3238 CamelMimeMessage *message)
3239 {
3240 CamelFolder *folder;
3241 guint32 mask, set;
3242
3243 mask = CAMEL_MESSAGE_SEEN;
3244 set = CAMEL_MESSAGE_SEEN;
3245
3246 folder = e_mail_reader_get_folder (reader);
3247 camel_folder_set_message_flags (folder, message_uid, mask, set);
3248 }
3249
3250 static void
3251 mail_reader_show_search_bar (EMailReader *reader)
3252 {
3253 EPreviewPane *preview_pane;
3254
3255 preview_pane = e_mail_reader_get_preview_pane (reader);
3256 e_preview_pane_show_search_bar (preview_pane);
3257 }
3258
3259 static void
3260 mail_reader_update_actions (EMailReader *reader,
3261 guint32 state)
3262 {
3263 GtkAction *action;
3264 const gchar *action_name;
3265 gboolean sensitive;
3266
3267 /* Be descriptive. */
3268 gboolean any_messages_selected;
3269 gboolean enable_flag_clear;
3270 gboolean enable_flag_completed;
3271 gboolean enable_flag_for_followup;
3272 gboolean have_enabled_account;
3273 gboolean multiple_messages_selected;
3274 gboolean selection_has_attachment_messages;
3275 gboolean selection_has_deleted_messages;
3276 gboolean selection_has_important_messages;
3277 gboolean selection_has_junk_messages;
3278 gboolean selection_has_not_junk_messages;
3279 gboolean selection_has_read_messages;
3280 gboolean selection_has_undeleted_messages;
3281 gboolean selection_has_unimportant_messages;
3282 gboolean selection_has_unread_messages;
3283 gboolean selection_is_mailing_list;
3284 gboolean single_message_selected;
3285 gboolean first_message_selected = FALSE;
3286 gboolean last_message_selected = FALSE;
3287
3288 have_enabled_account =
3289 (state & E_MAIL_READER_HAVE_ENABLED_ACCOUNT);
3290 single_message_selected =
3291 (state & E_MAIL_READER_SELECTION_SINGLE);
3292 multiple_messages_selected =
3293 (state & E_MAIL_READER_SELECTION_MULTIPLE);
3294 /* FIXME Missing CAN_ADD_SENDER */
3295 enable_flag_clear =
3296 (state & E_MAIL_READER_SELECTION_FLAG_CLEAR);
3297 enable_flag_completed =
3298 (state & E_MAIL_READER_SELECTION_FLAG_COMPLETED);
3299 enable_flag_for_followup =
3300 (state & E_MAIL_READER_SELECTION_FLAG_FOLLOWUP);
3301 selection_has_attachment_messages =
3302 (state & E_MAIL_READER_SELECTION_HAS_ATTACHMENTS);
3303 selection_has_deleted_messages =
3304 (state & E_MAIL_READER_SELECTION_HAS_DELETED);
3305 selection_has_important_messages =
3306 (state & E_MAIL_READER_SELECTION_HAS_IMPORTANT);
3307 selection_has_junk_messages =
3308 (state & E_MAIL_READER_SELECTION_HAS_JUNK);
3309 selection_has_not_junk_messages =
3310 (state & E_MAIL_READER_SELECTION_HAS_NOT_JUNK);
3311 selection_has_read_messages =
3312 (state & E_MAIL_READER_SELECTION_HAS_READ);
3313 selection_has_undeleted_messages =
3314 (state & E_MAIL_READER_SELECTION_HAS_UNDELETED);
3315 selection_has_unimportant_messages =
3316 (state & E_MAIL_READER_SELECTION_HAS_UNIMPORTANT);
3317 selection_has_unread_messages =
3318 (state & E_MAIL_READER_SELECTION_HAS_UNREAD);
3319 selection_is_mailing_list =
3320 (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST);
3321
3322 any_messages_selected =
3323 (single_message_selected || multiple_messages_selected);
3324
3325 if (any_messages_selected) {
3326 MessageList *message_list;
3327 gint row = -1, count = -1;
3328 ETreeTableAdapter *etta;
3329 ETreePath node = NULL;
3330
3331 message_list = MESSAGE_LIST (
3332 e_mail_reader_get_message_list (reader));
3333 etta = e_tree_get_table_adapter (E_TREE (message_list));
3334
3335 if (message_list->cursor_uid != NULL)
3336 node = g_hash_table_lookup (
3337 message_list->uid_nodemap,
3338 message_list->cursor_uid);
3339
3340 if (node != NULL) {
3341 row = e_tree_table_adapter_row_of_node (etta, node);
3342 count = e_table_model_row_count (E_TABLE_MODEL (etta));
3343 }
3344
3345 first_message_selected = row <= 0;
3346 last_message_selected = row < 0 || row + 1 >= count;
3347 }
3348
3349 action_name = "mail-add-sender";
3350 sensitive = single_message_selected;
3351 action = e_mail_reader_get_action (reader, action_name);
3352 gtk_action_set_sensitive (action, sensitive);
3353
3354 action_name = "mail-check-for-junk";
3355 sensitive = any_messages_selected;
3356 action = e_mail_reader_get_action (reader, action_name);
3357 gtk_action_set_sensitive (action, sensitive);
3358
3359 action_name = "mail-copy";
3360 sensitive = any_messages_selected;
3361 action = e_mail_reader_get_action (reader, action_name);
3362 gtk_action_set_sensitive (action, sensitive);
3363
3364 action_name = "mail-create-menu";
3365 sensitive = single_message_selected;
3366 action = e_mail_reader_get_action (reader, action_name);
3367 gtk_action_set_sensitive (action, sensitive);
3368
3369 /* If a single message is selected, let the user hit delete to
3370 * advance the cursor even if the message is already deleted. */
3371 action_name = "mail-delete";
3372 sensitive =
3373 single_message_selected ||
3374 selection_has_undeleted_messages;
3375 action = e_mail_reader_get_action (reader, action_name);
3376 gtk_action_set_sensitive (action, sensitive);
3377
3378 action_name = "mail-filters-apply";
3379 sensitive = any_messages_selected;
3380 action = e_mail_reader_get_action (reader, action_name);
3381 gtk_action_set_sensitive (action, sensitive);
3382
3383 action_name = "mail-find";
3384 sensitive = single_message_selected;
3385 action = e_mail_reader_get_action (reader, action_name);
3386 gtk_action_set_sensitive (action, sensitive);
3387
3388 action_name = "mail-flag-clear";
3389 sensitive = enable_flag_clear;
3390 action = e_mail_reader_get_action (reader, action_name);
3391 gtk_action_set_sensitive (action, sensitive);
3392
3393 action_name = "mail-flag-completed";
3394 sensitive = enable_flag_completed;
3395 action = e_mail_reader_get_action (reader, action_name);
3396 gtk_action_set_sensitive (action, sensitive);
3397
3398 action_name = "mail-flag-for-followup";
3399 sensitive = enable_flag_for_followup;
3400 action = e_mail_reader_get_action (reader, action_name);
3401 gtk_action_set_sensitive (action, sensitive);
3402
3403 action_name = "mail-forward";
3404 sensitive = have_enabled_account && any_messages_selected;
3405 action = e_mail_reader_get_action (reader, action_name);
3406 gtk_action_set_sensitive (action, sensitive);
3407
3408 action_name = "mail-forward-attached";
3409 sensitive = have_enabled_account && any_messages_selected;
3410 action = e_mail_reader_get_action (reader, action_name);
3411 gtk_action_set_sensitive (action, sensitive);
3412
3413 action_name = "mail-forward-attached-full";
3414 sensitive = have_enabled_account && any_messages_selected;
3415 action = e_mail_reader_get_action (reader, action_name);
3416 gtk_action_set_sensitive (action, sensitive);
3417
3418 action_name = "mail-forward-as-menu";
3419 sensitive = have_enabled_account && any_messages_selected;
3420 action = e_mail_reader_get_action (reader, action_name);
3421 gtk_action_set_sensitive (action, sensitive);
3422
3423 action_name = "mail-forward-inline";
3424 sensitive = have_enabled_account && single_message_selected;
3425 action = e_mail_reader_get_action (reader, action_name);
3426 gtk_action_set_sensitive (action, sensitive);
3427
3428 action_name = "mail-forward-inline-full";
3429 sensitive = have_enabled_account && single_message_selected;
3430 action = e_mail_reader_get_action (reader, action_name);
3431 gtk_action_set_sensitive (action, sensitive);
3432
3433 action_name = "mail-forward-quoted";
3434 sensitive = have_enabled_account && single_message_selected;
3435 action = e_mail_reader_get_action (reader, action_name);
3436 gtk_action_set_sensitive (action, sensitive);
3437
3438 action_name = "mail-forward-quoted-full";
3439 sensitive = have_enabled_account && single_message_selected;
3440 action = e_mail_reader_get_action (reader, action_name);
3441 gtk_action_set_sensitive (action, sensitive);
3442
3443 action_name = "mail-goto-menu";
3444 sensitive = any_messages_selected;
3445 action = e_mail_reader_get_action (reader, action_name);
3446 gtk_action_set_sensitive (action, sensitive);
3447
3448 action_name = "mail-load-images";
3449 sensitive = single_message_selected;
3450 action = e_mail_reader_get_action (reader, action_name);
3451 gtk_action_set_sensitive (action, sensitive);
3452
3453 action_name = "mail-mark-as-menu";
3454 sensitive = any_messages_selected;
3455 action = e_mail_reader_get_action (reader, action_name);
3456 gtk_action_set_sensitive (action, sensitive);
3457
3458 action_name = "mail-mark-important";
3459 sensitive = selection_has_unimportant_messages;
3460 action = e_mail_reader_get_action (reader, action_name);
3461 gtk_action_set_sensitive (action, sensitive);
3462
3463 action_name = "mail-mark-junk";
3464 sensitive =
3465 selection_has_not_junk_messages &&
3466 !(state & E_MAIL_READER_FOLDER_IS_JUNK);
3467 action = e_mail_reader_get_action (reader, action_name);
3468 gtk_action_set_sensitive (action, sensitive);
3469
3470 action_name = "mail-mark-notjunk";
3471 sensitive = selection_has_junk_messages;
3472 action = e_mail_reader_get_action (reader, action_name);
3473 gtk_action_set_sensitive (action, sensitive);
3474
3475 action_name = "mail-mark-read";
3476 sensitive = selection_has_unread_messages;
3477 action = e_mail_reader_get_action (reader, action_name);
3478 gtk_action_set_sensitive (action, sensitive);
3479
3480 action_name = "mail-mark-unimportant";
3481 sensitive = selection_has_important_messages;
3482 action = e_mail_reader_get_action (reader, action_name);
3483 gtk_action_set_sensitive (action, sensitive);
3484
3485 action_name = "mail-mark-unread";
3486 sensitive = selection_has_read_messages;
3487 action = e_mail_reader_get_action (reader, action_name);
3488 gtk_action_set_sensitive (action, sensitive);
3489
3490 action_name = "mail-message-edit";
3491 sensitive = have_enabled_account && single_message_selected;
3492 action = e_mail_reader_get_action (reader, action_name);
3493 gtk_action_set_sensitive (action, sensitive);
3494
3495 action_name = "mail-message-new";
3496 sensitive = have_enabled_account;
3497 action = e_mail_reader_get_action (reader, action_name);
3498 gtk_action_set_sensitive (action, sensitive);
3499
3500 action_name = "mail-message-open";
3501 sensitive = any_messages_selected;
3502 action = e_mail_reader_get_action (reader, action_name);
3503 gtk_action_set_sensitive (action, sensitive);
3504
3505 action_name = "mail-goto-folder";
3506 sensitive = e_mail_reader_get_enable_show_folder (reader);
3507 action = e_mail_reader_get_action (reader, action_name);
3508 gtk_action_set_sensitive (action, sensitive);
3509 gtk_action_set_visible (action, sensitive);
3510
3511 action_name = "mail-goto-nexttab";
3512 action = e_mail_reader_get_action (reader, action_name);
3513 gtk_action_set_sensitive (action, TRUE);
3514 gtk_action_set_visible (action, FALSE);
3515
3516 action_name = "mail-goto-prevtab";
3517 action = e_mail_reader_get_action (reader, action_name);
3518 gtk_action_set_sensitive (action, TRUE);
3519 gtk_action_set_visible (action, FALSE);
3520
3521 action_name = "mail-close-tab";
3522 action = e_mail_reader_get_action (reader, action_name);
3523 gtk_action_set_sensitive (action, TRUE);
3524 gtk_action_set_visible (action, FALSE);
3525
3526 action_name = "mail-move";
3527 sensitive = any_messages_selected;
3528 action = e_mail_reader_get_action (reader, action_name);
3529 gtk_action_set_sensitive (action, sensitive);
3530
3531 action_name = "mail-next";
3532 sensitive = any_messages_selected && !last_message_selected;
3533 action = e_mail_reader_get_action (reader, action_name);
3534 gtk_action_set_sensitive (action, sensitive);
3535
3536 action_name = "mail-next-important";
3537 sensitive = single_message_selected;
3538 action = e_mail_reader_get_action (reader, action_name);
3539 gtk_action_set_sensitive (action, sensitive);
3540
3541 action_name = "mail-next-thread";
3542 sensitive = single_message_selected && !last_message_selected;
3543 action = e_mail_reader_get_action (reader, action_name);
3544 gtk_action_set_sensitive (action, sensitive);
3545
3546 action_name = "mail-next-unread";
3547 sensitive = any_messages_selected;
3548 action = e_mail_reader_get_action (reader, action_name);
3549 gtk_action_set_sensitive (action, sensitive);
3550
3551 action_name = "mail-previous";
3552 sensitive = any_messages_selected && !first_message_selected;
3553 action = e_mail_reader_get_action (reader, action_name);
3554 gtk_action_set_sensitive (action, sensitive);
3555
3556 action_name = "mail-previous-important";
3557 sensitive = single_message_selected;
3558 action = e_mail_reader_get_action (reader, action_name);
3559 gtk_action_set_sensitive (action, sensitive);
3560
3561 action_name = "mail-previous-unread";
3562 sensitive = any_messages_selected;
3563 action = e_mail_reader_get_action (reader, action_name);
3564 gtk_action_set_sensitive (action, sensitive);
3565
3566 action_name = "mail-previous-thread";
3567 sensitive = any_messages_selected && !first_message_selected;
3568 action = e_mail_reader_get_action (reader, action_name);
3569 gtk_action_set_sensitive (action, sensitive);
3570
3571 action_name = "mail-print";
3572 sensitive = single_message_selected;
3573 action = e_mail_reader_get_action (reader, action_name);
3574 gtk_action_set_sensitive (action, sensitive);
3575
3576 action_name = "mail-print-preview";
3577 sensitive = single_message_selected;
3578 action = e_mail_reader_get_action (reader, action_name);
3579 gtk_action_set_sensitive (action, sensitive);
3580
3581 action_name = "mail-redirect";
3582 sensitive = have_enabled_account && single_message_selected;
3583 action = e_mail_reader_get_action (reader, action_name);
3584 gtk_action_set_sensitive (action, sensitive);
3585
3586 action_name = "mail-remove-attachments";
3587 sensitive = any_messages_selected && selection_has_attachment_messages;
3588 action = e_mail_reader_get_action (reader, action_name);
3589 gtk_action_set_sensitive (action, sensitive);
3590
3591 action_name = "mail-remove-duplicates";
3592 sensitive = multiple_messages_selected;
3593 action = e_mail_reader_get_action (reader, action_name);
3594 gtk_action_set_sensitive (action, sensitive);
3595
3596 action_name = "mail-reply-all";
3597 sensitive = have_enabled_account && single_message_selected;
3598 action = e_mail_reader_get_action (reader, action_name);
3599 gtk_action_set_sensitive (action, sensitive);
3600
3601 action_name = "mail-reply-group";
3602 sensitive = have_enabled_account && single_message_selected;
3603 action = e_mail_reader_get_action (reader, action_name);
3604 gtk_action_set_sensitive (action, sensitive);
3605
3606 action_name = "mail-reply-group-menu";
3607 sensitive = have_enabled_account && any_messages_selected;
3608 action = e_mail_reader_get_action (reader, action_name);
3609 gtk_action_set_sensitive (action, sensitive);
3610
3611 action_name = "mail-reply-list";
3612 sensitive = have_enabled_account && single_message_selected &&
3613 selection_is_mailing_list;
3614 action = e_mail_reader_get_action (reader, action_name);
3615 gtk_action_set_sensitive (action, sensitive);
3616
3617 action_name = "mail-reply-sender";
3618 sensitive = have_enabled_account && single_message_selected;
3619 action = e_mail_reader_get_action (reader, action_name);
3620 gtk_action_set_sensitive (action, sensitive);
3621
3622 action_name = "mail-save-as";
3623 sensitive = any_messages_selected;
3624 action = e_mail_reader_get_action (reader, action_name);
3625 gtk_action_set_sensitive (action, sensitive);
3626
3627 action_name = "mail-show-source";
3628 sensitive = single_message_selected;
3629 action = e_mail_reader_get_action (reader, action_name);
3630 gtk_action_set_sensitive (action, sensitive);
3631
3632 action_name = "mail-undelete";
3633 sensitive = selection_has_deleted_messages;
3634 action = e_mail_reader_get_action (reader, action_name);
3635 gtk_action_set_sensitive (action, sensitive);
3636
3637 action_name = "mail-zoom-100";
3638 sensitive = single_message_selected;
3639 action = e_mail_reader_get_action (reader, action_name);
3640 gtk_action_set_sensitive (action, sensitive);
3641
3642 action_name = "mail-zoom-in";
3643 sensitive = single_message_selected;
3644 action = e_mail_reader_get_action (reader, action_name);
3645 gtk_action_set_sensitive (action, sensitive);
3646
3647 action_name = "mail-zoom-out";
3648 sensitive = single_message_selected;
3649 action = e_mail_reader_get_action (reader, action_name);
3650 gtk_action_set_sensitive (action, sensitive);
3651 }
3652
3653 static void
3654 mail_reader_init_charset_actions (EMailReader *reader,
3655 GtkActionGroup *action_group)
3656 {
3657 GtkRadioAction *default_action;
3658 GSList *radio_group;
3659
3660 radio_group = e_charset_add_radio_actions (
3661 action_group, "mail-charset-", NULL,
3662 G_CALLBACK (action_mail_charset_cb), reader);
3663
3664 /* XXX Add a tooltip! */
3665 default_action = gtk_radio_action_new (
3666 "mail-charset-default", _("Default"), NULL, NULL, -1);
3667
3668 gtk_radio_action_set_group (default_action, radio_group);
3669
3670 g_signal_connect (
3671 default_action, "changed",
3672 G_CALLBACK (action_mail_charset_cb), reader);
3673
3674 gtk_action_group_add_action (
3675 action_group, GTK_ACTION (default_action));
3676
3677 gtk_radio_action_set_current_value (default_action, -1);
3678 }
3679
3680 static void
3681 e_mail_reader_default_init (EMailReaderInterface *interface)
3682 {
3683 quark_private = g_quark_from_static_string ("e-mail-reader-private");
3684
3685 interface->get_alert_sink = mail_reader_get_alert_sink;
3686 interface->get_selected_uids = mail_reader_get_selected_uids;
3687 interface->get_folder = mail_reader_get_folder;
3688 interface->enable_show_folder = mail_reader_get_enable_show_folder;
3689 interface->set_folder = mail_reader_set_folder;
3690 interface->set_message = mail_reader_set_message;
3691 interface->open_selected_mail = e_mail_reader_open_selected;
3692 interface->folder_loaded = mail_reader_folder_loaded;
3693 interface->message_loaded = mail_reader_message_loaded;
3694 interface->message_seen = mail_reader_message_seen;
3695 interface->show_search_bar = mail_reader_show_search_bar;
3696 interface->update_actions = mail_reader_update_actions;
3697
3698 g_object_interface_install_property (
3699 interface,
3700 g_param_spec_enum (
3701 "forward-style",
3702 "Forward Style",
3703 "How to forward messages",
3704 E_TYPE_MAIL_FORWARD_STYLE,
3705 E_MAIL_FORWARD_STYLE_ATTACHED,
3706 G_PARAM_READWRITE));
3707
3708 g_object_interface_install_property (
3709 interface,
3710 g_param_spec_boolean (
3711 "group-by-threads",
3712 "Group by Threads",
3713 "Whether to group messages by threads",
3714 FALSE,
3715 G_PARAM_READWRITE));
3716
3717 g_object_interface_install_property (
3718 interface,
3719 g_param_spec_enum (
3720 "reply-style",
3721 "Reply Style",
3722 "How to reply to messages",
3723 E_TYPE_MAIL_REPLY_STYLE,
3724 E_MAIL_REPLY_STYLE_QUOTED,
3725 G_PARAM_READWRITE));
3726
3727 signals[CHANGED] = g_signal_new (
3728 "changed",
3729 G_OBJECT_CLASS_TYPE (interface),
3730 G_SIGNAL_RUN_FIRST,
3731 0, NULL, NULL,
3732 g_cclosure_marshal_VOID__VOID,
3733 G_TYPE_NONE, 0);
3734
3735 signals[FOLDER_LOADED] = g_signal_new (
3736 "folder-loaded",
3737 G_OBJECT_CLASS_TYPE (interface),
3738 G_SIGNAL_RUN_FIRST,
3739 G_STRUCT_OFFSET (EMailReaderInterface, folder_loaded),
3740 NULL, NULL,
3741 g_cclosure_marshal_VOID__VOID,
3742 G_TYPE_NONE, 0);
3743
3744 signals[MESSAGE_LOADED] = g_signal_new (
3745 "message-loaded",
3746 G_OBJECT_CLASS_TYPE (interface),
3747 G_SIGNAL_RUN_LAST,
3748 G_STRUCT_OFFSET (EMailReaderInterface, message_loaded),
3749 NULL, NULL,
3750 e_marshal_VOID__STRING_OBJECT,
3751 G_TYPE_NONE, 2,
3752 G_TYPE_STRING,
3753 CAMEL_TYPE_MIME_MESSAGE);
3754
3755 signals[MESSAGE_SEEN] = g_signal_new (
3756 "message-seen",
3757 G_OBJECT_CLASS_TYPE (interface),
3758 G_SIGNAL_RUN_LAST,
3759 G_STRUCT_OFFSET (EMailReaderInterface, message_seen),
3760 NULL, NULL,
3761 e_marshal_VOID__STRING_OBJECT,
3762 G_TYPE_NONE, 2,
3763 G_TYPE_STRING,
3764 CAMEL_TYPE_MIME_MESSAGE);
3765
3766 signals[SHOW_SEARCH_BAR] = g_signal_new (
3767 "show-search-bar",
3768 G_OBJECT_CLASS_TYPE (interface),
3769 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3770 G_STRUCT_OFFSET (EMailReaderInterface, show_search_bar),
3771 NULL, NULL,
3772 g_cclosure_marshal_VOID__VOID,
3773 G_TYPE_NONE, 0);
3774
3775 signals[SHOW_FOLDER] = g_signal_new (
3776 "show-folder",
3777 G_OBJECT_CLASS_TYPE (interface),
3778 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3779 0,
3780 NULL, NULL,
3781 g_cclosure_marshal_VOID__VOID,
3782 G_TYPE_NONE, 0);
3783
3784 signals[SHOW_NEXTTAB] = g_signal_new (
3785 "show-next-tab",
3786 G_OBJECT_CLASS_TYPE (interface),
3787 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3788 0,
3789 NULL, NULL,
3790 g_cclosure_marshal_VOID__VOID,
3791 G_TYPE_NONE, 0);
3792
3793 signals[SHOW_PREVTAB] = g_signal_new (
3794 "show-previous-tab",
3795 G_OBJECT_CLASS_TYPE (interface),
3796 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3797 0,
3798 NULL, NULL,
3799 g_cclosure_marshal_VOID__VOID,
3800 G_TYPE_NONE, 0);
3801
3802 signals[CLOSE_TAB] = g_signal_new (
3803 "close-tab",
3804 G_OBJECT_CLASS_TYPE (interface),
3805 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3806 0,
3807 NULL, NULL,
3808 g_cclosure_marshal_VOID__VOID,
3809 G_TYPE_NONE, 0);
3810
3811 signals[UPDATE_ACTIONS] = g_signal_new (
3812 "update-actions",
3813 G_OBJECT_CLASS_TYPE (interface),
3814 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
3815 G_STRUCT_OFFSET (EMailReaderInterface, update_actions),
3816 NULL, NULL,
3817 g_cclosure_marshal_VOID__UINT,
3818 G_TYPE_NONE, 1,
3819 G_TYPE_UINT);
3820 }
3821
3822 void
3823 e_mail_reader_init (EMailReader *reader,
3824 gboolean init_actions,
3825 gboolean connect_signals)
3826 {
3827 EMenuToolAction *menu_tool_action;
3828 GtkActionGroup *action_group;
3829 GtkWidget *message_list;
3830 GtkAction *action;
3831 gboolean sensitive;
3832 const gchar *action_name;
3833 EMailDisplay *display;
3834 GSettings *settings;
3835
3836 g_return_if_fail (E_IS_MAIL_READER (reader));
3837
3838 message_list = e_mail_reader_get_message_list (reader);
3839 display = e_mail_reader_get_mail_display (reader);
3840
3841 /* Initialize a private struct. */
3842 g_object_set_qdata_full (
3843 G_OBJECT (reader), quark_private,
3844 g_slice_new0 (EMailReaderPrivate),
3845 (GDestroyNotify) mail_reader_private_free);
3846
3847 if (!init_actions)
3848 goto connect_signals;
3849
3850 /* Add the "standard" EMailReader actions. */
3851
3852 action_group = e_mail_reader_get_action_group (
3853 reader, E_MAIL_READER_ACTION_GROUP_STANDARD);
3854
3855 /* The "mail-forward" action is special: it uses a GtkMenuToolButton
3856 * for its toolbar item type. So we have to create it separately. */
3857
3858 menu_tool_action = e_menu_tool_action_new (
3859 "mail-forward", _("_Forward"),
3860 _("Forward the selected message to someone"), NULL);
3861
3862 gtk_action_set_icon_name (
3863 GTK_ACTION (menu_tool_action), "mail-forward");
3864
3865 g_signal_connect (
3866 menu_tool_action, "activate",
3867 G_CALLBACK (action_mail_forward_cb), reader);
3868
3869 gtk_action_group_add_action_with_accel (
3870 action_group, GTK_ACTION (menu_tool_action), "<Control>f");
3871
3872 /* Likewise the "mail-reply-group" action. */
3873
3874 /* For Translators: "Group Reply" will reply either to a mailing list
3875 (if possible and if that configuration option is enabled), or else
3876 it will reply to all. The word "Group" was chosen because it covers
3877 either of those, without too strongly implying one or the other. */
3878 menu_tool_action = e_menu_tool_action_new (
3879 "mail-reply-group", _("Group Reply"),
3880 _("Reply to the mailing list, or to all recipients"), NULL);
3881
3882 gtk_action_set_icon_name (
3883 GTK_ACTION (menu_tool_action), "mail-reply-all");
3884
3885 g_signal_connect (
3886 menu_tool_action, "activate",
3887 G_CALLBACK (action_mail_reply_group_cb), reader);
3888
3889 gtk_action_group_add_action_with_accel (
3890 action_group, GTK_ACTION (menu_tool_action), "<Control>g");
3891
3892 /* Add the other actions the normal way. */
3893 gtk_action_group_add_actions (
3894 action_group, mail_reader_entries,
3895 G_N_ELEMENTS (mail_reader_entries), reader);
3896 e_action_group_add_popup_actions (
3897 action_group, mail_reader_popup_entries,
3898 G_N_ELEMENTS (mail_reader_popup_entries));
3899 gtk_action_group_add_toggle_actions (
3900 action_group, mail_reader_toggle_entries,
3901 G_N_ELEMENTS (mail_reader_toggle_entries), reader);
3902
3903 mail_reader_init_charset_actions (reader, action_group);
3904
3905 /* Add EMailReader actions for Search Folders. The action group
3906 * should be made invisible if Search Folders are disabled. */
3907
3908 action_group = e_mail_reader_get_action_group (
3909 reader, E_MAIL_READER_ACTION_GROUP_SEARCH_FOLDERS);
3910
3911 gtk_action_group_add_actions (
3912 action_group, mail_reader_search_folder_entries,
3913 G_N_ELEMENTS (mail_reader_search_folder_entries), reader);
3914
3915 display = e_mail_reader_get_mail_display (reader);
3916
3917 /* Bind GObject properties to GSettings keys. */
3918
3919 settings = g_settings_new ("org.gnome.evolution.mail");
3920
3921 action_name = "mail-caret-mode";
3922 action = e_mail_reader_get_action (reader, action_name);
3923 g_settings_bind (
3924 settings, "caret-mode",
3925 action, "active", G_SETTINGS_BIND_DEFAULT);
3926
3927 action_name = "mail-show-all-headers";
3928 action = e_mail_reader_get_action (reader, action_name);
3929 g_settings_bind (
3930 settings, "show-all-headers",
3931 action, "active", G_SETTINGS_BIND_DEFAULT);
3932
3933 /* mode change when viewing message source is ignored */
3934 if (e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_SOURCE ||
3935 e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_RAW) {
3936 gtk_action_set_sensitive (action, FALSE);
3937 gtk_action_set_visible (action, FALSE);
3938 }
3939
3940 g_object_unref (settings);
3941
3942 /* Fine tuning. */
3943
3944 action_name = "mail-delete";
3945 action = e_mail_reader_get_action (reader, action_name);
3946 gtk_action_set_short_label (action, _("Delete"));
3947
3948 action_name = "mail-forward";
3949 action = e_mail_reader_get_action (reader, action_name);
3950 gtk_action_set_is_important (action, TRUE);
3951
3952 action_name = "mail-reply-group";
3953 action = e_mail_reader_get_action (reader, action_name);
3954 gtk_action_set_is_important (action, TRUE);
3955
3956 action_name = "mail-goto-folder";
3957 action = e_mail_reader_get_action (reader, action_name);
3958 sensitive = e_mail_reader_get_enable_show_folder (reader);
3959 gtk_action_set_sensitive (action, sensitive);
3960 gtk_action_set_visible (action, FALSE);
3961
3962 action_name = "mail-goto-nexttab";
3963 action = e_mail_reader_get_action (reader, action_name);
3964 gtk_action_set_sensitive (action, TRUE);
3965 gtk_action_set_visible (action, FALSE);
3966
3967 action_name = "mail-goto-prevtab";
3968 action = e_mail_reader_get_action (reader, action_name);
3969 gtk_action_set_sensitive (action, TRUE);
3970 gtk_action_set_visible (action, FALSE);
3971
3972 action_name = "mail-close-tab";
3973 action = e_mail_reader_get_action (reader, action_name);
3974 gtk_action_set_sensitive (action, TRUE);
3975 gtk_action_set_visible (action, FALSE);
3976
3977 action_name = "mail-next";
3978 action = e_mail_reader_get_action (reader, action_name);
3979 gtk_action_set_short_label (action, _("Next"));
3980
3981 action_name = "mail-previous";
3982 action = e_mail_reader_get_action (reader, action_name);
3983 gtk_action_set_short_label (action, _("Previous"));
3984
3985 action_name = "mail-reply-all";
3986 action = e_mail_reader_get_action (reader, action_name);
3987 gtk_action_set_is_important (action, TRUE);
3988
3989 action_name = "mail-reply-sender";
3990 action = e_mail_reader_get_action (reader, action_name);
3991 gtk_action_set_is_important (action, TRUE);
3992 gtk_action_set_short_label (action, _("Reply"));
3993
3994 action_name = "add-to-address-book";
3995 action = e_mail_display_get_action (display, action_name);
3996 g_signal_connect (
3997 action, "activate",
3998 G_CALLBACK (action_add_to_address_book_cb), reader);
3999
4000 action_name = "send-reply";
4001 action = e_mail_display_get_action (display, action_name);
4002 g_signal_connect (
4003 action, "activate",
4004 G_CALLBACK (action_mail_reply_recipient_cb), reader);
4005
4006 action_name = "search-folder-recipient";
4007 action = e_mail_display_get_action (display, action_name);
4008 g_signal_connect (
4009 action, "activate",
4010 G_CALLBACK (action_search_folder_recipient_cb), reader);
4011
4012 action_name = "search-folder-sender";
4013 action = e_mail_display_get_action (display, action_name);
4014 g_signal_connect (
4015 action, "activate",
4016 G_CALLBACK (action_search_folder_sender_cb), reader);
4017
4018 action_name = "image-save";
4019 action = e_mail_display_get_action (display, action_name);
4020 g_signal_connect (
4021 action, "activate",
4022 G_CALLBACK (action_mail_image_save_cb), reader);
4023
4024 #ifndef G_OS_WIN32
4025 /* Lockdown integration. */
4026
4027 settings = g_settings_new ("org.gnome.desktop.lockdown");
4028
4029 action_name = "mail-print";
4030 action = e_mail_reader_get_action (reader, action_name);
4031 g_settings_bind (
4032 settings, "disable-printing",
4033 action, "visible",
4034 G_SETTINGS_BIND_GET |
4035 G_SETTINGS_BIND_NO_SENSITIVITY |
4036 G_SETTINGS_BIND_INVERT_BOOLEAN);
4037
4038 action_name = "mail-print-preview";
4039 action = e_mail_reader_get_action (reader, action_name);
4040 g_settings_bind (
4041 settings, "disable-printing",
4042 action, "visible",
4043 G_SETTINGS_BIND_GET |
4044 G_SETTINGS_BIND_NO_SENSITIVITY |
4045 G_SETTINGS_BIND_INVERT_BOOLEAN);
4046
4047 action_name = "mail-save-as";
4048 action = e_mail_reader_get_action (reader, action_name);
4049 g_settings_bind (
4050 settings, "disable-save-to-disk",
4051 action, "visible",
4052 G_SETTINGS_BIND_GET |
4053 G_SETTINGS_BIND_NO_SENSITIVITY |
4054 G_SETTINGS_BIND_INVERT_BOOLEAN);
4055
4056 g_object_unref (settings);
4057 #endif
4058
4059 /* Bind properties. */
4060
4061 action_name = "mail-caret-mode";
4062 action = e_mail_reader_get_action (reader, action_name);
4063
4064 g_object_bind_property (
4065 action, "active",
4066 display, "caret-mode",
4067 G_BINDING_BIDIRECTIONAL |
4068 G_BINDING_SYNC_CREATE);
4069
4070 connect_signals:
4071
4072 if (!connect_signals)
4073 return;
4074
4075 /* Connect signals. */
4076 g_signal_connect_swapped (
4077 display, "key-press-event",
4078 G_CALLBACK (mail_reader_key_press_event_cb), reader);
4079
4080 g_signal_connect_swapped (
4081 message_list, "message-selected",
4082 G_CALLBACK (mail_reader_message_selected_cb), reader);
4083
4084 /* re-schedule mark-as-seen,... */
4085 g_signal_connect_swapped (
4086 message_list, "cursor-change",
4087 G_CALLBACK (mail_reader_message_cursor_change_cb), reader);
4088
4089 /* but do not mark-as-seen if... */
4090 g_signal_connect_swapped (
4091 message_list, "tree-drag-begin",
4092 G_CALLBACK (discard_timeout_mark_seen_cb), reader);
4093
4094 g_signal_connect_swapped (
4095 message_list, "tree-drag-end",
4096 G_CALLBACK (discard_timeout_mark_seen_cb), reader);
4097
4098 g_signal_connect_swapped (
4099 message_list, "right-click",
4100 G_CALLBACK (discard_timeout_mark_seen_cb), reader);
4101
4102 g_signal_connect_swapped (
4103 message_list, "message-list-built",
4104 G_CALLBACK (mail_reader_emit_folder_loaded), reader);
4105
4106 g_signal_connect_swapped (
4107 message_list, "double-click",
4108 G_CALLBACK (mail_reader_double_click_cb), reader);
4109
4110 g_signal_connect_swapped (
4111 message_list, "key-press",
4112 G_CALLBACK (mail_reader_key_press_cb), reader);
4113
4114 g_signal_connect_swapped (
4115 message_list, "selection-change",
4116 G_CALLBACK (e_mail_reader_changed), reader);
4117 }
4118
4119 void
4120 e_mail_reader_changed (EMailReader *reader)
4121 {
4122 g_return_if_fail (E_IS_MAIL_READER (reader));
4123
4124 g_signal_emit (reader, signals[CHANGED], 0);
4125 }
4126
4127 guint32
4128 e_mail_reader_check_state (EMailReader *reader)
4129 {
4130 EShell *shell;
4131 GPtrArray *uids;
4132 CamelFolder *folder;
4133 CamelStore *store = NULL;
4134 EMailBackend *backend;
4135 ESourceRegistry *registry;
4136 EMailSession *mail_session;
4137 EMailAccountStore *account_store;
4138 const gchar *tag;
4139 gboolean can_clear_flags = FALSE;
4140 gboolean can_flag_completed = FALSE;
4141 gboolean can_flag_for_followup = FALSE;
4142 gboolean has_attachments = FALSE;
4143 gboolean has_deleted = FALSE;
4144 gboolean has_important = FALSE;
4145 gboolean has_junk = FALSE;
4146 gboolean has_not_junk = FALSE;
4147 gboolean has_read = FALSE;
4148 gboolean has_undeleted = FALSE;
4149 gboolean has_unimportant = FALSE;
4150 gboolean has_unread = FALSE;
4151 gboolean have_enabled_account = FALSE;
4152 gboolean drafts_or_outbox = FALSE;
4153 gboolean store_supports_vjunk = FALSE;
4154 gboolean is_mailing_list;
4155 gboolean is_junk_folder = FALSE;
4156 guint32 state = 0;
4157 guint ii;
4158
4159 g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
4160
4161 backend = e_mail_reader_get_backend (reader);
4162 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
4163 registry = e_shell_get_registry (shell);
4164 mail_session = e_mail_backend_get_session (backend);
4165 account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (mail_session));
4166
4167 folder = e_mail_reader_get_folder (reader);
4168 uids = e_mail_reader_get_selected_uids (reader);
4169
4170 if (folder != NULL) {
4171 store = camel_folder_get_parent_store (folder);
4172 store_supports_vjunk = (store->flags & CAMEL_STORE_VJUNK);
4173 is_junk_folder =
4174 (folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
4175 drafts_or_outbox =
4176 em_utils_folder_is_drafts (registry, folder) ||
4177 em_utils_folder_is_outbox (registry, folder);
4178 }
4179
4180 /* Initialize this flag based on whether there are any
4181 * messages selected. We will update it in the loop. */
4182 is_mailing_list = (uids->len > 0);
4183
4184 for (ii = 0; ii < uids->len; ii++) {
4185 CamelMessageInfo *info;
4186 const gchar *string;
4187 guint32 flags;
4188
4189 info = camel_folder_get_message_info (
4190 folder, uids->pdata[ii]);
4191 if (info == NULL)
4192 continue;
4193
4194 flags = camel_message_info_flags (info);
4195
4196 if (flags & CAMEL_MESSAGE_SEEN)
4197 has_read = TRUE;
4198 else
4199 has_unread = TRUE;
4200
4201 if (flags & CAMEL_MESSAGE_ATTACHMENTS)
4202 has_attachments = TRUE;
4203
4204 if (drafts_or_outbox) {
4205 has_junk = FALSE;
4206 has_not_junk = FALSE;
4207 } else if (store_supports_vjunk) {
4208 guint32 bitmask;
4209
4210 /* XXX Strictly speaking, this logic is correct.
4211 * Problem is there's nothing in the message
4212 * list that indicates whether a message is
4213 * already marked "Not Junk". So the user may
4214 * think the "Not Junk" button is enabling and
4215 * disabling itself randomly as he reads mail. */
4216
4217 if (flags & CAMEL_MESSAGE_JUNK)
4218 has_junk = TRUE;
4219 if (flags & CAMEL_MESSAGE_NOTJUNK)
4220 has_not_junk = TRUE;
4221
4222 bitmask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK;
4223
4224 /* If neither junk flag is set, the
4225 * message can be marked either way. */
4226 if ((flags & bitmask) == 0) {
4227 has_junk = TRUE;
4228 has_not_junk = TRUE;
4229 }
4230
4231 } else {
4232 has_junk = TRUE;
4233 has_not_junk = TRUE;
4234 }
4235
4236 if (flags & CAMEL_MESSAGE_DELETED)
4237 has_deleted = TRUE;
4238 else
4239 has_undeleted = TRUE;
4240
4241 if (flags & CAMEL_MESSAGE_FLAGGED)
4242 has_important = TRUE;
4243 else
4244 has_unimportant = TRUE;
4245
4246 tag = camel_message_info_user_tag (info, "follow-up");
4247 if (tag != NULL && *tag != '\0') {
4248 can_clear_flags = TRUE;
4249 tag = camel_message_info_user_tag (
4250 info, "completed-on");
4251 if (tag == NULL || *tag == '\0')
4252 can_flag_completed = TRUE;
4253 } else
4254 can_flag_for_followup = TRUE;
4255
4256 string = camel_message_info_mlist (info);
4257 is_mailing_list &= (string != NULL && *string != '\0');
4258
4259 camel_folder_free_message_info (folder, info);
4260 }
4261
4262 have_enabled_account = e_mail_account_store_have_enabled_service (account_store, CAMEL_TYPE_STORE);
4263
4264 if (have_enabled_account)
4265 state |= E_MAIL_READER_HAVE_ENABLED_ACCOUNT;
4266 if (uids->len == 1)
4267 state |= E_MAIL_READER_SELECTION_SINGLE;
4268 if (uids->len > 1)
4269 state |= E_MAIL_READER_SELECTION_MULTIPLE;
4270 if (!drafts_or_outbox && uids->len == 1)
4271 state |= E_MAIL_READER_SELECTION_CAN_ADD_SENDER;
4272 if (can_clear_flags)
4273 state |= E_MAIL_READER_SELECTION_FLAG_CLEAR;
4274 if (can_flag_completed)
4275 state |= E_MAIL_READER_SELECTION_FLAG_COMPLETED;
4276 if (can_flag_for_followup)
4277 state |= E_MAIL_READER_SELECTION_FLAG_FOLLOWUP;
4278 if (has_attachments)
4279 state |= E_MAIL_READER_SELECTION_HAS_ATTACHMENTS;
4280 if (has_deleted)
4281 state |= E_MAIL_READER_SELECTION_HAS_DELETED;
4282 if (has_important)
4283 state |= E_MAIL_READER_SELECTION_HAS_IMPORTANT;
4284 if (has_junk)
4285 state |= E_MAIL_READER_SELECTION_HAS_JUNK;
4286 if (has_not_junk)
4287 state |= E_MAIL_READER_SELECTION_HAS_NOT_JUNK;
4288 if (has_read)
4289 state |= E_MAIL_READER_SELECTION_HAS_READ;
4290 if (has_undeleted)
4291 state |= E_MAIL_READER_SELECTION_HAS_UNDELETED;
4292 if (has_unimportant)
4293 state |= E_MAIL_READER_SELECTION_HAS_UNIMPORTANT;
4294 if (has_unread)
4295 state |= E_MAIL_READER_SELECTION_HAS_UNREAD;
4296 if (is_mailing_list)
4297 state |= E_MAIL_READER_SELECTION_IS_MAILING_LIST;
4298 if (is_junk_folder)
4299 state |= E_MAIL_READER_FOLDER_IS_JUNK;
4300
4301 em_utils_uids_free (uids);
4302
4303 return state;
4304 }
4305
4306 EActivity *
4307 e_mail_reader_new_activity (EMailReader *reader)
4308 {
4309 EActivity *activity;
4310 EMailBackend *backend;
4311 EAlertSink *alert_sink;
4312 GCancellable *cancellable;
4313
4314 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4315
4316 activity = e_activity_new ();
4317
4318 alert_sink = e_mail_reader_get_alert_sink (reader);
4319 e_activity_set_alert_sink (activity, alert_sink);
4320
4321 cancellable = camel_operation_new ();
4322 e_activity_set_cancellable (activity, cancellable);
4323 g_object_unref (cancellable);
4324
4325 backend = e_mail_reader_get_backend (reader);
4326 e_shell_backend_add_activity (E_SHELL_BACKEND (backend), activity);
4327
4328 return activity;
4329 }
4330
4331 void
4332 e_mail_reader_update_actions (EMailReader *reader,
4333 guint32 state)
4334 {
4335 g_return_if_fail (E_IS_MAIL_READER (reader));
4336
4337 g_signal_emit (reader, signals[UPDATE_ACTIONS], 0, state);
4338 }
4339
4340 GtkAction *
4341 e_mail_reader_get_action (EMailReader *reader,
4342 const gchar *action_name)
4343 {
4344 GtkAction *action = NULL;
4345 gint ii;
4346
4347 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4348 g_return_val_if_fail (action_name != NULL, NULL);
4349
4350 for (ii = 0; ii < E_MAIL_READER_NUM_ACTION_GROUPS; ii++) {
4351 GtkActionGroup *group;
4352
4353 group = e_mail_reader_get_action_group (reader, ii);
4354 action = gtk_action_group_get_action (group, action_name);
4355
4356 if (action != NULL)
4357 break;
4358 }
4359
4360 if (action == NULL)
4361 g_critical (
4362 "%s: action '%s' not found", G_STRFUNC, action_name);
4363
4364 return action;
4365 }
4366
4367 GtkActionGroup *
4368 e_mail_reader_get_action_group (EMailReader *reader,
4369 EMailReaderActionGroup group)
4370 {
4371 EMailReaderInterface *interface;
4372
4373 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4374
4375 interface = E_MAIL_READER_GET_INTERFACE (reader);
4376 g_return_val_if_fail (interface->get_action_group != NULL, NULL);
4377
4378 return interface->get_action_group (reader, group);
4379 }
4380
4381 EAlertSink *
4382 e_mail_reader_get_alert_sink (EMailReader *reader)
4383 {
4384 EMailReaderInterface *interface;
4385
4386 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4387
4388 interface = E_MAIL_READER_GET_INTERFACE (reader);
4389 g_return_val_if_fail (interface->get_alert_sink != NULL, NULL);
4390
4391 return interface->get_alert_sink (reader);
4392 }
4393
4394 EMailBackend *
4395 e_mail_reader_get_backend (EMailReader *reader)
4396 {
4397 EMailReaderInterface *interface;
4398
4399 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4400
4401 interface = E_MAIL_READER_GET_INTERFACE (reader);
4402 g_return_val_if_fail (interface->get_backend != NULL, NULL);
4403
4404 return interface->get_backend (reader);
4405 }
4406
4407 EMailDisplay *
4408 e_mail_reader_get_mail_display (EMailReader *reader)
4409 {
4410 EMailReaderInterface *interface;
4411
4412 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4413
4414 interface = E_MAIL_READER_GET_INTERFACE (reader);
4415 g_return_val_if_fail (interface->get_mail_display != NULL, NULL);
4416
4417 return interface->get_mail_display (reader);
4418 }
4419
4420 gboolean
4421 e_mail_reader_get_hide_deleted (EMailReader *reader)
4422 {
4423 EMailReaderInterface *interface;
4424
4425 g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
4426
4427 interface = E_MAIL_READER_GET_INTERFACE (reader);
4428 g_return_val_if_fail (interface->get_hide_deleted != NULL, FALSE);
4429
4430 return interface->get_hide_deleted (reader);
4431 }
4432
4433 GtkWidget *
4434 e_mail_reader_get_message_list (EMailReader *reader)
4435 {
4436 EMailReaderInterface *interface;
4437
4438 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4439
4440 interface = E_MAIL_READER_GET_INTERFACE (reader);
4441 g_return_val_if_fail (interface->get_message_list != NULL, NULL);
4442
4443 return interface->get_message_list (reader);
4444 }
4445
4446 GtkMenu *
4447 e_mail_reader_get_popup_menu (EMailReader *reader)
4448 {
4449 EMailReaderInterface *interface;
4450
4451 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4452
4453 interface = E_MAIL_READER_GET_INTERFACE (reader);
4454 g_return_val_if_fail (interface->get_popup_menu != NULL, NULL);
4455
4456 return interface->get_popup_menu (reader);
4457 }
4458
4459 EPreviewPane *
4460 e_mail_reader_get_preview_pane (EMailReader *reader)
4461 {
4462 EMailReaderInterface *interface;
4463
4464 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4465
4466 interface = E_MAIL_READER_GET_INTERFACE (reader);
4467 g_return_val_if_fail (interface->get_preview_pane != NULL, NULL);
4468
4469 return interface->get_preview_pane (reader);
4470 }
4471
4472 GPtrArray *
4473 e_mail_reader_get_selected_uids (EMailReader *reader)
4474 {
4475 EMailReaderInterface *interface;
4476
4477 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4478
4479 interface = E_MAIL_READER_GET_INTERFACE (reader);
4480 g_return_val_if_fail (interface->get_selected_uids != NULL, NULL);
4481
4482 return interface->get_selected_uids (reader);
4483 }
4484
4485 GtkWindow *
4486 e_mail_reader_get_window (EMailReader *reader)
4487 {
4488 EMailReaderInterface *interface;
4489
4490 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4491
4492 interface = E_MAIL_READER_GET_INTERFACE (reader);
4493 g_return_val_if_fail (interface->get_window != NULL, NULL);
4494
4495 return interface->get_window (reader);
4496 }
4497
4498 CamelFolder *
4499 e_mail_reader_get_folder (EMailReader *reader)
4500 {
4501 EMailReaderInterface *interface;
4502
4503 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
4504
4505 interface = E_MAIL_READER_GET_INTERFACE (reader);
4506 g_return_val_if_fail (interface->get_folder != NULL, NULL);
4507
4508 return interface->get_folder (reader);
4509 }
4510
4511 void
4512 e_mail_reader_set_folder (EMailReader *reader,
4513 CamelFolder *folder)
4514 {
4515 EMailReaderInterface *interface;
4516
4517 g_return_if_fail (E_IS_MAIL_READER (reader));
4518
4519 interface = E_MAIL_READER_GET_INTERFACE (reader);
4520 g_return_if_fail (interface->set_folder != NULL);
4521
4522 interface->set_folder (reader, folder);
4523 }
4524
4525 void
4526 e_mail_reader_set_message (EMailReader *reader,
4527 const gchar *message_uid)
4528 {
4529 EMailReaderInterface *interface;
4530
4531 g_return_if_fail (E_IS_MAIL_READER (reader));
4532
4533 interface = E_MAIL_READER_GET_INTERFACE (reader);
4534 g_return_if_fail (interface->set_message != NULL);
4535
4536 interface->set_message (reader, message_uid);
4537 }
4538
4539 guint
4540 e_mail_reader_open_selected_mail (EMailReader *reader)
4541 {
4542 EMailReaderInterface *interface;
4543
4544 g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
4545
4546 interface = E_MAIL_READER_GET_INTERFACE (reader);
4547 g_return_val_if_fail (interface->open_selected_mail != NULL, 0);
4548
4549 return interface->open_selected_mail (reader);
4550 }
4551
4552 EMailForwardStyle
4553 e_mail_reader_get_forward_style (EMailReader *reader)
4554 {
4555 EMailReaderPrivate *priv;
4556
4557 g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
4558
4559 priv = E_MAIL_READER_GET_PRIVATE (reader);
4560
4561 return priv->forward_style;
4562 }
4563
4564 void
4565 e_mail_reader_set_forward_style (EMailReader *reader,
4566 EMailForwardStyle style)
4567 {
4568 EMailReaderPrivate *priv;
4569
4570 g_return_if_fail (E_IS_MAIL_READER (reader));
4571
4572 priv = E_MAIL_READER_GET_PRIVATE (reader);
4573
4574 if (priv->forward_style == style)
4575 return;