1 /*
2 * e-mail-reader.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 *
17 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
18 *
19 */
20
21 #include "evolution-config.h"
22
23 #include "e-mail-reader.h"
24
25 #include <glib/gi18n.h>
26 #include <gdk/gdkkeysyms.h>
27
28 #ifdef HAVE_XFREE
29 #include <X11/XF86keysym.h>
30 #endif
31
32 #include <shell/e-shell-utils.h>
33
34 #include <libemail-engine/libemail-engine.h>
35
36 #include <em-format/e-mail-formatter.h>
37 #include <em-format/e-mail-parser.h>
38 #include <em-format/e-mail-part-utils.h>
39
40 #include "e-mail-backend.h"
41 #include "e-mail-browser.h"
42 #include "e-mail-enumtypes.h"
43 #include "e-mail-label-action.h"
44 #include "e-mail-label-dialog.h"
45 #include "e-mail-label-list-store.h"
46 #include "e-mail-notes.h"
47 #include "e-mail-reader-utils.h"
48 #include "e-mail-remote-content-popover.h"
49 #include "e-mail-ui-session.h"
50 #include "e-mail-view.h"
51 #include "em-composer-utils.h"
52 #include "em-event.h"
53 #include "em-folder-selector.h"
54 #include "em-folder-tree.h"
55 #include "em-utils.h"
56 #include "mail-autofilter.h"
57 #include "mail-vfolder-ui.h"
58 #include "message-list.h"
59
60 #define E_MAIL_READER_GET_PRIVATE(obj) \
61 ((EMailReaderPrivate *) g_object_get_qdata \
62 (G_OBJECT (obj), quark_private))
63
64 #define d(x)
65
66 typedef struct _EMailReaderClosure EMailReaderClosure;
67 typedef struct _EMailReaderPrivate EMailReaderPrivate;
68
69 struct _EMailReaderClosure {
70 EMailReader *reader;
71 EActivity *activity;
72 CamelMimeMessage *message;
73 CamelFolder *folder;
74 gchar *message_uid;
75 gboolean selection_is_html;
76 };
77
78 struct _EMailReaderPrivate {
79
80 EMailForwardStyle forward_style;
81 EMailReplyStyle reply_style;
82
83 /* This timer runs when the user selects a single message. */
84 guint message_selected_timeout_id;
85
86 /* This allows message retrieval to be cancelled if another
87 * message is selected before the retrieval has completed. */
88 GCancellable *retrieving_message;
89
90 /* These flags work to prevent a folder switch from
91 * automatically marking the message as read. We only want
92 * that to happen when the -user- selects a message. */
93 guint folder_was_just_selected : 1;
94 guint avoid_next_mark_as_seen : 1;
95 guint did_try_to_open_message : 1;
96
97 guint group_by_threads : 1;
98 guint mark_seen_always : 1;
99 guint delete_selects_previous : 1;
100
101 /* to be able to start the mark_seen timeout only after
102 * the message is loaded into the EMailDisplay */
103 gboolean schedule_mark_seen;
104 guint schedule_mark_seen_interval;
105
106 gpointer followup_alert; /* weak pointer to an EAlert */
107
108 GSList *ongoing_operations; /* GCancellable * */
109
110 guint main_menu_label_merge_id;
111 guint popup_menu_label_merge_id;
112 };
113
114 enum {
115 CHANGED,
116 COMPOSER_CREATED,
117 FOLDER_LOADED,
118 MESSAGE_LOADED,
119 MESSAGE_SEEN,
120 SHOW_SEARCH_BAR,
121 UPDATE_ACTIONS,
122 LAST_SIGNAL
123 };
124
125 /* Remembers the previously selected folder when transferring messages. */
126 static gchar *default_xfer_messages_uri;
127
128 static GQuark quark_private;
129 static guint signals[LAST_SIGNAL];
130
131 G_DEFINE_INTERFACE (EMailReader, e_mail_reader, G_TYPE_INITIALLY_UNOWNED)
132
133 static void
134 mail_reader_set_display_formatter_for_message (EMailReader *reader,
135 EMailDisplay *display,
136 const gchar *message_uid,
137 CamelMimeMessage *message,
138 CamelFolder *folder);
139
140 static void
mail_reader_closure_free(EMailReaderClosure * closure)141 mail_reader_closure_free (EMailReaderClosure *closure)
142 {
143 g_clear_object (&closure->reader);
144 g_clear_object (&closure->activity);
145 g_clear_object (&closure->folder);
146 g_clear_object (&closure->message);
147 g_free (closure->message_uid);
148
149 g_slice_free (EMailReaderClosure, closure);
150 }
151
152 static void
mail_reader_private_free(EMailReaderPrivate * priv)153 mail_reader_private_free (EMailReaderPrivate *priv)
154 {
155 if (priv->message_selected_timeout_id > 0)
156 g_source_remove (priv->message_selected_timeout_id);
157
158 if (priv->retrieving_message != NULL) {
159 g_cancellable_cancel (priv->retrieving_message);
160 g_object_unref (priv->retrieving_message);
161 priv->retrieving_message = NULL;
162 }
163
164 g_slice_free (EMailReaderPrivate, priv);
165 }
166
167 static void
action_mail_add_sender_cb(GtkAction * action,EMailReader * reader)168 action_mail_add_sender_cb (GtkAction *action,
169 EMailReader *reader)
170 {
171 EShell *shell;
172 EMailBackend *backend;
173 EMailSession *session;
174 EShellBackend *shell_backend;
175 CamelInternetAddress *cia;
176 CamelMessageInfo *info = NULL;
177 CamelFolder *folder;
178 GPtrArray *uids;
179 const gchar *address;
180 const gchar *message_uid;
181
182 folder = e_mail_reader_ref_folder (reader);
183 backend = e_mail_reader_get_backend (reader);
184 session = e_mail_backend_get_session (backend);
185
186 uids = e_mail_reader_get_selected_uids (reader);
187 g_return_if_fail (uids != NULL && uids->len == 1);
188 message_uid = g_ptr_array_index (uids, 0);
189
190 info = camel_folder_get_message_info (folder, message_uid);
191 if (info == NULL)
192 goto exit;
193
194 address = camel_message_info_get_from (info);
195 if (address == NULL || *address == '\0')
196 goto exit;
197
198 /* XXX EBookShellBackend should be listening for this
199 * event. Kind of kludgey, but works for now. */
200 shell_backend = E_SHELL_BACKEND (backend);
201 shell = e_shell_backend_get_shell (shell_backend);
202 e_shell_event (shell, "contact-quick-add-email", (gpointer) address);
203
204 /* Remove this address from the photo cache. */
205 cia = camel_internet_address_new ();
206 if (camel_address_decode (CAMEL_ADDRESS (cia), address) > 0) {
207 EPhotoCache *photo_cache;
208 const gchar *address_only = NULL;
209
210 photo_cache = e_mail_ui_session_get_photo_cache (
211 E_MAIL_UI_SESSION (session));
212 if (camel_internet_address_get (cia, 0, NULL, &address_only))
213 e_photo_cache_remove_photo (photo_cache, address_only);
214 }
215 g_object_unref (cia);
216
217 exit:
218 g_clear_object (&info);
219 g_ptr_array_unref (uids);
220
221 g_clear_object (&folder);
222 }
223
224 static void
action_add_to_address_book_cb(GtkAction * action,EMailReader * reader)225 action_add_to_address_book_cb (GtkAction *action,
226 EMailReader *reader)
227 {
228 EShell *shell;
229 EMailBackend *backend;
230 EMailDisplay *display;
231 EMailSession *session;
232 EShellBackend *shell_backend;
233 CamelInternetAddress *cia;
234 EPhotoCache *photo_cache;
235 EWebView *web_view;
236 CamelURL *curl;
237 const gchar *uri;
238 const gchar *address_only = NULL;
239 gchar *email;
240
241 /* This action is defined in EMailDisplay. */
242
243 backend = e_mail_reader_get_backend (reader);
244 session = e_mail_backend_get_session (backend);
245
246 display = e_mail_reader_get_mail_display (reader);
247 if (display == NULL)
248 return;
249
250 web_view = E_WEB_VIEW (display);
251 uri = e_web_view_get_selected_uri (web_view);
252 g_return_if_fail (uri != NULL);
253
254 curl = camel_url_new (uri, NULL);
255 g_return_if_fail (curl != NULL);
256
257 if (curl->path == NULL || *curl->path == '\0')
258 goto exit;
259
260 cia = camel_internet_address_new ();
261 if (camel_address_decode (CAMEL_ADDRESS (cia), curl->path) < 0) {
262 g_object_unref (cia);
263 goto exit;
264 }
265
266 /* XXX EBookShellBackend should be listening for this
267 * event. Kind of kludgey, but works for now. */
268 shell_backend = E_SHELL_BACKEND (backend);
269 shell = e_shell_backend_get_shell (shell_backend);
270 email = camel_address_format (CAMEL_ADDRESS (cia));
271 e_shell_event (shell, "contact-quick-add-email", email);
272 g_free (email);
273
274 /* Remove this address from the photo cache. */
275 photo_cache = e_mail_ui_session_get_photo_cache (
276 E_MAIL_UI_SESSION (session));
277 if (camel_internet_address_get (cia, 0, NULL, &address_only))
278 e_photo_cache_remove_photo (photo_cache, address_only);
279
280 g_object_unref (cia);
281
282 exit:
283 camel_url_free (curl);
284 }
285
286 static void
action_mail_charset_cb(GtkRadioAction * action,GtkRadioAction * current,EMailReader * reader)287 action_mail_charset_cb (GtkRadioAction *action,
288 GtkRadioAction *current,
289 EMailReader *reader)
290 {
291 EMailDisplay *display;
292 EMailFormatter *formatter;
293
294 if (action != current)
295 return;
296
297 display = e_mail_reader_get_mail_display (reader);
298 formatter = e_mail_display_get_formatter (display);
299
300 if (formatter != NULL) {
301 const gchar *charset;
302
303 /* Charset for "Default" action will be NULL. */
304 charset = g_object_get_data (G_OBJECT (action), "charset");
305 e_mail_formatter_set_charset (formatter, charset);
306 }
307 }
308
309 static void
action_mail_check_for_junk_cb(GtkAction * action,EMailReader * reader)310 action_mail_check_for_junk_cb (GtkAction *action,
311 EMailReader *reader)
312 {
313 EMailBackend *backend;
314 EMailSession *session;
315 CamelFolder *folder;
316 GPtrArray *uids;
317
318 folder = e_mail_reader_ref_folder (reader);
319 backend = e_mail_reader_get_backend (reader);
320 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
321
322 session = e_mail_backend_get_session (backend);
323
324 mail_filter_folder (
325 session, folder, uids,
326 E_FILTER_SOURCE_JUNKTEST, FALSE);
327
328 g_clear_object (&folder);
329 g_ptr_array_unref (uids);
330 }
331
332 static void
mail_reader_copy_or_move_selected_messages(EMailReader * reader,gboolean is_move)333 mail_reader_copy_or_move_selected_messages (EMailReader *reader,
334 gboolean is_move)
335 {
336 CamelFolder *folder;
337 EMailBackend *backend;
338 EMailSession *session;
339 EMFolderSelector *selector;
340 EMFolderTree *folder_tree;
341 EMFolderTreeModel *model;
342 GSettings *settings;
343 GtkWidget *dialog;
344 GtkWindow *window;
345 GPtrArray *uids;
346 const gchar *uri;
347
348 backend = e_mail_reader_get_backend (reader);
349 session = e_mail_backend_get_session (backend);
350
351 folder = e_mail_reader_ref_folder (reader);
352 window = e_mail_reader_get_window (reader);
353 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
354
355 model = em_folder_tree_model_get_default ();
356
357 dialog = em_folder_selector_new (window, model);
358
359 gtk_window_set_title (GTK_WINDOW (dialog), is_move ? _("Move to Folder") : _("Copy to Folder"));
360
361 selector = EM_FOLDER_SELECTOR (dialog);
362 em_folder_selector_set_can_create (selector, TRUE);
363 em_folder_selector_set_default_button_label (selector, is_move ? _("_Move") : _("C_opy"));
364
365 folder_tree = em_folder_selector_get_folder_tree (selector);
366
367 em_folder_tree_set_excluded (
368 folder_tree,
369 EMFT_EXCLUDE_NOSELECT |
370 EMFT_EXCLUDE_VIRTUAL |
371 EMFT_EXCLUDE_VTRASH);
372
373 settings = e_util_ref_settings ("org.gnome.evolution.mail");
374
375 if (!g_settings_get_boolean (settings, "copy-move-to-folder-preserve-expand"))
376 gtk_tree_view_expand_all (GTK_TREE_VIEW (folder_tree));
377
378 g_clear_object (&settings);
379
380 em_folder_selector_maybe_collapse_archive_folders (selector);
381
382 if (default_xfer_messages_uri != NULL) {
383 em_folder_tree_set_selected (
384 folder_tree, default_xfer_messages_uri, FALSE);
385 } else if (folder) {
386 gchar *uri = e_mail_folder_uri_from_folder (folder);
387
388 if (uri) {
389 em_folder_tree_set_selected (folder_tree, uri, FALSE);
390 g_free (uri);
391 }
392 }
393
394 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
395 goto exit;
396
397 uri = em_folder_selector_get_selected_uri (selector);
398
399 g_free (default_xfer_messages_uri);
400 default_xfer_messages_uri = g_strdup (uri);
401
402 if (uri != NULL)
403 mail_transfer_messages (
404 session, folder, uids,
405 is_move, uri, 0, NULL, NULL);
406
407 exit:
408 gtk_widget_destroy (dialog);
409
410 g_clear_object (&folder);
411 g_ptr_array_unref (uids);
412 }
413
414 static void
mail_reader_manage_color_flag_on_selection(EMailReader * reader,const gchar * color)415 mail_reader_manage_color_flag_on_selection (EMailReader *reader,
416 const gchar *color)
417 {
418 CamelFolder *folder;
419
420 g_return_if_fail (E_IS_MAIL_READER (reader));
421
422 folder = e_mail_reader_ref_folder (reader);
423
424 if (folder != NULL) {
425 GPtrArray *uids;
426 guint ii;
427
428 camel_folder_freeze (folder);
429
430 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
431
432 for (ii = 0; ii < uids->len; ii++) {
433 CamelMessageInfo *info;
434
435 info = camel_folder_get_message_info (folder, uids->pdata[ii]);
436 if (info) {
437 camel_message_info_set_user_tag (info, "color", color);
438 g_object_unref (info);
439 }
440 }
441
442 g_ptr_array_unref (uids);
443
444 camel_folder_thaw (folder);
445
446 g_object_unref (folder);
447 }
448 }
449
450 static void
action_mail_color_assign_cb(GtkAction * action,EMailReader * reader)451 action_mail_color_assign_cb (GtkAction *action,
452 EMailReader *reader)
453 {
454 GtkWidget *dialog;
455
456 dialog = gtk_color_chooser_dialog_new (NULL, e_mail_reader_get_window (reader));
457
458 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
459 GdkRGBA rgba;
460 gchar *color;
461
462 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (dialog), &rgba);
463
464 color = g_strdup_printf ("#%02X%02X%02X",
465 0xFF & ((gint) (255 * rgba.red)),
466 0xFF & ((gint) (255 * rgba.green)),
467 0xFF & ((gint) (255 * rgba.blue)));
468
469 if (color) {
470 mail_reader_manage_color_flag_on_selection (reader, color);
471
472 g_free (color);
473 }
474 }
475
476 gtk_widget_destroy (dialog);
477 }
478
479 static void
action_mail_color_unset_cb(GtkAction * action,EMailReader * reader)480 action_mail_color_unset_cb (GtkAction *action,
481 EMailReader *reader)
482 {
483 mail_reader_manage_color_flag_on_selection (reader, NULL);
484 }
485
486 static void
action_mail_copy_cb(GtkAction * action,EMailReader * reader)487 action_mail_copy_cb (GtkAction *action,
488 EMailReader *reader)
489 {
490 mail_reader_copy_or_move_selected_messages (reader, FALSE);
491 }
492
493 static gboolean
mail_reader_replace_vee_folder_with_real(CamelFolder ** inout_folder,const gchar * uid,gchar ** out_real_uid)494 mail_reader_replace_vee_folder_with_real (CamelFolder **inout_folder,
495 const gchar *uid,
496 gchar **out_real_uid)
497 {
498 g_return_val_if_fail (inout_folder != NULL, FALSE);
499 g_return_val_if_fail (CAMEL_IS_FOLDER (*inout_folder), FALSE);
500 g_return_val_if_fail (uid != NULL, FALSE);
501 g_return_val_if_fail (out_real_uid != NULL, FALSE);
502
503 *out_real_uid = NULL;
504
505 if (CAMEL_IS_VEE_FOLDER (*inout_folder)) {
506 CamelMessageInfo *info;
507
508 info = camel_folder_get_message_info (*inout_folder, uid);
509 if (info) {
510 CamelFolder *real_folder;
511
512 real_folder = camel_vee_folder_get_location (CAMEL_VEE_FOLDER (*inout_folder), CAMEL_VEE_MESSAGE_INFO (info), out_real_uid);
513
514 if (real_folder && *out_real_uid) {
515 g_object_unref (*inout_folder);
516
517 *inout_folder = g_object_ref (real_folder);
518 }
519
520 g_object_unref (info);
521 } else {
522 g_warn_if_reached ();
523 }
524 }
525
526 return *out_real_uid != NULL;
527 }
528
529 static void
action_mail_edit_note_cb(GtkAction * action,EMailReader * reader)530 action_mail_edit_note_cb (GtkAction *action,
531 EMailReader *reader)
532 {
533 CamelFolder *folder;
534 GPtrArray *uids;
535
536 folder = e_mail_reader_ref_folder (reader);
537 uids = e_mail_reader_get_selected_uids (reader);
538
539 if (uids && uids->len == 1) {
540 gchar *real_uid = NULL;
541 const gchar *uid = uids->pdata[0];
542
543 if (mail_reader_replace_vee_folder_with_real (&folder, uid, &real_uid))
544 uid = real_uid;
545
546 e_mail_notes_edit (e_mail_reader_get_window (reader), folder, uid);
547
548 g_free (real_uid);
549 } else {
550 g_warn_if_reached ();
551 }
552
553 g_clear_object (&folder);
554 g_ptr_array_unref (uids);
555 }
556
557 typedef struct {
558 CamelFolder *folder;
559 gchar *uid;
560 } DeleteNoteData;
561
562 static void
delete_note_data_free(gpointer ptr)563 delete_note_data_free (gpointer ptr)
564 {
565 DeleteNoteData *dnd = ptr;
566
567 if (dnd) {
568 g_clear_object (&dnd->folder);
569 g_free (dnd->uid);
570 g_slice_free (DeleteNoteData, dnd);
571 }
572 }
573
574 static void
mail_delete_note_thread(EAlertSinkThreadJobData * job_data,gpointer user_data,GCancellable * cancellable,GError ** error)575 mail_delete_note_thread (EAlertSinkThreadJobData *job_data,
576 gpointer user_data,
577 GCancellable *cancellable,
578 GError **error)
579 {
580 DeleteNoteData *dnd = user_data;
581
582 g_return_if_fail (dnd != NULL);
583 g_return_if_fail (CAMEL_IS_FOLDER (dnd->folder));
584 g_return_if_fail (dnd->uid != NULL);
585
586 e_mail_notes_remove_sync (dnd->folder, dnd->uid, cancellable, error);
587 }
588
589 static void
action_mail_delete_note_cb(GtkAction * action,EMailReader * reader)590 action_mail_delete_note_cb (GtkAction *action,
591 EMailReader *reader)
592 {
593 CamelFolder *folder;
594 GPtrArray *uids;
595
596 folder = e_mail_reader_ref_folder (reader);
597 uids = e_mail_reader_get_selected_uids (reader);
598
599 if (uids && uids->len == 1) {
600 DeleteNoteData *dnd;
601 EAlertSink *alert_sink;
602 EActivity *activity;
603 gchar *full_display_name;
604 gchar *real_uid = NULL;
605 const gchar *uid = uids->pdata[0];
606
607 if (mail_reader_replace_vee_folder_with_real (&folder, uid, &real_uid))
608 uid = real_uid;
609
610 dnd = g_slice_new0 (DeleteNoteData);
611 dnd->folder = g_object_ref (folder);
612 dnd->uid = g_strdup (uid);
613
614 full_display_name = e_mail_folder_to_full_display_name (folder, NULL);
615 alert_sink = e_mail_reader_get_alert_sink (reader);
616
617 activity = e_alert_sink_submit_thread_job (alert_sink,
618 _("Deleting message note…"),
619 "mail:failed-delete-note",
620 full_display_name ? full_display_name : camel_folder_get_full_name (folder),
621 mail_delete_note_thread, dnd, delete_note_data_free);
622
623 if (activity)
624 e_shell_backend_add_activity (E_SHELL_BACKEND (e_mail_reader_get_backend (reader)), activity);
625
626 g_clear_object (&activity);
627 g_free (full_display_name);
628 g_free (real_uid);
629 } else {
630 g_warn_if_reached ();
631 }
632
633 g_clear_object (&folder);
634 g_ptr_array_unref (uids);
635 }
636
637 static void
action_mail_delete_cb(GtkAction * action,EMailReader * reader)638 action_mail_delete_cb (GtkAction *action,
639 EMailReader *reader)
640 {
641 guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
642 guint32 set = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
643
644 if (!e_mail_reader_confirm_delete (reader))
645 return;
646
647 /* FIXME Verify all selected messages are deletable.
648 * But handle it by disabling this action. */
649
650 if (e_mail_reader_mark_selected (reader, mask, set) != 0 &&
651 !e_mail_reader_close_on_delete_or_junk (reader)) {
652 if (e_mail_reader_get_delete_selects_previous (reader))
653 e_mail_reader_select_previous_message (reader, FALSE);
654 else
655 e_mail_reader_select_next_message (reader, FALSE);
656 }
657 }
658
659 static void
action_mail_filter_on_mailing_list_cb(GtkAction * action,EMailReader * reader)660 action_mail_filter_on_mailing_list_cb (GtkAction *action,
661 EMailReader *reader)
662 {
663 e_mail_reader_create_filter_from_selected (reader, AUTO_MLIST);
664 }
665
666 static void
action_mail_filter_on_recipients_cb(GtkAction * action,EMailReader * reader)667 action_mail_filter_on_recipients_cb (GtkAction *action,
668 EMailReader *reader)
669 {
670 e_mail_reader_create_filter_from_selected (reader, AUTO_TO);
671 }
672
673 static void
action_mail_filter_on_sender_cb(GtkAction * action,EMailReader * reader)674 action_mail_filter_on_sender_cb (GtkAction *action,
675 EMailReader *reader)
676 {
677 e_mail_reader_create_filter_from_selected (reader, AUTO_FROM);
678 }
679
680 static void
action_mail_filter_on_subject_cb(GtkAction * action,EMailReader * reader)681 action_mail_filter_on_subject_cb (GtkAction *action,
682 EMailReader *reader)
683 {
684 e_mail_reader_create_filter_from_selected (reader, AUTO_SUBJECT);
685 }
686
687 static void
action_mail_filters_apply_cb(GtkAction * action,EMailReader * reader)688 action_mail_filters_apply_cb (GtkAction *action,
689 EMailReader *reader)
690 {
691 EMailBackend *backend;
692 EMailSession *session;
693 CamelFolder *folder;
694 GPtrArray *uids;
695
696 folder = e_mail_reader_ref_folder (reader);
697 backend = e_mail_reader_get_backend (reader);
698 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
699
700 session = e_mail_backend_get_session (backend);
701
702 mail_filter_folder (
703 session, folder, uids,
704 E_FILTER_SOURCE_DEMAND, FALSE);
705
706 g_clear_object (&folder);
707 g_ptr_array_unref (uids);
708 }
709
710 static void
action_mail_remove_attachments_cb(GtkAction * action,EMailReader * reader)711 action_mail_remove_attachments_cb (GtkAction *action,
712 EMailReader *reader)
713 {
714 e_mail_reader_remove_attachments (reader);
715 }
716
717 static void
action_mail_remove_duplicates_cb(GtkAction * action,EMailReader * reader)718 action_mail_remove_duplicates_cb (GtkAction *action,
719 EMailReader *reader)
720 {
721 e_mail_reader_remove_duplicates (reader);
722 }
723
724 static void
action_mail_find_cb(GtkAction * action,EMailReader * reader)725 action_mail_find_cb (GtkAction *action,
726 EMailReader *reader)
727 {
728 e_mail_reader_show_search_bar (reader);
729 }
730
731 static void
action_mail_flag_clear_cb(GtkAction * action,EMailReader * reader)732 action_mail_flag_clear_cb (GtkAction *action,
733 EMailReader *reader)
734 {
735 CamelFolder *folder;
736 GtkWindow *window;
737 GPtrArray *uids;
738
739 folder = e_mail_reader_ref_folder (reader);
740 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
741 window = e_mail_reader_get_window (reader);
742
743 em_utils_flag_for_followup_clear (window, folder, uids);
744
745 e_mail_reader_reload (reader);
746
747 g_clear_object (&folder);
748 g_ptr_array_unref (uids);
749 }
750
751 static void
action_mail_flag_completed_cb(GtkAction * action,EMailReader * reader)752 action_mail_flag_completed_cb (GtkAction *action,
753 EMailReader *reader)
754 {
755 CamelFolder *folder;
756 GtkWindow *window;
757 GPtrArray *uids;
758
759 folder = e_mail_reader_ref_folder (reader);
760 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
761 window = e_mail_reader_get_window (reader);
762
763 em_utils_flag_for_followup_completed (window, folder, uids);
764
765 e_mail_reader_reload (reader);
766
767 g_clear_object (&folder);
768 g_ptr_array_unref (uids);
769 }
770
771 static void
action_mail_flag_for_followup_cb(GtkAction * action,EMailReader * reader)772 action_mail_flag_for_followup_cb (GtkAction *action,
773 EMailReader *reader)
774 {
775 CamelFolder *folder;
776 GPtrArray *uids;
777
778 folder = e_mail_reader_ref_folder (reader);
779 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
780
781 em_utils_flag_for_followup (reader, folder, uids);
782
783 e_mail_reader_reload (reader);
784
785 g_clear_object (&folder);
786 g_ptr_array_unref (uids);
787 }
788
789 static void
action_mail_forward_cb(GtkAction * action,EMailReader * reader)790 action_mail_forward_cb (GtkAction *action,
791 EMailReader *reader)
792 {
793 GtkWindow *window;
794 GPtrArray *uids;
795
796 window = e_mail_reader_get_window (reader);
797 uids = e_mail_reader_get_selected_uids (reader);
798 g_return_if_fail (uids != NULL);
799
800 if (em_utils_ask_open_many (window, uids->len)) {
801 CamelFolder *folder;
802
803 folder = e_mail_reader_ref_folder (reader);
804
805 e_mail_reader_forward_messages (
806 reader, folder, uids,
807 e_mail_reader_get_forward_style (reader));
808
809 g_clear_object (&folder);
810 }
811
812 g_ptr_array_unref (uids);
813 }
814
815 static void
action_mail_forward_attached_cb(GtkAction * action,EMailReader * reader)816 action_mail_forward_attached_cb (GtkAction *action,
817 EMailReader *reader)
818 {
819 GtkWindow *window;
820 GPtrArray *uids;
821
822 window = e_mail_reader_get_window (reader);
823 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
824 g_return_if_fail (uids != NULL);
825
826 if (em_utils_ask_open_many (window, uids->len)) {
827 CamelFolder *folder;
828
829 folder = e_mail_reader_ref_folder (reader);
830
831 e_mail_reader_forward_messages (
832 reader, folder, uids,
833 E_MAIL_FORWARD_STYLE_ATTACHED);
834
835 g_clear_object (&folder);
836 }
837
838 g_ptr_array_unref (uids);
839 }
840
841 static void
action_mail_forward_inline_cb(GtkAction * action,EMailReader * reader)842 action_mail_forward_inline_cb (GtkAction *action,
843 EMailReader *reader)
844 {
845 GtkWindow *window;
846 GPtrArray *uids;
847
848 window = e_mail_reader_get_window (reader);
849 uids = e_mail_reader_get_selected_uids (reader);
850 g_return_if_fail (uids != NULL);
851
852 if (em_utils_ask_open_many (window, uids->len)) {
853 CamelFolder *folder;
854
855 folder = e_mail_reader_ref_folder (reader);
856
857 e_mail_reader_forward_messages (
858 reader, folder, uids,
859 E_MAIL_FORWARD_STYLE_INLINE);
860
861 g_clear_object (&folder);
862 }
863
864 g_ptr_array_unref (uids);
865 }
866
867 static void
action_mail_forward_quoted_cb(GtkAction * action,EMailReader * reader)868 action_mail_forward_quoted_cb (GtkAction *action,
869 EMailReader *reader)
870 {
871 GtkWindow *window;
872 GPtrArray *uids;
873
874 window = e_mail_reader_get_window (reader);
875 uids = e_mail_reader_get_selected_uids (reader);
876 g_return_if_fail (uids != NULL);
877
878 if (em_utils_ask_open_many (window, uids->len)) {
879 CamelFolder *folder;
880
881 folder = e_mail_reader_ref_folder (reader);
882
883 e_mail_reader_forward_messages (
884 reader, folder, uids,
885 E_MAIL_FORWARD_STYLE_QUOTED);
886
887 g_clear_object (&folder);
888 }
889
890 g_ptr_array_unref (uids);
891 }
892
893 static void
action_mail_label_new_cb(GtkAction * action,EMailReader * reader)894 action_mail_label_new_cb (GtkAction *action,
895 EMailReader *reader)
896 {
897 EMailLabelDialog *label_dialog;
898 EMailLabelListStore *label_store;
899 EMailBackend *backend;
900 EMailSession *session;
901 GtkTreeModel *model;
902 GtkTreeIter iter;
903 GtkWidget *dialog;
904 GPtrArray *uids;
905 GdkColor label_color;
906 const gchar *label_name;
907 gchar *label_tag;
908 gint n_children;
909 guint ii;
910
911 dialog = e_mail_label_dialog_new (e_mail_reader_get_window (reader));
912
913 gtk_window_set_title (GTK_WINDOW (dialog), _("Add Label"));
914
915 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
916 goto exit;
917
918 backend = e_mail_reader_get_backend (reader);
919 session = e_mail_backend_get_session (backend);
920 label_store = e_mail_ui_session_get_label_store (
921 E_MAIL_UI_SESSION (session));
922
923 label_dialog = E_MAIL_LABEL_DIALOG (dialog);
924 label_name = e_mail_label_dialog_get_label_name (label_dialog);
925 e_mail_label_dialog_get_label_color (label_dialog, &label_color);
926
927 e_mail_label_list_store_set (
928 label_store, NULL, label_name, &label_color);
929
930 /* XXX This is awkward. We've added a new label to the list store
931 * but we don't have the new label's tag nor an iterator to use
932 * to fetch it. We know the label was appended to the store,
933 * so we have to dig it out manually. EMailLabelListStore API
934 * probably needs some rethinking. */
935 model = GTK_TREE_MODEL (label_store);
936 n_children = gtk_tree_model_iter_n_children (model, NULL);
937 g_warn_if_fail (gtk_tree_model_iter_nth_child (model, &iter, NULL, n_children - 1));
938 label_tag = e_mail_label_list_store_get_tag (label_store, &iter);
939
940 uids = e_mail_reader_get_selected_uids (reader);
941 if (uids) {
942 CamelFolder *folder;
943
944 folder = e_mail_reader_ref_folder (reader);
945
946 for (ii = 0; ii < uids->len; ii++) {
947 camel_folder_set_message_user_flag (
948 folder, uids->pdata[ii], label_tag, TRUE);
949 }
950
951 g_clear_object (&folder);
952 g_ptr_array_unref (uids);
953 }
954
955 g_free (label_tag);
956
957 exit:
958 gtk_widget_destroy (dialog);
959 }
960
961 static void
action_mail_label_none_cb(GtkAction * action,EMailReader * reader)962 action_mail_label_none_cb (GtkAction *action,
963 EMailReader *reader)
964 {
965 EMailBackend *backend;
966 EMailSession *session;
967 EMailLabelListStore *label_store;
968 CamelFolder *folder;
969 GtkTreeIter iter;
970 GPtrArray *uids;
971 gboolean valid;
972 guint ii;
973
974 uids = e_mail_reader_get_selected_uids (reader);
975 if (!uids)
976 return;
977
978 backend = e_mail_reader_get_backend (reader);
979 session = e_mail_backend_get_session (backend);
980 label_store = e_mail_ui_session_get_label_store (
981 E_MAIL_UI_SESSION (session));
982
983 folder = e_mail_reader_ref_folder (reader);
984
985 valid = gtk_tree_model_get_iter_first (
986 GTK_TREE_MODEL (label_store), &iter);
987
988 while (valid) {
989 gchar *tag;
990
991 tag = e_mail_label_list_store_get_tag (label_store, &iter);
992
993 for (ii = 0; ii < uids->len; ii++) {
994 camel_folder_set_message_user_flag (
995 folder, uids->pdata[ii], tag, FALSE);
996 camel_folder_set_message_user_tag (
997 folder, uids->pdata[ii], "label", NULL);
998 }
999
1000 g_free (tag);
1001
1002 valid = gtk_tree_model_iter_next (
1003 GTK_TREE_MODEL (label_store), &iter);
1004 }
1005
1006 g_clear_object (&folder);
1007 g_ptr_array_unref (uids);
1008 }
1009
1010 static void
action_mail_load_images_cb(GtkAction * action,EMailReader * reader)1011 action_mail_load_images_cb (GtkAction *action,
1012 EMailReader *reader)
1013 {
1014 EMailDisplay *display;
1015
1016 display = e_mail_reader_get_mail_display (reader);
1017
1018 e_mail_display_load_images (display);
1019 }
1020
1021 static void
action_mail_mark_important_cb(GtkAction * action,EMailReader * reader)1022 action_mail_mark_important_cb (GtkAction *action,
1023 EMailReader *reader)
1024 {
1025 guint32 mask = CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_DELETED;
1026 guint32 set = CAMEL_MESSAGE_FLAGGED;
1027
1028 e_mail_reader_mark_selected (reader, mask, set);
1029 }
1030
1031 static void
action_mail_mark_junk_cb(GtkAction * action,EMailReader * reader)1032 action_mail_mark_junk_cb (GtkAction *action,
1033 EMailReader *reader)
1034 {
1035 guint32 mask =
1036 CAMEL_MESSAGE_SEEN |
1037 CAMEL_MESSAGE_JUNK |
1038 CAMEL_MESSAGE_NOTJUNK |
1039 CAMEL_MESSAGE_JUNK_LEARN;
1040 guint32 set =
1041 CAMEL_MESSAGE_SEEN |
1042 CAMEL_MESSAGE_JUNK |
1043 CAMEL_MESSAGE_JUNK_LEARN;
1044
1045 if (e_mail_reader_mark_selected (reader, mask, set) != 0 &&
1046 !e_mail_reader_close_on_delete_or_junk (reader)) {
1047 if (e_mail_reader_get_delete_selects_previous (reader))
1048 e_mail_reader_select_previous_message (reader, TRUE);
1049 else
1050 e_mail_reader_select_next_message (reader, TRUE);
1051 }
1052 }
1053
1054 static void
action_mail_mark_notjunk_cb(GtkAction * action,EMailReader * reader)1055 action_mail_mark_notjunk_cb (GtkAction *action,
1056 EMailReader *reader)
1057 {
1058 guint32 mask =
1059 CAMEL_MESSAGE_JUNK |
1060 CAMEL_MESSAGE_NOTJUNK |
1061 CAMEL_MESSAGE_JUNK_LEARN;
1062 guint32 set =
1063 CAMEL_MESSAGE_NOTJUNK |
1064 CAMEL_MESSAGE_JUNK_LEARN;
1065
1066 if (e_mail_reader_mark_selected (reader, mask, set) != 0) {
1067 if (e_mail_reader_get_delete_selects_previous (reader))
1068 e_mail_reader_select_previous_message (reader, TRUE);
1069 else
1070 e_mail_reader_select_next_message (reader, TRUE);
1071 }
1072 }
1073
1074 static void
action_mail_mark_read_cb(GtkAction * action,EMailReader * reader)1075 action_mail_mark_read_cb (GtkAction *action,
1076 EMailReader *reader)
1077 {
1078 guint32 mask = CAMEL_MESSAGE_SEEN;
1079 guint32 set = CAMEL_MESSAGE_SEEN;
1080
1081 e_mail_reader_mark_selected (reader, mask, set);
1082 }
1083
1084 static void
action_mail_mark_unimportant_cb(GtkAction * action,EMailReader * reader)1085 action_mail_mark_unimportant_cb (GtkAction *action,
1086 EMailReader *reader)
1087 {
1088 guint32 mask = CAMEL_MESSAGE_FLAGGED;
1089 guint32 set = 0;
1090
1091 e_mail_reader_mark_selected (reader, mask, set);
1092 }
1093
1094 static void
action_mail_mark_ignore_thread_sub_cb(GtkAction * action,EMailReader * reader)1095 action_mail_mark_ignore_thread_sub_cb (GtkAction *action,
1096 EMailReader *reader)
1097 {
1098 e_mail_reader_mark_selected_ignore_thread (reader, E_IGNORE_THREAD_SUBSET_SET);
1099 }
1100
1101 static void
action_mail_mark_unignore_thread_sub_cb(GtkAction * action,EMailReader * reader)1102 action_mail_mark_unignore_thread_sub_cb (GtkAction *action,
1103 EMailReader *reader)
1104 {
1105 e_mail_reader_mark_selected_ignore_thread (reader, E_IGNORE_THREAD_SUBSET_UNSET);
1106 }
1107
1108 static void
action_mail_mark_ignore_thread_whole_cb(GtkAction * action,EMailReader * reader)1109 action_mail_mark_ignore_thread_whole_cb (GtkAction *action,
1110 EMailReader *reader)
1111 {
1112 e_mail_reader_mark_selected_ignore_thread (reader, E_IGNORE_THREAD_WHOLE_SET);
1113 }
1114
1115 static void
action_mail_mark_unignore_thread_whole_cb(GtkAction * action,EMailReader * reader)1116 action_mail_mark_unignore_thread_whole_cb (GtkAction *action,
1117 EMailReader *reader)
1118 {
1119 e_mail_reader_mark_selected_ignore_thread (reader, E_IGNORE_THREAD_WHOLE_UNSET);
1120 }
1121
1122 static void
action_mail_mark_unread_cb(GtkAction * action,EMailReader * reader)1123 action_mail_mark_unread_cb (GtkAction *action,
1124 EMailReader *reader)
1125 {
1126 GtkWidget *message_list;
1127 EMFolderTreeModel *model;
1128 CamelFolder *folder;
1129 guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
1130 guint32 set = 0;
1131 guint n_marked;
1132
1133 message_list = e_mail_reader_get_message_list (reader);
1134
1135 n_marked = e_mail_reader_mark_selected (reader, mask, set);
1136
1137 if (MESSAGE_LIST (message_list)->seen_id != 0) {
1138 g_source_remove (MESSAGE_LIST (message_list)->seen_id);
1139 MESSAGE_LIST (message_list)->seen_id = 0;
1140 }
1141
1142 folder = e_mail_reader_ref_folder (reader);
1143
1144 /* Notify the tree model that the user has marked messages as
1145 * unread so it doesn't mistake the event as new mail arriving. */
1146 model = em_folder_tree_model_get_default ();
1147 em_folder_tree_model_user_marked_unread (model, folder, n_marked);
1148
1149 g_clear_object (&folder);
1150 }
1151
1152 static void
action_mail_message_edit_cb(GtkAction * action,EMailReader * reader)1153 action_mail_message_edit_cb (GtkAction *action,
1154 EMailReader *reader)
1155 {
1156 EShell *shell;
1157 EMailBackend *backend;
1158 ESourceRegistry *registry;
1159 CamelFolder *folder;
1160 GPtrArray *uids;
1161 gboolean replace;
1162
1163 uids = e_mail_reader_get_selected_uids (reader);
1164 g_return_if_fail (uids != NULL);
1165
1166 backend = e_mail_reader_get_backend (reader);
1167 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
1168 registry = e_shell_get_registry (shell);
1169
1170 folder = e_mail_reader_ref_folder (reader);
1171 replace = em_utils_folder_is_drafts (registry, folder);
1172 e_mail_reader_edit_messages (reader, folder, uids, replace, replace);
1173 g_clear_object (&folder);
1174
1175 g_ptr_array_unref (uids);
1176 }
1177
1178 typedef struct _CreateComposerData {
1179 EMailReader *reader;
1180 CamelMimeMessage *message;
1181 CamelFolder *folder;
1182 const gchar *message_uid; /* In the Camel string pool */
1183 gboolean is_redirect;
1184 } CreateComposerData;
1185
1186 static void
mail_reader_new_composer_created_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)1187 mail_reader_new_composer_created_cb (GObject *source_object,
1188 GAsyncResult *result,
1189 gpointer user_data)
1190 {
1191 CreateComposerData *ccd = user_data;
1192 EMsgComposer *composer;
1193 GError *error = NULL;
1194
1195 g_return_if_fail (ccd != NULL);
1196
1197 composer = e_msg_composer_new_finish (result, &error);
1198 if (error) {
1199 g_warning ("%s: Failed to create msg composer: %s", G_STRFUNC, error->message);
1200 g_clear_error (&error);
1201 } else {
1202 if (ccd->is_redirect)
1203 em_utils_redirect_message (composer, ccd->message);
1204 else
1205 em_utils_compose_new_message_with_selection (composer, ccd->folder, ccd->message_uid);
1206
1207 e_mail_reader_composer_created (ccd->reader, composer, ccd->message);
1208 }
1209
1210 g_clear_object (&ccd->reader);
1211 g_clear_object (&ccd->message);
1212 g_clear_object (&ccd->folder);
1213 camel_pstring_free (ccd->message_uid);
1214 g_slice_free (CreateComposerData, ccd);
1215 }
1216
1217 static void
action_mail_message_new_cb(GtkAction * action,EMailReader * reader)1218 action_mail_message_new_cb (GtkAction *action,
1219 EMailReader *reader)
1220 {
1221 EShell *shell;
1222 EMailBackend *backend;
1223 EShellBackend *shell_backend;
1224 CamelFolder *folder;
1225 CreateComposerData *ccd;
1226 GPtrArray *selected_uids = NULL;
1227 const gchar *selected_uid = NULL;
1228
1229 folder = e_mail_reader_ref_folder (reader);
1230 backend = e_mail_reader_get_backend (reader);
1231
1232 selected_uids = e_mail_reader_get_selected_uids (reader);
1233 if (selected_uids && selected_uids->len > 0)
1234 selected_uid = g_ptr_array_index (selected_uids, 0);
1235
1236 if (!selected_uid) {
1237 GtkWidget *message_list;
1238
1239 message_list = e_mail_reader_get_message_list (reader);
1240 if (message_list)
1241 selected_uid = MESSAGE_LIST (message_list)->cursor_uid;
1242 }
1243
1244 shell_backend = E_SHELL_BACKEND (backend);
1245 shell = e_shell_backend_get_shell (shell_backend);
1246
1247 ccd = g_slice_new0 (CreateComposerData);
1248 ccd->reader = g_object_ref (reader);
1249 ccd->folder = folder;
1250 ccd->message_uid = camel_pstring_strdup (selected_uid);
1251 ccd->is_redirect = FALSE;
1252
1253 e_msg_composer_new (shell, mail_reader_new_composer_created_cb, ccd);
1254
1255 if (selected_uids)
1256 g_ptr_array_unref (selected_uids);
1257 }
1258
1259 static void
action_mail_message_open_cb(GtkAction * action,EMailReader * reader)1260 action_mail_message_open_cb (GtkAction *action,
1261 EMailReader *reader)
1262 {
1263 e_mail_reader_open_selected_mail (reader);
1264 }
1265
1266 static void
action_mail_archive_cb(GtkAction * action,EMailReader * reader)1267 action_mail_archive_cb (GtkAction *action,
1268 EMailReader *reader)
1269 {
1270 CamelFolder *folder;
1271 EMailBackend *backend;
1272 EMailSession *session;
1273 GPtrArray *uids;
1274 gchar *archive_folder;
1275
1276 backend = e_mail_reader_get_backend (reader);
1277 session = e_mail_backend_get_session (backend);
1278
1279 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
1280 g_return_if_fail (uids != NULL);
1281
1282 folder = e_mail_reader_ref_folder (reader);
1283 archive_folder = em_utils_get_archive_folder_uri_from_folder (folder, backend, uids, TRUE);
1284
1285 if (archive_folder != NULL)
1286 mail_transfer_messages (
1287 session, folder, uids,
1288 TRUE, archive_folder, 0, NULL, NULL);
1289
1290 g_clear_object (&folder);
1291 g_ptr_array_unref (uids);
1292 g_free (archive_folder);
1293 }
1294
1295 static void
action_mail_move_cb(GtkAction * action,EMailReader * reader)1296 action_mail_move_cb (GtkAction *action,
1297 EMailReader *reader)
1298 {
1299 mail_reader_copy_or_move_selected_messages (reader, TRUE);
1300 }
1301
1302 static void
action_mail_next_cb(GtkAction * action,EMailReader * reader)1303 action_mail_next_cb (GtkAction *action,
1304 EMailReader *reader)
1305 {
1306 GtkWidget *message_list;
1307 MessageListSelectDirection direction;
1308 guint32 flags, mask;
1309
1310 direction = MESSAGE_LIST_SELECT_NEXT;
1311 flags = 0;
1312 mask = 0;
1313
1314 message_list = e_mail_reader_get_message_list (reader);
1315
1316 message_list_select (
1317 MESSAGE_LIST (message_list), direction, flags, mask);
1318 }
1319
1320 static void
action_mail_next_important_cb(GtkAction * action,EMailReader * reader)1321 action_mail_next_important_cb (GtkAction *action,
1322 EMailReader *reader)
1323 {
1324 GtkWidget *message_list;
1325 MessageListSelectDirection direction;
1326 guint32 flags, mask;
1327
1328 direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
1329 flags = CAMEL_MESSAGE_FLAGGED;
1330 mask = CAMEL_MESSAGE_FLAGGED;
1331
1332 message_list = e_mail_reader_get_message_list (reader);
1333
1334 message_list_select (
1335 MESSAGE_LIST (message_list), direction, flags, mask);
1336 }
1337
1338 static void
action_mail_next_thread_cb(GtkAction * action,EMailReader * reader)1339 action_mail_next_thread_cb (GtkAction *action,
1340 EMailReader *reader)
1341 {
1342 GtkWidget *message_list;
1343
1344 message_list = e_mail_reader_get_message_list (reader);
1345
1346 message_list_select_next_thread (MESSAGE_LIST (message_list));
1347 }
1348
1349 static void
mail_reader_select_unread(EMailReader * reader,gboolean move_forward)1350 mail_reader_select_unread (EMailReader *reader,
1351 gboolean move_forward)
1352 {
1353 GtkWidget *message_list;
1354 MessageListSelectDirection direction;
1355 guint32 flags, mask;
1356
1357 g_return_if_fail (E_IS_MAIL_READER (reader));
1358
1359 direction = (move_forward ? MESSAGE_LIST_SELECT_NEXT : MESSAGE_LIST_SELECT_PREVIOUS) |
1360 MESSAGE_LIST_SELECT_WRAP | MESSAGE_LIST_SELECT_INCLUDE_COLLAPSED;
1361 flags = 0;
1362 mask = CAMEL_MESSAGE_SEEN;
1363
1364 message_list = e_mail_reader_get_message_list (reader);
1365
1366 if (!message_list_select (MESSAGE_LIST (message_list), direction, flags, mask)) {
1367 GtkWindow *window;
1368
1369 window = e_mail_reader_get_window (reader);
1370 if (E_IS_SHELL_WINDOW (window)) {
1371 EShellWindow *shell_window;
1372 EMFolderTree *folder_tree = NULL;
1373 const gchar *active_view;
1374
1375 shell_window = E_SHELL_WINDOW (window);
1376 active_view = e_shell_window_get_active_view (shell_window);
1377
1378 if (g_strcmp0 (active_view, "mail") == 0) {
1379 EShellView *shell_view;
1380 EShellSidebar *shell_sidebar;
1381
1382 shell_view = e_shell_window_get_shell_view (shell_window, "mail");
1383 shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
1384 g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
1385
1386 if (folder_tree) {
1387 gboolean selected;
1388
1389 if (move_forward)
1390 selected = em_folder_tree_select_next_path (folder_tree, TRUE);
1391 else
1392 selected = em_folder_tree_select_prev_path (folder_tree, TRUE);
1393
1394 if (selected)
1395 message_list_set_regen_selects_unread (MESSAGE_LIST (message_list), TRUE);
1396 }
1397
1398 g_clear_object (&folder_tree);
1399 }
1400 }
1401 }
1402 }
1403
1404 static void
action_mail_next_unread_cb(GtkAction * action,EMailReader * reader)1405 action_mail_next_unread_cb (GtkAction *action,
1406 EMailReader *reader)
1407 {
1408 mail_reader_select_unread (reader, TRUE);
1409 }
1410
1411 static void
action_mail_previous_cb(GtkAction * action,EMailReader * reader)1412 action_mail_previous_cb (GtkAction *action,
1413 EMailReader *reader)
1414 {
1415 GtkWidget *message_list;
1416 MessageListSelectDirection direction;
1417 guint32 flags, mask;
1418
1419 direction = MESSAGE_LIST_SELECT_PREVIOUS;
1420 flags = 0;
1421 mask = 0;
1422
1423 message_list = e_mail_reader_get_message_list (reader);
1424
1425 message_list_select (
1426 MESSAGE_LIST (message_list), direction, flags, mask);
1427 }
1428
1429 static void
action_mail_previous_important_cb(GtkAction * action,EMailReader * reader)1430 action_mail_previous_important_cb (GtkAction *action,
1431 EMailReader *reader)
1432 {
1433 GtkWidget *message_list;
1434 MessageListSelectDirection direction;
1435 guint32 flags, mask;
1436
1437 direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
1438 flags = CAMEL_MESSAGE_FLAGGED;
1439 mask = CAMEL_MESSAGE_FLAGGED;
1440
1441 message_list = e_mail_reader_get_message_list (reader);
1442
1443 message_list_select (
1444 MESSAGE_LIST (message_list), direction, flags, mask);
1445 }
1446
1447 static void
action_mail_previous_thread_cb(GtkAction * action,EMailReader * reader)1448 action_mail_previous_thread_cb (GtkAction *action,
1449 EMailReader *reader)
1450 {
1451 GtkWidget *message_list;
1452
1453 message_list = e_mail_reader_get_message_list (reader);
1454
1455 message_list_select_prev_thread (MESSAGE_LIST (message_list));
1456 }
1457
1458 static void
action_mail_previous_unread_cb(GtkAction * action,EMailReader * reader)1459 action_mail_previous_unread_cb (GtkAction *action,
1460 EMailReader *reader)
1461 {
1462 mail_reader_select_unread (reader, FALSE);
1463 }
1464
1465 static void
action_mail_print_cb(GtkAction * action,EMailReader * reader)1466 action_mail_print_cb (GtkAction *action,
1467 EMailReader *reader)
1468 {
1469 GtkPrintOperationAction print_action;
1470
1471 print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
1472 e_mail_reader_print (reader, print_action);
1473 }
1474
1475 static void
action_mail_print_preview_cb(GtkAction * action,EMailReader * reader)1476 action_mail_print_preview_cb (GtkAction *action,
1477 EMailReader *reader)
1478 {
1479 GtkPrintOperationAction print_action;
1480
1481 print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
1482 e_mail_reader_print (reader, print_action);
1483 }
1484
1485 static void
mail_reader_redirect_cb(CamelFolder * folder,GAsyncResult * result,EMailReaderClosure * closure)1486 mail_reader_redirect_cb (CamelFolder *folder,
1487 GAsyncResult *result,
1488 EMailReaderClosure *closure)
1489 {
1490 EShell *shell;
1491 EMailBackend *backend;
1492 EAlertSink *alert_sink;
1493 CamelMimeMessage *message;
1494 CreateComposerData *ccd;
1495 GError *error = NULL;
1496
1497 alert_sink = e_activity_get_alert_sink (closure->activity);
1498
1499 message = camel_folder_get_message_finish (folder, result, &error);
1500
1501 if (e_activity_handle_cancellation (closure->activity, error)) {
1502 g_warn_if_fail (message == NULL);
1503 mail_reader_closure_free (closure);
1504 g_error_free (error);
1505 return;
1506
1507 } else if (error != NULL) {
1508 g_warn_if_fail (message == NULL);
1509 e_alert_submit (
1510 alert_sink, "mail:no-retrieve-message",
1511 error->message, NULL);
1512 mail_reader_closure_free (closure);
1513 g_error_free (error);
1514 return;
1515 }
1516
1517 g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1518
1519 backend = e_mail_reader_get_backend (closure->reader);
1520 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
1521
1522 ccd = g_slice_new0 (CreateComposerData);
1523 ccd->reader = g_object_ref (closure->reader);
1524 ccd->message = message;
1525 ccd->message_uid = camel_pstring_strdup (closure->message_uid);
1526 ccd->is_redirect = TRUE;
1527
1528 e_msg_composer_new (shell, mail_reader_new_composer_created_cb, ccd);
1529
1530 mail_reader_closure_free (closure);
1531 }
1532
1533 static void
action_mail_redirect_cb(GtkAction * action,EMailReader * reader)1534 action_mail_redirect_cb (GtkAction *action,
1535 EMailReader *reader)
1536 {
1537 EActivity *activity;
1538 GCancellable *cancellable;
1539 EMailReaderClosure *closure;
1540 GtkWidget *message_list;
1541 CamelFolder *folder;
1542 const gchar *message_uid;
1543
1544 message_list = e_mail_reader_get_message_list (reader);
1545 message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1546 g_return_if_fail (message_uid != NULL);
1547
1548 /* Open the message asynchronously. */
1549
1550 activity = e_mail_reader_new_activity (reader);
1551 cancellable = e_activity_get_cancellable (activity);
1552
1553 closure = g_slice_new0 (EMailReaderClosure);
1554 closure->activity = activity;
1555 closure->reader = g_object_ref (reader);
1556 closure->message_uid = g_strdup (message_uid);
1557
1558 folder = e_mail_reader_ref_folder (reader);
1559
1560 camel_folder_get_message (
1561 folder, message_uid, G_PRIORITY_DEFAULT,
1562 cancellable, (GAsyncReadyCallback)
1563 mail_reader_redirect_cb, closure);
1564
1565 g_clear_object (&folder);
1566 }
1567
1568 static void
action_mail_reply_all_check(CamelFolder * folder,GAsyncResult * result,EMailReaderClosure * closure)1569 action_mail_reply_all_check (CamelFolder *folder,
1570 GAsyncResult *result,
1571 EMailReaderClosure *closure)
1572 {
1573 EAlertSink *alert_sink;
1574 CamelMimeMessage *message;
1575 CamelInternetAddress *to, *cc;
1576 gint recip_count = 0;
1577 EMailReplyType type = E_MAIL_REPLY_TO_ALL;
1578 GError *error = NULL;
1579
1580 alert_sink = e_activity_get_alert_sink (closure->activity);
1581
1582 message = camel_folder_get_message_finish (folder, result, &error);
1583
1584 if (e_activity_handle_cancellation (closure->activity, error)) {
1585 g_warn_if_fail (message == NULL);
1586 mail_reader_closure_free (closure);
1587 g_error_free (error);
1588 return;
1589
1590 } else if (error != NULL) {
1591 g_warn_if_fail (message == NULL);
1592 e_alert_submit (
1593 alert_sink, "mail:no-retrieve-message",
1594 error->message, NULL);
1595 mail_reader_closure_free (closure);
1596 g_error_free (error);
1597 return;
1598 }
1599
1600 g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1601
1602 to = camel_mime_message_get_recipients (
1603 message, CAMEL_RECIPIENT_TYPE_TO);
1604 cc = camel_mime_message_get_recipients (
1605 message, CAMEL_RECIPIENT_TYPE_CC);
1606
1607 recip_count = camel_address_length (CAMEL_ADDRESS (to));
1608 recip_count += camel_address_length (CAMEL_ADDRESS (cc));
1609
1610 if (recip_count >= 15) {
1611 GtkWidget *dialog;
1612 GtkWidget *check;
1613 GtkWidget *container;
1614 gint response;
1615
1616 dialog = e_alert_dialog_new_for_args (
1617 e_mail_reader_get_window (closure->reader),
1618 "mail:ask-reply-many-recips", NULL);
1619
1620 container = e_alert_dialog_get_content_area (
1621 E_ALERT_DIALOG (dialog));
1622
1623 /* Check buttons */
1624 check = gtk_check_button_new_with_mnemonic (
1625 _("_Do not ask me again."));
1626 gtk_box_pack_start (
1627 GTK_BOX (container), check, FALSE, FALSE, 0);
1628 gtk_widget_show (check);
1629
1630 response = gtk_dialog_run (GTK_DIALOG (dialog));
1631
1632 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check))) {
1633 GSettings *settings;
1634 const gchar *key;
1635
1636 settings = e_util_ref_settings ("org.gnome.evolution.mail");
1637
1638 key = "prompt-on-reply-many-recips";
1639 g_settings_set_boolean (settings, key, FALSE);
1640
1641 g_object_unref (settings);
1642 }
1643
1644 gtk_widget_destroy (dialog);
1645
1646 switch (response) {
1647 case GTK_RESPONSE_NO:
1648 type = E_MAIL_REPLY_TO_SENDER;
1649 break;
1650 case GTK_RESPONSE_CANCEL:
1651 case GTK_RESPONSE_DELETE_EVENT:
1652 goto exit;
1653 default:
1654 break;
1655 }
1656 }
1657
1658 e_mail_reader_reply_to_message (closure->reader, message, type);
1659
1660 exit:
1661 g_object_unref (message);
1662
1663 mail_reader_closure_free (closure);
1664 }
1665
1666 static void
action_mail_reply_all_cb(GtkAction * action,EMailReader * reader)1667 action_mail_reply_all_cb (GtkAction *action,
1668 EMailReader *reader)
1669 {
1670 GSettings *settings;
1671 const gchar *key;
1672 guint32 state;
1673 gboolean ask;
1674
1675 state = e_mail_reader_check_state (reader);
1676
1677 settings = e_util_ref_settings ("org.gnome.evolution.mail");
1678
1679 key = "prompt-on-reply-many-recips";
1680 ask = g_settings_get_boolean (settings, key);
1681
1682 g_object_unref (settings);
1683
1684 if (ask && !(state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
1685 EActivity *activity;
1686 GCancellable *cancellable;
1687 EMailReaderClosure *closure;
1688 CamelFolder *folder;
1689 GtkWidget *message_list;
1690 const gchar *message_uid;
1691
1692 message_list = e_mail_reader_get_message_list (reader);
1693 message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1694 g_return_if_fail (message_uid != NULL);
1695
1696 activity = e_mail_reader_new_activity (reader);
1697 cancellable = e_activity_get_cancellable (activity);
1698
1699 closure = g_slice_new0 (EMailReaderClosure);
1700 closure->activity = activity;
1701 closure->reader = g_object_ref (reader);
1702
1703 folder = e_mail_reader_ref_folder (reader);
1704
1705 camel_folder_get_message (
1706 folder, message_uid, G_PRIORITY_DEFAULT,
1707 cancellable, (GAsyncReadyCallback)
1708 action_mail_reply_all_check, closure);
1709
1710 g_clear_object (&folder);
1711
1712 return;
1713 }
1714
1715 e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_ALL);
1716 }
1717
1718 static void
action_mail_reply_alternative_got_message(GObject * source_object,GAsyncResult * result,gpointer user_data)1719 action_mail_reply_alternative_got_message (GObject *source_object,
1720 GAsyncResult *result,
1721 gpointer user_data)
1722 {
1723 EMailReaderClosure *closure = user_data;
1724 EAlertSink *alert_sink;
1725 CamelMimeMessage *message;
1726 gboolean is_selection;
1727 CamelFolder *folder = NULL;
1728 const gchar *message_uid = NULL;
1729 EMailPartList *part_list = NULL;
1730 EMailPartValidityFlags validity_pgp_sum = 0;
1731 EMailPartValidityFlags validity_smime_sum = 0;
1732 GError *error = NULL;
1733
1734 alert_sink = e_activity_get_alert_sink (closure->activity);
1735
1736 message = e_mail_reader_utils_get_selection_or_message_finish (E_MAIL_READER (source_object), result,
1737 &is_selection, &folder, &message_uid, &part_list, &validity_pgp_sum, &validity_smime_sum, &error);
1738
1739 if (e_activity_handle_cancellation (closure->activity, error)) {
1740 g_warn_if_fail (message == NULL);
1741 mail_reader_closure_free (closure);
1742 g_error_free (error);
1743 return;
1744
1745 } else if (error != NULL) {
1746 g_warn_if_fail (message == NULL);
1747 e_alert_submit (
1748 alert_sink, "mail:no-retrieve-message",
1749 error->message, NULL);
1750 mail_reader_closure_free (closure);
1751 g_error_free (error);
1752 return;
1753 }
1754
1755 g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
1756
1757 g_clear_object (&closure->activity);
1758
1759 em_utils_reply_alternative (e_mail_reader_get_window (closure->reader),
1760 e_shell_backend_get_shell (E_SHELL_BACKEND (e_mail_reader_get_backend (closure->reader))),
1761 alert_sink, message, folder, message_uid,
1762 e_mail_reader_get_reply_style (closure->reader),
1763 is_selection ? NULL : part_list, validity_pgp_sum, validity_smime_sum);
1764
1765 mail_reader_closure_free (closure);
1766 camel_pstring_free (message_uid);
1767 g_clear_object (&message);
1768 g_clear_object (&folder);
1769 g_clear_object (&part_list);
1770 g_clear_error (&error);
1771 }
1772
1773 static void
action_mail_reply_alternative_cb(GtkAction * action,EMailReader * reader)1774 action_mail_reply_alternative_cb (GtkAction *action,
1775 EMailReader *reader)
1776 {
1777 EActivity *activity;
1778 GCancellable *cancellable;
1779 EMailReaderClosure *closure;
1780 GtkWidget *message_list;
1781 const gchar *message_uid;
1782
1783 message_list = e_mail_reader_get_message_list (reader);
1784 message_uid = MESSAGE_LIST (message_list)->cursor_uid;
1785 g_return_if_fail (message_uid != NULL);
1786
1787 activity = e_mail_reader_new_activity (reader);
1788 cancellable = e_activity_get_cancellable (activity);
1789
1790 closure = g_slice_new0 (EMailReaderClosure);
1791 closure->activity = activity;
1792 closure->reader = g_object_ref (reader);
1793
1794 e_mail_reader_utils_get_selection_or_message (reader, NULL, cancellable,
1795 action_mail_reply_alternative_got_message, closure);
1796 }
1797
1798 static void
action_mail_reply_group_cb(GtkAction * action,EMailReader * reader)1799 action_mail_reply_group_cb (GtkAction *action,
1800 EMailReader *reader)
1801 {
1802 GSettings *settings;
1803 gboolean reply_list;
1804 guint32 state;
1805 const gchar *key;
1806
1807 state = e_mail_reader_check_state (reader);
1808
1809 settings = e_util_ref_settings ("org.gnome.evolution.mail");
1810
1811 key = "composer-group-reply-to-list";
1812 reply_list = g_settings_get_boolean (settings, key);
1813
1814 g_object_unref (settings);
1815
1816 if (reply_list && (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
1817 e_mail_reader_reply_to_message (
1818 reader, NULL, E_MAIL_REPLY_TO_LIST);
1819 } else
1820 action_mail_reply_all_cb (action, reader);
1821 }
1822
1823 static void
action_mail_reply_list_cb(GtkAction * action,EMailReader * reader)1824 action_mail_reply_list_cb (GtkAction *action,
1825 EMailReader *reader)
1826 {
1827 e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_LIST);
1828 }
1829
1830 static gboolean
message_is_list_administrative(CamelMimeMessage * message)1831 message_is_list_administrative (CamelMimeMessage *message)
1832 {
1833 const gchar *header;
1834
1835 header = camel_medium_get_header (
1836 CAMEL_MEDIUM (message), "X-List-Administrivia");
1837 if (header == NULL)
1838 return FALSE;
1839
1840 while (*header == ' ' || *header == '\t')
1841 header++;
1842
1843 return g_ascii_strncasecmp (header, "yes", 3) == 0;
1844 }
1845
1846 static void
action_mail_reply_sender_check(CamelFolder * folder,GAsyncResult * result,EMailReaderClosure * closure)1847 action_mail_reply_sender_check (CamelFolder *folder,
1848 GAsyncResult *result,
1849 EMailReaderClosure *closure)
1850 {
1851 EAlertSink *alert_sink;
1852 CamelMimeMessage *message;
1853 EMailReplyType type = E_MAIL_REPLY_TO_SENDER;
1854 GSettings *settings;
1855 gboolean ask_ignore_list_reply_to;
1856 gboolean ask_list_reply_to;
1857 gboolean munged_list_message;
1858 gboolean active;
1859 const gchar *key;
1860 GError *local_error = NULL;
1861
1862 alert_sink = e_activity_get_alert_sink (closure->activity);
1863
1864 message = camel_folder_get_message_finish (
1865 folder, result, &local_error);
1866
1867 /* Sanity check. */
1868 g_return_if_fail (
1869 ((message != NULL) && (local_error == NULL)) ||
1870 ((message == NULL) && (local_error != NULL)));
1871
1872 if (e_activity_handle_cancellation (closure->activity, local_error)) {
1873 mail_reader_closure_free (closure);
1874 g_error_free (local_error);
1875 return;
1876
1877 } else if (local_error != NULL) {
1878 e_alert_submit (
1879 alert_sink, "mail:no-retrieve-message",
1880 local_error->message, NULL);
1881 mail_reader_closure_free (closure);
1882 g_error_free (local_error);
1883 return;
1884 }
1885
1886 settings = e_util_ref_settings ("org.gnome.evolution.mail");
1887
1888 key = "composer-ignore-list-reply-to";
1889 ask_ignore_list_reply_to = g_settings_get_boolean (settings, key);
1890
1891 key = "prompt-on-list-reply-to";
1892 ask_list_reply_to = g_settings_get_boolean (settings, key);
1893
1894 munged_list_message = em_utils_is_munged_list_message (message);
1895
1896 if (message_is_list_administrative (message)) {
1897 /* Do not ask for messages which are list administrative,
1898 * like list confirmation messages. */
1899 } else if (ask_ignore_list_reply_to || !munged_list_message) {
1900 /* Don't do the "Are you sure you want to reply in private?"
1901 * pop-up if it's a Reply-To: munged list message... unless
1902 * we're ignoring munging. */
1903 GtkWidget *dialog;
1904 GtkWidget *check;
1905 GtkWidget *container;
1906 gint response;
1907
1908 dialog = e_alert_dialog_new_for_args (
1909 e_mail_reader_get_window (closure->reader),
1910 "mail:ask-list-private-reply", NULL);
1911
1912 container = e_alert_dialog_get_content_area (
1913 E_ALERT_DIALOG (dialog));
1914
1915 /* Check buttons */
1916 check = gtk_check_button_new_with_mnemonic (
1917 _("_Do not ask me again."));
1918 gtk_box_pack_start (
1919 GTK_BOX (container), check, FALSE, FALSE, 0);
1920 gtk_widget_show (check);
1921
1922 response = gtk_dialog_run (GTK_DIALOG (dialog));
1923
1924 active = gtk_toggle_button_get_active (
1925 GTK_TOGGLE_BUTTON (check));
1926 if (active) {
1927 key = "prompt-on-private-list-reply";
1928 g_settings_set_boolean (settings, key, FALSE);
1929 }
1930
1931 gtk_widget_destroy (dialog);
1932
1933 if (response == GTK_RESPONSE_YES)
1934 type = E_MAIL_REPLY_TO_ALL;
1935 else if (response == GTK_RESPONSE_OK)
1936 type = E_MAIL_REPLY_TO_LIST;
1937 else if (response == GTK_RESPONSE_CANCEL ||
1938 response == GTK_RESPONSE_DELETE_EVENT) {
1939 goto exit;
1940 }
1941
1942 } else if (ask_list_reply_to) {
1943 GtkWidget *dialog;
1944 GtkWidget *container;
1945 GtkWidget *check_again;
1946 GtkWidget *check_always_ignore;
1947 gint response;
1948
1949 dialog = e_alert_dialog_new_for_args (
1950 e_mail_reader_get_window (closure->reader),
1951 "mail:ask-list-honour-reply-to", NULL);
1952
1953 container = e_alert_dialog_get_content_area (
1954 E_ALERT_DIALOG (dialog));
1955
1956 check_again = gtk_check_button_new_with_mnemonic (
1957 _("_Do not ask me again."));
1958 gtk_box_pack_start (
1959 GTK_BOX (container), check_again, FALSE, FALSE, 0);
1960 gtk_widget_show (check_again);
1961
1962 check_always_ignore = gtk_check_button_new_with_mnemonic (
1963 _("_Always ignore Reply-To: for mailing lists."));
1964 gtk_box_pack_start (
1965 GTK_BOX (container), check_always_ignore,
1966 FALSE, FALSE, 0);
1967 gtk_widget_show (check_always_ignore);
1968
1969 response = gtk_dialog_run (GTK_DIALOG (dialog));
1970
1971 active = gtk_toggle_button_get_active (
1972 GTK_TOGGLE_BUTTON (check_again));
1973 if (active) {
1974 key = "prompt-on-list-reply-to";
1975 g_settings_set_boolean (settings, key, FALSE);
1976 }
1977
1978 key = "composer-ignore-list-reply-to";
1979 active = gtk_toggle_button_get_active (
1980 GTK_TOGGLE_BUTTON (check_always_ignore));
1981 g_settings_set_boolean (settings, key, active);
1982
1983 gtk_widget_destroy (dialog);
1984
1985 switch (response) {
1986 case GTK_RESPONSE_NO:
1987 type = E_MAIL_REPLY_TO_FROM;
1988 break;
1989 case GTK_RESPONSE_OK:
1990 type = E_MAIL_REPLY_TO_LIST;
1991 break;
1992 case GTK_RESPONSE_CANCEL:
1993 case GTK_RESPONSE_DELETE_EVENT:
1994 goto exit;
1995 default:
1996 break;
1997 }
1998 }
1999
2000 e_mail_reader_reply_to_message (closure->reader, message, type);
2001
2002 exit:
2003 g_object_unref (settings);
2004 g_object_unref (message);
2005
2006 mail_reader_closure_free (closure);
2007 }
2008
2009 static void
action_mail_reply_sender_cb(GtkAction * action,EMailReader * reader)2010 action_mail_reply_sender_cb (GtkAction *action,
2011 EMailReader *reader)
2012 {
2013 GSettings *settings;
2014 gboolean ask_list_reply_to;
2015 gboolean ask_private_list_reply;
2016 gboolean ask;
2017 guint32 state;
2018 const gchar *key;
2019
2020 state = e_mail_reader_check_state (reader);
2021
2022 settings = e_util_ref_settings ("org.gnome.evolution.mail");
2023
2024 key = "prompt-on-list-reply-to";
2025 ask_list_reply_to = g_settings_get_boolean (settings, key);
2026
2027 key = "prompt-on-private-list-reply";
2028 ask_private_list_reply = g_settings_get_boolean (settings, key);
2029
2030 g_object_unref (settings);
2031
2032 ask = (ask_private_list_reply || ask_list_reply_to);
2033
2034 if (ask && (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST)) {
2035 EActivity *activity;
2036 GCancellable *cancellable;
2037 EMailReaderClosure *closure;
2038 CamelFolder *folder;
2039 GtkWidget *message_list;
2040 const gchar *message_uid;
2041
2042 message_list = e_mail_reader_get_message_list (reader);
2043 message_uid = MESSAGE_LIST (message_list)->cursor_uid;
2044 g_return_if_fail (message_uid != NULL);
2045
2046 activity = e_mail_reader_new_activity (reader);
2047 cancellable = e_activity_get_cancellable (activity);
2048
2049 closure = g_slice_new0 (EMailReaderClosure);
2050 closure->activity = activity;
2051 closure->reader = g_object_ref (reader);
2052
2053 folder = e_mail_reader_ref_folder (reader);
2054
2055 camel_folder_get_message (
2056 folder, message_uid, G_PRIORITY_DEFAULT,
2057 cancellable, (GAsyncReadyCallback)
2058 action_mail_reply_sender_check, closure);
2059
2060 g_clear_object (&folder);
2061
2062 return;
2063 }
2064
2065 e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_SENDER);
2066 }
2067
2068 static void
action_mail_reply_recipient_cb(GtkAction * action,EMailReader * reader)2069 action_mail_reply_recipient_cb (GtkAction *action,
2070 EMailReader *reader)
2071 {
2072 e_mail_reader_reply_to_message (reader, NULL, E_MAIL_REPLY_TO_RECIPIENT);
2073 }
2074
2075 static void
action_mail_save_as_cb(GtkAction * action,EMailReader * reader)2076 action_mail_save_as_cb (GtkAction *action,
2077 EMailReader *reader)
2078 {
2079 e_mail_reader_save_messages (reader);
2080 }
2081
2082 static void
action_mail_search_folder_from_mailing_list_cb(GtkAction * action,EMailReader * reader)2083 action_mail_search_folder_from_mailing_list_cb (GtkAction *action,
2084 EMailReader *reader)
2085 {
2086 e_mail_reader_create_vfolder_from_selected (reader, AUTO_MLIST);
2087 }
2088
2089 static void
action_mail_search_folder_from_recipients_cb(GtkAction * action,EMailReader * reader)2090 action_mail_search_folder_from_recipients_cb (GtkAction *action,
2091 EMailReader *reader)
2092 {
2093 e_mail_reader_create_vfolder_from_selected (reader, AUTO_TO);
2094 }
2095
2096 static void
action_mail_search_folder_from_sender_cb(GtkAction * action,EMailReader * reader)2097 action_mail_search_folder_from_sender_cb (GtkAction *action,
2098 EMailReader *reader)
2099 {
2100 e_mail_reader_create_vfolder_from_selected (reader, AUTO_FROM);
2101 }
2102
2103 static void
action_mail_search_folder_from_subject_cb(GtkAction * action,EMailReader * reader)2104 action_mail_search_folder_from_subject_cb (GtkAction *action,
2105 EMailReader *reader)
2106 {
2107 e_mail_reader_create_vfolder_from_selected (reader, AUTO_SUBJECT);
2108 }
2109
2110 static void
action_mail_show_all_headers_cb(GtkToggleAction * action,EMailReader * reader)2111 action_mail_show_all_headers_cb (GtkToggleAction *action,
2112 EMailReader *reader)
2113 {
2114 EMailDisplay *display;
2115 EMailFormatterMode mode;
2116
2117 display = e_mail_reader_get_mail_display (reader);
2118
2119 /* Ignore action when viewing message source. */
2120 mode = e_mail_display_get_mode (display);
2121 if (mode == E_MAIL_FORMATTER_MODE_SOURCE)
2122 return;
2123 if (mode == E_MAIL_FORMATTER_MODE_RAW)
2124 return;
2125
2126 if (gtk_toggle_action_get_active (action))
2127 mode = E_MAIL_FORMATTER_MODE_ALL_HEADERS;
2128 else
2129 mode = E_MAIL_FORMATTER_MODE_NORMAL;
2130
2131 e_mail_display_set_mode (display, mode);
2132 }
2133
2134 static void
mail_source_retrieved(GObject * source_object,GAsyncResult * result,gpointer user_data)2135 mail_source_retrieved (GObject *source_object,
2136 GAsyncResult *result,
2137 gpointer user_data)
2138 {
2139 EMailReaderClosure *closure;
2140 CamelMimeMessage *message;
2141 EMailDisplay *display;
2142 GError *error = NULL;
2143
2144 closure = (EMailReaderClosure *) user_data;
2145 display = e_mail_reader_get_mail_display (closure->reader);
2146
2147 message = camel_folder_get_message_finish (
2148 CAMEL_FOLDER (source_object), result, &error);
2149
2150 /* Sanity check. */
2151 g_return_if_fail (
2152 ((message != NULL) && (error == NULL)) ||
2153 ((message == NULL) && (error != NULL)));
2154
2155 if (message != NULL) {
2156 mail_reader_set_display_formatter_for_message (
2157 closure->reader, display,
2158 closure->message_uid, message,
2159 CAMEL_FOLDER (source_object));
2160 g_object_unref (message);
2161 } else if (error) {
2162 if (display) {
2163 gchar *status;
2164
2165 status = g_strdup_printf (
2166 "%s<br>%s",
2167 _("Failed to retrieve message:"),
2168 error->message);
2169 e_mail_display_set_status (display, status);
2170 g_free (status);
2171 }
2172
2173 g_error_free (error);
2174 }
2175
2176 e_activity_set_state (closure->activity, E_ACTIVITY_COMPLETED);
2177
2178 mail_reader_closure_free (closure);
2179 }
2180
2181 static void
action_mail_show_source_cb(GtkAction * action,EMailReader * reader)2182 action_mail_show_source_cb (GtkAction *action,
2183 EMailReader *reader)
2184 {
2185 EMailDisplay *display;
2186 EMailBackend *backend;
2187 GtkWidget *browser;
2188 CamelFolder *folder;
2189 GPtrArray *uids;
2190 const gchar *message_uid;
2191 gchar *string;
2192 EActivity *activity;
2193 GCancellable *cancellable;
2194 EMailReaderClosure *closure;
2195 MessageList *ml;
2196
2197 backend = e_mail_reader_get_backend (reader);
2198 folder = e_mail_reader_ref_folder (reader);
2199 uids = e_mail_reader_get_selected_uids (reader);
2200 g_return_if_fail (uids != NULL && uids->len == 1);
2201 message_uid = g_ptr_array_index (uids, 0);
2202
2203 if (!E_IS_MAIL_BROWSER (e_mail_reader_get_window (reader))) {
2204 EMailBrowser *mail_browser;
2205
2206 mail_browser = em_utils_find_message_window (E_MAIL_FORMATTER_MODE_SOURCE, folder, message_uid);
2207
2208 if (mail_browser) {
2209 gtk_window_present (GTK_WINDOW (mail_browser));
2210 g_ptr_array_unref (uids);
2211 g_clear_object (&folder);
2212 return;
2213 }
2214 }
2215
2216 browser = e_mail_browser_new (backend, E_MAIL_FORMATTER_MODE_SOURCE);
2217 ml = MESSAGE_LIST (e_mail_reader_get_message_list (E_MAIL_READER (browser)));
2218
2219 message_list_freeze (ml);
2220 e_mail_reader_set_folder (E_MAIL_READER (browser), folder);
2221 e_mail_reader_set_message (E_MAIL_READER (browser), message_uid);
2222 message_list_thaw (ml);
2223
2224 display = e_mail_reader_get_mail_display (E_MAIL_READER (browser));
2225
2226 string = g_strdup_printf (_("Retrieving message “%s”"), message_uid);
2227 e_mail_display_set_part_list (display, NULL);
2228 e_mail_display_set_status (display, string);
2229 gtk_widget_show (browser);
2230
2231 activity = e_mail_reader_new_activity (E_MAIL_READER (browser));
2232 e_activity_set_text (activity, string);
2233 cancellable = e_activity_get_cancellable (activity);
2234 g_free (string);
2235
2236 closure = g_slice_new0 (EMailReaderClosure);
2237 closure->reader = E_MAIL_READER (g_object_ref (browser));
2238 closure->activity = g_object_ref (activity);
2239 closure->message_uid = g_strdup (message_uid);
2240
2241 camel_folder_get_message (
2242 folder, message_uid, G_PRIORITY_DEFAULT,
2243 cancellable, mail_source_retrieved, closure);
2244
2245 g_object_unref (activity);
2246
2247 g_ptr_array_unref (uids);
2248
2249 g_clear_object (&folder);
2250 }
2251
2252 static void
action_mail_toggle_important_cb(GtkAction * action,EMailReader * reader)2253 action_mail_toggle_important_cb (GtkAction *action,
2254 EMailReader *reader)
2255 {
2256 CamelFolder *folder;
2257 GPtrArray *uids;
2258 guint ii;
2259
2260 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
2261 if (!uids)
2262 return;
2263
2264 folder = e_mail_reader_ref_folder (reader);
2265
2266 camel_folder_freeze (folder);
2267
2268 for (ii = 0; ii < uids->len; ii++) {
2269 guint32 flags;
2270
2271 flags = camel_folder_get_message_flags (
2272 folder, uids->pdata[ii]);
2273 flags ^= CAMEL_MESSAGE_FLAGGED;
2274 if (flags & CAMEL_MESSAGE_FLAGGED)
2275 flags &= ~CAMEL_MESSAGE_DELETED;
2276
2277 camel_folder_set_message_flags (
2278 folder, uids->pdata[ii], CAMEL_MESSAGE_FLAGGED |
2279 CAMEL_MESSAGE_DELETED, flags);
2280 }
2281
2282 camel_folder_thaw (folder);
2283
2284 g_clear_object (&folder);
2285 g_ptr_array_unref (uids);
2286 }
2287
2288 static void
action_mail_undelete_cb(GtkAction * action,EMailReader * reader)2289 action_mail_undelete_cb (GtkAction *action,
2290 EMailReader *reader)
2291 {
2292 guint32 mask = CAMEL_MESSAGE_DELETED;
2293 guint32 set = 0;
2294
2295 e_mail_reader_mark_selected (reader, mask, set);
2296 }
2297
2298 static void
action_mail_zoom_100_cb(GtkAction * action,EMailReader * reader)2299 action_mail_zoom_100_cb (GtkAction *action,
2300 EMailReader *reader)
2301 {
2302 EMailDisplay *display;
2303
2304 display = e_mail_reader_get_mail_display (reader);
2305
2306 e_web_view_zoom_100 (E_WEB_VIEW (display));
2307 }
2308
2309 static void
action_mail_zoom_in_cb(GtkAction * action,EMailReader * reader)2310 action_mail_zoom_in_cb (GtkAction *action,
2311 EMailReader *reader)
2312 {
2313 EMailDisplay *display;
2314
2315 display = e_mail_reader_get_mail_display (reader);
2316
2317 e_web_view_zoom_in (E_WEB_VIEW (display));
2318 }
2319
2320 static void
action_mail_zoom_out_cb(GtkAction * action,EMailReader * reader)2321 action_mail_zoom_out_cb (GtkAction *action,
2322 EMailReader *reader)
2323 {
2324 EMailDisplay *display;
2325
2326 display = e_mail_reader_get_mail_display (reader);
2327
2328 e_web_view_zoom_out (E_WEB_VIEW (display));
2329 }
2330
2331 static void
action_mail_search_web_cb(GtkAction * action,EMailReader * reader)2332 action_mail_search_web_cb (GtkAction *action,
2333 EMailReader *reader)
2334 {
2335 EMailDisplay *display;
2336 GtkAction *wv_action;
2337
2338 display = e_mail_reader_get_mail_display (reader);
2339 wv_action = e_web_view_get_action (E_WEB_VIEW (display), "search-web");
2340
2341 gtk_action_activate (wv_action);
2342 }
2343
2344 static void
action_search_folder_recipient_cb(GtkAction * action,EMailReader * reader)2345 action_search_folder_recipient_cb (GtkAction *action,
2346 EMailReader *reader)
2347 {
2348 EMailBackend *backend;
2349 EMailSession *session;
2350 EWebView *web_view;
2351 CamelURL *curl;
2352 const gchar *uri;
2353
2354 /* This action is defined in EMailDisplay. */
2355
2356 web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
2357
2358 uri = e_web_view_get_selected_uri (web_view);
2359 g_return_if_fail (uri != NULL);
2360
2361 curl = camel_url_new (uri, NULL);
2362 g_return_if_fail (curl != NULL);
2363
2364 backend = e_mail_reader_get_backend (reader);
2365 session = e_mail_backend_get_session (backend);
2366
2367 if (curl->path != NULL && *curl->path != '\0') {
2368 CamelFolder *folder;
2369 CamelInternetAddress *inet_addr;
2370
2371 folder = e_mail_reader_ref_folder (reader);
2372
2373 inet_addr = camel_internet_address_new ();
2374 camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
2375 vfolder_gui_add_from_address (
2376 session, inet_addr, AUTO_TO, folder);
2377 g_object_unref (inet_addr);
2378
2379 g_clear_object (&folder);
2380 }
2381
2382 camel_url_free (curl);
2383 }
2384
2385 static void
action_search_folder_sender_cb(GtkAction * action,EMailReader * reader)2386 action_search_folder_sender_cb (GtkAction *action,
2387 EMailReader *reader)
2388 {
2389 EMailBackend *backend;
2390 EMailSession *session;
2391 EWebView *web_view;
2392 CamelURL *curl;
2393 const gchar *uri;
2394
2395 /* This action is defined in EMailDisplay. */
2396
2397 web_view = E_WEB_VIEW (e_mail_reader_get_mail_display (reader));
2398
2399 uri = e_web_view_get_selected_uri (web_view);
2400 g_return_if_fail (uri != NULL);
2401
2402 curl = camel_url_new (uri, NULL);
2403 g_return_if_fail (curl != NULL);
2404
2405 backend = e_mail_reader_get_backend (reader);
2406 session = e_mail_backend_get_session (backend);
2407
2408 if (curl->path != NULL && *curl->path != '\0') {
2409 CamelFolder *folder;
2410 CamelInternetAddress *inet_addr;
2411
2412 folder = e_mail_reader_ref_folder (reader);
2413
2414 inet_addr = camel_internet_address_new ();
2415 camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
2416 vfolder_gui_add_from_address (
2417 session, inet_addr, AUTO_FROM, folder);
2418 g_object_unref (inet_addr);
2419
2420 g_clear_object (&folder);
2421 }
2422
2423 camel_url_free (curl);
2424 }
2425
2426 static GtkActionEntry mail_reader_entries[] = {
2427
2428 { "mail-add-sender",
2429 NULL,
2430 N_("A_dd Sender to Address Book"),
2431 NULL,
2432 N_("Add sender to address book"),
2433 G_CALLBACK (action_mail_add_sender_cb) },
2434
2435 { "mail-archive",
2436 "mail-archive",
2437 N_("_Archive…"),
2438 "<Alt><Control>a",
2439 N_("Move selected messages to the Archive folder for the account"),
2440 G_CALLBACK (action_mail_archive_cb) },
2441
2442 { "mail-check-for-junk",
2443 "mail-mark-junk",
2444 N_("Check for _Junk"),
2445 "<Control><Alt>j",
2446 N_("Filter the selected messages for junk status"),
2447 G_CALLBACK (action_mail_check_for_junk_cb) },
2448
2449 { "mail-color-assign",
2450 NULL,
2451 N_("Assign C_olor…"),
2452 NULL,
2453 N_("Assign color for the selected messages"),
2454 G_CALLBACK (action_mail_color_assign_cb) },
2455
2456 { "mail-color-unset",
2457 NULL,
2458 N_("Unse_t Color"),
2459 NULL,
2460 N_("Unset color for the selected messages"),
2461 G_CALLBACK (action_mail_color_unset_cb) },
2462
2463 { "mail-copy",
2464 "mail-copy",
2465 N_("_Copy to Folder…"),
2466 "<Shift><Control>y",
2467 N_("Copy selected messages to another folder"),
2468 G_CALLBACK (action_mail_copy_cb) },
2469
2470 { "mail-delete",
2471 "user-trash",
2472 N_("_Delete Message"),
2473 "<Control>d",
2474 N_("Mark the selected messages for deletion"),
2475 G_CALLBACK (action_mail_delete_cb) },
2476
2477 { "mail-add-note",
2478 "evolution-memos",
2479 N_("_Add note…"),
2480 NULL,
2481 N_("Add a note for the selected message"),
2482 G_CALLBACK (action_mail_edit_note_cb) },
2483
2484 { "mail-delete-note",
2485 NULL,
2486 N_("Delete no_te"),
2487 NULL,
2488 N_("Delete the note for the selected message"),
2489 G_CALLBACK (action_mail_delete_note_cb) },
2490
2491 { "mail-edit-note",
2492 "evolution-memos",
2493 N_("_Edit note…"),
2494 NULL,
2495 N_("Edit a note for the selected message"),
2496 G_CALLBACK (action_mail_edit_note_cb) },
2497
2498 { "mail-filter-rule-for-mailing-list",
2499 NULL,
2500 N_("Create a Filter Rule for Mailing _List…"),
2501 NULL,
2502 N_("Create a rule to filter messages to this mailing list"),
2503 G_CALLBACK (action_mail_filter_on_mailing_list_cb) },
2504
2505 { "mail-filter-rule-for-recipients",
2506 NULL,
2507 N_("Create a Filter Rule for _Recipients…"),
2508 NULL,
2509 N_("Create a rule to filter messages to these recipients"),
2510 G_CALLBACK (action_mail_filter_on_recipients_cb) },
2511
2512 { "mail-filter-rule-for-sender",
2513 NULL,
2514 N_("Create a Filter Rule for Se_nder…"),
2515 NULL,
2516 N_("Create a rule to filter messages from this sender"),
2517 G_CALLBACK (action_mail_filter_on_sender_cb) },
2518
2519 { "mail-filter-rule-for-subject",
2520 NULL,
2521 N_("Create a Filter Rule for _Subject…"),
2522 NULL,
2523 N_("Create a rule to filter messages with this subject"),
2524 G_CALLBACK (action_mail_filter_on_subject_cb) },
2525
2526 { "mail-filters-apply",
2527 "stock_mail-filters-apply",
2528 N_("A_pply Filters"),
2529 "<Control>y",
2530 N_("Apply filter rules to the selected messages"),
2531 G_CALLBACK (action_mail_filters_apply_cb) },
2532
2533 { "mail-find",
2534 "edit-find",
2535 N_("_Find in Message…"),
2536 "<Shift><Control>f",
2537 N_("Search for text in the body of the displayed message"),
2538 G_CALLBACK (action_mail_find_cb) },
2539
2540 { "mail-flag-clear",
2541 NULL,
2542 N_("_Clear Flag"),
2543 NULL,
2544 N_("Remove the follow-up flag from the selected messages"),
2545 G_CALLBACK (action_mail_flag_clear_cb) },
2546
2547 { "mail-flag-completed",
2548 NULL,
2549 N_("_Flag Completed"),
2550 NULL,
2551 N_("Set the follow-up flag to completed on the selected messages"),
2552 G_CALLBACK (action_mail_flag_completed_cb) },
2553
2554 { "mail-flag-for-followup",
2555 "stock_mail-flag-for-followup",
2556 N_("Follow _Up…"),
2557 "<Shift><Control>g",
2558 N_("Flag the selected messages for follow-up"),
2559 G_CALLBACK (action_mail_flag_for_followup_cb) },
2560
2561 { "mail-forward-attached",
2562 NULL,
2563 N_("_Attached"),
2564 NULL,
2565 N_("Forward the selected message to someone as an attachment"),
2566 G_CALLBACK (action_mail_forward_attached_cb) },
2567
2568 { "mail-forward-attached-full",
2569 NULL,
2570 N_("Forward As _Attached"),
2571 NULL,
2572 N_("Forward the selected message to someone as an attachment"),
2573 G_CALLBACK (action_mail_forward_attached_cb) },
2574
2575 { "mail-forward-inline",
2576 NULL,
2577 N_("_Inline"),
2578 NULL,
2579 N_("Forward the selected message in the body of a new message"),
2580 G_CALLBACK (action_mail_forward_inline_cb) },
2581
2582 { "mail-forward-inline-full",
2583 NULL,
2584 N_("Forward As _Inline"),
2585 NULL,
2586 N_("Forward the selected message in the body of a new message"),
2587 G_CALLBACK (action_mail_forward_inline_cb) },
2588
2589 { "mail-forward-quoted",
2590 NULL,
2591 N_("_Quoted"),
2592 NULL,
2593 N_("Forward the selected message quoted like a reply"),
2594 G_CALLBACK (action_mail_forward_quoted_cb) },
2595
2596 { "mail-forward-quoted-full",
2597 NULL,
2598 N_("Forward As _Quoted"),
2599 NULL,
2600 N_("Forward the selected message quoted like a reply"),
2601 G_CALLBACK (action_mail_forward_quoted_cb) },
2602
2603 { "mail-label-new",
2604 NULL,
2605 N_("_New Label"),
2606 NULL,
2607 NULL, /* XXX Add a tooltip! */
2608 G_CALLBACK (action_mail_label_new_cb) },
2609
2610 { "mail-label-none",
2611 NULL,
2612 /* Translators: "None" is used in the message label context menu.
2613 * It removes all labels from the selected messages. */
2614 N_("N_one"),
2615 "0",
2616 NULL, /* XXX Add a tooltip! */
2617 G_CALLBACK (action_mail_label_none_cb) },
2618
2619 { "mail-load-images",
2620 "image-x-generic",
2621 N_("_Load Images"),
2622 "<Control>i",
2623 N_("Force images in HTML mail to be loaded"),
2624 G_CALLBACK (action_mail_load_images_cb) },
2625
2626 { "mail-mark-ignore-thread-sub",
2627 NULL,
2628 N_("_Ignore Subthread"),
2629 NULL,
2630 N_("Mark new mails in a subthread as read automatically"),
2631 G_CALLBACK (action_mail_mark_ignore_thread_sub_cb) },
2632
2633 { "mail-mark-ignore-thread-whole",
2634 NULL,
2635 N_("_Ignore Thread"),
2636 NULL,
2637 N_("Mark new mails in this thread as read automatically"),
2638 G_CALLBACK (action_mail_mark_ignore_thread_whole_cb) },
2639
2640 { "mail-mark-important",
2641 "mail-mark-important",
2642 N_("_Important"),
2643 NULL,
2644 N_("Mark the selected messages as important"),
2645 G_CALLBACK (action_mail_mark_important_cb) },
2646
2647 { "mail-mark-junk",
2648 "mail-mark-junk",
2649 N_("_Junk"),
2650 "<Control>j",
2651 N_("Mark the selected messages as junk"),
2652 G_CALLBACK (action_mail_mark_junk_cb) },
2653
2654 { "mail-mark-notjunk",
2655 "mail-mark-notjunk",
2656 N_("_Not Junk"),
2657 "<Shift><Control>j",
2658 N_("Mark the selected messages as not being junk"),
2659 G_CALLBACK (action_mail_mark_notjunk_cb) },
2660
2661 { "mail-mark-read",
2662 "mail-mark-read",
2663 N_("_Read"),
2664 "<Control>k",
2665 N_("Mark the selected messages as having been read"),
2666 G_CALLBACK (action_mail_mark_read_cb) },
2667
2668 { "mail-mark-unignore-thread-sub",
2669 NULL,
2670 N_("Do not _Ignore Subthread"),
2671 NULL,
2672 N_("Do not mark new mails in a subthread as read automatically"),
2673 G_CALLBACK (action_mail_mark_unignore_thread_sub_cb) },
2674
2675 { "mail-mark-unignore-thread-whole",
2676 NULL,
2677 N_("Do not _Ignore Thread"),
2678 NULL,
2679 N_("Do not mark new mails in this thread as read automatically"),
2680 G_CALLBACK (action_mail_mark_unignore_thread_whole_cb) },
2681
2682 { "mail-mark-unimportant",
2683 NULL,
2684 N_("Uni_mportant"),
2685 NULL,
2686 N_("Mark the selected messages as unimportant"),
2687 G_CALLBACK (action_mail_mark_unimportant_cb) },
2688
2689 { "mail-mark-unread",
2690 "mail-mark-unread",
2691 N_("_Unread"),
2692 "<Shift><Control>k",
2693 N_("Mark the selected messages as not having been read"),
2694 G_CALLBACK (action_mail_mark_unread_cb) },
2695
2696 { "mail-message-edit",
2697 NULL,
2698 N_("_Edit as New Message…"),
2699 NULL,
2700 N_("Open the selected messages in the composer for editing"),
2701 G_CALLBACK (action_mail_message_edit_cb) },
2702
2703 { "mail-message-new",
2704 "mail-message-new",
2705 N_("Compose _New Message"),
2706 "<Shift><Control>m",
2707 N_("Open a window for composing a mail message"),
2708 G_CALLBACK (action_mail_message_new_cb) },
2709
2710 { "mail-message-open",
2711 NULL,
2712 N_("_Open in New Window"),
2713 "<Control>o",
2714 N_("Open the selected messages in a new window"),
2715 G_CALLBACK (action_mail_message_open_cb) },
2716
2717 { "mail-move",
2718 "mail-move",
2719 N_("_Move to Folder…"),
2720 "<Shift><Control>v",
2721 N_("Move selected messages to another folder"),
2722 G_CALLBACK (action_mail_move_cb) },
2723
2724 { "mail-next",
2725 "go-next",
2726 N_("_Next Message"),
2727 "<Control>Page_Down",
2728 N_("Display the next message"),
2729 G_CALLBACK (action_mail_next_cb) },
2730
2731 { "mail-next-important",
2732 NULL,
2733 N_("Next _Important Message"),
2734 NULL,
2735 N_("Display the next important message"),
2736 G_CALLBACK (action_mail_next_important_cb) },
2737
2738 { "mail-next-thread",
2739 NULL,
2740 N_("Next _Thread"),
2741 NULL,
2742 N_("Display the next thread"),
2743 G_CALLBACK (action_mail_next_thread_cb) },
2744
2745 { "mail-next-unread",
2746 "go-jump",
2747 N_("Next _Unread Message"),
2748 "<Control>bracketright",
2749 N_("Display the next unread message"),
2750 G_CALLBACK (action_mail_next_unread_cb) },
2751
2752 { "mail-previous",
2753 "go-previous",
2754 N_("_Previous Message"),
2755 "<Control>Page_Up",
2756 N_("Display the previous message"),
2757 G_CALLBACK (action_mail_previous_cb) },
2758
2759 { "mail-previous-important",
2760 NULL,
2761 N_("Pr_evious Important Message"),
2762 NULL,
2763 N_("Display the previous important message"),
2764 G_CALLBACK (action_mail_previous_important_cb) },
2765
2766 { "mail-previous-thread",
2767 NULL,
2768 N_("Previous T_hread"),
2769 NULL,
2770 N_("Display the previous thread"),
2771 G_CALLBACK (action_mail_previous_thread_cb) },
2772
2773 { "mail-previous-unread",
2774 NULL,
2775 N_("P_revious Unread Message"),
2776 "<Control>bracketleft",
2777 N_("Display the previous unread message"),
2778 G_CALLBACK (action_mail_previous_unread_cb) },
2779
2780 { "mail-print",
2781 "document-print",
2782 N_("_Print…"),
2783 "<Control>p",
2784 N_("Print this message"),
2785 G_CALLBACK (action_mail_print_cb) },
2786
2787 { "mail-print-preview",
2788 "document-print-preview",
2789 N_("Pre_view…"),
2790 NULL,
2791 N_("Preview the message to be printed"),
2792 G_CALLBACK (action_mail_print_preview_cb) },
2793
2794 { "mail-redirect",
2795 NULL,
2796 N_("Re_direct"),
2797 NULL,
2798 N_("Redirect (bounce) the selected message to someone"),
2799 G_CALLBACK (action_mail_redirect_cb) },
2800
2801 { "mail-remove-attachments",
2802 "edit-delete",
2803 N_("Remo_ve Attachments"),
2804 NULL,
2805 N_("Remove attachments"),
2806 G_CALLBACK (action_mail_remove_attachments_cb) },
2807
2808 { "mail-remove-duplicates",
2809 NULL,
2810 N_("Remove Du_plicate Messages"),
2811 NULL,
2812 N_("Checks selected messages for duplicates"),
2813 G_CALLBACK (action_mail_remove_duplicates_cb) },
2814
2815 { "mail-reply-all",
2816 NULL,
2817 N_("Reply to _All"),
2818 "<Shift><Control>r",
2819 N_("Compose a reply to all the recipients of the selected message"),
2820 G_CALLBACK (action_mail_reply_all_cb) },
2821
2822 { "mail-reply-alternative",
2823 NULL,
2824 N_("Al_ternative Reply…"),
2825 "<Alt><Control>r",
2826 N_("Choose reply options for the selected message"),
2827 G_CALLBACK (action_mail_reply_alternative_cb) },
2828
2829 { "mail-reply-list",
2830 NULL,
2831 N_("Reply to _List"),
2832 "<Control>l",
2833 N_("Compose a reply to the mailing list of the selected message"),
2834 G_CALLBACK (action_mail_reply_list_cb) },
2835
2836 { "mail-reply-sender",
2837 "mail-reply-sender",
2838 N_("_Reply to Sender"),
2839 "<Control>r",
2840 N_("Compose a reply to the sender of the selected message"),
2841 G_CALLBACK (action_mail_reply_sender_cb) },
2842
2843 { "mail-reply-template",
2844 NULL,
2845 N_("Repl_y with Template"),
2846 NULL,
2847 NULL,
2848 NULL },
2849
2850 { "mail-save-as",
2851 "document-save-as",
2852 N_("_Save as mbox…"),
2853 "<Control>s",
2854 N_("Save selected messages as an mbox file"),
2855 G_CALLBACK (action_mail_save_as_cb) },
2856
2857 { "mail-search-web",
2858 NULL,
2859 N_("Search _Web…"),
2860 NULL,
2861 N_("Search the Web with the selected text"),
2862 G_CALLBACK (action_mail_search_web_cb) },
2863
2864 { "mail-show-source",
2865 NULL,
2866 N_("_Message Source"),
2867 "<Control>u",
2868 N_("Show the raw email source of the message"),
2869 G_CALLBACK (action_mail_show_source_cb) },
2870
2871 { "mail-toggle-important",
2872 NULL,
2873 NULL, /* No menu item; key press only */
2874 NULL,
2875 NULL,
2876 G_CALLBACK (action_mail_toggle_important_cb) },
2877
2878 { "mail-undelete",
2879 NULL,
2880 N_("_Undelete Message"),
2881 "<Shift><Control>d",
2882 N_("Undelete the selected messages"),
2883 G_CALLBACK (action_mail_undelete_cb) },
2884
2885 { "mail-zoom-100",
2886 "zoom-original",
2887 N_("_Normal Size"),
2888 "<Control>0",
2889 N_("Reset the text to its original size"),
2890 G_CALLBACK (action_mail_zoom_100_cb) },
2891
2892 { "mail-zoom-in",
2893 "zoom-in",
2894 N_("_Zoom In"),
2895 "<Control>plus",
2896 N_("Increase the text size"),
2897 G_CALLBACK (action_mail_zoom_in_cb) },
2898
2899 { "mail-zoom-out",
2900 "zoom-out",
2901 N_("Zoom _Out"),
2902 "<Control>minus",
2903 N_("Decrease the text size"),
2904 G_CALLBACK (action_mail_zoom_out_cb) },
2905
2906 /*** Menus ***/
2907
2908 { "mail-create-menu",
2909 NULL,
2910 N_("Cre_ate"),
2911 NULL,
2912 NULL,
2913 NULL },
2914
2915 { "mail-encoding-menu",
2916 NULL,
2917 N_("Ch_aracter Encoding"),
2918 NULL,
2919 NULL,
2920 NULL },
2921
2922 { "mail-forward-as-menu",
2923 NULL,
2924 N_("F_orward As"),
2925 NULL,
2926 NULL,
2927 NULL },
2928
2929 { "mail-label-menu",
2930 NULL,
2931 N_("_Label"),
2932 NULL,
2933 NULL,
2934 NULL },
2935
2936 { "mail-reply-group-menu",
2937 NULL,
2938 N_("_Group Reply"),
2939 NULL,
2940 NULL,
2941 NULL },
2942
2943 { "mail-goto-menu",
2944 NULL,
2945 N_("_Go To"),
2946 NULL,
2947 NULL,
2948 NULL },
2949
2950 { "mail-mark-as-menu",
2951 NULL,
2952 N_("Mar_k As"),
2953 NULL,
2954 NULL,
2955 NULL },
2956
2957 { "mail-message-menu",
2958 NULL,
2959 N_("_Message"),
2960 NULL,
2961 NULL,
2962 NULL },
2963
2964 { "mail-zoom-menu",
2965 NULL,
2966 N_("_Zoom"),
2967 NULL,
2968 NULL,
2969 NULL }
2970 };
2971
2972 static GtkActionEntry mail_reader_search_folder_entries[] = {
2973
2974 { "mail-search-folder-from-mailing-list",
2975 NULL,
2976 N_("Create a Search Folder from Mailing _List…"),
2977 NULL,
2978 N_("Create a search folder for this mailing list"),
2979 G_CALLBACK (action_mail_search_folder_from_mailing_list_cb) },
2980
2981 { "mail-search-folder-from-recipients",
2982 NULL,
2983 N_("Create a Search Folder from Recipien_ts…"),
2984 NULL,
2985 N_("Create a search folder for these recipients"),
2986 G_CALLBACK (action_mail_search_folder_from_recipients_cb) },
2987
2988 { "mail-search-folder-from-sender",
2989 NULL,
2990 N_("Create a Search Folder from Sen_der…"),
2991 NULL,
2992 N_("Create a search folder for this sender"),
2993 G_CALLBACK (action_mail_search_folder_from_sender_cb) },
2994
2995 { "mail-search-folder-from-subject",
2996 NULL,
2997 N_("Create a Search Folder from S_ubject…"),
2998 NULL,
2999 N_("Create a search folder for this subject"),
3000 G_CALLBACK (action_mail_search_folder_from_subject_cb) },
3001 };
3002
3003 static EPopupActionEntry mail_reader_popup_entries[] = {
3004
3005 { "mail-popup-archive",
3006 NULL,
3007 "mail-archive" },
3008
3009 { "mail-popup-color-assign",
3010 NULL,
3011 "mail-color-assign" },
3012
3013 { "mail-popup-color-unset",
3014 NULL,
3015 "mail-color-unset" },
3016
3017 { "mail-popup-copy",
3018 NULL,
3019 "mail-copy" },
3020
3021 { "mail-popup-delete",
3022 NULL,
3023 "mail-delete" },
3024
3025 { "mail-popup-add-note",
3026 NULL,
3027 "mail-add-note" },
3028
3029 { "mail-popup-delete-note",
3030 NULL,
3031 "mail-delete-note" },
3032
3033 { "mail-popup-edit-note",
3034 NULL,
3035 "mail-edit-note" },
3036
3037 { "mail-popup-flag-clear",
3038 NULL,
3039 "mail-flag-clear" },
3040
3041 { "mail-popup-flag-completed",
3042 NULL,
3043 "mail-flag-completed" },
3044
3045 { "mail-popup-flag-for-followup",
3046 N_("Mark for Follo_w Up…"),
3047 "mail-flag-for-followup" },
3048
3049 { "mail-popup-forward",
3050 NULL,
3051 "mail-forward" },
3052
3053 { "mail-popup-mark-ignore-thread-sub",
3054 N_("_Ignore Subthread"),
3055 "mail-mark-ignore-thread-sub" },
3056
3057 { "mail-popup-mark-ignore-thread-whole",
3058 N_("_Ignore Thread"),
3059 "mail-mark-ignore-thread-whole" },
3060
3061 { "mail-popup-mark-important",
3062 N_("Mark as _Important"),
3063 "mail-mark-important" },
3064
3065 { "mail-popup-mark-junk",
3066 N_("Mark as _Junk"),
3067 "mail-mark-junk" },
3068
3069 { "mail-popup-mark-notjunk",
3070 N_("Mark as _Not Junk"),
3071 "mail-mark-notjunk" },
3072
3073 { "mail-popup-mark-read",
3074 N_("Mar_k as Read"),
3075 "mail-mark-read" },
3076
3077 { "mail-popup-mark-unignore-thread-sub",
3078 N_("Do not _Ignore Subthread"),
3079 "mail-mark-unignore-thread-sub" },
3080
3081 { "mail-popup-mark-unignore-thread-whole",
3082 N_("Do not _Ignore Thread"),
3083 "mail-mark-unignore-thread-whole" },
3084
3085 { "mail-popup-mark-unimportant",
3086 N_("Mark as Uni_mportant"),
3087 "mail-mark-unimportant" },
3088
3089 { "mail-popup-mark-unread",
3090 N_("Mark as _Unread"),
3091 "mail-mark-unread" },
3092
3093 { "mail-popup-message-edit",
3094 NULL,
3095 "mail-message-edit" },
3096
3097 { "mail-popup-move",
3098 NULL,
3099 "mail-move" },
3100
3101 { "mail-popup-print",
3102 NULL,
3103 "mail-print" },
3104
3105 { "mail-popup-remove-attachments",
3106 NULL,
3107 "mail-remove-attachments" },
3108
3109 { "mail-popup-remove-duplicates",
3110 NULL,
3111 "mail-remove-duplicates" },
3112
3113 { "mail-popup-reply-all",
3114 NULL,
3115 "mail-reply-all" },
3116
3117 { "mail-popup-reply-sender",
3118 NULL,
3119 "mail-reply-sender" },
3120
3121 { "mail-popup-reply-template",
3122 NULL,
3123 "mail-reply-template" },
3124
3125 { "mail-popup-save-as",
3126 NULL,
3127 "mail-save-as" },
3128
3129 { "mail-popup-search-web",
3130 NULL,
3131 "mail-search-web" },
3132
3133 { "mail-popup-undelete",
3134 NULL,
3135 "mail-undelete" }
3136 };
3137
3138 static GtkToggleActionEntry mail_reader_toggle_entries[] = {
3139
3140 { "mail-caret-mode",
3141 NULL,
3142 N_("_Caret Mode"),
3143 "F7",
3144 N_("Show a blinking cursor in the body of displayed messages"),
3145 NULL, /* No callback required */
3146 FALSE },
3147
3148 { "mail-show-all-headers",
3149 NULL,
3150 N_("All Message _Headers"),
3151 NULL,
3152 N_("Show messages with all email headers"),
3153 G_CALLBACK (action_mail_show_all_headers_cb),
3154 FALSE }
3155 };
3156
3157 static void
mail_reader_double_click_cb(EMailReader * reader,gint row,ETreePath path,gint col,GdkEvent * event)3158 mail_reader_double_click_cb (EMailReader *reader,
3159 gint row,
3160 ETreePath path,
3161 gint col,
3162 GdkEvent *event)
3163 {
3164 GtkAction *action;
3165
3166 /* Ignore double clicks on columns that handle their own state. */
3167 if (MESSAGE_LIST_COLUMN_IS_ACTIVE (col))
3168 return;
3169
3170 action = e_mail_reader_get_action (reader, "mail-message-open");
3171 gtk_action_activate (action);
3172 }
3173
3174 static gboolean
mail_reader_key_press_event_cb(EMailReader * reader,GdkEventKey * event)3175 mail_reader_key_press_event_cb (EMailReader *reader,
3176 GdkEventKey *event)
3177 {
3178 GtkAction *action;
3179 const gchar *action_name;
3180
3181 if (!gtk_widget_has_focus (GTK_WIDGET (reader))) {
3182 EMailDisplay *display;
3183
3184 display = e_mail_reader_get_mail_display (reader);
3185 if (e_web_view_get_need_input (E_WEB_VIEW (display)) &&
3186 gtk_widget_has_focus (GTK_WIDGET (display)))
3187 return FALSE;
3188 }
3189
3190 if ((event->state & GDK_CONTROL_MASK) != 0)
3191 goto ctrl;
3192
3193 /* <keyval> alone */
3194 switch (event->keyval) {
3195 case GDK_KEY_Delete:
3196 case GDK_KEY_KP_Delete:
3197 action_name = "mail-delete";
3198 break;
3199
3200 case GDK_KEY_Return:
3201 case GDK_KEY_KP_Enter:
3202 case GDK_KEY_ISO_Enter:
3203 if (E_IS_MAIL_BROWSER (reader))
3204 return FALSE;
3205
3206 action_name = "mail-message-open";
3207 break;
3208
3209 case GDK_KEY_period:
3210 case GDK_KEY_bracketright:
3211 action_name = "mail-next-unread";
3212 break;
3213
3214 case GDK_KEY_comma:
3215 case GDK_KEY_bracketleft:
3216 action_name = "mail-previous-unread";
3217 break;
3218
3219 #ifdef HAVE_XFREE
3220 case XF86XK_Reply:
3221 action_name = "mail-reply-all";
3222 break;
3223
3224 case XF86XK_MailForward:
3225 action_name = "mail-forward";
3226 break;
3227 #endif
3228
3229 case GDK_KEY_exclam:
3230 action_name = "mail-toggle-important";
3231 break;
3232
3233 case GDK_KEY_ZoomIn:
3234 action_name = "mail-zoom-in";
3235 break;
3236
3237 case GDK_KEY_ZoomOut:
3238 action_name = "mail-zoom-out";
3239 break;
3240
3241 default:
3242 return FALSE;
3243 }
3244
3245 goto exit;
3246
3247 ctrl:
3248
3249 /* Ctrl + <keyval> */
3250 switch (event->keyval) {
3251 case GDK_KEY_period:
3252 action_name = "mail-next-unread";
3253 break;
3254
3255 case GDK_KEY_comma:
3256 action_name = "mail-previous-unread";
3257 break;
3258
3259 case GDK_KEY_equal:
3260 case GDK_KEY_KP_Add:
3261 action_name = "mail-zoom-in";
3262 break;
3263
3264 case GDK_KEY_KP_Subtract:
3265 action_name = "mail-zoom-out";
3266 break;
3267
3268 default:
3269 return FALSE;
3270 }
3271
3272 exit:
3273 action = e_mail_reader_get_action (reader, action_name);
3274 gtk_action_activate (action);
3275
3276 return TRUE;
3277 }
3278
3279 static gint
mail_reader_key_press_cb(EMailReader * reader,gint row,ETreePath path,gint col,GdkEvent * event)3280 mail_reader_key_press_cb (EMailReader *reader,
3281 gint row,
3282 ETreePath path,
3283 gint col,
3284 GdkEvent *event)
3285 {
3286 return mail_reader_key_press_event_cb (reader, &event->key);
3287 }
3288
3289 static gboolean
mail_reader_message_seen_cb(gpointer user_data)3290 mail_reader_message_seen_cb (gpointer user_data)
3291 {
3292 EMailReaderClosure *closure = user_data;
3293 EMailReader *reader;
3294 GtkWidget *message_list;
3295 EMailPartList *parts;
3296 EMailDisplay *display;
3297 CamelMimeMessage *message;
3298 const gchar *current_uid;
3299 const gchar *message_uid;
3300 gboolean uid_is_current = TRUE;
3301
3302 reader = closure->reader;
3303 message_uid = closure->message_uid;
3304
3305 display = e_mail_reader_get_mail_display (reader);
3306 parts = e_mail_display_get_part_list (display);
3307 message_list = e_mail_reader_get_message_list (reader);
3308
3309 g_return_val_if_fail (IS_MESSAGE_LIST (message_list), FALSE);
3310
3311 /* zero the timeout id now, if it was not rescheduled */
3312 if (g_source_get_id (g_main_current_source ()) == MESSAGE_LIST (message_list)->seen_id)
3313 MESSAGE_LIST (message_list)->seen_id = 0;
3314
3315 if (e_tree_is_dragging (E_TREE (message_list)))
3316 return FALSE;
3317
3318 current_uid = MESSAGE_LIST (message_list)->cursor_uid;
3319 uid_is_current &= (g_strcmp0 (current_uid, message_uid) == 0);
3320
3321 if (parts != NULL)
3322 message = e_mail_part_list_get_message (parts);
3323 else
3324 message = NULL;
3325
3326 if (uid_is_current && message != NULL)
3327 g_signal_emit (
3328 reader, signals[MESSAGE_SEEN], 0,
3329 message_uid, message);
3330
3331 return FALSE;
3332 }
3333
3334 static void
schedule_timeout_mark_seen(EMailReader * reader)3335 schedule_timeout_mark_seen (EMailReader *reader)
3336 {
3337 EMailReaderPrivate *priv;
3338 MessageList *message_list;
3339
3340 g_return_if_fail (E_IS_MAIL_READER (reader));
3341
3342 priv = E_MAIL_READER_GET_PRIVATE (reader);
3343
3344 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
3345 g_return_if_fail (message_list != NULL);
3346
3347 if (message_list->cursor_uid) {
3348 EMailReaderClosure *timeout_closure;
3349
3350 if (message_list->seen_id > 0) {
3351 g_source_remove (message_list->seen_id);
3352 message_list->seen_id = 0;
3353 }
3354
3355 timeout_closure = g_slice_new0 (EMailReaderClosure);
3356 timeout_closure->reader = g_object_ref (reader);
3357 timeout_closure->message_uid = g_strdup (message_list->cursor_uid);
3358
3359 MESSAGE_LIST (message_list)->seen_id =
3360 e_named_timeout_add_full (
3361 G_PRIORITY_DEFAULT, priv->schedule_mark_seen_interval,
3362 mail_reader_message_seen_cb,
3363 timeout_closure, (GDestroyNotify)
3364 mail_reader_closure_free);
3365 }
3366 }
3367
3368 static void
mail_reader_load_changed_cb(EMailReader * reader,WebKitLoadEvent event,EMailDisplay * display)3369 mail_reader_load_changed_cb (EMailReader *reader,
3370 WebKitLoadEvent event,
3371 EMailDisplay *display)
3372 {
3373 EMailReaderPrivate *priv;
3374
3375 if (event != WEBKIT_LOAD_FINISHED)
3376 return;
3377
3378 priv = E_MAIL_READER_GET_PRIVATE (reader);
3379 if (priv->schedule_mark_seen &&
3380 E_IS_MAIL_VIEW (reader) &&
3381 e_mail_display_get_part_list (display) &&
3382 e_mail_view_get_preview_visible (E_MAIL_VIEW (reader))) {
3383 if (priv->folder_was_just_selected)
3384 priv->folder_was_just_selected = FALSE;
3385 else
3386 schedule_timeout_mark_seen (reader);
3387 }
3388 }
3389
3390 static void
mail_reader_remote_content_clicked_cb(EMailReader * reader,const GdkRectangle * position,gpointer user_data)3391 mail_reader_remote_content_clicked_cb (EMailReader *reader,
3392 const GdkRectangle *position,
3393 gpointer user_data)
3394 {
3395 GtkWidget *mail_display = user_data;
3396
3397 g_return_if_fail (E_IS_MAIL_READER (reader));
3398 g_return_if_fail (E_IS_MAIL_DISPLAY (mail_display));
3399
3400 e_mail_remote_content_popover_run (reader, mail_display, position);
3401 }
3402
3403 static void
maybe_schedule_timeout_mark_seen(EMailReader * reader)3404 maybe_schedule_timeout_mark_seen (EMailReader *reader)
3405 {
3406 EMailReaderPrivate *priv;
3407 MessageList *message_list;
3408 gboolean schedule_timeout;
3409 gint timeout_interval = -1;
3410 const gchar *message_uid;
3411
3412 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
3413
3414 message_uid = message_list->cursor_uid;
3415 if (message_uid == NULL ||
3416 e_tree_is_dragging (E_TREE (message_list)))
3417 return;
3418
3419 schedule_timeout =
3420 (message_uid != NULL) &&
3421 e_mail_reader_utils_get_mark_seen_setting (reader, &timeout_interval);
3422
3423 if (message_list->seen_id > 0) {
3424 g_source_remove (message_list->seen_id);
3425 message_list->seen_id = 0;
3426 }
3427
3428 priv = E_MAIL_READER_GET_PRIVATE (reader);
3429 priv->schedule_mark_seen = schedule_timeout;
3430 priv->schedule_mark_seen_interval = timeout_interval;
3431 }
3432
3433 static gboolean
discard_timeout_mark_seen_cb(EMailReader * reader)3434 discard_timeout_mark_seen_cb (EMailReader *reader)
3435 {
3436 EMailReaderPrivate *priv;
3437 MessageList *message_list;
3438
3439 g_return_val_if_fail (reader != NULL, FALSE);
3440
3441 priv = E_MAIL_READER_GET_PRIVATE (reader);
3442 priv->schedule_mark_seen = FALSE;
3443
3444 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
3445 g_return_val_if_fail (message_list != NULL, FALSE);
3446
3447 if (message_list->seen_id > 0) {
3448 g_source_remove (message_list->seen_id);
3449 message_list->seen_id = 0;
3450 }
3451
3452 return FALSE;
3453 }
3454
3455
3456 static void
mail_reader_preview_pane_visible_changed_cb(EMailReader * reader,GParamSpec * param,GtkWidget * widget)3457 mail_reader_preview_pane_visible_changed_cb (EMailReader *reader,
3458 GParamSpec *param,
3459 GtkWidget *widget)
3460 {
3461 g_return_if_fail (E_IS_MAIL_READER (reader));
3462 g_return_if_fail (GTK_IS_WIDGET (widget));
3463
3464 if (!gtk_widget_get_visible (widget))
3465 discard_timeout_mark_seen_cb (reader);
3466 }
3467
3468 static void
mail_reader_remove_followup_alert(EMailReader * reader)3469 mail_reader_remove_followup_alert (EMailReader *reader)
3470 {
3471 EMailReaderPrivate *priv;
3472
3473 g_return_if_fail (E_IS_MAIL_READER (reader));
3474
3475 priv = E_MAIL_READER_GET_PRIVATE (reader);
3476 if (!priv)
3477 return;
3478
3479 if (priv->followup_alert)
3480 e_alert_response (priv->followup_alert, GTK_RESPONSE_OK);
3481 }
3482
3483 static void
mail_reader_manage_followup_flag(EMailReader * reader,CamelFolder * folder,const gchar * message_uid)3484 mail_reader_manage_followup_flag (EMailReader *reader,
3485 CamelFolder *folder,
3486 const gchar *message_uid)
3487 {
3488 EMailReaderPrivate *priv;
3489 CamelMessageInfo *info;
3490 const gchar *followup, *completed_on, *due_by;
3491 time_t date;
3492 gchar *date_str = NULL;
3493 gboolean alert_added = FALSE;
3494
3495 g_return_if_fail (E_IS_MAIL_READER (reader));
3496 g_return_if_fail (CAMEL_IS_FOLDER (folder));
3497 g_return_if_fail (message_uid != NULL);
3498
3499 priv = E_MAIL_READER_GET_PRIVATE (reader);
3500 if (!priv)
3501 return;
3502
3503 info = camel_folder_get_message_info (folder, message_uid);
3504 if (!info)
3505 return;
3506
3507 followup = camel_message_info_get_user_tag (info, "follow-up");
3508 if (followup && *followup) {
3509 EPreviewPane *preview_pane;
3510 const gchar *alert_tag;
3511 EAlert *alert;
3512
3513 completed_on = camel_message_info_get_user_tag (info, "completed-on");
3514 due_by = camel_message_info_get_user_tag (info, "due-by");
3515
3516 if (completed_on && *completed_on) {
3517 alert_tag = "mail:follow-up-completed-info";
3518 date = camel_header_decode_date (completed_on, NULL);
3519 date_str = e_datetime_format_format ("mail", "header", DTFormatKindDateTime, date);
3520 } else if (due_by && *due_by) {
3521 time_t now;
3522
3523 alert_tag = "mail:follow-up-dueby-info";
3524 date = camel_header_decode_date (due_by, NULL);
3525 date_str = e_datetime_format_format ("mail", "header", DTFormatKindDateTime, date);
3526
3527 now = time (NULL);
3528 if (now > date)
3529 alert_tag = "mail:follow-up-overdue-error";
3530 } else {
3531 alert_tag = "mail:follow-up-flag-info";
3532 }
3533
3534 alert = e_alert_new (alert_tag, followup, date_str ? date_str : "???", NULL);
3535
3536 g_free (date_str);
3537
3538 preview_pane = e_mail_reader_get_preview_pane (reader);
3539 e_alert_sink_submit_alert (E_ALERT_SINK (preview_pane), alert);
3540
3541 alert_added = TRUE;
3542
3543 mail_reader_remove_followup_alert (reader);
3544 priv->followup_alert = alert;
3545 g_object_add_weak_pointer (G_OBJECT (priv->followup_alert), &priv->followup_alert);
3546
3547 g_object_unref (alert);
3548 }
3549
3550 g_clear_object (&info);
3551
3552 if (!alert_added)
3553 mail_reader_remove_followup_alert (reader);
3554 }
3555
3556 static void
mail_reader_reload(EMailReader * reader)3557 mail_reader_reload (EMailReader *reader)
3558 {
3559 CamelFolder *folder;
3560 GPtrArray *uids;
3561 EMailDisplay *mail_display;
3562
3563 g_return_if_fail (E_IS_MAIL_READER (reader));
3564
3565 folder = e_mail_reader_ref_folder (reader);
3566 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
3567
3568 if (uids && uids->len == 1)
3569 mail_reader_manage_followup_flag (reader, folder, uids->pdata[0]);
3570
3571 g_clear_object (&folder);
3572 if (uids)
3573 g_ptr_array_unref (uids);
3574
3575 mail_display = e_mail_reader_get_mail_display (reader);
3576 e_mail_display_reload (mail_display);
3577 }
3578
3579 static void
mail_reader_remove_ui(EMailReader * reader)3580 mail_reader_remove_ui (EMailReader *reader)
3581 {
3582 EMailReaderPrivate *priv;
3583 GtkWindow *window;
3584 GtkUIManager *ui_manager = NULL;
3585
3586 g_return_if_fail (E_IS_MAIL_READER (reader));
3587
3588 priv = E_MAIL_READER_GET_PRIVATE (reader);
3589
3590 if (!priv->main_menu_label_merge_id)
3591 return;
3592
3593 window = e_mail_reader_get_window (reader);
3594 g_return_if_fail (window != NULL);
3595
3596 if (E_IS_SHELL_WINDOW (window))
3597 ui_manager = e_shell_window_get_ui_manager (E_SHELL_WINDOW (window));
3598 else if (E_IS_MAIL_BROWSER (window))
3599 ui_manager = e_mail_browser_get_ui_manager (E_MAIL_BROWSER (window));
3600
3601 g_return_if_fail (ui_manager != NULL);
3602 g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
3603
3604 gtk_ui_manager_remove_ui (ui_manager, priv->main_menu_label_merge_id);
3605 }
3606
3607 static void
mail_reader_message_loaded_cb(CamelFolder * folder,GAsyncResult * result,EMailReaderClosure * closure)3608 mail_reader_message_loaded_cb (CamelFolder *folder,
3609 GAsyncResult *result,
3610 EMailReaderClosure *closure)
3611 {
3612 EMailReader *reader;
3613 EMailReaderPrivate *priv;
3614 CamelMimeMessage *message = NULL;
3615 GtkWidget *message_list;
3616 const gchar *message_uid;
3617 GError *error = NULL;
3618
3619 reader = closure->reader;
3620 message_uid = closure->message_uid;
3621
3622 priv = E_MAIL_READER_GET_PRIVATE (reader);
3623
3624 /* If the private struct is NULL, the EMailReader was destroyed
3625 * while we were loading the message and we're likely holding the
3626 * last reference. Nothing to do but drop the reference.
3627 * FIXME Use a GWeakRef instead of this hack. */
3628 if (priv == NULL) {
3629 mail_reader_closure_free (closure);
3630 return;
3631 }
3632
3633 message = camel_folder_get_message_finish (folder, result, &error);
3634
3635 /* If the user picked a different message in the time it took
3636 * to fetch this message, then don't bother rendering it. */
3637 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
3638 g_clear_error (&error);
3639 goto exit;
3640 }
3641
3642 message_list = e_mail_reader_get_message_list (reader);
3643
3644 if (message_list == NULL) {
3645 /* For cases where message fetching took so long that
3646 * user closed the message window before this was called. */
3647 goto exit;
3648 }
3649
3650 if (message != NULL) {
3651 CamelMessageInfo *mi;
3652
3653 mail_reader_manage_followup_flag (reader, folder, message_uid);
3654
3655 mi = camel_folder_get_message_info (folder, message_uid);
3656 if (mi) {
3657 if (camel_util_fill_message_info_user_headers (mi, camel_medium_get_headers (CAMEL_MEDIUM (message))))
3658 gtk_widget_queue_draw (message_list);
3659
3660 g_object_unref (mi);
3661 }
3662
3663 g_signal_emit (
3664 reader, signals[MESSAGE_LOADED], 0,
3665 message_uid, message);
3666 }
3667
3668 exit:
3669 if (error != NULL) {
3670 EPreviewPane *preview_pane;
3671 EWebView *web_view;
3672
3673 preview_pane = e_mail_reader_get_preview_pane (reader);
3674 web_view = e_preview_pane_get_web_view (preview_pane);
3675
3676 if (g_error_matches (error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE) &&
3677 CAMEL_IS_OFFLINE_FOLDER (folder) &&
3678 camel_service_get_connection_status (CAMEL_SERVICE (camel_folder_get_parent_store (folder))) != CAMEL_SERVICE_CONNECTED)
3679 e_alert_submit (
3680 E_ALERT_SINK (web_view),
3681 "mail:no-retrieve-message-offline",
3682 NULL);
3683 else
3684 e_alert_submit (
3685 E_ALERT_SINK (web_view),
3686 "mail:no-retrieve-message",
3687 error->message, NULL);
3688 }
3689
3690 g_clear_error (&error);
3691
3692 mail_reader_closure_free (closure);
3693
3694 g_clear_object (&message);
3695 }
3696
3697 static gboolean
mail_reader_message_selected_timeout_cb(gpointer user_data)3698 mail_reader_message_selected_timeout_cb (gpointer user_data)
3699 {
3700 EMailReader *reader;
3701 EMailReaderPrivate *priv;
3702 EMailDisplay *display;
3703 GtkWidget *message_list;
3704 const gchar *cursor_uid;
3705 const gchar *format_uid;
3706 EMailPartList *parts;
3707
3708 reader = E_MAIL_READER (user_data);
3709 priv = E_MAIL_READER_GET_PRIVATE (reader);
3710
3711 message_list = e_mail_reader_get_message_list (reader);
3712 display = e_mail_reader_get_mail_display (reader);
3713 parts = e_mail_display_get_part_list (display);
3714
3715 cursor_uid = MESSAGE_LIST (message_list)->cursor_uid;
3716 if (parts != NULL)
3717 format_uid = e_mail_part_list_get_message_uid (parts);
3718 else
3719 format_uid = NULL;
3720
3721 if (MESSAGE_LIST (message_list)->last_sel_single) {
3722 GtkWidget *widget;
3723 gboolean display_visible;
3724 gboolean selected_uid_changed;
3725
3726 /* Decide whether to download the full message now. */
3727 widget = GTK_WIDGET (display);
3728 display_visible = gtk_widget_get_mapped (widget);
3729
3730 selected_uid_changed = (g_strcmp0 (cursor_uid, format_uid) != 0);
3731
3732 if (display_visible && selected_uid_changed) {
3733 EMailReaderClosure *closure;
3734 GCancellable *cancellable;
3735 CamelFolder *folder;
3736 EActivity *activity;
3737 gchar *string;
3738
3739 string = g_strdup_printf (
3740 _("Retrieving message “%s”"), cursor_uid);
3741 e_mail_display_set_part_list (display, NULL);
3742 e_mail_display_set_status (display, string);
3743 g_free (string);
3744
3745 activity = e_mail_reader_new_activity (reader);
3746 e_activity_set_text (activity, _("Retrieving message"));
3747 cancellable = e_activity_get_cancellable (activity);
3748
3749 closure = g_slice_new0 (EMailReaderClosure);
3750 closure->activity = activity;
3751 closure->reader = g_object_ref (reader);
3752 closure->message_uid = g_strdup (cursor_uid);
3753
3754 folder = e_mail_reader_ref_folder (reader);
3755
3756 camel_folder_get_message (
3757 folder, cursor_uid, G_PRIORITY_DEFAULT,
3758 cancellable, (GAsyncReadyCallback)
3759 mail_reader_message_loaded_cb, closure);
3760
3761 g_clear_object (&folder);
3762
3763 if (priv->retrieving_message != NULL)
3764 g_object_unref (priv->retrieving_message);
3765 priv->retrieving_message = g_object_ref (cancellable);
3766 }
3767 } else {
3768 e_mail_display_set_part_list (display, NULL);
3769 }
3770
3771 priv->message_selected_timeout_id = 0;
3772
3773 return FALSE;
3774 }
3775
3776 static void
mail_reader_message_selected_cb(EMailReader * reader,const gchar * message_uid)3777 mail_reader_message_selected_cb (EMailReader *reader,
3778 const gchar *message_uid)
3779 {
3780 EMailReaderPrivate *priv;
3781 MessageList *message_list;
3782
3783 priv = E_MAIL_READER_GET_PRIVATE (reader);
3784
3785 /* Cancel the previous message retrieval activity. */
3786 g_cancellable_cancel (priv->retrieving_message);
3787
3788 /* Cancel the message selected timer. */
3789 if (priv->message_selected_timeout_id > 0) {
3790 g_source_remove (priv->message_selected_timeout_id);
3791 priv->message_selected_timeout_id = 0;
3792 }
3793
3794 if (priv->folder_was_just_selected && message_uid) {
3795 if (priv->did_try_to_open_message)
3796 priv->folder_was_just_selected = FALSE;
3797 else
3798 priv->did_try_to_open_message = TRUE;
3799 }
3800
3801 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
3802 if (message_list) {
3803 EMailPartList *parts;
3804 const gchar *cursor_uid, *format_uid;
3805
3806 parts = e_mail_display_get_part_list (e_mail_reader_get_mail_display (reader));
3807
3808 cursor_uid = MESSAGE_LIST (message_list)->cursor_uid;
3809 if (parts != NULL)
3810 format_uid = e_mail_part_list_get_message_uid (parts);
3811 else
3812 format_uid = NULL;
3813
3814 /* It can happen when the message was loaded that quickly that
3815 it was delivered before this callback. */
3816 if (g_strcmp0 (cursor_uid, format_uid) == 0) {
3817 e_mail_reader_changed (reader);
3818 return;
3819 }
3820 }
3821
3822 /* Cancel the seen timer. */
3823 if (message_list != NULL && message_list->seen_id) {
3824 g_source_remove (message_list->seen_id);
3825 message_list->seen_id = 0;
3826 }
3827
3828 if (message_list_selected_count (message_list) != 1) {
3829 EMailDisplay *display;
3830
3831 display = e_mail_reader_get_mail_display (reader);
3832 e_mail_display_set_part_list (display, NULL);
3833 e_web_view_clear (E_WEB_VIEW (display));
3834
3835 } else if (priv->folder_was_just_selected) {
3836 /* Skip the timeout if we're restoring the previous message
3837 * selection. The timeout is there for when we're scrolling
3838 * rapidly through the message list. */
3839 mail_reader_message_selected_timeout_cb (reader);
3840
3841 } else {
3842 priv->message_selected_timeout_id = e_named_timeout_add (
3843 100, mail_reader_message_selected_timeout_cb, reader);
3844 }
3845
3846 e_mail_reader_changed (reader);
3847 }
3848
3849 static void
mail_reader_message_cursor_change_cb(EMailReader * reader)3850 mail_reader_message_cursor_change_cb (EMailReader *reader)
3851 {
3852 MessageList *message_list;
3853 EMailReaderPrivate *priv;
3854
3855 g_return_if_fail (reader != NULL);
3856
3857 priv = E_MAIL_READER_GET_PRIVATE (reader);
3858 g_return_if_fail (priv != NULL);
3859
3860 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
3861 g_return_if_fail (message_list != NULL);
3862
3863 if (message_list->seen_id == 0 &&
3864 E_IS_MAIL_VIEW (reader) &&
3865 e_mail_view_get_preview_visible (E_MAIL_VIEW (reader)) &&
3866 !priv->avoid_next_mark_as_seen)
3867 maybe_schedule_timeout_mark_seen (reader);
3868 }
3869
3870 static void
mail_reader_emit_folder_loaded(EMailReader * reader)3871 mail_reader_emit_folder_loaded (EMailReader *reader)
3872 {
3873 EMailReaderPrivate *priv;
3874 MessageList *message_list;
3875
3876 priv = E_MAIL_READER_GET_PRIVATE (reader);
3877 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
3878
3879 if (priv && (message_list_count (message_list) <= 0 ||
3880 message_list_selected_count (message_list) <= 0))
3881 priv->avoid_next_mark_as_seen = FALSE;
3882
3883 g_signal_emit (reader, signals[FOLDER_LOADED], 0);
3884 }
3885
3886 static void
mail_reader_message_list_built_cb(MessageList * message_list,EMailReader * reader)3887 mail_reader_message_list_built_cb (MessageList *message_list,
3888 EMailReader *reader)
3889 {
3890 EMailReaderPrivate *priv;
3891
3892 priv = E_MAIL_READER_GET_PRIVATE (reader);
3893 mail_reader_emit_folder_loaded (reader);
3894
3895 /* No cursor_uid means that there will not be emitted any
3896 "cursor-changed" and "message-selected" signal, thus
3897 unset the "just selected folder" flag */
3898 if (!message_list->cursor_uid)
3899 priv->folder_was_just_selected = FALSE;
3900 }
3901
3902 static EAlertSink *
mail_reader_get_alert_sink(EMailReader * reader)3903 mail_reader_get_alert_sink (EMailReader *reader)
3904 {
3905 EPreviewPane *preview_pane;
3906
3907 preview_pane = e_mail_reader_get_preview_pane (reader);
3908
3909 if (!gtk_widget_is_visible (GTK_WIDGET (preview_pane))) {
3910 GtkWindow *window;
3911
3912 window = e_mail_reader_get_window (reader);
3913
3914 if (E_IS_SHELL_WINDOW (window))
3915 return E_ALERT_SINK (window);
3916 }
3917
3918 return E_ALERT_SINK (preview_pane);
3919 }
3920
3921 static GPtrArray *
mail_reader_get_selected_uids(EMailReader * reader)3922 mail_reader_get_selected_uids (EMailReader *reader)
3923 {
3924 GtkWidget *message_list;
3925
3926 message_list = e_mail_reader_get_message_list (reader);
3927
3928 return message_list_get_selected (MESSAGE_LIST (message_list));
3929 }
3930
3931 static GPtrArray *
mail_reader_get_selected_uids_with_collapsed_threads(EMailReader * reader)3932 mail_reader_get_selected_uids_with_collapsed_threads (EMailReader *reader)
3933 {
3934 GtkWidget *message_list;
3935
3936 message_list = e_mail_reader_get_message_list (reader);
3937
3938 return message_list_get_selected_with_collapsed_threads (MESSAGE_LIST (message_list));
3939 }
3940
3941 static CamelFolder *
mail_reader_ref_folder(EMailReader * reader)3942 mail_reader_ref_folder (EMailReader *reader)
3943 {
3944 GtkWidget *message_list;
3945
3946 message_list = e_mail_reader_get_message_list (reader);
3947
3948 return message_list_ref_folder (MESSAGE_LIST (message_list));
3949 }
3950
3951 static void
mail_reader_set_folder(EMailReader * reader,CamelFolder * folder)3952 mail_reader_set_folder (EMailReader *reader,
3953 CamelFolder *folder)
3954 {
3955 EMailReaderPrivate *priv;
3956 EMailDisplay *display;
3957 CamelFolder *previous_folder;
3958 GtkWidget *message_list;
3959 EMailBackend *backend;
3960 EShell *shell;
3961 gboolean sync_folder;
3962
3963 priv = E_MAIL_READER_GET_PRIVATE (reader);
3964
3965 display = e_mail_reader_get_mail_display (reader);
3966 message_list = e_mail_reader_get_message_list (reader);
3967
3968 previous_folder = e_mail_reader_ref_folder (reader);
3969
3970 backend = e_mail_reader_get_backend (reader);
3971 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
3972
3973 /* Only synchronize the real folder if we're online. */
3974 sync_folder =
3975 (previous_folder != NULL) &&
3976 (CAMEL_IS_VEE_FOLDER (previous_folder) ||
3977 e_shell_get_online (shell));
3978 if (sync_folder)
3979 mail_sync_folder (previous_folder, TRUE, NULL, NULL);
3980
3981 /* Skip the rest if we're already viewing the folder. */
3982 if (folder != previous_folder) {
3983 e_web_view_clear (E_WEB_VIEW (display));
3984
3985 priv->folder_was_just_selected = (folder != NULL) && !priv->mark_seen_always;
3986 priv->did_try_to_open_message = FALSE;
3987
3988 /* This is to make sure any post-poned changes in Search
3989 * Folders will be propagated on folder selection. */
3990 if (CAMEL_IS_VEE_FOLDER (folder))
3991 mail_sync_folder (folder, FALSE, NULL, NULL);
3992
3993 message_list_set_folder (MESSAGE_LIST (message_list), folder);
3994
3995 mail_reader_emit_folder_loaded (reader);
3996 }
3997
3998 g_clear_object (&previous_folder);
3999 }
4000
4001 static void
mail_reader_set_message(EMailReader * reader,const gchar * message_uid)4002 mail_reader_set_message (EMailReader *reader,
4003 const gchar *message_uid)
4004 {
4005 GtkWidget *message_list;
4006 EMailReaderPrivate *priv;
4007
4008 priv = E_MAIL_READER_GET_PRIVATE (reader);
4009
4010 /* For a case when the preview panel had been disabled */
4011 priv->folder_was_just_selected = FALSE;
4012
4013 message_list = e_mail_reader_get_message_list (reader);
4014
4015 message_list_select_uid (
4016 MESSAGE_LIST (message_list), message_uid, FALSE);
4017 }
4018
4019 static void
mail_reader_folder_loaded(EMailReader * reader)4020 mail_reader_folder_loaded (EMailReader *reader)
4021 {
4022 guint32 state;
4023
4024 state = e_mail_reader_check_state (reader);
4025 e_mail_reader_update_actions (reader, state);
4026 }
4027
4028 static void
mail_reader_message_list_suggest_update_actions_cb(EMailReader * reader)4029 mail_reader_message_list_suggest_update_actions_cb (EMailReader *reader)
4030 {
4031 guint32 state;
4032
4033 state = e_mail_reader_check_state (reader);
4034 e_mail_reader_update_actions (reader, state);
4035 }
4036
4037 static void
set_mail_display_part_list(GObject * object,GAsyncResult * result,gpointer user_data)4038 set_mail_display_part_list (GObject *object,
4039 GAsyncResult *result,
4040 gpointer user_data)
4041 {
4042 EMailPartList *part_list;
4043 EMailReader *reader;
4044 EMailDisplay *display;
4045 GError *local_error = NULL;
4046
4047 reader = E_MAIL_READER (object);
4048
4049 part_list = e_mail_reader_parse_message_finish (reader, result, &local_error);
4050
4051 if (local_error) {
4052 g_warn_if_fail (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED));
4053
4054 g_clear_error (&local_error);
4055 return;
4056 }
4057
4058 display = e_mail_reader_get_mail_display (reader);
4059
4060 e_mail_display_set_part_list (display, part_list);
4061 e_mail_display_load (display, NULL);
4062
4063 /* Remove the reference added when parts list was
4064 * created, so that only owners are EMailDisplays. */
4065 g_object_unref (part_list);
4066 }
4067
4068 static void
mail_reader_set_display_formatter_for_message(EMailReader * reader,EMailDisplay * display,const gchar * message_uid,CamelMimeMessage * message,CamelFolder * folder)4069 mail_reader_set_display_formatter_for_message (EMailReader *reader,
4070 EMailDisplay *display,
4071 const gchar *message_uid,
4072 CamelMimeMessage *message,
4073 CamelFolder *folder)
4074 {
4075 CamelObjectBag *registry;
4076 EMailPartList *parts;
4077 EMailReaderPrivate *priv;
4078 gchar *mail_uri;
4079
4080 priv = E_MAIL_READER_GET_PRIVATE (reader);
4081 mail_uri = e_mail_part_build_uri (folder, message_uid, NULL, NULL);
4082 registry = e_mail_part_list_get_registry ();
4083 parts = camel_object_bag_peek (registry, mail_uri);
4084 g_free (mail_uri);
4085
4086 if (parts == NULL) {
4087 if (!priv->retrieving_message)
4088 priv->retrieving_message = camel_operation_new ();
4089
4090 e_mail_reader_parse_message (
4091 reader, folder, message_uid, message,
4092 priv->retrieving_message,
4093 set_mail_display_part_list, NULL);
4094 } else {
4095 e_mail_display_set_part_list (display, parts);
4096 e_mail_display_load (display, NULL);
4097 g_object_unref (parts);
4098 }
4099 }
4100
4101 static void
mail_reader_message_loaded(EMailReader * reader,const gchar * message_uid,CamelMimeMessage * message)4102 mail_reader_message_loaded (EMailReader *reader,
4103 const gchar *message_uid,
4104 CamelMimeMessage *message)
4105 {
4106 EMailReaderPrivate *priv;
4107 GtkWidget *message_list;
4108 EMailBackend *backend;
4109 CamelFolder *folder;
4110 EMailDisplay *display;
4111 EShellBackend *shell_backend;
4112 EShell *shell;
4113 EMEvent *event;
4114 EMEventTargetMessage *target;
4115
4116 priv = E_MAIL_READER_GET_PRIVATE (reader);
4117
4118 folder = e_mail_reader_ref_folder (reader);
4119 backend = e_mail_reader_get_backend (reader);
4120 display = e_mail_reader_get_mail_display (reader);
4121 message_list = e_mail_reader_get_message_list (reader);
4122
4123 shell_backend = E_SHELL_BACKEND (backend);
4124 shell = e_shell_backend_get_shell (shell_backend);
4125
4126 /** @Event: message.reading
4127 * @Title: Viewing a message
4128 * @Target: EMEventTargetMessage
4129 *
4130 * message.reading is emitted whenever a user views a message.
4131 */
4132 event = em_event_peek ();
4133 target = em_event_target_new_message (
4134 event, folder, message, message_uid, 0, NULL);
4135 e_event_emit (
4136 (EEvent *) event, "message.reading",
4137 (EEventTarget *) target);
4138
4139 mail_reader_set_display_formatter_for_message (
4140 reader, display, message_uid, message, folder);
4141
4142 /* Reset the shell view icon. */
4143 e_shell_event (shell, "mail-icon", (gpointer) "evolution-mail");
4144
4145 if (MESSAGE_LIST (message_list)->seen_id > 0) {
4146 g_source_remove (MESSAGE_LIST (message_list)->seen_id);
4147 MESSAGE_LIST (message_list)->seen_id = 0;
4148 }
4149
4150 /* Determine whether to mark the message as read. */
4151 if (message != NULL &&
4152 !priv->avoid_next_mark_as_seen)
4153 maybe_schedule_timeout_mark_seen (reader);
4154
4155 priv->avoid_next_mark_as_seen = FALSE;
4156
4157 g_clear_object (&folder);
4158 }
4159
4160 static void
mail_reader_message_seen(EMailReader * reader,const gchar * message_uid,CamelMimeMessage * message)4161 mail_reader_message_seen (EMailReader *reader,
4162 const gchar *message_uid,
4163 CamelMimeMessage *message)
4164 {
4165 CamelFolder *folder;
4166 guint32 mask, set;
4167
4168 mask = CAMEL_MESSAGE_SEEN;
4169 set = CAMEL_MESSAGE_SEEN;
4170
4171 folder = e_mail_reader_ref_folder (reader);
4172 camel_folder_set_message_flags (folder, message_uid, mask, set);
4173 g_clear_object (&folder);
4174 }
4175
4176 static void
mail_reader_show_search_bar(EMailReader * reader)4177 mail_reader_show_search_bar (EMailReader *reader)
4178 {
4179 EPreviewPane *preview_pane;
4180
4181 preview_pane = e_mail_reader_get_preview_pane (reader);
4182 e_preview_pane_show_search_bar (preview_pane);
4183 }
4184
4185 static void
action_mail_label_cb(GtkToggleAction * action,EMailReader * reader)4186 action_mail_label_cb (GtkToggleAction *action,
4187 EMailReader *reader)
4188 {
4189 CamelFolder *folder;
4190 GPtrArray *uids;
4191 const gchar *tag;
4192 gint ii;
4193
4194 tag = g_object_get_data (G_OBJECT (action), "tag");
4195 g_return_if_fail (tag != NULL);
4196
4197 uids = e_mail_reader_get_selected_uids (reader);
4198 if (!uids)
4199 return;
4200
4201 folder = e_mail_reader_ref_folder (reader);
4202
4203 camel_folder_freeze (folder);
4204 for (ii = 0; ii < uids->len; ii++) {
4205 if (gtk_toggle_action_get_active (action))
4206 camel_folder_set_message_user_flag (
4207 folder, uids->pdata[ii], tag, TRUE);
4208 else {
4209 camel_folder_set_message_user_flag (
4210 folder, uids->pdata[ii], tag, FALSE);
4211 camel_folder_set_message_user_tag (
4212 folder, uids->pdata[ii], "label", NULL);
4213 }
4214 }
4215 camel_folder_thaw (folder);
4216
4217 g_clear_object (&folder);
4218 g_ptr_array_unref (uids);
4219 }
4220
4221 #define LABEL_UNKNOWN 0
4222 #define LABEL_EXISTS (1 << 0)
4223 #define LABEL_NOTEXIST (1 << 1)
4224
4225 static GHashTable *
mail_reader_gather_labels_info(EMailReader * reader,EMailLabelListStore * label_store,GPtrArray * uids)4226 mail_reader_gather_labels_info (EMailReader *reader,
4227 EMailLabelListStore *label_store,
4228 GPtrArray *uids)
4229 {
4230 GHashTable *labels_info;
4231 CamelFolder *folder;
4232 GtkTreeIter iter;
4233 GtkTreeModel *model;
4234 gboolean valid;
4235 guint ii;
4236
4237 labels_info = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
4238
4239 model = GTK_TREE_MODEL (label_store);
4240 folder = e_mail_reader_ref_folder (reader);
4241
4242 if (!folder)
4243 return labels_info;
4244
4245 for (ii = 0; ii < uids->len; ii++) {
4246 CamelMessageInfo *info;
4247
4248 info = camel_folder_get_message_info (folder, uids->pdata[ii]);
4249 if (!info)
4250 continue;
4251
4252 for (valid = gtk_tree_model_get_iter_first (model, &iter);
4253 valid;
4254 valid = gtk_tree_model_iter_next (model, &iter)) {
4255 gchar *tag;
4256 guint value;
4257
4258 tag = e_mail_label_list_store_get_tag (label_store, &iter);
4259 value = GPOINTER_TO_UINT (g_hash_table_lookup (labels_info, tag));
4260 if ((!(value & LABEL_EXISTS)) || (!(value & LABEL_NOTEXIST))) {
4261 gboolean exists = FALSE, notexist = FALSE;
4262
4263 /* Check for new-style labels. */
4264 if (camel_message_info_get_user_flag (info, tag)) {
4265 exists = TRUE;
4266 } else {
4267 /* Check for old-style labels. */
4268 const gchar *old_label = camel_message_info_get_user_tag (info, "label");
4269 if (old_label) {
4270 gchar *new_label;
4271
4272 /* Convert old-style labels ("<name>") to "$Label<name>". */
4273 new_label = g_alloca (strlen (old_label) + 10);
4274 g_stpcpy (g_stpcpy (new_label, "$Label"), old_label);
4275
4276 if (g_strcmp0 (new_label, tag) == 0)
4277 exists = TRUE;
4278 else
4279 notexist = TRUE;
4280 } else {
4281 notexist = TRUE;
4282 }
4283 }
4284
4285 value = value |
4286 (exists ? LABEL_EXISTS : LABEL_UNKNOWN) |
4287 (notexist ? LABEL_NOTEXIST : LABEL_UNKNOWN);
4288
4289 g_hash_table_insert (labels_info, tag, GUINT_TO_POINTER (value));
4290
4291 /* the hash table took the 'tag' */
4292 tag = NULL;
4293 }
4294
4295 g_free (tag);
4296 }
4297
4298 g_clear_object (&info);
4299 }
4300
4301 g_clear_object (&folder);
4302
4303 return labels_info;
4304 }
4305
4306 static void
mail_reader_update_label_action(GtkToggleAction * action,GHashTable * labels_info,const gchar * label_tag)4307 mail_reader_update_label_action (GtkToggleAction *action,
4308 GHashTable *labels_info, /* gchar * ~> guint */
4309 const gchar *label_tag)
4310 {
4311 gboolean exists = FALSE;
4312 gboolean not_exists = FALSE;
4313 gboolean sensitive;
4314 guint value;
4315
4316 /* Figure out the proper label action state for the selected
4317 * messages. If all the selected messages have the given label,
4318 * make the toggle action active. If all the selected message
4319 * DO NOT have the given label, make the toggle action inactive.
4320 * If some do and some don't, make the action insensitive. */
4321
4322 value = GPOINTER_TO_UINT (g_hash_table_lookup (labels_info, label_tag));
4323 exists = (value & LABEL_EXISTS) != 0;
4324 not_exists = (value & LABEL_NOTEXIST) != 0;
4325
4326 sensitive = !(exists && not_exists);
4327 gtk_toggle_action_set_active (action, exists);
4328 gtk_action_set_sensitive (GTK_ACTION (action), sensitive);
4329 }
4330
4331 static void
mail_reader_update_labels_menu(EMailReader * reader)4332 mail_reader_update_labels_menu (EMailReader *reader)
4333 {
4334 EMailReaderPrivate *priv;
4335 EMailLabelListStore *label_store;
4336 EMailBackend *backend;
4337 EMailSession *session;
4338 GtkWindow *window;
4339 GtkUIManager *ui_manager = NULL;
4340 GtkActionGroup *action_group;
4341 GtkTreeIter iter;
4342 GHashTable *labels_info; /* gchar * ~> guint { LABEL_EXISTS | LABEL_NOTEXIST | LABEL_UNKNOWN } */
4343 GPtrArray *uids;
4344 const gchar *main_menu_path, *popup_menu_path;
4345 gboolean valid;
4346 gint ii = 0;
4347
4348 priv = E_MAIL_READER_GET_PRIVATE (reader);
4349
4350 window = e_mail_reader_get_window (reader);
4351 g_return_if_fail (window != NULL);
4352
4353 if (E_IS_SHELL_WINDOW (window))
4354 ui_manager = e_shell_window_get_ui_manager (E_SHELL_WINDOW (window));
4355 else if (E_IS_MAIL_BROWSER (window))
4356 ui_manager = e_mail_browser_get_ui_manager (E_MAIL_BROWSER (window));
4357
4358 g_return_if_fail (ui_manager != NULL);
4359 g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
4360
4361 backend = e_mail_reader_get_backend (reader);
4362 session = e_mail_backend_get_session (backend);
4363 label_store = e_mail_ui_session_get_label_store (E_MAIL_UI_SESSION (session));
4364
4365 action_group = e_mail_reader_get_action_group (reader, E_MAIL_READER_ACTION_GROUP_LABELS);
4366 main_menu_path = "/main-menu/custom-menus/mail-message-menu/mail-mark-as-menu/mail-label-menu/mail-label-actions";
4367 popup_menu_path = "/mail-message-popup/mail-label-menu/mail-label-actions";
4368
4369 /* Unmerge the previous menu items. */
4370 if (priv->main_menu_label_merge_id)
4371 gtk_ui_manager_remove_ui (ui_manager, priv->main_menu_label_merge_id);
4372 else
4373 priv->main_menu_label_merge_id = gtk_ui_manager_new_merge_id (ui_manager);
4374
4375 if (priv->popup_menu_label_merge_id)
4376 gtk_ui_manager_remove_ui (ui_manager, priv->popup_menu_label_merge_id);
4377 else
4378 priv->popup_menu_label_merge_id = gtk_ui_manager_new_merge_id (ui_manager);
4379
4380 e_action_group_remove_all_actions (action_group);
4381 gtk_ui_manager_ensure_update (ui_manager);
4382
4383 uids = e_mail_reader_get_selected_uids (reader);
4384 labels_info = mail_reader_gather_labels_info (reader, label_store, uids);
4385
4386 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (label_store), &iter);
4387
4388 while (valid) {
4389 EMailLabelAction *label_action;
4390 GtkAction *action;
4391 gchar *action_name;
4392 gchar *stock_id;
4393 gchar *label;
4394 gchar *tag;
4395
4396 label = e_mail_label_list_store_get_name (label_store, &iter);
4397 stock_id = e_mail_label_list_store_get_stock_id (label_store, &iter);
4398 tag = e_mail_label_list_store_get_tag (label_store, &iter);
4399 action_name = g_strdup_printf ("mail-label-%d", ii);
4400
4401 /* XXX Add a tooltip! */
4402 label_action = e_mail_label_action_new (action_name, label, NULL, stock_id);
4403
4404 g_object_set_data_full (
4405 G_OBJECT (label_action), "tag",
4406 tag, (GDestroyNotify) g_free);
4407
4408 /* Configure the action before we connect to signals. */
4409 mail_reader_update_label_action (GTK_TOGGLE_ACTION (label_action), labels_info, tag);
4410
4411 g_signal_connect (
4412 label_action, "toggled",
4413 G_CALLBACK (action_mail_label_cb), reader);
4414
4415 /* The action group takes ownership of the action. */
4416 action = GTK_ACTION (label_action);
4417
4418 if (ii + 1 < 10) {
4419 gchar accel[5];
4420
4421 accel[0] = '1' + ii;
4422 accel[1] = '\0';
4423
4424 gtk_action_group_add_action_with_accel (action_group, action, accel);
4425 } else {
4426 gtk_action_group_add_action (action_group, action);
4427 }
4428 g_object_unref (label_action);
4429
4430 gtk_ui_manager_add_ui (
4431 ui_manager, priv->main_menu_label_merge_id, main_menu_path,
4432 action_name, action_name, GTK_UI_MANAGER_AUTO, FALSE);
4433
4434 gtk_ui_manager_add_ui (
4435 ui_manager, priv->popup_menu_label_merge_id, popup_menu_path,
4436 action_name, action_name, GTK_UI_MANAGER_AUTO, FALSE);
4437
4438 g_free (label);
4439 g_free (stock_id);
4440 g_free (action_name);
4441
4442 valid = gtk_tree_model_iter_next (
4443 GTK_TREE_MODEL (label_store), &iter);
4444 ii++;
4445 }
4446
4447 g_hash_table_destroy (labels_info);
4448 g_ptr_array_unref (uids);
4449 }
4450
4451 static void
mail_reader_update_actions(EMailReader * reader,guint32 state)4452 mail_reader_update_actions (EMailReader *reader,
4453 guint32 state)
4454 {
4455 GtkAction *action;
4456 const gchar *action_name;
4457 gboolean sensitive;
4458 EMailDisplay *mail_display;
4459
4460 /* Be descriptive. */
4461 gboolean any_messages_selected;
4462 gboolean enable_flag_clear;
4463 gboolean enable_flag_completed;
4464 gboolean have_enabled_account;
4465 gboolean multiple_messages_selected;
4466 gboolean selection_has_attachment_messages;
4467 gboolean selection_has_deleted_messages;
4468 gboolean selection_has_ignore_thread_messages;
4469 gboolean selection_has_notignore_thread_messages;
4470 gboolean selection_has_important_messages;
4471 gboolean selection_has_junk_messages;
4472 gboolean selection_has_not_junk_messages;
4473 gboolean selection_has_read_messages;
4474 gboolean selection_has_undeleted_messages;
4475 gboolean selection_has_unimportant_messages;
4476 gboolean selection_has_unread_messages;
4477 gboolean selection_has_mail_note;
4478 gboolean selection_has_color;
4479 gboolean selection_is_mailing_list;
4480 gboolean single_message_selected;
4481 gboolean first_message_selected = FALSE;
4482 gboolean last_message_selected = FALSE;
4483
4484 have_enabled_account =
4485 (state & E_MAIL_READER_HAVE_ENABLED_ACCOUNT);
4486 single_message_selected =
4487 (state & E_MAIL_READER_SELECTION_SINGLE);
4488 multiple_messages_selected =
4489 (state & E_MAIL_READER_SELECTION_MULTIPLE);
4490 /* FIXME Missing CAN_ADD_SENDER */
4491 enable_flag_clear =
4492 (state & E_MAIL_READER_SELECTION_FLAG_CLEAR);
4493 enable_flag_completed =
4494 (state & E_MAIL_READER_SELECTION_FLAG_COMPLETED);
4495 selection_has_attachment_messages =
4496 (state & E_MAIL_READER_SELECTION_HAS_ATTACHMENTS);
4497 selection_has_deleted_messages =
4498 (state & E_MAIL_READER_SELECTION_HAS_DELETED);
4499 selection_has_ignore_thread_messages =
4500 (state & E_MAIL_READER_SELECTION_HAS_IGNORE_THREAD);
4501 selection_has_notignore_thread_messages =
4502 (state & E_MAIL_READER_SELECTION_HAS_NOTIGNORE_THREAD);
4503 selection_has_important_messages =
4504 (state & E_MAIL_READER_SELECTION_HAS_IMPORTANT);
4505 selection_has_junk_messages =
4506 (state & E_MAIL_READER_SELECTION_HAS_JUNK);
4507 selection_has_not_junk_messages =
4508 (state & E_MAIL_READER_SELECTION_HAS_NOT_JUNK);
4509 selection_has_read_messages =
4510 (state & E_MAIL_READER_SELECTION_HAS_READ);
4511 selection_has_undeleted_messages =
4512 (state & E_MAIL_READER_SELECTION_HAS_UNDELETED);
4513 selection_has_unimportant_messages =
4514 (state & E_MAIL_READER_SELECTION_HAS_UNIMPORTANT);
4515 selection_has_unread_messages =
4516 (state & E_MAIL_READER_SELECTION_HAS_UNREAD);
4517 selection_has_mail_note =
4518 (state & E_MAIL_READER_SELECTION_HAS_MAIL_NOTE);
4519 selection_has_color =
4520 (state & E_MAIL_READER_SELECTION_HAS_COLOR);
4521 selection_is_mailing_list =
4522 (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST);
4523
4524 any_messages_selected =
4525 (single_message_selected || multiple_messages_selected);
4526
4527 mail_display = e_mail_reader_get_mail_display (reader);
4528
4529 if (any_messages_selected) {
4530 MessageList *message_list;
4531 gint row = -1, count = -1;
4532 ETreeTableAdapter *etta;
4533 ETreePath node = NULL;
4534
4535 message_list = MESSAGE_LIST (
4536 e_mail_reader_get_message_list (reader));
4537 etta = e_tree_get_table_adapter (E_TREE (message_list));
4538
4539 if (message_list->cursor_uid != NULL)
4540 node = g_hash_table_lookup (
4541 message_list->uid_nodemap,
4542 message_list->cursor_uid);
4543
4544 if (node != NULL) {
4545 row = e_tree_table_adapter_row_of_node (etta, node);
4546 count = e_table_model_row_count (E_TABLE_MODEL (etta));
4547 }
4548
4549 first_message_selected = row <= 0;
4550 last_message_selected = row < 0 || row + 1 >= count;
4551 }
4552
4553 action_name = "mail-add-sender";
4554 sensitive = single_message_selected;
4555 action = e_mail_reader_get_action (reader, action_name);
4556 gtk_action_set_sensitive (action, sensitive);
4557
4558 action_name = "mail-archive";
4559 sensitive = any_messages_selected && (state & E_MAIL_READER_FOLDER_ARCHIVE_FOLDER_SET) != 0;
4560 action = e_mail_reader_get_action (reader, action_name);
4561 gtk_action_set_sensitive (action, sensitive);
4562
4563 action_name = "mail-check-for-junk";
4564 sensitive = any_messages_selected;
4565 action = e_mail_reader_get_action (reader, action_name);
4566 gtk_action_set_sensitive (action, sensitive);
4567
4568 action_name = "mail-color-assign";
4569 sensitive = any_messages_selected;
4570 action = e_mail_reader_get_action (reader, action_name);
4571 gtk_action_set_sensitive (action, sensitive);
4572
4573 action_name = "mail-color-unset";
4574 sensitive = any_messages_selected && selection_has_color;
4575 action = e_mail_reader_get_action (reader, action_name);
4576 gtk_action_set_sensitive (action, sensitive);
4577
4578 action_name = "mail-copy";
4579 sensitive = any_messages_selected;
4580 action = e_mail_reader_get_action (reader, action_name);
4581 gtk_action_set_sensitive (action, sensitive);
4582
4583 action_name = "mail-create-menu";
4584 sensitive = single_message_selected;
4585 action = e_mail_reader_get_action (reader, action_name);
4586 gtk_action_set_sensitive (action, sensitive);
4587
4588 /* If a single message is selected, let the user hit delete to
4589 * advance the cursor even if the message is already deleted. */
4590 action_name = "mail-delete";
4591 sensitive =
4592 (single_message_selected ||
4593 selection_has_undeleted_messages) &&
4594 (state & E_MAIL_READER_FOLDER_IS_VTRASH) == 0;
4595 action = e_mail_reader_get_action (reader, action_name);
4596 gtk_action_set_sensitive (action, sensitive);
4597
4598 action_name = "mail-add-note";
4599 sensitive = single_message_selected && !selection_has_mail_note;
4600 action = e_mail_reader_get_action (reader, action_name);
4601 gtk_action_set_sensitive (action, sensitive);
4602 gtk_action_set_visible (action, sensitive);
4603
4604 action_name = "mail-edit-note";
4605 sensitive = single_message_selected && selection_has_mail_note;
4606 action = e_mail_reader_get_action (reader, action_name);
4607 gtk_action_set_sensitive (action, sensitive);
4608 gtk_action_set_visible (action, sensitive);
4609
4610 action_name = "mail-delete-note";
4611 sensitive = single_message_selected && selection_has_mail_note;
4612 action = e_mail_reader_get_action (reader, action_name);
4613 gtk_action_set_sensitive (action, sensitive);
4614 gtk_action_set_visible (action, sensitive);
4615
4616 action_name = "mail-filters-apply";
4617 sensitive = any_messages_selected;
4618 action = e_mail_reader_get_action (reader, action_name);
4619 gtk_action_set_sensitive (action, sensitive);
4620
4621 action_name = "mail-filter-rule-for-mailing-list";
4622 sensitive = single_message_selected && selection_is_mailing_list;
4623 action = e_mail_reader_get_action (reader, action_name);
4624 gtk_action_set_sensitive (action, sensitive);
4625
4626 action_name = "mail-find";
4627 sensitive = single_message_selected;
4628 action = e_mail_reader_get_action (reader, action_name);
4629 gtk_action_set_sensitive (action, sensitive);
4630
4631 action_name = "mail-flag-clear";
4632 sensitive = enable_flag_clear;
4633 action = e_mail_reader_get_action (reader, action_name);
4634 gtk_action_set_sensitive (action, sensitive);
4635
4636 action_name = "mail-flag-completed";
4637 sensitive = enable_flag_completed;
4638 action = e_mail_reader_get_action (reader, action_name);
4639 gtk_action_set_sensitive (action, sensitive);
4640
4641 action_name = "mail-flag-for-followup";
4642 sensitive = any_messages_selected;
4643 action = e_mail_reader_get_action (reader, action_name);
4644 gtk_action_set_sensitive (action, sensitive);
4645
4646 action_name = "mail-forward";
4647 sensitive = have_enabled_account && any_messages_selected;
4648 action = e_mail_reader_get_action (reader, action_name);
4649 gtk_action_set_sensitive (action, sensitive);
4650
4651 action_name = "mail-forward-attached";
4652 sensitive = have_enabled_account && any_messages_selected;
4653 action = e_mail_reader_get_action (reader, action_name);
4654 gtk_action_set_sensitive (action, sensitive);
4655
4656 action_name = "mail-forward-attached-full";
4657 sensitive = have_enabled_account && any_messages_selected;
4658 action = e_mail_reader_get_action (reader, action_name);
4659 gtk_action_set_sensitive (action, sensitive);
4660
4661 action_name = "mail-forward-as-menu";
4662 sensitive = have_enabled_account && any_messages_selected;
4663 action = e_mail_reader_get_action (reader, action_name);
4664 gtk_action_set_sensitive (action, sensitive);
4665
4666 action_name = "mail-forward-inline";
4667 sensitive = have_enabled_account && single_message_selected;
4668 action = e_mail_reader_get_action (reader, action_name);
4669 gtk_action_set_sensitive (action, sensitive);
4670
4671 action_name = "mail-forward-inline-full";
4672 sensitive = have_enabled_account && single_message_selected;
4673 action = e_mail_reader_get_action (reader, action_name);
4674 gtk_action_set_sensitive (action, sensitive);
4675
4676 action_name = "mail-forward-quoted";
4677 sensitive = have_enabled_account && single_message_selected;
4678 action = e_mail_reader_get_action (reader, action_name);
4679 gtk_action_set_sensitive (action, sensitive);
4680
4681 action_name = "mail-forward-quoted-full";
4682 sensitive = have_enabled_account && single_message_selected;
4683 action = e_mail_reader_get_action (reader, action_name);
4684 gtk_action_set_sensitive (action, sensitive);
4685
4686 action_name = "mail-goto-menu";
4687 sensitive = any_messages_selected;
4688 action = e_mail_reader_get_action (reader, action_name);
4689 gtk_action_set_sensitive (action, sensitive);
4690
4691 action_name = "mail-load-images";
4692 sensitive = single_message_selected;
4693 action = e_mail_reader_get_action (reader, action_name);
4694 gtk_action_set_sensitive (action, sensitive);
4695
4696 action_name = "mail-mark-as-menu";
4697 sensitive = any_messages_selected;
4698 action = e_mail_reader_get_action (reader, action_name);
4699 gtk_action_set_sensitive (action, sensitive);
4700
4701 action_name = "mail-mark-ignore-thread-sub";
4702 sensitive = selection_has_notignore_thread_messages;
4703 action = e_mail_reader_get_action (reader, action_name);
4704 gtk_action_set_sensitive (action, sensitive);
4705 gtk_action_set_visible (action, sensitive);
4706
4707 action_name = "mail-mark-ignore-thread-whole";
4708 sensitive = selection_has_notignore_thread_messages;
4709 action = e_mail_reader_get_action (reader, action_name);
4710 gtk_action_set_sensitive (action, sensitive);
4711 gtk_action_set_visible (action, sensitive);
4712
4713 action_name = "mail-mark-important";
4714 sensitive = selection_has_unimportant_messages;
4715 action = e_mail_reader_get_action (reader, action_name);
4716 gtk_action_set_sensitive (action, sensitive);
4717
4718 action_name = "mail-mark-junk";
4719 sensitive = selection_has_not_junk_messages;
4720 action = e_mail_reader_get_action (reader, action_name);
4721 gtk_action_set_sensitive (action, sensitive);
4722
4723 action_name = "mail-mark-notjunk";
4724 sensitive = selection_has_junk_messages;
4725 action = e_mail_reader_get_action (reader, action_name);
4726 gtk_action_set_sensitive (action, sensitive);
4727
4728 action_name = "mail-mark-read";
4729 sensitive = selection_has_unread_messages;
4730 action = e_mail_reader_get_action (reader, action_name);
4731 gtk_action_set_sensitive (action, sensitive);
4732
4733 action_name = "mail-mark-unignore-thread-sub";
4734 sensitive = selection_has_ignore_thread_messages;
4735 action = e_mail_reader_get_action (reader, action_name);
4736 gtk_action_set_sensitive (action, sensitive);
4737 gtk_action_set_visible (action, sensitive);
4738
4739 action_name = "mail-mark-unignore-thread-whole";
4740 sensitive = selection_has_ignore_thread_messages;
4741 action = e_mail_reader_get_action (reader, action_name);
4742 gtk_action_set_sensitive (action, sensitive);
4743 gtk_action_set_visible (action, sensitive);
4744
4745 action_name = "mail-mark-unimportant";
4746 sensitive = selection_has_important_messages;
4747 action = e_mail_reader_get_action (reader, action_name);
4748 gtk_action_set_sensitive (action, sensitive);
4749
4750 action_name = "mail-mark-unread";
4751 sensitive = selection_has_read_messages;
4752 action = e_mail_reader_get_action (reader, action_name);
4753 gtk_action_set_sensitive (action, sensitive);
4754
4755 action_name = "mail-message-edit";
4756 sensitive = have_enabled_account && single_message_selected;
4757 action = e_mail_reader_get_action (reader, action_name);
4758 gtk_action_set_sensitive (action, sensitive);
4759
4760 action_name = "mail-message-new";
4761 sensitive = have_enabled_account;
4762 action = e_mail_reader_get_action (reader, action_name);
4763 gtk_action_set_sensitive (action, sensitive);
4764
4765 action_name = "mail-message-open";
4766 sensitive = any_messages_selected;
4767 action = e_mail_reader_get_action (reader, action_name);
4768 gtk_action_set_sensitive (action, sensitive);
4769
4770 action_name = "mail-move";
4771 sensitive = any_messages_selected;
4772 action = e_mail_reader_get_action (reader, action_name);
4773 gtk_action_set_sensitive (action, sensitive);
4774
4775 action_name = "mail-next";
4776 sensitive = any_messages_selected && !last_message_selected;
4777 action = e_mail_reader_get_action (reader, action_name);
4778 gtk_action_set_sensitive (action, sensitive);
4779
4780 action_name = "mail-next-important";
4781 sensitive = single_message_selected;
4782 action = e_mail_reader_get_action (reader, action_name);
4783 gtk_action_set_sensitive (action, sensitive);
4784
4785 action_name = "mail-next-thread";
4786 sensitive = single_message_selected && !last_message_selected;
4787 action = e_mail_reader_get_action (reader, action_name);
4788 gtk_action_set_sensitive (action, sensitive);
4789
4790 action_name = "mail-next-unread";
4791 sensitive = any_messages_selected;
4792 action = e_mail_reader_get_action (reader, action_name);
4793 gtk_action_set_sensitive (action, sensitive);
4794
4795 action_name = "mail-previous";
4796 sensitive = any_messages_selected && !first_message_selected;
4797 action = e_mail_reader_get_action (reader, action_name);
4798 gtk_action_set_sensitive (action, sensitive);
4799
4800 action_name = "mail-previous-important";
4801 sensitive = single_message_selected;
4802 action = e_mail_reader_get_action (reader, action_name);
4803 gtk_action_set_sensitive (action, sensitive);
4804
4805 action_name = "mail-previous-unread";
4806 sensitive = any_messages_selected;
4807 action = e_mail_reader_get_action (reader, action_name);
4808 gtk_action_set_sensitive (action, sensitive);
4809
4810 action_name = "mail-previous-thread";
4811 sensitive = any_messages_selected && !first_message_selected;
4812 action = e_mail_reader_get_action (reader, action_name);
4813 gtk_action_set_sensitive (action, sensitive);
4814
4815 action_name = "mail-print";
4816 sensitive = single_message_selected;
4817 action = e_mail_reader_get_action (reader, action_name);
4818 gtk_action_set_sensitive (action, sensitive);
4819
4820 action_name = "mail-print-preview";
4821 sensitive = single_message_selected;
4822 action = e_mail_reader_get_action (reader, action_name);
4823 gtk_action_set_sensitive (action, sensitive);
4824
4825 action_name = "mail-redirect";
4826 sensitive = have_enabled_account && single_message_selected;
4827 action = e_mail_reader_get_action (reader, action_name);
4828 gtk_action_set_sensitive (action, sensitive);
4829
4830 action_name = "mail-remove-attachments";
4831 sensitive = any_messages_selected && selection_has_attachment_messages;
4832 action = e_mail_reader_get_action (reader, action_name);
4833 gtk_action_set_sensitive (action, sensitive);
4834
4835 action_name = "mail-remove-duplicates";
4836 sensitive = multiple_messages_selected;
4837 action = e_mail_reader_get_action (reader, action_name);
4838 gtk_action_set_sensitive (action, sensitive);
4839
4840 action_name = "mail-reply-all";
4841 sensitive = have_enabled_account && single_message_selected;
4842 action = e_mail_reader_get_action (reader, action_name);
4843 gtk_action_set_sensitive (action, sensitive);
4844
4845 action_name = "mail-reply-alternative";
4846 sensitive = have_enabled_account && single_message_selected;
4847 action = e_mail_reader_get_action (reader, action_name);
4848 gtk_action_set_sensitive (action, sensitive);
4849
4850 action_name = "mail-reply-group";
4851 sensitive = have_enabled_account && single_message_selected;
4852 action = e_mail_reader_get_action (reader, action_name);
4853 gtk_action_set_sensitive (action, sensitive);
4854
4855 action_name = "mail-reply-group-menu";
4856 sensitive = have_enabled_account && any_messages_selected;
4857 action = e_mail_reader_get_action (reader, action_name);
4858 gtk_action_set_sensitive (action, sensitive);
4859
4860 action_name = "mail-reply-list";
4861 sensitive = have_enabled_account && single_message_selected &&
4862 selection_is_mailing_list;
4863 action = e_mail_reader_get_action (reader, action_name);
4864 gtk_action_set_sensitive (action, sensitive);
4865
4866 action_name = "mail-reply-sender";
4867 sensitive = have_enabled_account && single_message_selected;
4868 action = e_mail_reader_get_action (reader, action_name);
4869 gtk_action_set_sensitive (action, sensitive);
4870
4871 action_name = "mail-save-as";
4872 sensitive = any_messages_selected;
4873 action = e_mail_reader_get_action (reader, action_name);
4874 gtk_action_set_sensitive (action, sensitive);
4875
4876 action_name = "mail-show-source";
4877 sensitive = single_message_selected;
4878 action = e_mail_reader_get_action (reader, action_name);
4879 gtk_action_set_sensitive (action, sensitive);
4880
4881 action_name = "mail-undelete";
4882 sensitive = selection_has_deleted_messages;
4883 action = e_mail_reader_get_action (reader, action_name);
4884 gtk_action_set_sensitive (action, sensitive);
4885
4886 action_name = "mail-zoom-100";
4887 sensitive = single_message_selected;
4888 action = e_mail_reader_get_action (reader, action_name);
4889 gtk_action_set_sensitive (action, sensitive);
4890
4891 action_name = "mail-zoom-in";
4892 sensitive = single_message_selected;
4893 action = e_mail_reader_get_action (reader, action_name);
4894 gtk_action_set_sensitive (action, sensitive);
4895
4896 action_name = "mail-zoom-out";
4897 sensitive = single_message_selected;
4898 action = e_mail_reader_get_action (reader, action_name);
4899 gtk_action_set_sensitive (action, sensitive);
4900
4901 action = e_mail_reader_get_action (reader, "mail-search-web");
4902 gtk_action_set_sensitive (action, single_message_selected &&
4903 mail_display && e_web_view_has_selection (E_WEB_VIEW (mail_display)));
4904
4905 mail_reader_update_labels_menu (reader);
4906 }
4907
4908 static gboolean
mail_reader_close_on_delete_or_junk(EMailReader * reader)4909 mail_reader_close_on_delete_or_junk (EMailReader *reader)
4910 {
4911 return FALSE;
4912 }
4913
4914 static void
mail_reader_init_charset_actions(EMailReader * reader,GtkActionGroup * action_group)4915 mail_reader_init_charset_actions (EMailReader *reader,
4916 GtkActionGroup *action_group)
4917 {
4918 GtkRadioAction *default_action;
4919 GSList *radio_group;
4920
4921 radio_group = e_charset_add_radio_actions (
4922 action_group, "mail-charset-", NULL,
4923 G_CALLBACK (action_mail_charset_cb), reader);
4924
4925 /* XXX Add a tooltip! */
4926 default_action = gtk_radio_action_new (
4927 "mail-charset-default", _("Default"), NULL, NULL, -1);
4928
4929 gtk_radio_action_set_group (default_action, radio_group);
4930
4931 g_signal_connect (
4932 default_action, "changed",
4933 G_CALLBACK (action_mail_charset_cb), reader);
4934
4935 gtk_action_group_add_action (
4936 action_group, GTK_ACTION (default_action));
4937
4938 gtk_radio_action_set_current_value (default_action, -1);
4939 }
4940
4941 static void
e_mail_reader_default_init(EMailReaderInterface * iface)4942 e_mail_reader_default_init (EMailReaderInterface *iface)
4943 {
4944 quark_private = g_quark_from_static_string ("e-mail-reader-private");
4945
4946 iface->get_alert_sink = mail_reader_get_alert_sink;
4947 iface->get_selected_uids = mail_reader_get_selected_uids;
4948 iface->get_selected_uids_with_collapsed_threads = mail_reader_get_selected_uids_with_collapsed_threads;
4949 iface->ref_folder = mail_reader_ref_folder;
4950 iface->set_folder = mail_reader_set_folder;
4951 iface->set_message = mail_reader_set_message;
4952 iface->open_selected_mail = e_mail_reader_open_selected;
4953 iface->folder_loaded = mail_reader_folder_loaded;
4954 iface->message_loaded = mail_reader_message_loaded;
4955 iface->message_seen = mail_reader_message_seen;
4956 iface->show_search_bar = mail_reader_show_search_bar;
4957 iface->update_actions = mail_reader_update_actions;
4958 iface->close_on_delete_or_junk = mail_reader_close_on_delete_or_junk;
4959 iface->reload = mail_reader_reload;
4960 iface->remove_ui = mail_reader_remove_ui;
4961
4962 g_object_interface_install_property (
4963 iface,
4964 g_param_spec_enum (
4965 "forward-style",
4966 "Forward Style",
4967 "How to forward messages",
4968 E_TYPE_MAIL_FORWARD_STYLE,
4969 E_MAIL_FORWARD_STYLE_ATTACHED,
4970 G_PARAM_READWRITE));
4971
4972 g_object_interface_install_property (
4973 iface,
4974 g_param_spec_boolean (
4975 "group-by-threads",
4976 "Group by Threads",
4977 "Whether to group messages by threads",
4978 FALSE,
4979 G_PARAM_READWRITE));
4980
4981 g_object_interface_install_property (
4982 iface,
4983 g_param_spec_enum (
4984 "reply-style",
4985 "Reply Style",
4986 "How to reply to messages",
4987 E_TYPE_MAIL_REPLY_STYLE,
4988 E_MAIL_REPLY_STYLE_QUOTED,
4989 G_PARAM_READWRITE));
4990
4991 g_object_interface_install_property (
4992 iface,
4993 g_param_spec_boolean (
4994 "mark-seen-always",
4995 "Mark Seen Always",
4996 "Whether to mark unread message seen even after folder change",
4997 FALSE,
4998 G_PARAM_READWRITE));
4999
5000 g_object_interface_install_property (
5001 iface,
5002 g_param_spec_boolean (
5003 "delete-selects-previous",
5004 "Delete Selects Previous",
5005 "Whether go to the previous message after message deletion",
5006 FALSE,
5007 G_PARAM_READWRITE));
5008
5009 signals[CHANGED] = g_signal_new (
5010 "changed",
5011 G_OBJECT_CLASS_TYPE (iface),
5012 G_SIGNAL_RUN_FIRST,
5013 0, NULL, NULL,
5014 g_cclosure_marshal_VOID__VOID,
5015 G_TYPE_NONE, 0);
5016
5017 signals[COMPOSER_CREATED] = g_signal_new (
5018 "composer-created",
5019 G_OBJECT_CLASS_TYPE (iface),
5020 G_SIGNAL_RUN_FIRST,
5021 G_STRUCT_OFFSET (EMailReaderInterface, composer_created),
5022 NULL, NULL, NULL,
5023 G_TYPE_NONE, 2,
5024 E_TYPE_MSG_COMPOSER,
5025 CAMEL_TYPE_MIME_MESSAGE);
5026
5027 signals[FOLDER_LOADED] = g_signal_new (
5028 "folder-loaded",
5029 G_OBJECT_CLASS_TYPE (iface),
5030 G_SIGNAL_RUN_FIRST,
5031 G_STRUCT_OFFSET (EMailReaderInterface, folder_loaded),
5032 NULL, NULL,
5033 g_cclosure_marshal_VOID__VOID,
5034 G_TYPE_NONE, 0);
5035
5036 signals[MESSAGE_LOADED] = g_signal_new (
5037 "message-loaded",
5038 G_OBJECT_CLASS_TYPE (iface),
5039 G_SIGNAL_RUN_LAST,
5040 G_STRUCT_OFFSET (EMailReaderInterface, message_loaded),
5041 NULL, NULL,
5042 e_marshal_VOID__STRING_OBJECT,
5043 G_TYPE_NONE, 2,
5044 G_TYPE_STRING,
5045 CAMEL_TYPE_MIME_MESSAGE);
5046
5047 signals[MESSAGE_SEEN] = g_signal_new (
5048 "message-seen",
5049 G_OBJECT_CLASS_TYPE (iface),
5050 G_SIGNAL_RUN_LAST,
5051 G_STRUCT_OFFSET (EMailReaderInterface, message_seen),
5052 NULL, NULL,
5053 e_marshal_VOID__STRING_OBJECT,
5054 G_TYPE_NONE, 2,
5055 G_TYPE_STRING,
5056 CAMEL_TYPE_MIME_MESSAGE);
5057
5058 signals[SHOW_SEARCH_BAR] = g_signal_new (
5059 "show-search-bar",
5060 G_OBJECT_CLASS_TYPE (iface),
5061 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
5062 G_STRUCT_OFFSET (EMailReaderInterface, show_search_bar),
5063 NULL, NULL,
5064 g_cclosure_marshal_VOID__VOID,
5065 G_TYPE_NONE, 0);
5066
5067 signals[UPDATE_ACTIONS] = g_signal_new (
5068 "update-actions",
5069 G_OBJECT_CLASS_TYPE (iface),
5070 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
5071 G_STRUCT_OFFSET (EMailReaderInterface, update_actions),
5072 NULL, NULL,
5073 g_cclosure_marshal_VOID__UINT,
5074 G_TYPE_NONE, 1,
5075 G_TYPE_UINT);
5076 }
5077
5078 void
e_mail_reader_init(EMailReader * reader,gboolean init_actions,gboolean connect_signals)5079 e_mail_reader_init (EMailReader *reader,
5080 gboolean init_actions,
5081 gboolean connect_signals)
5082 {
5083 EMenuToolAction *menu_tool_action;
5084 GtkActionGroup *action_group;
5085 GtkWidget *message_list;
5086 GtkAction *action;
5087 const gchar *action_name;
5088 EMailDisplay *display;
5089 GSettings *settings;
5090
5091 g_return_if_fail (E_IS_MAIL_READER (reader));
5092
5093 message_list = e_mail_reader_get_message_list (reader);
5094 display = e_mail_reader_get_mail_display (reader);
5095
5096 /* Initialize a private struct. */
5097 g_object_set_qdata_full (
5098 G_OBJECT (reader), quark_private,
5099 g_slice_new0 (EMailReaderPrivate),
5100 (GDestroyNotify) mail_reader_private_free);
5101
5102 e_binding_bind_property (
5103 reader, "group-by-threads",
5104 message_list, "group-by-threads",
5105 G_BINDING_SYNC_CREATE);
5106
5107 if (!init_actions)
5108 goto connect_signals;
5109
5110 /* Add the "standard" EMailReader actions. */
5111
5112 action_group = e_mail_reader_get_action_group (
5113 reader, E_MAIL_READER_ACTION_GROUP_STANDARD);
5114
5115 /* The "mail-forward" action is special: it uses a GtkMenuToolButton
5116 * for its toolbar item type. So we have to create it separately. */
5117
5118 menu_tool_action = e_menu_tool_action_new (
5119 "mail-forward", _("_Forward"),
5120 _("Forward the selected message to someone"));
5121
5122 gtk_action_set_icon_name (
5123 GTK_ACTION (menu_tool_action), "mail-forward");
5124
5125 g_signal_connect (
5126 menu_tool_action, "activate",
5127 G_CALLBACK (action_mail_forward_cb), reader);
5128
5129 gtk_action_group_add_action_with_accel (
5130 action_group, GTK_ACTION (menu_tool_action), "<Control>f");
5131
5132 /* Likewise the "mail-reply-group" action. */
5133
5134 menu_tool_action = e_menu_tool_action_new (
5135 /* For Translators: "Group Reply" will reply either to a mailing list
5136 * (if possible and if that configuration option is enabled), or else
5137 * it will reply to all. The word "Group" was chosen because it covers
5138 * either of those, without too strongly implying one or the other. */
5139 "mail-reply-group", _("Group Reply"),
5140 _("Reply to the mailing list, or to all recipients"));
5141
5142 gtk_action_set_icon_name (
5143 GTK_ACTION (menu_tool_action), "mail-reply-all");
5144
5145 g_signal_connect (
5146 menu_tool_action, "activate",
5147 G_CALLBACK (action_mail_reply_group_cb), reader);
5148
5149 gtk_action_group_add_action_with_accel (
5150 action_group, GTK_ACTION (menu_tool_action), "<Control>g");
5151
5152 /* Add the other actions the normal way. */
5153 gtk_action_group_add_actions (
5154 action_group, mail_reader_entries,
5155 G_N_ELEMENTS (mail_reader_entries), reader);
5156 e_action_group_add_popup_actions (
5157 action_group, mail_reader_popup_entries,
5158 G_N_ELEMENTS (mail_reader_popup_entries));
5159 gtk_action_group_add_toggle_actions (
5160 action_group, mail_reader_toggle_entries,
5161 G_N_ELEMENTS (mail_reader_toggle_entries), reader);
5162
5163 mail_reader_init_charset_actions (reader, action_group);
5164
5165 /* Add EMailReader actions for Search Folders. The action group
5166 * should be made invisible if Search Folders are disabled. */
5167
5168 action_group = e_mail_reader_get_action_group (
5169 reader, E_MAIL_READER_ACTION_GROUP_SEARCH_FOLDERS);
5170
5171 gtk_action_group_add_actions (
5172 action_group, mail_reader_search_folder_entries,
5173 G_N_ELEMENTS (mail_reader_search_folder_entries), reader);
5174
5175 display = e_mail_reader_get_mail_display (reader);
5176
5177 /* Bind GObject properties to GSettings keys. */
5178
5179 settings = e_util_ref_settings ("org.gnome.evolution.mail");
5180
5181 action_name = "mail-caret-mode";
5182 action = e_mail_reader_get_action (reader, action_name);
5183 g_settings_bind (
5184 settings, "caret-mode",
5185 action, "active", G_SETTINGS_BIND_DEFAULT);
5186
5187 action_name = "mail-show-all-headers";
5188 action = e_mail_reader_get_action (reader, action_name);
5189 g_settings_bind (
5190 settings, "show-all-headers",
5191 action, "active", G_SETTINGS_BIND_DEFAULT);
5192
5193 /* Mode change when viewing message source is ignored. */
5194 if (e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_SOURCE ||
5195 e_mail_display_get_mode (display) == E_MAIL_FORMATTER_MODE_RAW) {
5196 gtk_action_set_sensitive (action, FALSE);
5197 gtk_action_set_visible (action, FALSE);
5198 }
5199
5200 g_object_unref (settings);
5201
5202 /* Fine tuning. */
5203
5204 action_name = "mail-delete";
5205 action = e_mail_reader_get_action (reader, action_name);
5206 gtk_action_set_short_label (action, _("Delete"));
5207
5208 action_name = "mail-forward";
5209 action = e_mail_reader_get_action (reader, action_name);
5210 gtk_action_set_is_important (action, TRUE);
5211
5212 action_name = "mail-reply-group";
5213 action = e_mail_reader_get_action (reader, action_name);
5214 gtk_action_set_is_important (action, TRUE);
5215
5216 action_name = "mail-next";
5217 action = e_mail_reader_get_action (reader, action_name);
5218 gtk_action_set_short_label (action, _("Next"));
5219
5220 action_name = "mail-previous";
5221 action = e_mail_reader_get_action (reader, action_name);
5222 gtk_action_set_short_label (action, _("Previous"));
5223
5224 action_name = "mail-reply-all";
5225 action = e_mail_reader_get_action (reader, action_name);
5226 gtk_action_set_is_important (action, TRUE);
5227
5228 action_name = "mail-reply-sender";
5229 action = e_mail_reader_get_action (reader, action_name);
5230 gtk_action_set_is_important (action, TRUE);
5231 gtk_action_set_short_label (action, _("Reply"));
5232
5233 action_name = "add-to-address-book";
5234 action = e_mail_display_get_action (display, action_name);
5235 g_signal_connect (
5236 action, "activate",
5237 G_CALLBACK (action_add_to_address_book_cb), reader);
5238
5239 action_name = "send-reply";
5240 action = e_mail_display_get_action (display, action_name);
5241 g_signal_connect (
5242 action, "activate",
5243 G_CALLBACK (action_mail_reply_recipient_cb), reader);
5244
5245 action_name = "search-folder-recipient";
5246 action = e_mail_display_get_action (display, action_name);
5247 g_signal_connect (
5248 action, "activate",
5249 G_CALLBACK (action_search_folder_recipient_cb), reader);
5250
5251 action_name = "search-folder-sender";
5252 action = e_mail_display_get_action (display, action_name);
5253 g_signal_connect (
5254 action, "activate",
5255 G_CALLBACK (action_search_folder_sender_cb), reader);
5256
5257 #ifndef G_OS_WIN32
5258 /* Lockdown integration. */
5259
5260 settings = e_util_ref_settings ("org.gnome.desktop.lockdown");
5261
5262 action_name = "mail-print";
5263 action = e_mail_reader_get_action (reader, action_name);
5264 g_settings_bind (
5265 settings, "disable-printing",
5266 action, "visible",
5267 G_SETTINGS_BIND_GET |
5268 G_SETTINGS_BIND_NO_SENSITIVITY |
5269 G_SETTINGS_BIND_INVERT_BOOLEAN);
5270
5271 action_name = "mail-print-preview";
5272 action = e_mail_reader_get_action (reader, action_name);
5273 g_settings_bind (
5274 settings, "disable-printing",
5275 action, "visible",
5276 G_SETTINGS_BIND_GET |
5277 G_SETTINGS_BIND_NO_SENSITIVITY |
5278 G_SETTINGS_BIND_INVERT_BOOLEAN);
5279
5280 action_name = "mail-save-as";
5281 action = e_mail_reader_get_action (reader, action_name);
5282 g_settings_bind (
5283 settings, "disable-save-to-disk",
5284 action, "visible",
5285 G_SETTINGS_BIND_GET |
5286 G_SETTINGS_BIND_NO_SENSITIVITY |
5287 G_SETTINGS_BIND_INVERT_BOOLEAN);
5288
5289 g_object_unref (settings);
5290 #endif
5291
5292 /* Bind properties. */
5293
5294 action_name = "mail-caret-mode";
5295 action = e_mail_reader_get_action (reader, action_name);
5296
5297 e_binding_bind_property (
5298 action, "active",
5299 display, "caret-mode",
5300 G_BINDING_BIDIRECTIONAL |
5301 G_BINDING_SYNC_CREATE);
5302
5303 connect_signals:
5304
5305 if (!connect_signals)
5306 return;
5307
5308 /* Connect signals. */
5309 g_signal_connect_swapped (
5310 display, "key-press-event",
5311 G_CALLBACK (mail_reader_key_press_event_cb), reader);
5312
5313 g_signal_connect_swapped (
5314 display, "load-changed",
5315 G_CALLBACK (mail_reader_load_changed_cb), reader);
5316
5317 g_signal_connect_swapped (
5318 display, "remote-content-clicked",
5319 G_CALLBACK (mail_reader_remote_content_clicked_cb), reader);
5320
5321 g_signal_connect_swapped (
5322 message_list, "message-selected",
5323 G_CALLBACK (mail_reader_message_selected_cb), reader);
5324
5325 g_signal_connect_swapped (
5326 message_list, "update-actions",
5327 G_CALLBACK (mail_reader_message_list_suggest_update_actions_cb), reader);
5328
5329 /* re-schedule mark-as-seen,... */
5330 g_signal_connect_swapped (
5331 message_list, "cursor-change",
5332 G_CALLBACK (mail_reader_message_cursor_change_cb), reader);
5333
5334 /* but do not mark-as-seen if... */
5335 g_signal_connect_swapped (
5336 message_list, "tree-drag-begin",
5337 G_CALLBACK (discard_timeout_mark_seen_cb), reader);
5338
5339 g_signal_connect_swapped (
5340 message_list, "tree-drag-end",
5341 G_CALLBACK (discard_timeout_mark_seen_cb), reader);
5342
5343 g_signal_connect_swapped (
5344 message_list, "right-click",
5345 G_CALLBACK (discard_timeout_mark_seen_cb), reader);
5346
5347 g_signal_connect_swapped (
5348 e_mail_reader_get_preview_pane (reader), "notify::visible",
5349 G_CALLBACK (mail_reader_preview_pane_visible_changed_cb), reader);
5350
5351 g_signal_connect_after (
5352 message_list, "message-list-built",
5353 G_CALLBACK (mail_reader_message_list_built_cb), reader);
5354
5355 g_signal_connect_swapped (
5356 message_list, "double-click",
5357 G_CALLBACK (mail_reader_double_click_cb), reader);
5358
5359 g_signal_connect_swapped (
5360 message_list, "key-press",
5361 G_CALLBACK (mail_reader_key_press_cb), reader);
5362
5363 g_signal_connect_swapped (
5364 message_list, "selection-change",
5365 G_CALLBACK (e_mail_reader_changed), reader);
5366 }
5367
5368 static void
mail_reader_ongoing_operation_destroyed(gpointer user_data,GObject * cancellable)5369 mail_reader_ongoing_operation_destroyed (gpointer user_data,
5370 GObject *cancellable)
5371 {
5372 EMailReader *reader = user_data;
5373 EMailReaderPrivate *priv;
5374
5375 g_return_if_fail (E_IS_MAIL_READER (reader));
5376
5377 priv = E_MAIL_READER_GET_PRIVATE (reader);
5378
5379 priv->ongoing_operations = g_slist_remove (priv->ongoing_operations, cancellable);
5380 }
5381
5382 void
e_mail_reader_dispose(EMailReader * reader)5383 e_mail_reader_dispose (EMailReader *reader)
5384 {
5385 EMailReaderPrivate *priv;
5386 EMailDisplay *mail_display;
5387 GtkWidget *message_list;
5388 GSList *ongoing_operations, *link;
5389
5390 g_return_if_fail (E_IS_MAIL_READER (reader));
5391
5392 priv = E_MAIL_READER_GET_PRIVATE (reader);
5393
5394 if (priv->message_selected_timeout_id > 0) {
5395 g_source_remove (priv->message_selected_timeout_id);
5396 priv->message_selected_timeout_id = 0;
5397 }
5398
5399 if (priv->retrieving_message)
5400 g_cancellable_cancel (priv->retrieving_message);
5401
5402 ongoing_operations = g_slist_copy_deep (priv->ongoing_operations, (GCopyFunc) g_object_ref, NULL);
5403 g_slist_free (priv->ongoing_operations);
5404 priv->ongoing_operations = NULL;
5405
5406 for (link = ongoing_operations; link; link = g_slist_next (link)) {
5407 GCancellable *cancellable = link->data;
5408
5409 g_object_weak_unref (G_OBJECT (cancellable), mail_reader_ongoing_operation_destroyed, reader);
5410
5411 g_cancellable_cancel (cancellable);
5412 }
5413
5414 g_slist_free_full (ongoing_operations, g_object_unref);
5415
5416 mail_display = e_mail_reader_get_mail_display (reader);
5417 if (mail_display)
5418 g_signal_handlers_disconnect_by_data (mail_display, reader);
5419
5420 message_list = e_mail_reader_get_message_list (reader);
5421 if (message_list)
5422 g_signal_handlers_disconnect_by_data (message_list, reader);
5423 }
5424
5425 void
e_mail_reader_changed(EMailReader * reader)5426 e_mail_reader_changed (EMailReader *reader)
5427 {
5428 MessageList *message_list;
5429
5430 g_return_if_fail (E_IS_MAIL_READER (reader));
5431
5432 g_signal_emit (reader, signals[CHANGED], 0);
5433
5434 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
5435
5436 if (!message_list || message_list_selected_count (message_list) != 1)
5437 mail_reader_remove_followup_alert (reader);
5438 }
5439
5440 guint32
e_mail_reader_check_state(EMailReader * reader)5441 e_mail_reader_check_state (EMailReader *reader)
5442 {
5443 EShell *shell;
5444 GPtrArray *uids;
5445 CamelFolder *folder;
5446 CamelStore *store = NULL;
5447 EMailBackend *backend;
5448 ESourceRegistry *registry;
5449 EMailSession *mail_session;
5450 EMailAccountStore *account_store;
5451 const gchar *tag;
5452 gboolean can_clear_flags = FALSE;
5453 gboolean can_flag_completed = FALSE;
5454 gboolean can_flag_for_followup = FALSE;
5455 gboolean has_attachments = FALSE;
5456 gboolean has_deleted = FALSE;
5457 gboolean has_ignore_thread = FALSE;
5458 gboolean has_notignore_thread = FALSE;
5459 gboolean has_important = FALSE;
5460 gboolean has_junk = FALSE;
5461 gboolean has_not_junk = FALSE;
5462 gboolean has_read = FALSE;
5463 gboolean has_undeleted = FALSE;
5464 gboolean has_unimportant = FALSE;
5465 gboolean has_unread = FALSE;
5466 gboolean has_mail_note = FALSE;
5467 gboolean has_color = FALSE;
5468 gboolean have_enabled_account = FALSE;
5469 gboolean drafts_or_outbox = FALSE;
5470 gboolean is_mailing_list;
5471 gboolean is_junk_folder = FALSE;
5472 gboolean is_vtrash_folder = FALSE;
5473 gboolean archive_folder_set = FALSE;
5474 guint32 state = 0;
5475 guint ii;
5476
5477 g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
5478
5479 backend = e_mail_reader_get_backend (reader);
5480 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
5481 registry = e_shell_get_registry (shell);
5482 mail_session = e_mail_backend_get_session (backend);
5483 account_store = e_mail_ui_session_get_account_store (
5484 E_MAIL_UI_SESSION (mail_session));
5485
5486 folder = e_mail_reader_ref_folder (reader);
5487 uids = e_mail_reader_get_selected_uids_with_collapsed_threads (reader);
5488
5489 if (folder != NULL) {
5490 gchar *archive_folder;
5491 guint32 folder_flags;
5492
5493 store = camel_folder_get_parent_store (folder);
5494 folder_flags = camel_folder_get_flags (folder);
5495 is_junk_folder = (folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
5496 is_vtrash_folder = (camel_store_get_flags (store) & CAMEL_STORE_VTRASH) != 0 && (folder_flags & CAMEL_FOLDER_IS_TRASH) != 0;
5497 drafts_or_outbox =
5498 em_utils_folder_is_drafts (registry, folder) ||
5499 em_utils_folder_is_outbox (registry, folder);
5500
5501 archive_folder = em_utils_get_archive_folder_uri_from_folder (folder, backend, uids, TRUE);
5502 if (archive_folder && *archive_folder)
5503 archive_folder_set = TRUE;
5504
5505 g_free (archive_folder);
5506 }
5507
5508 /* Initialize this flag based on whether there are any
5509 * messages selected. We will update it in the loop. */
5510 is_mailing_list = (uids->len > 0);
5511
5512 for (ii = 0; ii < uids->len; ii++) {
5513 CamelMessageInfo *info;
5514 const gchar *string;
5515 guint32 flags;
5516
5517 info = camel_folder_get_message_info (
5518 folder, uids->pdata[ii]);
5519 if (info == NULL)
5520 continue;
5521
5522 flags = camel_message_info_get_flags (info);
5523
5524 if (flags & CAMEL_MESSAGE_SEEN)
5525 has_read = TRUE;
5526 else
5527 has_unread = TRUE;
5528
5529 if (flags & CAMEL_MESSAGE_ATTACHMENTS)
5530 has_attachments = TRUE;
5531
5532 if (drafts_or_outbox) {
5533 has_junk = FALSE;
5534 has_not_junk = FALSE;
5535 } else {
5536 guint32 bitmask;
5537
5538 /* XXX Strictly speaking, this logic is correct.
5539 * Problem is there's nothing in the message
5540 * list that indicates whether a message is
5541 * already marked "Not Junk". So the user may
5542 * think the "Not Junk" button is enabling and
5543 * disabling itself randomly as he reads mail. */
5544
5545 if (flags & CAMEL_MESSAGE_JUNK)
5546 has_junk = TRUE;
5547 if (flags & CAMEL_MESSAGE_NOTJUNK)
5548 has_not_junk = TRUE;
5549
5550 bitmask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK;
5551
5552 /* If neither junk flag is set, the
5553 * message can be marked either way. */
5554 if ((flags & bitmask) == 0) {
5555 has_junk = TRUE;
5556 has_not_junk = TRUE;
5557 }
5558 }
5559
5560 if (flags & CAMEL_MESSAGE_DELETED)
5561 has_deleted = TRUE;
5562 else
5563 has_undeleted = TRUE;
5564
5565 if (flags & CAMEL_MESSAGE_FLAGGED)
5566 has_important = TRUE;
5567 else
5568 has_unimportant = TRUE;
5569
5570 tag = camel_message_info_get_user_tag (info, "follow-up");
5571 if (tag != NULL && *tag != '\0') {
5572 can_clear_flags = TRUE;
5573 tag = camel_message_info_get_user_tag (
5574 info, "completed-on");
5575 if (tag == NULL || *tag == '\0')
5576 can_flag_completed = TRUE;
5577 } else
5578 can_flag_for_followup = TRUE;
5579
5580 string = camel_message_info_get_mlist (info);
5581 is_mailing_list &= (string != NULL && *string != '\0');
5582
5583 has_ignore_thread = has_ignore_thread || camel_message_info_get_user_flag (info, "ignore-thread");
5584 has_notignore_thread = has_notignore_thread || !camel_message_info_get_user_flag (info, "ignore-thread");
5585 has_mail_note = has_mail_note || camel_message_info_get_user_flag (info, E_MAIL_NOTES_USER_FLAG);
5586 has_color = has_color || camel_message_info_get_user_tag (info, "color") != NULL;
5587
5588 g_clear_object (&info);
5589 }
5590
5591 have_enabled_account =
5592 e_mail_account_store_have_enabled_service (
5593 account_store, CAMEL_TYPE_STORE);
5594
5595 if (have_enabled_account)
5596 state |= E_MAIL_READER_HAVE_ENABLED_ACCOUNT;
5597 if (uids->len == 1)
5598 state |= E_MAIL_READER_SELECTION_SINGLE;
5599 if (uids->len > 1)
5600 state |= E_MAIL_READER_SELECTION_MULTIPLE;
5601 if (!drafts_or_outbox && uids->len == 1)
5602 state |= E_MAIL_READER_SELECTION_CAN_ADD_SENDER;
5603 if (can_clear_flags)
5604 state |= E_MAIL_READER_SELECTION_FLAG_CLEAR;
5605 if (can_flag_completed)
5606 state |= E_MAIL_READER_SELECTION_FLAG_COMPLETED;
5607 if (can_flag_for_followup)
5608 state |= E_MAIL_READER_SELECTION_FLAG_FOLLOWUP;
5609 if (has_attachments)
5610 state |= E_MAIL_READER_SELECTION_HAS_ATTACHMENTS;
5611 if (has_deleted)
5612 state |= E_MAIL_READER_SELECTION_HAS_DELETED;
5613 if (has_ignore_thread)
5614 state |= E_MAIL_READER_SELECTION_HAS_IGNORE_THREAD;
5615 if (has_notignore_thread)
5616 state |= E_MAIL_READER_SELECTION_HAS_NOTIGNORE_THREAD;
5617 if (has_important)
5618 state |= E_MAIL_READER_SELECTION_HAS_IMPORTANT;
5619 if (has_junk)
5620 state |= E_MAIL_READER_SELECTION_HAS_JUNK;
5621 if (has_not_junk)
5622 state |= E_MAIL_READER_SELECTION_HAS_NOT_JUNK;
5623 if (has_read)
5624 state |= E_MAIL_READER_SELECTION_HAS_READ;
5625 if (has_undeleted)
5626 state |= E_MAIL_READER_SELECTION_HAS_UNDELETED;
5627 if (has_unimportant)
5628 state |= E_MAIL_READER_SELECTION_HAS_UNIMPORTANT;
5629 if (has_unread)
5630 state |= E_MAIL_READER_SELECTION_HAS_UNREAD;
5631 if (is_mailing_list)
5632 state |= E_MAIL_READER_SELECTION_IS_MAILING_LIST;
5633 if (is_junk_folder)
5634 state |= E_MAIL_READER_FOLDER_IS_JUNK;
5635 if (is_vtrash_folder)
5636 state |= E_MAIL_READER_FOLDER_IS_VTRASH;
5637 if (archive_folder_set)
5638 state |= E_MAIL_READER_FOLDER_ARCHIVE_FOLDER_SET;
5639 if (has_mail_note)
5640 state |= E_MAIL_READER_SELECTION_HAS_MAIL_NOTE;
5641 if (has_color)
5642 state |= E_MAIL_READER_SELECTION_HAS_COLOR;
5643
5644 if (!(state & E_MAIL_READER_SELECTION_SINGLE)) {
5645 GPtrArray *real_selected_uids;
5646
5647 real_selected_uids = e_mail_reader_get_selected_uids (reader);
5648
5649 if (real_selected_uids && real_selected_uids->len == 1) {
5650 state |= E_MAIL_READER_SELECTION_SINGLE;
5651 }
5652
5653 if (real_selected_uids)
5654 g_ptr_array_unref (real_selected_uids);
5655 }
5656
5657 g_clear_object (&folder);
5658 g_ptr_array_unref (uids);
5659
5660 return state;
5661 }
5662
5663 EActivity *
e_mail_reader_new_activity(EMailReader * reader)5664 e_mail_reader_new_activity (EMailReader *reader)
5665 {
5666 EMailReaderPrivate *priv;
5667 EActivity *activity;
5668 EMailBackend *backend;
5669 EAlertSink *alert_sink;
5670 GCancellable *cancellable;
5671
5672 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5673
5674 priv = E_MAIL_READER_GET_PRIVATE (reader);
5675
5676 activity = e_activity_new ();
5677
5678 alert_sink = e_mail_reader_get_alert_sink (reader);
5679 e_activity_set_alert_sink (activity, alert_sink);
5680
5681 cancellable = camel_operation_new ();
5682
5683 priv->ongoing_operations = g_slist_prepend (priv->ongoing_operations, cancellable);
5684 g_object_weak_ref (G_OBJECT (cancellable), mail_reader_ongoing_operation_destroyed, reader);
5685
5686 e_activity_set_cancellable (activity, cancellable);
5687 g_object_unref (cancellable);
5688
5689 backend = e_mail_reader_get_backend (reader);
5690 e_shell_backend_add_activity (E_SHELL_BACKEND (backend), activity);
5691
5692 return activity;
5693 }
5694
5695 void
e_mail_reader_update_actions(EMailReader * reader,guint32 state)5696 e_mail_reader_update_actions (EMailReader *reader,
5697 guint32 state)
5698 {
5699 g_return_if_fail (E_IS_MAIL_READER (reader));
5700
5701 g_signal_emit (reader, signals[UPDATE_ACTIONS], 0, state);
5702 }
5703
5704 GtkAction *
e_mail_reader_get_action(EMailReader * reader,const gchar * action_name)5705 e_mail_reader_get_action (EMailReader *reader,
5706 const gchar *action_name)
5707 {
5708 GtkAction *action = NULL;
5709 gint ii;
5710
5711 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5712 g_return_val_if_fail (action_name != NULL, NULL);
5713
5714 for (ii = 0; ii < E_MAIL_READER_NUM_ACTION_GROUPS; ii++) {
5715 GtkActionGroup *group;
5716
5717 group = e_mail_reader_get_action_group (reader, ii);
5718 action = gtk_action_group_get_action (group, action_name);
5719
5720 if (action != NULL)
5721 break;
5722 }
5723
5724 if (action == NULL)
5725 g_critical (
5726 "%s: action '%s' not found", G_STRFUNC, action_name);
5727
5728 return action;
5729 }
5730
5731 GtkActionGroup *
e_mail_reader_get_action_group(EMailReader * reader,EMailReaderActionGroup group)5732 e_mail_reader_get_action_group (EMailReader *reader,
5733 EMailReaderActionGroup group)
5734 {
5735 EMailReaderInterface *iface;
5736
5737 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5738
5739 iface = E_MAIL_READER_GET_INTERFACE (reader);
5740 g_return_val_if_fail (iface->get_action_group != NULL, NULL);
5741
5742 return iface->get_action_group (reader, group);
5743 }
5744
5745 EAlertSink *
e_mail_reader_get_alert_sink(EMailReader * reader)5746 e_mail_reader_get_alert_sink (EMailReader *reader)
5747 {
5748 EMailReaderInterface *iface;
5749
5750 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5751
5752 iface = E_MAIL_READER_GET_INTERFACE (reader);
5753 g_return_val_if_fail (iface->get_alert_sink != NULL, NULL);
5754
5755 return iface->get_alert_sink (reader);
5756 }
5757
5758 EMailBackend *
e_mail_reader_get_backend(EMailReader * reader)5759 e_mail_reader_get_backend (EMailReader *reader)
5760 {
5761 EMailReaderInterface *iface;
5762
5763 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5764
5765 iface = E_MAIL_READER_GET_INTERFACE (reader);
5766 g_return_val_if_fail (iface->get_backend != NULL, NULL);
5767
5768 return iface->get_backend (reader);
5769 }
5770
5771 EMailDisplay *
e_mail_reader_get_mail_display(EMailReader * reader)5772 e_mail_reader_get_mail_display (EMailReader *reader)
5773 {
5774 EMailReaderInterface *iface;
5775
5776 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5777
5778 iface = E_MAIL_READER_GET_INTERFACE (reader);
5779 g_return_val_if_fail (iface->get_mail_display != NULL, NULL);
5780
5781 return iface->get_mail_display (reader);
5782 }
5783
5784 gboolean
e_mail_reader_get_hide_deleted(EMailReader * reader)5785 e_mail_reader_get_hide_deleted (EMailReader *reader)
5786 {
5787 EMailReaderInterface *iface;
5788
5789 g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
5790
5791 iface = E_MAIL_READER_GET_INTERFACE (reader);
5792 g_return_val_if_fail (iface->get_hide_deleted != NULL, FALSE);
5793
5794 return iface->get_hide_deleted (reader);
5795 }
5796
5797 GtkWidget *
e_mail_reader_get_message_list(EMailReader * reader)5798 e_mail_reader_get_message_list (EMailReader *reader)
5799 {
5800 EMailReaderInterface *iface;
5801
5802 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5803
5804 iface = E_MAIL_READER_GET_INTERFACE (reader);
5805 g_return_val_if_fail (iface->get_message_list != NULL, NULL);
5806
5807 return iface->get_message_list (reader);
5808 }
5809
5810 static void
e_mail_reader_popup_menu_deactivate_cb(GtkMenu * popup_menu,EMailReader * reader)5811 e_mail_reader_popup_menu_deactivate_cb (GtkMenu *popup_menu,
5812 EMailReader *reader)
5813 {
5814 g_return_if_fail (GTK_IS_MENU (popup_menu));
5815
5816 g_signal_handlers_disconnect_by_func (popup_menu, e_mail_reader_popup_menu_deactivate_cb, reader);
5817 gtk_menu_detach (popup_menu);
5818 }
5819
5820 GtkMenu *
e_mail_reader_get_popup_menu(EMailReader * reader)5821 e_mail_reader_get_popup_menu (EMailReader *reader)
5822 {
5823 EMailReaderInterface *iface;
5824 GtkMenu *menu;
5825
5826 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5827
5828 iface = E_MAIL_READER_GET_INTERFACE (reader);
5829 g_return_val_if_fail (iface->get_popup_menu != NULL, NULL);
5830
5831 menu = iface->get_popup_menu (reader);
5832 if (!gtk_menu_get_attach_widget (GTK_MENU (menu))) {
5833 gtk_menu_attach_to_widget (GTK_MENU (menu),
5834 GTK_WIDGET (reader),
5835 NULL);
5836 g_signal_connect (
5837 menu, "deactivate",
5838 G_CALLBACK (e_mail_reader_popup_menu_deactivate_cb), reader);
5839 }
5840
5841 return menu;
5842 }
5843
5844 EPreviewPane *
e_mail_reader_get_preview_pane(EMailReader * reader)5845 e_mail_reader_get_preview_pane (EMailReader *reader)
5846 {
5847 EMailReaderInterface *iface;
5848
5849 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5850
5851 iface = E_MAIL_READER_GET_INTERFACE (reader);
5852 g_return_val_if_fail (iface->get_preview_pane != NULL, NULL);
5853
5854 return iface->get_preview_pane (reader);
5855 }
5856
5857 GPtrArray *
e_mail_reader_get_selected_uids(EMailReader * reader)5858 e_mail_reader_get_selected_uids (EMailReader *reader)
5859 {
5860 EMailReaderInterface *iface;
5861
5862 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5863
5864 iface = E_MAIL_READER_GET_INTERFACE (reader);
5865 g_return_val_if_fail (iface->get_selected_uids != NULL, NULL);
5866
5867 return iface->get_selected_uids (reader);
5868 }
5869
5870 GPtrArray *
e_mail_reader_get_selected_uids_with_collapsed_threads(EMailReader * reader)5871 e_mail_reader_get_selected_uids_with_collapsed_threads (EMailReader *reader)
5872 {
5873 EMailReaderInterface *iface;
5874
5875 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5876
5877 iface = E_MAIL_READER_GET_INTERFACE (reader);
5878 g_return_val_if_fail (iface->get_selected_uids_with_collapsed_threads != NULL, NULL);
5879
5880 return iface->get_selected_uids_with_collapsed_threads (reader);
5881 }
5882
5883 GtkWindow *
e_mail_reader_get_window(EMailReader * reader)5884 e_mail_reader_get_window (EMailReader *reader)
5885 {
5886 EMailReaderInterface *iface;
5887
5888 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5889
5890 iface = E_MAIL_READER_GET_INTERFACE (reader);
5891 g_return_val_if_fail (iface->get_window != NULL, NULL);
5892
5893 return iface->get_window (reader);
5894 }
5895
5896 gboolean
e_mail_reader_close_on_delete_or_junk(EMailReader * reader)5897 e_mail_reader_close_on_delete_or_junk (EMailReader *reader)
5898 {
5899 EMailReaderInterface *iface;
5900
5901 g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
5902
5903 iface = E_MAIL_READER_GET_INTERFACE (reader);
5904
5905 return iface->close_on_delete_or_junk != NULL &&
5906 iface->close_on_delete_or_junk (reader);
5907 }
5908
5909 CamelFolder *
e_mail_reader_ref_folder(EMailReader * reader)5910 e_mail_reader_ref_folder (EMailReader *reader)
5911 {
5912 EMailReaderInterface *iface;
5913
5914 g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
5915
5916 iface = E_MAIL_READER_GET_INTERFACE (reader);
5917 g_return_val_if_fail (iface->ref_folder != NULL, NULL);
5918
5919 return iface->ref_folder (reader);
5920 }
5921
5922 void
e_mail_reader_set_folder(EMailReader * reader,CamelFolder * folder)5923 e_mail_reader_set_folder (EMailReader *reader,
5924 CamelFolder *folder)
5925 {
5926 EMailReaderInterface *iface;
5927
5928 g_return_if_fail (E_IS_MAIL_READER (reader));
5929
5930 iface = E_MAIL_READER_GET_INTERFACE (reader);
5931 g_return_if_fail (iface->set_folder != NULL);
5932
5933 iface->set_folder (reader, folder);
5934 }
5935
5936 void
e_mail_reader_set_message(EMailReader * reader,const gchar * message_uid)5937 e_mail_reader_set_message (EMailReader *reader,
5938 const gchar *message_uid)
5939 {
5940 EMailReaderInterface *iface;
5941
5942 g_return_if_fail (E_IS_MAIL_READER (reader));
5943
5944 iface = E_MAIL_READER_GET_INTERFACE (reader);
5945 g_return_if_fail (iface->set_message != NULL);
5946
5947 iface->set_message (reader, message_uid);
5948 }
5949
5950 guint
e_mail_reader_open_selected_mail(EMailReader * reader)5951 e_mail_reader_open_selected_mail (EMailReader *reader)
5952 {
5953 EMailReaderInterface *iface;
5954
5955 g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
5956
5957 iface = E_MAIL_READER_GET_INTERFACE (reader);
5958 g_return_val_if_fail (iface->open_selected_mail != NULL, 0);
5959
5960 return iface->open_selected_mail (reader);
5961 }
5962
5963 EMailForwardStyle
e_mail_reader_get_forward_style(EMailReader * reader)5964 e_mail_reader_get_forward_style (EMailReader *reader)
5965 {
5966 EMailReaderPrivate *priv;
5967
5968 g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
5969
5970 priv = E_MAIL_READER_GET_PRIVATE (reader);
5971
5972 return priv->forward_style;
5973 }
5974
5975 void
e_mail_reader_set_forward_style(EMailReader * reader,EMailForwardStyle style)5976 e_mail_reader_set_forward_style (EMailReader *reader,
5977 EMailForwardStyle style)
5978 {
5979 EMailReaderPrivate *priv;
5980
5981 g_return_if_fail (E_IS_MAIL_READER (reader));
5982
5983 priv = E_MAIL_READER_GET_PRIVATE (reader);
5984
5985 if (priv->forward_style == style)
5986 return;
5987
5988 priv->forward_style = style;
5989
5990 g_object_notify (G_OBJECT (reader), "forward-style");
5991 }
5992
5993 gboolean
e_mail_reader_get_group_by_threads(EMailReader * reader)5994 e_mail_reader_get_group_by_threads (EMailReader *reader)
5995 {
5996 EMailReaderPrivate *priv;
5997
5998 g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
5999
6000 priv = E_MAIL_READER_GET_PRIVATE (reader);
6001
6002 return priv->group_by_threads;
6003 }
6004
6005 void
e_mail_reader_set_group_by_threads(EMailReader * reader,gboolean group_by_threads)6006 e_mail_reader_set_group_by_threads (EMailReader *reader,
6007 gboolean group_by_threads)
6008 {
6009 EMailReaderPrivate *priv;
6010
6011 g_return_if_fail (E_IS_MAIL_READER (reader));
6012
6013 priv = E_MAIL_READER_GET_PRIVATE (reader);
6014
6015 if (priv->group_by_threads == group_by_threads)
6016 return;
6017
6018 priv->group_by_threads = group_by_threads;
6019
6020 g_object_notify (G_OBJECT (reader), "group-by-threads");
6021 }
6022
6023 EMailReplyStyle
e_mail_reader_get_reply_style(EMailReader * reader)6024 e_mail_reader_get_reply_style (EMailReader *reader)
6025 {
6026 EMailReaderPrivate *priv;
6027
6028 g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
6029
6030 priv = E_MAIL_READER_GET_PRIVATE (reader);
6031
6032 return priv->reply_style;
6033 }
6034
6035 void
e_mail_reader_set_reply_style(EMailReader * reader,EMailReplyStyle style)6036 e_mail_reader_set_reply_style (EMailReader *reader,
6037 EMailReplyStyle style)
6038 {
6039 EMailReaderPrivate *priv;
6040
6041 g_return_if_fail (E_IS_MAIL_READER (reader));
6042
6043 priv = E_MAIL_READER_GET_PRIVATE (reader);
6044
6045 if (priv->reply_style == style)
6046 return;
6047
6048 priv->reply_style = style;
6049
6050 g_object_notify (G_OBJECT (reader), "reply-style");
6051 }
6052
6053 gboolean
e_mail_reader_get_mark_seen_always(EMailReader * reader)6054 e_mail_reader_get_mark_seen_always (EMailReader *reader)
6055 {
6056 EMailReaderPrivate *priv;
6057
6058 g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
6059
6060 priv = E_MAIL_READER_GET_PRIVATE (reader);
6061
6062 return priv->mark_seen_always;
6063 }
6064
6065 void
e_mail_reader_set_mark_seen_always(EMailReader * reader,gboolean mark_seen_always)6066 e_mail_reader_set_mark_seen_always (EMailReader *reader,
6067 gboolean mark_seen_always)
6068 {
6069 EMailReaderPrivate *priv;
6070
6071 g_return_if_fail (E_IS_MAIL_READER (reader));
6072
6073 priv = E_MAIL_READER_GET_PRIVATE (reader);
6074
6075 if (priv->mark_seen_always == mark_seen_always)
6076 return;
6077
6078 priv->mark_seen_always = mark_seen_always;
6079
6080 g_object_notify (G_OBJECT (reader), "mark-seen-always");
6081 }
6082
6083 gboolean
e_mail_reader_get_delete_selects_previous(EMailReader * reader)6084 e_mail_reader_get_delete_selects_previous (EMailReader *reader)
6085 {
6086 EMailReaderPrivate *priv;
6087
6088 g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
6089
6090 priv = E_MAIL_READER_GET_PRIVATE (reader);
6091
6092 return priv->delete_selects_previous;
6093 }
6094
6095 void
e_mail_reader_set_delete_selects_previous(EMailReader * reader,gboolean delete_selects_previous)6096 e_mail_reader_set_delete_selects_previous (EMailReader *reader,
6097 gboolean delete_selects_previous)
6098 {
6099 EMailReaderPrivate *priv;
6100
6101 g_return_if_fail (E_IS_MAIL_READER (reader));
6102
6103 priv = E_MAIL_READER_GET_PRIVATE (reader);
6104
6105 if (priv->delete_selects_previous == delete_selects_previous)
6106 return;
6107
6108 priv->delete_selects_previous = delete_selects_previous;
6109
6110 g_object_notify (G_OBJECT (reader), "delete-selects-previous");
6111 }
6112
6113 void
e_mail_reader_create_charset_menu(EMailReader * reader,GtkUIManager * ui_manager,guint merge_id)6114 e_mail_reader_create_charset_menu (EMailReader *reader,
6115 GtkUIManager *ui_manager,
6116 guint merge_id)
6117 {
6118 GtkAction *action;
6119 const gchar *action_name;
6120 const gchar *path;
6121 GSList *list;
6122
6123 g_return_if_fail (E_IS_MAIL_READER (reader));
6124 g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
6125
6126 action_name = "mail-charset-default";
6127 action = e_mail_reader_get_action (reader, action_name);
6128 g_return_if_fail (action != NULL);
6129
6130 list = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
6131 list = g_slist_copy (list);
6132 list = g_slist_remove (list, action);
6133 list = g_slist_sort (list, (GCompareFunc) e_action_compare_by_label);
6134
6135 path = "/main-menu/view-menu/mail-message-view-actions/mail-encoding-menu";
6136
6137 while (list != NULL) {
6138 action = list->data;
6139
6140 gtk_ui_manager_add_ui (
6141 ui_manager, merge_id, path,
6142 gtk_action_get_name (action),
6143 gtk_action_get_name (action),
6144 GTK_UI_MANAGER_AUTO, FALSE);
6145
6146 list = g_slist_delete_link (list, list);
6147 }
6148
6149 gtk_ui_manager_ensure_update (ui_manager);
6150 }
6151
6152 void
e_mail_reader_show_search_bar(EMailReader * reader)6153 e_mail_reader_show_search_bar (EMailReader *reader)
6154 {
6155 g_return_if_fail (E_IS_MAIL_READER (reader));
6156
6157 g_signal_emit (reader, signals[SHOW_SEARCH_BAR], 0);
6158 }
6159
6160 void
e_mail_reader_avoid_next_mark_as_seen(EMailReader * reader)6161 e_mail_reader_avoid_next_mark_as_seen (EMailReader *reader)
6162 {
6163 EMailReaderPrivate *priv;
6164 MessageList *message_list;
6165
6166 g_return_if_fail (reader != NULL);
6167
6168 priv = E_MAIL_READER_GET_PRIVATE (reader);
6169 g_return_if_fail (priv != NULL);
6170
6171 message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
6172 g_return_if_fail (message_list != NULL);
6173
6174 priv->avoid_next_mark_as_seen = TRUE;
6175 }
6176
6177 void
e_mail_reader_unset_folder_just_selected(EMailReader * reader)6178 e_mail_reader_unset_folder_just_selected (EMailReader *reader)
6179 {
6180 EMailReaderPrivate *priv;
6181
6182 g_return_if_fail (reader != NULL);
6183
6184 priv = E_MAIL_READER_GET_PRIVATE (reader);
6185 g_return_if_fail (priv != NULL);
6186
6187 priv->folder_was_just_selected = FALSE;
6188 }
6189
6190 /**
6191 * e_mail_reader_composer_created:
6192 * @reader: an #EMailReader
6193 * @composer: an #EMsgComposer
6194 * @message: the source #CamelMimeMessage, or %NULL
6195 *
6196 * Emits an #EMailReader::composer-created signal to indicate the @composer
6197 * window was created in response to a user action on @reader. Examples of
6198 * such actions include replying, forwarding, and composing a new message.
6199 * If applicable, the source @message (i.e. the message being replied to or
6200 * forwarded) should be included.
6201 **/
6202 void
e_mail_reader_composer_created(EMailReader * reader,EMsgComposer * composer,CamelMimeMessage * message)6203 e_mail_reader_composer_created (EMailReader *reader,
6204 EMsgComposer *composer,
6205 CamelMimeMessage *message)
6206 {
6207 g_return_if_fail (E_IS_MAIL_READER (reader));
6208 g_return_if_fail (E_IS_MSG_COMPOSER (composer));
6209
6210 if (message != NULL)
6211 g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
6212
6213 g_signal_emit (
6214 reader, signals[COMPOSER_CREATED], 0, composer, message);
6215 }
6216
6217 void
e_mail_reader_reload(EMailReader * reader)6218 e_mail_reader_reload (EMailReader *reader)
6219 {
6220 EMailReaderInterface *iface;
6221
6222 g_return_if_fail (E_IS_MAIL_READER (reader));
6223
6224 iface = E_MAIL_READER_GET_INTERFACE (reader);
6225 g_return_if_fail (iface->reload != NULL);
6226
6227 iface->reload (reader);
6228 }
6229
6230 void
e_mail_reader_remove_ui(EMailReader * reader)6231 e_mail_reader_remove_ui (EMailReader *reader)
6232 {
6233 EMailReaderInterface *iface;
6234
6235 g_return_if_fail (E_IS_MAIL_READER (reader));
6236
6237 iface = E_MAIL_READER_GET_INTERFACE (reader);
6238 g_return_if_fail (iface->remove_ui != NULL);
6239
6240 iface->remove_ui (reader);
6241 }
6242