1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
49 #ifdef MODEST_PLATFORM_MAEMO
50 #include "maemo/modest-osso-state-saving.h"
51 #endif /* MODEST_PLATFORM_MAEMO */
53 #include "widgets/modest-ui-constants.h"
54 #include <widgets/modest-main-window.h>
55 #include <widgets/modest-msg-view-window.h>
56 #include <widgets/modest-account-view-window.h>
57 #include <widgets/modest-details-dialog.h>
58 #include <widgets/modest-attachments-view.h>
59 #include "widgets/modest-folder-view.h"
60 #include "widgets/modest-global-settings-dialog.h"
61 #include "modest-connection-specific-smtp-window.h"
62 #include "modest-account-mgr-helpers.h"
63 #include "modest-mail-operation.h"
64 #include "modest-text-utils.h"
66 #ifdef MODEST_HAVE_EASYSETUP
67 #include "easysetup/modest-easysetup-wizard.h"
68 #endif /* MODEST_HAVE_EASYSETUP */
70 #include <modest-widget-memory.h>
71 #include <tny-error.h>
72 #include <tny-simple-list.h>
73 #include <tny-msg-view.h>
74 #include <tny-device.h>
75 #include <tny-merge-folder.h>
77 #include <gtkhtml/gtkhtml.h>
79 typedef struct _GetMsgAsyncHelper {
81 ModestMailOperation *mail_op;
88 typedef enum _ReplyForwardAction {
94 typedef struct _ReplyForwardHelper {
95 guint reply_forward_type;
96 ReplyForwardAction action;
98 GtkWidget *parent_window;
103 * The do_headers_action uses this kind of functions to perform some
104 * action to each member of a list of headers
106 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
109 do_headers_action (ModestWindow *win,
114 static void open_msg_cb (ModestMailOperation *mail_op,
119 static void reply_forward_cb (ModestMailOperation *mail_op,
124 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
127 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
128 ModestMailOperationState *state,
134 run_account_setup_wizard (ModestWindow *win)
136 ModestEasysetupWizardDialog *wizard;
138 g_return_if_fail (MODEST_IS_WINDOW(win));
140 wizard = modest_easysetup_wizard_dialog_new ();
141 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
142 gtk_dialog_run (GTK_DIALOG (wizard));
143 gtk_widget_destroy (GTK_WIDGET (wizard));
148 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
151 const gchar *authors[] = {
152 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
155 about = gtk_about_dialog_new ();
156 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
157 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
158 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
159 _("Copyright (c) 2006, Nokia Corporation\n"
160 "All rights reserved."));
161 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
162 _("a modest e-mail client\n\n"
163 "design and implementation: Dirk-Jan C. Binnema\n"
164 "contributions from the fine people at KC and Ig\n"
165 "uses the tinymail email framework written by Philip van Hoof"));
166 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
167 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
169 gtk_dialog_run (GTK_DIALOG (about));
170 gtk_widget_destroy(about);
174 * Gets the list of currently selected messages. If the win is the
175 * main window, then it returns a newly allocated list of the headers
176 * selected in the header view. If win is the msg view window, then
177 * the value returned is a list with just a single header.
179 * The caller of this funcion must free the list.
182 get_selected_headers (ModestWindow *win)
184 if (MODEST_IS_MAIN_WINDOW(win)) {
185 GtkWidget *header_view;
187 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
188 MODEST_WIDGET_TYPE_HEADER_VIEW);
189 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
191 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
192 /* for MsgViewWindows, we simply return a list with one element */
194 TnyList *list = NULL;
196 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
197 if (header != NULL) {
198 list = tny_simple_list_new ();
199 tny_list_prepend (list, G_OBJECT(header));
200 g_object_unref (G_OBJECT(header));
210 headers_action_mark_as_read (TnyHeader *header,
214 TnyHeaderFlags flags;
216 g_return_if_fail (TNY_IS_HEADER(header));
218 flags = tny_header_get_flags (header);
219 if (flags & TNY_HEADER_FLAG_SEEN) return;
220 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
224 headers_action_mark_as_unread (TnyHeader *header,
228 TnyHeaderFlags flags;
230 g_return_if_fail (TNY_IS_HEADER(header));
232 flags = tny_header_get_flags (header);
233 if (flags & TNY_HEADER_FLAG_SEEN) {
234 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
240 headers_action_delete (TnyHeader *header,
244 ModestMailOperation *mail_op = NULL;
246 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
247 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
250 /* Always delete. TODO: Move to trash still not supported */
251 modest_mail_operation_remove_msg (mail_op, header, FALSE);
252 g_object_unref (G_OBJECT (mail_op));
254 /* refilter treemodel to hide marked-as-deleted rows */
255 if (MODEST_IS_HEADER_VIEW (user_data))
256 modest_header_view_refilter (MODEST_HEADER_VIEW (user_data));
260 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
262 TnyList *header_list = NULL;
263 TnyIterator *iter = NULL;
264 TnyHeader *header = NULL;
265 gchar *message = NULL;
268 ModestWindowMgr *mgr;
269 GtkWidget *header_view = NULL;
271 g_return_if_fail (MODEST_IS_WINDOW(win));
273 /* Check first if the header view has the focus */
274 if (MODEST_IS_MAIN_WINDOW (win)) {
276 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
277 MODEST_WIDGET_TYPE_HEADER_VIEW);
278 if (!gtk_widget_is_focus (header_view))
282 header_list = get_selected_headers (win);
283 if (!header_list) return;
285 /* Check if any of the headers is already opened, or in the process of being opened */
286 if (MODEST_IS_MAIN_WINDOW (win)) {
288 iter = tny_list_create_iterator (header_list);
290 mgr = modest_runtime_get_window_mgr ();
291 while (!tny_iterator_is_done (iter) && !found) {
292 header = TNY_HEADER (tny_iterator_get_current (iter));
293 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
294 g_object_unref (header);
295 tny_iterator_next (iter);
297 g_object_unref (iter);
302 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
303 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
305 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
309 g_object_unref (header_list);
315 if (tny_list_get_length(header_list) == 1) {
316 iter = tny_list_create_iterator (header_list);
317 header = TNY_HEADER (tny_iterator_get_current (iter));
318 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
319 g_object_unref (header);
320 g_object_unref (iter);
322 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
323 tny_list_get_length(header_list)), desc);
325 /* Confirmation dialog */
326 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
330 if (response == GTK_RESPONSE_OK) {
331 ModestMainWindow *main_window;
332 ModestWindowMgr *mgr;
334 /* Remove each header. If it's a view window header_view == NULL */
335 do_headers_action (win, headers_action_delete, header_view);
337 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
338 /* Close msg view window or select next */
339 if (modest_msg_view_window_last_message_selected (MODEST_MSG_VIEW_WINDOW (win)) &&
340 modest_msg_view_window_first_message_selected (MODEST_MSG_VIEW_WINDOW (win))) {
341 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
343 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (win));
347 /* Refilter header view model, if main window still exists */
348 mgr = modest_runtime_get_window_mgr ();
349 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
353 widget = modest_main_window_get_child_widget (main_window,
354 MODEST_WIDGET_TYPE_HEADER_VIEW);
355 modest_header_view_refilter (MODEST_HEADER_VIEW (widget));
358 /* Update toolbar dimming state */
359 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
365 g_object_unref (header_list);
370 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
372 #ifdef MODEST_PLATFORM_MAEMO
373 modest_osso_save_state();
374 #endif /* MODEST_PLATFORM_MAEMO */
376 g_debug ("closing down, clearing %d item(s) from operation queue",
377 modest_mail_operation_queue_num_elements
378 (modest_runtime_get_mail_operation_queue()));
380 /* cancel all outstanding operations */
381 modest_mail_operation_queue_cancel_all
382 (modest_runtime_get_mail_operation_queue());
384 g_debug ("queue has been cleared");
386 /* note: when modest-tny-account-store is finalized,
387 it will automatically set all network connections
394 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
397 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
399 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
400 /* gtk_widget_destroy (GTK_WIDGET (win)); */
401 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
402 /* gboolean ret_value; */
403 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
404 /* } else if (MODEST_IS_WINDOW (win)) { */
405 /* gtk_widget_destroy (GTK_WIDGET (win)); */
407 /* g_return_if_reached (); */
412 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
414 GtkClipboard *clipboard = NULL;
415 gchar *selection = NULL;
417 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
418 selection = gtk_clipboard_wait_for_text (clipboard);
420 /* Question: why is the clipboard being used here?
421 * It doesn't really make a lot of sense. */
425 modest_address_book_add_address (selection);
431 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
433 /* This is currently only implemented for Maemo */
434 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
435 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
436 run_account_setup_wizard (win);
439 /* Show the list of accounts: */
440 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
441 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
442 gtk_dialog_run (account_win);
443 gtk_widget_destroy (GTK_WIDGET(account_win));
446 GtkWidget *dialog, *label;
448 /* Create the widgets */
450 dialog = gtk_dialog_new_with_buttons ("Message",
452 GTK_DIALOG_DESTROY_WITH_PARENT,
456 label = gtk_label_new ("Hello World!");
458 /* Ensure that the dialog box is destroyed when the user responds. */
460 g_signal_connect_swapped (dialog, "response",
461 G_CALLBACK (gtk_widget_destroy),
464 /* Add the label, and show everything we've added to the dialog. */
466 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
468 gtk_widget_show_all (dialog);
469 #endif /* MODEST_PLATFORM_MAEMO */
473 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
475 ModestWindow *main_window = MODEST_WINDOW (user_data);
477 /* Save any changes. */
478 modest_connection_specific_smtp_window_save_server_accounts (
479 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
480 modest_window_get_active_account (main_window));
481 gtk_widget_destroy (GTK_WIDGET (window));
487 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
489 /* This is currently only implemented for Maemo,
490 * because it requires an API (libconic) to detect different connection
493 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
495 /* Create the window if necessary: */
496 const gchar *active_account_name = modest_window_get_active_account (win);
498 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
499 * or show the default account?
500 * If we show the default account then the account name should be shown in
501 * the window when we show it. */
502 if (!active_account_name) {
503 g_warning ("%s: No account is active.", __FUNCTION__);
507 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
508 modest_connection_specific_smtp_window_fill_with_connections (
509 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
510 modest_runtime_get_account_mgr(),
511 active_account_name);
513 /* Show the window: */
514 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
515 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
516 gtk_widget_show (specific_window);
518 /* Save changes when the window is hidden: */
519 g_signal_connect (specific_window, "hide",
520 G_CALLBACK (on_smtp_servers_window_hide), win);
521 #endif /* MODEST_PLATFORM_MAEMO */
525 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
527 ModestWindow *msg_win = NULL;
529 TnyFolder *folder = NULL;
530 gchar *account_name = NULL;
531 gchar *from_str = NULL;
532 /* GError *err = NULL; */
533 TnyAccount *account = NULL;
534 ModestWindowMgr *mgr;
535 gchar *signature = NULL, *blank_and_signature = NULL;
537 /* if there are no accounts yet, just show the wizard */
538 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
539 run_account_setup_wizard (win);
543 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
545 account_name = g_strdup (modest_window_get_active_account (win));
547 g_printerr ("modest: no account found\n");
551 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
553 TNY_ACCOUNT_TYPE_STORE);
555 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
559 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
561 g_printerr ("modest: failed get from string for '%s'\n", account_name);
565 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
566 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
567 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
568 MODEST_ACCOUNT_SIGNATURE, FALSE);
569 blank_and_signature = g_strconcat ("\n", signature, NULL);
572 blank_and_signature = g_strdup ("");
575 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
577 g_printerr ("modest: failed to create new msg\n");
581 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
583 g_printerr ("modest: failed to find Drafts folder\n");
588 /* Create and register edit window */
589 /* This is destroyed by TOOD. */
590 msg_win = modest_msg_edit_window_new (msg, account_name);
591 mgr = modest_runtime_get_window_mgr ();
592 modest_window_mgr_register_window (mgr, msg_win);
595 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
597 gtk_widget_show_all (GTK_WIDGET (msg_win));
600 g_free (account_name);
602 g_free (blank_and_signature);
604 g_object_unref (msg_win);
606 g_object_unref (G_OBJECT(account));
608 g_object_unref (G_OBJECT(msg));
610 g_object_unref (G_OBJECT(folder));
614 open_msg_cb (ModestMailOperation *mail_op,
619 ModestWindowMgr *mgr = NULL;
620 ModestWindow *parent_win = NULL;
621 ModestWindow *win = NULL;
622 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
623 gchar *account = NULL;
626 /* TODO: Show an error? (review the specs) */
630 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
631 folder = tny_header_get_folder (header);
633 /* Mark header as read */
634 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
637 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
639 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
641 /* Gets folder type (OUTBOX headers will be opened in edit window */
642 if (modest_tny_folder_is_local_folder (folder))
643 folder_type = modest_tny_folder_get_local_folder_type (folder);
645 /* If the header is in the drafts folder then open the editor,
646 else the message view window */
647 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
648 /* we cannot edit without a valid account... */
649 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
650 run_account_setup_wizard(parent_win);
653 win = modest_msg_edit_window_new (msg, account);
655 gchar *uid = modest_tny_folder_get_header_unique_id (header);
657 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
658 GtkWidget *header_view;
659 GtkTreeSelection *sel;
660 GList *sel_list = NULL;
663 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
664 MODEST_WIDGET_TYPE_HEADER_VIEW);
666 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
667 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
669 if (sel_list != NULL) {
670 GtkTreeRowReference *row_reference;
672 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
673 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
674 g_list_free (sel_list);
676 win = modest_msg_view_window_new_with_header_model (msg,
681 gtk_tree_row_reference_free (row_reference);
683 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
686 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
691 /* Register and show new window */
693 mgr = modest_runtime_get_window_mgr ();
694 modest_window_mgr_register_window (mgr, win);
695 g_object_unref (win);
696 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
697 gtk_widget_show_all (GTK_WIDGET(win));
700 /* Update toolbar dimming state */
701 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
702 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
708 g_object_unref (parent_win);
709 /* g_object_unref (msg); */
710 g_object_unref (folder);
714 * This function is the error handler of the
715 * modest_mail_operation_get_msgs_full operation
718 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
723 error = modest_mail_operation_get_error (mail_op);
724 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
725 GObject *win = modest_mail_operation_get_source (mail_op);
727 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
729 g_object_unref (win);
734 * This function is used by both modest_ui_actions_on_open and
735 * modest_ui_actions_on_header_activated. This way we always do the
736 * same when trying to open messages.
739 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
741 ModestWindowMgr *mgr = NULL;
742 TnyIterator *iter = NULL;
743 ModestMailOperation *mail_op1 = NULL;
744 ModestMailOperation *mail_op2 = NULL;
745 TnyList *not_opened_headers = NULL;
746 TnyList *not_opened_cached_headers = NULL;
747 TnyHeaderFlags flags;
749 /* Look if we already have a message view for each header. If
750 true, then remove the header from the list of headers to
752 mgr = modest_runtime_get_window_mgr ();
753 iter = tny_list_create_iterator (headers);
754 not_opened_headers = tny_simple_list_new ();
755 not_opened_cached_headers = tny_simple_list_new ();
756 while (!tny_iterator_is_done (iter)) {
758 ModestWindow *window;
762 header = TNY_HEADER (tny_iterator_get_current (iter));
763 flags = tny_header_get_flags (header);
766 found = modest_window_mgr_find_registered_header (mgr, header, &window);
768 /* Do not open again the message and present the
769 window to the user */
772 gtk_window_present (GTK_WINDOW (window));
774 /* the header has been registered already, we don't do
775 * anything but wait for the window to come up*/
776 g_warning ("debug: header %p already registered, waiting for window",
779 /* register the header before actually creating the window */
780 modest_window_mgr_register_header (mgr, header);
782 if (!(flags & TNY_HEADER_FLAG_CACHED))
783 tny_list_append (not_opened_headers, G_OBJECT (header));
784 /* Check if msg has already been retreived */
786 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
788 g_object_unref (header);
789 tny_iterator_next (iter);
792 /* Open each uncached message */
793 if (tny_list_get_length (not_opened_headers) > 0) {
794 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
796 modest_ui_actions_get_msgs_full_error_handler,
798 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
799 if (tny_list_get_length (not_opened_headers) > 1) {
800 modest_mail_operation_get_msgs_full (mail_op1,
806 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
807 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
808 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
809 g_object_unref (header);
810 g_object_unref (iter);
814 /* Open each cached message */
815 if (tny_list_get_length (not_opened_cached_headers) > 0) {
816 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
818 modest_ui_actions_get_msgs_full_error_handler,
820 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
821 if (tny_list_get_length (not_opened_cached_headers) > 1) {
822 modest_mail_operation_get_msgs_full (mail_op2,
828 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
829 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
830 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
831 g_object_unref (header);
832 g_object_unref (iter);
837 if (not_opened_headers != NULL)
838 g_object_unref (not_opened_headers);
839 if (not_opened_cached_headers != NULL)
840 g_object_unref (not_opened_cached_headers);
842 g_object_unref (iter);
843 if (mail_op1 != NULL)
844 g_object_unref (mail_op1);
845 if (mail_op2 != NULL)
846 g_object_unref (mail_op2);
850 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
855 headers = get_selected_headers (win);
860 _modest_ui_actions_open (headers, win);
862 g_object_unref(headers);
867 free_reply_forward_helper (gpointer data)
869 ReplyForwardHelper *helper;
871 helper = (ReplyForwardHelper *) data;
872 g_free (helper->account_name);
873 g_slice_free (ReplyForwardHelper, helper);
877 reply_forward_cb (ModestMailOperation *mail_op,
883 ReplyForwardHelper *rf_helper;
884 ModestWindow *msg_win = NULL;
885 ModestEditType edit_type;
887 TnyAccount *account = NULL;
888 ModestWindowMgr *mgr = NULL;
889 gchar *signature = NULL;
891 g_return_if_fail (user_data != NULL);
892 rf_helper = (ReplyForwardHelper *) user_data;
894 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
895 rf_helper->account_name);
896 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
897 rf_helper->account_name,
898 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
899 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
900 rf_helper->account_name,
901 MODEST_ACCOUNT_SIGNATURE, FALSE);
904 /* Create reply mail */
905 switch (rf_helper->action) {
908 modest_tny_msg_create_reply_msg (msg, from, signature,
909 rf_helper->reply_forward_type,
910 MODEST_TNY_MSG_REPLY_MODE_SENDER);
912 case ACTION_REPLY_TO_ALL:
914 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
915 MODEST_TNY_MSG_REPLY_MODE_ALL);
916 edit_type = MODEST_EDIT_TYPE_REPLY;
920 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
921 edit_type = MODEST_EDIT_TYPE_FORWARD;
924 g_return_if_reached ();
931 g_printerr ("modest: failed to create message\n");
935 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
936 rf_helper->account_name,
937 TNY_ACCOUNT_TYPE_STORE);
939 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
943 /* Create and register the windows */
944 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
945 mgr = modest_runtime_get_window_mgr ();
946 modest_window_mgr_register_window (mgr, msg_win);
948 if (rf_helper->parent_window != NULL) {
951 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
952 modest_window_set_zoom (msg_win, parent_zoom);
955 /* Show edit window */
956 gtk_widget_show_all (GTK_WIDGET (msg_win));
960 g_object_unref (msg_win);
962 g_object_unref (G_OBJECT (new_msg));
964 g_object_unref (G_OBJECT (account));
965 /* g_object_unref (msg); */
966 g_object_unref (header);
967 free_reply_forward_helper (rf_helper);
971 * Checks a list of headers. If any of them are not currently
972 * downloaded (CACHED) then it asks the user for permission to
975 * Returns FALSE if the user does not want to download the
976 * messages. Returns TRUE if the user allowed the download or if all
977 * of them are currently downloaded
980 download_uncached_messages (TnyList *header_list, GtkWindow *win)
984 gint uncached_messages = 0;
986 iter = tny_list_create_iterator (header_list);
987 while (!tny_iterator_is_done (iter)) {
989 TnyHeaderFlags flags;
991 header = TNY_HEADER (tny_iterator_get_current (iter));
992 flags = tny_header_get_flags (header);
993 /* TODO: is this the right flag?, it seems that some
994 headers that have been previously downloaded do not
996 if (! (flags & TNY_HEADER_FLAG_CACHED))
997 uncached_messages ++;
998 g_object_unref (header);
999 tny_iterator_next (iter);
1001 g_object_unref (iter);
1003 /* Ask for user permission to download the messages */
1005 if (uncached_messages > 0) {
1006 GtkResponseType response;
1008 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1009 ngettext("mcen_nc_get_msg",
1011 uncached_messages));
1012 if (response == GTK_RESPONSE_CANCEL)
1020 * Common code for the reply and forward actions
1023 reply_forward (ReplyForwardAction action, ModestWindow *win)
1025 ModestMailOperation *mail_op = NULL;
1026 TnyList *header_list = NULL;
1027 ReplyForwardHelper *rf_helper = NULL;
1028 guint reply_forward_type;
1029 gboolean continue_download;
1031 g_return_if_fail (MODEST_IS_WINDOW(win));
1033 /* we need an account when editing */
1034 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1035 run_account_setup_wizard (win);
1039 header_list = get_selected_headers (win);
1043 /* Check that the messages have been previously downloaded */
1044 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1045 if (!continue_download) {
1046 g_object_unref (header_list);
1050 reply_forward_type =
1051 modest_conf_get_int (modest_runtime_get_conf (),
1052 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1054 /* We assume that we can only select messages of the
1055 same folder and that we reply all of them from the
1056 same account. In fact the interface currently only
1057 allows single selection */
1060 rf_helper = g_slice_new0 (ReplyForwardHelper);
1061 rf_helper->reply_forward_type = reply_forward_type;
1062 rf_helper->action = action;
1063 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1064 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1065 rf_helper->parent_window = GTK_WIDGET (win);
1066 if (!rf_helper->account_name)
1067 rf_helper->account_name =
1068 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1070 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1073 /* Get header and message. Do not free them here, the
1074 reply_forward_cb must do it */
1075 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1076 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1077 if (!msg || !header) {
1079 g_object_unref (msg);
1081 g_object_unref (header);
1082 g_printerr ("modest: no message found\n");
1085 reply_forward_cb (NULL, header, msg, rf_helper);
1090 /* Retrieve messages */
1091 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1093 modest_ui_actions_get_msgs_full_error_handler,
1095 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1097 /* Only reply/forward to one message */
1098 iter = tny_list_create_iterator (header_list);
1099 header = TNY_HEADER (tny_iterator_get_current (iter));
1100 g_object_unref (iter);
1102 modest_mail_operation_get_msg (mail_op,
1107 /* modest_mail_operation_get_msgs_full (mail_op, */
1109 /* reply_forward_cb, */
1111 /* free_reply_forward_helper); */
1114 g_object_unref(mail_op);
1118 g_object_unref (header_list);
1122 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1124 g_return_if_fail (MODEST_IS_WINDOW(win));
1126 reply_forward (ACTION_REPLY, win);
1130 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1132 g_return_if_fail (MODEST_IS_WINDOW(win));
1134 reply_forward (ACTION_FORWARD, win);
1138 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1140 g_return_if_fail (MODEST_IS_WINDOW(win));
1142 reply_forward (ACTION_REPLY_TO_ALL, win);
1146 modest_ui_actions_on_next (GtkAction *action,
1147 ModestWindow *window)
1149 if (MODEST_IS_MAIN_WINDOW (window)) {
1150 GtkWidget *header_view;
1152 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1153 MODEST_WIDGET_TYPE_HEADER_VIEW);
1157 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1158 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1159 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1161 g_return_if_reached ();
1166 modest_ui_actions_on_prev (GtkAction *action,
1167 ModestWindow *window)
1169 g_return_if_fail (MODEST_IS_WINDOW(window));
1171 if (MODEST_IS_MAIN_WINDOW (window)) {
1172 GtkWidget *header_view;
1173 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1174 MODEST_WIDGET_TYPE_HEADER_VIEW);
1178 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1179 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1180 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1182 g_return_if_reached ();
1187 modest_ui_actions_on_sort (GtkAction *action,
1188 ModestWindow *window)
1190 g_return_if_fail (MODEST_IS_WINDOW(window));
1192 if (MODEST_IS_MAIN_WINDOW (window)) {
1193 GtkWidget *header_view;
1194 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1195 MODEST_WIDGET_TYPE_HEADER_VIEW);
1199 /* Show sorting dialog */
1200 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1205 new_messages_arrived (ModestMailOperation *self,
1209 if (new_messages == 0)
1212 modest_platform_on_new_msg ();
1216 * This function performs the send & receive required actions. The
1217 * window is used to create the mail operation. Typically it should
1218 * always be the main window, but we pass it as argument in order to
1222 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1224 gchar *acc_name = NULL;
1225 ModestMailOperation *mail_op;
1227 /* If no account name was provided then get the current account, and if
1228 there is no current account then pick the default one: */
1229 if (!account_name) {
1230 acc_name = g_strdup (modest_window_get_active_account(win));
1232 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1234 g_printerr ("modest: cannot get default account\n");
1238 acc_name = g_strdup (account_name);
1241 /* Set send/receive operation in progress */
1242 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1244 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1246 modest_ui_actions_send_receive_error_handler,
1249 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1250 G_CALLBACK (_on_send_receive_progress_changed),
1253 /* Send & receive. */
1254 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1255 /* Receive and then send. The operation is tagged initially as
1256 a receive operation because the account update performs a
1257 receive and then a send. The operation changes its type
1258 internally, so the progress objects will receive the proper
1259 progress information */
1260 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1261 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1262 g_object_unref (G_OBJECT (mail_op));
1269 * Refreshes all accounts. This function will be used by automatic
1273 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1275 GSList *account_names, *iter;
1277 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1280 iter = account_names;
1282 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1283 iter = g_slist_next (iter);
1286 modest_account_mgr_free_account_names (account_names);
1287 account_names = NULL;
1291 * Handler of the click on Send&Receive button in the main toolbar
1294 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1296 /* Check if accounts exist */
1297 gboolean accounts_exist =
1298 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1300 /* If not, allow the user to create an account before trying to send/receive. */
1301 if (!accounts_exist)
1302 modest_ui_actions_on_accounts (NULL, win);
1304 /* Refresh the active account */
1305 modest_ui_actions_do_send_receive (NULL, win);
1310 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1313 GtkWidget *header_view;
1315 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1317 header_view = modest_main_window_get_child_widget (main_window,
1318 MODEST_WIDGET_TYPE_HEADER_VIEW);
1322 conf = modest_runtime_get_conf ();
1324 /* what is saved/restored is depending on the style; thus; we save with
1325 * old style, then update the style, and restore for this new style
1327 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1329 if (modest_header_view_get_style
1330 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1331 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1332 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1334 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1335 MODEST_HEADER_VIEW_STYLE_DETAILS);
1337 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1338 MODEST_CONF_HEADER_VIEW_KEY);
1343 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1345 ModestMainWindow *main_window)
1347 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1348 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1350 /* If no header has been selected then exit */
1355 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1356 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1358 /* Update Main window title */
1359 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1360 const gchar *subject = tny_header_get_subject (header);
1361 if (subject && strlen(subject) > 0)
1362 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1364 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1367 /* Update toolbar dimming state */
1368 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1372 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1374 ModestMainWindow *main_window)
1378 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1383 headers = tny_simple_list_new ();
1384 tny_list_prepend (headers, G_OBJECT (header));
1386 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1388 g_object_unref (headers);
1392 set_active_account_from_tny_account (TnyAccount *account,
1393 ModestWindow *window)
1395 const gchar *server_acc_name = tny_account_get_id (account);
1397 /* We need the TnyAccount provided by the
1398 account store because that is the one that
1399 knows the name of the Modest account */
1400 TnyAccount *modest_server_account = modest_server_account =
1401 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1402 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1405 const gchar *modest_acc_name =
1406 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1407 modest_window_set_active_account (window, modest_acc_name);
1408 g_object_unref (modest_server_account);
1413 folder_refreshed_cb (const GObject *obj,
1417 ModestMainWindow *win = NULL;
1418 GtkWidget *header_view;
1420 g_return_if_fail (TNY_IS_FOLDER (folder));
1422 win = MODEST_MAIN_WINDOW (user_data);
1424 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1426 /* Check if folder is empty and set headers view contents style */
1427 if (tny_folder_get_all_count (folder) == 0) {
1428 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1429 modest_main_window_set_contents_style (win,
1430 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1432 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1437 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1438 TnyFolderStore *folder_store,
1440 ModestMainWindow *main_window)
1443 GtkWidget *header_view;
1445 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1447 header_view = modest_main_window_get_child_widget(main_window,
1448 MODEST_WIDGET_TYPE_HEADER_VIEW);
1452 conf = modest_runtime_get_conf ();
1454 if (TNY_IS_ACCOUNT (folder_store)) {
1456 /* Update active account */
1457 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1458 /* Show account details */
1459 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1462 if (TNY_IS_FOLDER (folder_store) && selected) {
1464 /* Update the active account */
1465 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1467 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1468 g_object_unref (account);
1472 /* Set the header style by default, it could
1473 be changed later by the refresh callback to
1475 modest_main_window_set_contents_style (main_window,
1476 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1478 /* Set folder on header view. This function
1479 will call tny_folder_refresh_async so we
1480 pass a callback that will be called when
1481 finished. We use that callback to set the
1482 empty view if there are no messages */
1483 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1484 TNY_FOLDER (folder_store),
1485 folder_refreshed_cb,
1488 /* Restore configuration. We need to do this
1489 *after* the set_folder because the widget
1490 memory asks the header view about its
1492 modest_widget_memory_restore (modest_runtime_get_conf (),
1493 G_OBJECT(header_view),
1494 MODEST_CONF_HEADER_VIEW_KEY);
1496 /* Update the active account */
1497 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1498 /* Save only if we're seeing headers */
1499 if (modest_main_window_get_contents_style (main_window) ==
1500 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1501 modest_widget_memory_save (conf, G_OBJECT (header_view),
1502 MODEST_CONF_HEADER_VIEW_KEY);
1503 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1507 /* Update toolbar dimming state */
1508 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1512 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1519 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1521 online = tny_device_is_online (modest_runtime_get_device());
1524 /* already online -- the item is simply not there... */
1525 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1527 GTK_MESSAGE_WARNING,
1529 _("The %s you selected cannot be found"),
1531 gtk_dialog_run (GTK_DIALOG(dialog));
1533 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1537 GTK_RESPONSE_REJECT,
1539 GTK_RESPONSE_ACCEPT,
1541 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1542 "Do you want to get online?"), item);
1543 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1544 gtk_label_new (txt), FALSE, FALSE, 0);
1545 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1548 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1549 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1550 // modest_platform_connect_and_wait ();
1553 gtk_widget_destroy (dialog);
1557 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1560 /* g_message ("%s %s", __FUNCTION__, link); */
1565 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1568 modest_platform_activate_uri (link);
1572 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1575 modest_platform_show_uri_popup (link);
1579 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1582 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1586 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1587 const gchar *address,
1590 /* g_message ("%s %s", __FUNCTION__, address); */
1594 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1596 TnyTransportAccount *transport_account;
1597 ModestMailOperation *mail_operation;
1599 gchar *account_name, *from;
1600 ModestAccountMgr *account_mgr;
1601 gchar *info_text = NULL;
1603 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1605 data = modest_msg_edit_window_get_msg_data (edit_window);
1607 account_mgr = modest_runtime_get_account_mgr();
1608 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1610 account_name = modest_account_mgr_get_default_account (account_mgr);
1611 if (!account_name) {
1612 g_printerr ("modest: no account found\n");
1613 modest_msg_edit_window_free_msg_data (edit_window, data);
1617 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1618 account_name = g_strdup (data->account_name);
1622 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1623 (modest_runtime_get_account_store(),
1625 TNY_ACCOUNT_TYPE_TRANSPORT));
1626 if (!transport_account) {
1627 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1628 g_free (account_name);
1629 modest_msg_edit_window_free_msg_data (edit_window, data);
1632 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1634 /* Create the mail operation */
1635 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1636 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1638 modest_mail_operation_save_to_drafts (mail_operation,
1649 data->priority_flags);
1652 g_free (account_name);
1653 g_object_unref (G_OBJECT (transport_account));
1654 g_object_unref (G_OBJECT (mail_operation));
1656 modest_msg_edit_window_free_msg_data (edit_window, data);
1658 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1659 modest_platform_information_banner (NULL, NULL, info_text);
1663 /* For instance, when clicking the Send toolbar button when editing a message: */
1665 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1667 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1669 if (!modest_msg_edit_window_check_names (edit_window))
1672 /* FIXME: Code added just for testing. The final version will
1673 use the send queue provided by tinymail and some
1675 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1676 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1678 account_name = modest_account_mgr_get_default_account (account_mgr);
1680 if (!account_name) {
1681 g_printerr ("modest: no account found\n");
1685 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1687 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1688 account_name = g_strdup (data->account_name);
1691 /* Get the currently-active transport account for this modest account: */
1692 TnyTransportAccount *transport_account =
1693 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1694 (modest_runtime_get_account_store(),
1696 if (!transport_account) {
1697 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1698 g_free (account_name);
1699 modest_msg_edit_window_free_msg_data (edit_window, data);
1703 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1705 /* mail content checks and dialogs */
1706 if (data->subject == NULL || data->subject[0] == '\0') {
1707 GtkResponseType response;
1708 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1709 _("mcen_nc_subject_is_empty_send"));
1710 if (response == GTK_RESPONSE_CANCEL) {
1711 g_free (account_name);
1716 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1717 GtkResponseType response;
1718 gchar *note_message;
1719 gchar *note_subject = data->subject;
1720 if (note_subject == NULL || note_subject[0] == '\0')
1721 note_subject = _("mail_va_no_subject");
1722 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1723 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1725 g_free (note_message);
1726 if (response == GTK_RESPONSE_CANCEL) {
1727 g_free (account_name);
1732 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1734 /* Create the mail operation */
1735 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1736 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1738 modest_mail_operation_send_new_mail (mail_operation,
1749 data->priority_flags);
1753 g_free (account_name);
1754 g_object_unref (G_OBJECT (transport_account));
1755 g_object_unref (G_OBJECT (mail_operation));
1757 modest_msg_edit_window_free_msg_data (edit_window, data);
1758 modest_msg_edit_window_set_sent (edit_window, TRUE);
1760 /* Save settings and close the window: */
1761 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
1765 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1766 ModestMsgEditWindow *window)
1768 ModestMsgEditFormatState *format_state = NULL;
1770 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1771 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1773 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1776 format_state = modest_msg_edit_window_get_format_state (window);
1777 g_return_if_fail (format_state != NULL);
1779 format_state->bold = gtk_toggle_action_get_active (action);
1780 modest_msg_edit_window_set_format_state (window, format_state);
1781 g_free (format_state);
1786 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1787 ModestMsgEditWindow *window)
1789 ModestMsgEditFormatState *format_state = NULL;
1791 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1792 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1794 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1797 format_state = modest_msg_edit_window_get_format_state (window);
1798 g_return_if_fail (format_state != NULL);
1800 format_state->italics = gtk_toggle_action_get_active (action);
1801 modest_msg_edit_window_set_format_state (window, format_state);
1802 g_free (format_state);
1807 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1808 ModestMsgEditWindow *window)
1810 ModestMsgEditFormatState *format_state = NULL;
1812 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1813 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1815 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1818 format_state = modest_msg_edit_window_get_format_state (window);
1819 g_return_if_fail (format_state != NULL);
1821 format_state->bullet = gtk_toggle_action_get_active (action);
1822 modest_msg_edit_window_set_format_state (window, format_state);
1823 g_free (format_state);
1828 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1829 GtkRadioAction *selected,
1830 ModestMsgEditWindow *window)
1832 ModestMsgEditFormatState *format_state = NULL;
1833 GtkJustification value;
1835 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1837 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1840 value = gtk_radio_action_get_current_value (selected);
1842 format_state = modest_msg_edit_window_get_format_state (window);
1843 g_return_if_fail (format_state != NULL);
1845 format_state->justification = value;
1846 modest_msg_edit_window_set_format_state (window, format_state);
1847 g_free (format_state);
1851 modest_ui_actions_on_select_editor_color (GtkAction *action,
1852 ModestMsgEditWindow *window)
1854 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1855 g_return_if_fail (GTK_IS_ACTION (action));
1857 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1860 modest_msg_edit_window_select_color (window);
1864 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1865 ModestMsgEditWindow *window)
1867 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1868 g_return_if_fail (GTK_IS_ACTION (action));
1870 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1873 modest_msg_edit_window_select_background_color (window);
1877 modest_ui_actions_on_insert_image (GtkAction *action,
1878 ModestMsgEditWindow *window)
1880 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1881 g_return_if_fail (GTK_IS_ACTION (action));
1883 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1886 modest_msg_edit_window_insert_image (window);
1890 modest_ui_actions_on_attach_file (GtkAction *action,
1891 ModestMsgEditWindow *window)
1893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1894 g_return_if_fail (GTK_IS_ACTION (action));
1896 modest_msg_edit_window_attach_file (window);
1900 modest_ui_actions_on_remove_attachments (GtkAction *action,
1901 ModestMsgEditWindow *window)
1903 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1904 g_return_if_fail (GTK_IS_ACTION (action));
1906 modest_msg_edit_window_remove_attachments (window, NULL);
1910 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1912 TnyFolderStore *parent_folder;
1913 GtkWidget *folder_view;
1915 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1917 folder_view = modest_main_window_get_child_widget (main_window,
1918 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1922 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1924 if (parent_folder) {
1925 gboolean finished = FALSE;
1927 gchar *folder_name = NULL, *suggested_name = NULL;
1929 /* Run the new folder dialog */
1931 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1936 if (result == GTK_RESPONSE_REJECT) {
1939 ModestMailOperation *mail_op;
1940 TnyFolder *new_folder = NULL;
1942 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1943 G_OBJECT(main_window));
1944 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1946 new_folder = modest_mail_operation_create_folder (mail_op,
1948 (const gchar *) folder_name);
1950 g_object_unref (new_folder);
1953 g_object_unref (mail_op);
1955 g_free (folder_name);
1959 g_object_unref (parent_folder);
1964 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1967 GObject *win = modest_mail_operation_get_source (mail_op);
1968 const GError *error = NULL;
1969 const gchar *message = NULL;
1971 /* Get error message */
1972 error = modest_mail_operation_get_error (mail_op);
1973 if (error != NULL && error->message != NULL) {
1974 message = error->message;
1976 message = _("!!! FIXME: Unable to rename");
1979 /* Show notification dialog */
1980 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
1981 g_object_unref (win);
1985 modest_ui_actions_on_rename_folder (GtkAction *action,
1986 ModestMainWindow *main_window)
1988 TnyFolderStore *folder;
1989 GtkWidget *folder_view;
1990 GtkWidget *header_view;
1992 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1994 folder_view = modest_main_window_get_child_widget (main_window,
1995 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1999 header_view = modest_main_window_get_child_widget (main_window,
2000 MODEST_WIDGET_TYPE_HEADER_VIEW);
2005 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2007 if (folder && TNY_IS_FOLDER (folder)) {
2010 const gchar *current_name;
2012 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2013 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2014 current_name, &folder_name);
2016 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2017 ModestMailOperation *mail_op;
2020 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2021 G_OBJECT(main_window),
2022 modest_ui_actions_rename_folder_error_handler,
2026 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2029 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2031 modest_mail_operation_rename_folder (mail_op,
2032 TNY_FOLDER (folder),
2033 (const gchar *) folder_name);
2035 g_object_unref (mail_op);
2036 g_free (folder_name);
2038 g_object_unref (folder);
2043 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2046 GObject *win = modest_mail_operation_get_source (mail_op);
2048 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2049 _("mail_in_ui_folder_delete_error"));
2050 g_object_unref (win);
2054 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2056 TnyFolderStore *folder;
2057 GtkWidget *folder_view;
2061 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2063 folder_view = modest_main_window_get_child_widget (main_window,
2064 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2068 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2070 /* Show an error if it's an account */
2071 if (!TNY_IS_FOLDER (folder)) {
2072 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2073 _("mail_in_ui_folder_delete_error"));
2078 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2079 tny_folder_get_name (TNY_FOLDER (folder)));
2080 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2081 (const gchar *) message);
2084 if (response == GTK_RESPONSE_OK) {
2085 ModestMailOperation *mail_op =
2086 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2087 G_OBJECT(main_window),
2088 modest_ui_actions_delete_folder_error_handler,
2091 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2093 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2094 g_object_unref (G_OBJECT (mail_op));
2097 g_object_unref (G_OBJECT (folder));
2101 modest_ui_actions_on_delete_folder (GtkAction *action,
2102 ModestMainWindow *main_window)
2104 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2106 delete_folder (main_window, FALSE);
2110 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2112 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2114 delete_folder (main_window, TRUE);
2118 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2119 const gchar* server_account_name,
2124 ModestMainWindow *main_window)
2126 g_return_if_fail(server_account_name);
2127 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2129 /* Initalize output parameters: */
2136 #ifdef MODEST_PLATFORM_MAEMO
2137 /* Maemo uses a different (awkward) button order,
2138 * It should probably just use gtk_alternative_dialog_button_order ().
2140 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2144 GTK_RESPONSE_ACCEPT,
2146 GTK_RESPONSE_REJECT,
2149 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2153 GTK_RESPONSE_REJECT,
2155 GTK_RESPONSE_ACCEPT,
2157 #endif /* MODEST_PLATFORM_MAEMO */
2159 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2161 gchar *server_name = modest_server_account_get_hostname (
2162 modest_runtime_get_account_mgr(), server_account_name);
2163 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2164 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2169 /* This causes a warning because the logical ID has no %s in it,
2170 * though the translation does, but there is not much we can do about that: */
2171 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2172 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2175 g_free (server_name);
2179 gchar *initial_username = modest_server_account_get_username (
2180 modest_runtime_get_account_mgr(), server_account_name);
2182 GtkWidget *entry_username = gtk_entry_new ();
2183 if (initial_username)
2184 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2185 /* Dim this if a connection has ever succeeded with this username,
2186 * as per the UI spec: */
2187 const gboolean username_known =
2188 modest_server_account_get_username_has_succeeded(
2189 modest_runtime_get_account_mgr(), server_account_name);
2190 gtk_widget_set_sensitive (entry_username, !username_known);
2192 #ifdef MODEST_PLATFORM_MAEMO
2193 /* Auto-capitalization is the default, so let's turn it off: */
2194 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2196 /* Create a size group to be used by all captions.
2197 * Note that HildonCaption does not create a default size group if we do not specify one.
2198 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2199 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2201 GtkWidget *caption = hildon_caption_new (sizegroup,
2202 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2203 gtk_widget_show (entry_username);
2204 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2205 FALSE, FALSE, MODEST_MARGIN_HALF);
2206 gtk_widget_show (caption);
2208 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2210 #endif /* MODEST_PLATFORM_MAEMO */
2213 GtkWidget *entry_password = gtk_entry_new ();
2214 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2215 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2217 #ifdef MODEST_PLATFORM_MAEMO
2218 /* Auto-capitalization is the default, so let's turn it off: */
2219 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2220 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2222 caption = hildon_caption_new (sizegroup,
2223 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2224 gtk_widget_show (entry_password);
2225 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2226 FALSE, FALSE, MODEST_MARGIN_HALF);
2227 gtk_widget_show (caption);
2228 g_object_unref (sizegroup);
2230 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2232 #endif /* MODEST_PLATFORM_MAEMO */
2234 /* This is not in the Maemo UI spec:
2235 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2236 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2240 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2242 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2244 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2246 modest_server_account_set_username (
2247 modest_runtime_get_account_mgr(), server_account_name,
2250 const gboolean username_was_changed =
2251 (strcmp (*username, initial_username) != 0);
2252 if (username_was_changed) {
2253 g_warning ("%s: tinymail does not yet support changing the "
2254 "username in the get_password() callback.\n", __FUNCTION__);
2259 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2261 /* We do not save the password in the configuration,
2262 * because this function is only called for passwords that should
2263 * not be remembered:
2264 modest_server_account_set_password (
2265 modest_runtime_get_account_mgr(), server_account_name,
2284 /* This is not in the Maemo UI spec:
2285 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2291 gtk_widget_destroy (dialog);
2293 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2297 modest_ui_actions_on_cut (GtkAction *action,
2298 ModestWindow *window)
2300 GtkWidget *focused_widget;
2302 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2303 if (GTK_IS_EDITABLE (focused_widget)) {
2304 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2305 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2306 GtkTextBuffer *buffer;
2307 GtkClipboard *clipboard;
2309 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2310 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2311 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2312 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2313 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2314 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2315 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2320 modest_ui_actions_on_copy (GtkAction *action,
2321 ModestWindow *window)
2323 GtkClipboard *clipboard;
2324 GtkWidget *focused_widget;
2326 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2327 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2329 if (GTK_IS_LABEL (focused_widget)) {
2330 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2331 } else if (GTK_IS_EDITABLE (focused_widget)) {
2332 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2333 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2334 GtkTextBuffer *buffer;
2335 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2336 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2337 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2338 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2339 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2340 TnyIterator *iter = tny_list_create_iterator (header_list);
2341 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2342 TnyFolder *folder = tny_header_get_folder (header);
2343 TnyAccount *account = tny_folder_get_account (folder);
2344 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2345 /* If it's POP then ask */
2346 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2347 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2348 g_object_unref (account);
2349 g_object_unref (folder);
2350 g_object_unref (header);
2351 g_object_unref (iter);
2353 /* Check that the messages have been previously downloaded */
2354 gboolean continue_download = TRUE;
2356 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2357 if (continue_download)
2358 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2359 g_object_unref (header_list);
2360 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2361 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2364 /* Show information banner */
2365 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2370 modest_ui_actions_on_undo (GtkAction *action,
2371 ModestWindow *window)
2373 ModestEmailClipboard *clipboard = NULL;
2375 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2376 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2377 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2378 /* Clear clipboard source */
2379 clipboard = modest_runtime_get_email_clipboard ();
2380 modest_email_clipboard_clear (clipboard);
2383 g_return_if_reached ();
2388 modest_ui_actions_on_paste (GtkAction *action,
2389 ModestWindow *window)
2391 GtkWidget *focused_widget;
2392 ModestMailOperation *mail_op = NULL;
2394 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2395 if (GTK_IS_EDITABLE (focused_widget)) {
2396 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2397 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2398 GtkTextBuffer *buffer;
2399 GtkClipboard *clipboard;
2401 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2402 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2403 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2404 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2405 ModestEmailClipboard *clipboard = NULL;
2406 TnyFolder *src_folder = NULL;
2407 TnyFolderStore *folder_store = NULL;
2408 TnyList *data = NULL;
2409 gboolean delete = FALSE;
2411 /* Check clipboard source */
2412 clipboard = modest_runtime_get_email_clipboard ();
2413 if (modest_email_clipboard_cleared (clipboard))
2416 /* Get elements to paste */
2417 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2419 /* Create a new mail operation */
2420 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2421 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2424 /* Get destination folder */
2425 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2427 /* transfer messages */
2429 modest_mail_operation_xfer_msgs (mail_op,
2431 TNY_FOLDER (folder_store),
2436 } else if (src_folder != NULL) {
2437 modest_mail_operation_xfer_folder (mail_op,
2445 g_object_unref (data);
2446 if (src_folder != NULL)
2447 g_object_unref (src_folder);
2448 if (folder_store != NULL)
2449 g_object_unref (folder_store);
2454 modest_ui_actions_on_select_all (GtkAction *action,
2455 ModestWindow *window)
2457 GtkWidget *focused_widget;
2459 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2460 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2461 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2462 } else if (GTK_IS_LABEL (focused_widget)) {
2463 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2464 } else if (GTK_IS_EDITABLE (focused_widget)) {
2465 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2466 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2467 GtkTextBuffer *buffer;
2468 GtkTextIter start, end;
2470 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2471 gtk_text_buffer_get_start_iter (buffer, &start);
2472 gtk_text_buffer_get_end_iter (buffer, &end);
2473 gtk_text_buffer_select_range (buffer, &start, &end);
2474 } else if (GTK_IS_HTML (focused_widget)) {
2475 gtk_html_select_all (GTK_HTML (focused_widget));
2476 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2477 GtkWidget *header_view = focused_widget;
2478 GtkTreeSelection *selection = NULL;
2480 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2481 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2482 MODEST_WIDGET_TYPE_HEADER_VIEW);
2484 /* Select all messages */
2485 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2486 gtk_tree_selection_select_all (selection);
2488 /* Set focuse on header view */
2489 gtk_widget_grab_focus (header_view);
2495 modest_ui_actions_on_mark_as_read (GtkAction *action,
2496 ModestWindow *window)
2498 g_return_if_fail (MODEST_IS_WINDOW(window));
2500 /* Mark each header as read */
2501 do_headers_action (window, headers_action_mark_as_read, NULL);
2505 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2506 ModestWindow *window)
2508 g_return_if_fail (MODEST_IS_WINDOW(window));
2510 /* Mark each header as read */
2511 do_headers_action (window, headers_action_mark_as_unread, NULL);
2515 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2516 GtkRadioAction *selected,
2517 ModestWindow *window)
2521 value = gtk_radio_action_get_current_value (selected);
2522 if (MODEST_IS_WINDOW (window)) {
2523 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2527 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2528 GtkRadioAction *selected,
2529 ModestWindow *window)
2531 TnyHeaderFlags flags;
2532 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2534 flags = gtk_radio_action_get_current_value (selected);
2535 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2538 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2539 GtkRadioAction *selected,
2540 ModestWindow *window)
2544 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2546 file_format = gtk_radio_action_get_current_value (selected);
2547 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2552 modest_ui_actions_on_zoom_plus (GtkAction *action,
2553 ModestWindow *window)
2555 g_return_if_fail (MODEST_IS_WINDOW (window));
2557 modest_window_zoom_plus (MODEST_WINDOW (window));
2561 modest_ui_actions_on_zoom_minus (GtkAction *action,
2562 ModestWindow *window)
2564 g_return_if_fail (MODEST_IS_WINDOW (window));
2566 modest_window_zoom_minus (MODEST_WINDOW (window));
2570 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2571 ModestWindow *window)
2573 ModestWindowMgr *mgr;
2574 gboolean fullscreen, active;
2575 g_return_if_fail (MODEST_IS_WINDOW (window));
2577 mgr = modest_runtime_get_window_mgr ();
2579 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2580 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2582 if (active != fullscreen) {
2583 modest_window_mgr_set_fullscreen_mode (mgr, active);
2584 gtk_window_present (GTK_WINDOW (window));
2589 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2590 ModestWindow *window)
2592 ModestWindowMgr *mgr;
2593 gboolean fullscreen;
2595 g_return_if_fail (MODEST_IS_WINDOW (window));
2597 mgr = modest_runtime_get_window_mgr ();
2598 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2599 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2601 gtk_window_present (GTK_WINDOW (window));
2605 * Used by modest_ui_actions_on_details to call do_headers_action
2608 headers_action_show_details (TnyHeader *header,
2609 ModestWindow *window,
2616 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2619 gtk_widget_show_all (dialog);
2620 gtk_dialog_run (GTK_DIALOG (dialog));
2622 gtk_widget_destroy (dialog);
2626 * Show the folder details in a ModestDetailsDialog widget
2629 show_folder_details (TnyFolder *folder,
2635 dialog = modest_details_dialog_new_with_folder (window, folder);
2638 gtk_widget_show_all (dialog);
2639 gtk_dialog_run (GTK_DIALOG (dialog));
2641 gtk_widget_destroy (dialog);
2645 * Show the header details in a ModestDetailsDialog widget
2648 modest_ui_actions_on_details (GtkAction *action,
2651 TnyList * headers_list;
2655 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2658 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2661 g_object_unref (msg);
2663 headers_list = get_selected_headers (win);
2667 iter = tny_list_create_iterator (headers_list);
2669 header = TNY_HEADER (tny_iterator_get_current (iter));
2670 headers_action_show_details (header, win, NULL);
2671 g_object_unref (header);
2673 g_object_unref (iter);
2674 g_object_unref (headers_list);
2676 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2677 GtkWidget *folder_view, *header_view;
2679 /* Check which widget has the focus */
2680 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2681 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2682 if (gtk_widget_is_focus (folder_view)) {
2683 TnyFolderStore *folder_store
2684 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2685 if (!folder_store) {
2686 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2689 /* Show only when it's a folder */
2690 /* This function should not be called for account items,
2691 * because we dim the menu item for them. */
2692 if (TNY_IS_FOLDER (folder_store)) {
2693 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2696 g_object_unref (folder_store);
2699 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2700 MODEST_WIDGET_TYPE_HEADER_VIEW);
2701 /* Show details of each header */
2702 do_headers_action (win, headers_action_show_details, header_view);
2708 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2709 ModestMsgEditWindow *window)
2711 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2713 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2717 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2718 ModestMsgEditWindow *window)
2720 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2722 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2726 modest_ui_actions_toggle_folders_view (GtkAction *action,
2727 ModestMainWindow *main_window)
2731 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2733 conf = modest_runtime_get_conf ();
2735 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2736 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2738 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2742 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2743 ModestWindow *window)
2745 gboolean active, fullscreen = FALSE;
2746 ModestWindowMgr *mgr;
2748 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2750 /* Check if we want to toggle the toolbar vuew in fullscreen
2752 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2753 "ViewShowToolbarFullScreen")) {
2757 /* Toggle toolbar */
2758 mgr = modest_runtime_get_window_mgr ();
2759 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2763 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2764 ModestMsgEditWindow *window)
2766 modest_msg_edit_window_select_font (window);
2770 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2771 const gchar *display_name,
2774 /* Do not change the application name if the widget has not
2775 the focus. This callback could be called even if the folder
2776 view has not the focus, because the handled signal could be
2777 emitted when the folder view is redrawn */
2778 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2780 gtk_window_set_title (window, display_name);
2782 gtk_window_set_title (window, " ");
2787 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2789 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2790 modest_msg_edit_window_select_contacts (window);
2794 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2796 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2797 modest_msg_edit_window_check_names (window);
2802 create_move_to_dialog (ModestWindow *win,
2803 GtkWidget *folder_view,
2804 GtkWidget **tree_view)
2806 GtkWidget *dialog, *scroll;
2808 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2810 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2812 GTK_RESPONSE_ACCEPT,
2814 GTK_RESPONSE_REJECT,
2817 /* Create scrolled window */
2818 scroll = gtk_scrolled_window_new (NULL, NULL);
2819 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2820 GTK_POLICY_AUTOMATIC,
2821 GTK_POLICY_AUTOMATIC);
2823 /* Create folder view */
2824 *tree_view = modest_platform_create_folder_view (NULL);
2826 /* It could happen that we're trying to move a message from a
2827 window (msg window for example) after the main window was
2828 closed, so we can not just get the model of the folder
2830 if (MODEST_IS_FOLDER_VIEW (folder_view))
2831 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2832 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2834 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2835 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2837 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2839 /* Add scroll to dialog */
2840 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2841 scroll, FALSE, FALSE, 0);
2843 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2845 /* Select INBOX or local account */
2846 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2852 * Returns TRUE if at least one of the headers of the list belongs to
2853 * a message that has been fully retrieved.
2856 has_retrieved_msgs (TnyList *list)
2859 gboolean found = FALSE;
2861 iter = tny_list_create_iterator (list);
2862 while (tny_iterator_is_done (iter) && !found) {
2864 TnyHeaderFlags flags;
2866 header = TNY_HEADER (tny_iterator_get_current (iter));
2867 flags = tny_header_get_flags (header);
2868 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2872 tny_iterator_next (iter);
2874 g_object_unref (iter);
2880 * Shows a confirmation dialog to the user when we're moving messages
2881 * from a remote server to the local storage. Returns the dialog
2882 * response. If it's other kind of movement the it always returns
2886 msgs_move_to_confirmation (GtkWindow *win,
2887 TnyFolder *dest_folder,
2890 gint response = GTK_RESPONSE_OK;
2892 /* If the destination is a local folder */
2893 if (modest_tny_folder_is_local_folder (dest_folder)) {
2894 TnyFolder *src_folder;
2898 /* Get source folder */
2899 iter = tny_list_create_iterator (headers);
2900 header = TNY_HEADER (tny_iterator_get_current (iter));
2901 src_folder = tny_header_get_folder (header);
2902 g_object_unref (header);
2903 g_object_unref (iter);
2905 /* if no src_folder, message may be an attahcment */
2906 if (src_folder == NULL)
2907 return GTK_RESPONSE_CANCEL;
2909 /* If the source is a remote folder */
2910 if (!modest_tny_folder_is_local_folder (src_folder)) {
2911 const gchar *message;
2913 if (has_retrieved_msgs (headers))
2914 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2915 tny_list_get_length (headers));
2917 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2918 tny_list_get_length (headers));
2920 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2921 (const gchar *) message);
2923 g_object_unref (src_folder);
2930 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2932 ModestMsgViewWindow *self = NULL;
2933 gboolean last, first;
2935 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2936 self = MODEST_MSG_VIEW_WINDOW (object);
2938 last = modest_msg_view_window_last_message_selected (self);
2939 first = modest_msg_view_window_first_message_selected (self);
2941 /* No more messages to view, so close this window */
2942 /* gboolean ret_value; */
2943 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2944 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
2946 modest_msg_view_window_select_previous_message (self);
2948 modest_msg_view_window_select_next_message (self);
2952 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2955 GObject *win = modest_mail_operation_get_source (mail_op);
2956 const GError *error = NULL;
2957 const gchar *message = NULL;
2959 /* Get error message */
2960 error = modest_mail_operation_get_error (mail_op);
2961 if (error != NULL && error->message != NULL) {
2962 message = error->message;
2964 message = _("mail_in_ui_folder_move_target_error");
2967 /* Show notification dialog */
2968 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2969 g_object_unref (win);
2973 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
2976 GObject *win = modest_mail_operation_get_source (mail_op);
2977 const GError *error = modest_mail_operation_get_error (mail_op);
2979 g_return_if_fail (error != NULL);
2980 if (error->message != NULL)
2981 g_printerr ("modest: %s\n", error->message);
2983 g_printerr ("modest: unkonw error on send&receive operation");
2985 /* Show error message */
2986 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
2987 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
2988 /* _CS("sfil_ib_unable_to_receive")); */
2990 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
2991 /* _CS("sfil_ib_unable_to_send")); */
2992 g_object_unref (win);
2996 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3003 gint pending_purges = 0;
3004 gboolean some_purged = FALSE;
3005 ModestWindow *win = MODEST_WINDOW (user_data);
3009 /* Once the message has been retrieved for purging, we check if
3010 * it's all ok for purging */
3012 parts = tny_simple_list_new ();
3013 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3014 iter = tny_list_create_iterator (parts);
3016 while (!tny_iterator_is_done (iter)) {
3018 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3019 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3020 if (tny_mime_part_is_purged (part))
3025 tny_iterator_next (iter);
3028 if (pending_purges>0) {
3030 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3032 if (response == GTK_RESPONSE_OK) {
3033 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3034 tny_iterator_first (iter);
3035 while (!tny_iterator_is_done (iter)) {
3038 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3039 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3040 tny_mime_part_set_purged (part);
3041 tny_iterator_next (iter);
3044 tny_msg_rewrite_cache (msg);
3047 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3050 /* remove attachments */
3051 tny_iterator_first (iter);
3052 while (!tny_iterator_is_done (iter)) {
3055 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3056 g_object_unref (part);
3057 tny_iterator_next (iter);
3060 g_object_unref (iter);
3061 g_object_unref (parts);
3065 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3066 ModestMainWindow *win)
3068 GtkWidget *header_view;
3069 TnyList *header_list;
3072 TnyHeaderFlags flags;
3073 ModestWindow *msg_view_window = NULL;
3076 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3078 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3079 MODEST_WIDGET_TYPE_HEADER_VIEW);
3081 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3083 if (tny_list_get_length (header_list) == 1) {
3084 iter = tny_list_create_iterator (header_list);
3085 header = TNY_HEADER (tny_iterator_get_current (iter));
3086 g_object_unref (iter);
3091 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3092 header, &msg_view_window);
3093 flags = tny_header_get_flags (header);
3094 if (!(flags & TNY_HEADER_FLAG_CACHED))
3097 if (msg_view_window != NULL)
3098 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3100 /* do nothing; uid was registered before, so window is probably on it's way */
3101 g_warning ("debug: header %p has already been registered", header);
3104 ModestMailOperation *mail_op = NULL;
3105 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3106 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3108 modest_ui_actions_get_msgs_full_error_handler,
3110 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3111 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3113 g_object_unref (mail_op);
3116 g_object_unref (header);
3118 g_object_unref (header_list);
3122 * UI handler for the "Move to" action when invoked from the
3126 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3127 ModestMainWindow *win)
3129 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3130 GtkWidget *header_view = NULL;
3132 TnyFolderStore *folder_store = NULL;
3133 ModestMailOperation *mail_op = NULL;
3135 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3137 /* Get the folder view */
3138 folder_view = modest_main_window_get_child_widget (win,
3139 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3141 /* Get header view */
3142 header_view = modest_main_window_get_child_widget (win,
3143 MODEST_WIDGET_TYPE_HEADER_VIEW);
3145 /* Create and run the dialog */
3146 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3147 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3148 result = gtk_dialog_run (GTK_DIALOG(dialog));
3149 g_object_ref (tree_view);
3151 /* We do this to save an indentation level ;-) */
3152 if (result != GTK_RESPONSE_ACCEPT)
3155 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3157 if (TNY_IS_ACCOUNT (folder_store) &&
3158 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3161 /* Get folder or messages to transfer */
3162 if (gtk_widget_is_focus (folder_view)) {
3163 TnyFolderStore *src_folder;
3164 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3166 /* Clean folder on header view before moving it */
3167 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3169 if (TNY_IS_FOLDER (src_folder)) {
3171 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3173 modest_ui_actions_move_folder_error_handler,
3175 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3177 modest_mail_operation_xfer_folder (mail_op,
3178 TNY_FOLDER (src_folder),
3181 /* Unref mail operation */
3182 g_object_unref (G_OBJECT (mail_op));
3186 g_object_unref (G_OBJECT (src_folder));
3188 if (gtk_widget_is_focus (header_view)) {
3192 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3194 /* Ask for user confirmation */
3195 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3196 TNY_FOLDER (folder_store),
3199 /* Transfer messages */
3200 if (response == GTK_RESPONSE_OK) {
3202 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3204 modest_ui_actions_move_folder_error_handler,
3206 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3209 modest_mail_operation_xfer_msgs (mail_op,
3211 TNY_FOLDER (folder_store),
3216 g_object_unref (G_OBJECT (mail_op));
3218 g_object_unref (headers);
3222 if (folder_store != NULL)
3223 g_object_unref (folder_store);
3224 gtk_widget_destroy (dialog);
3229 * UI handler for the "Move to" action when invoked from the
3230 * ModestMsgViewWindow
3233 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3234 ModestMsgViewWindow *win)
3236 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3238 ModestMainWindow *main_window;
3242 /* Get the folder view */
3243 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3245 folder_view = modest_main_window_get_child_widget (main_window,
3246 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3250 /* Create and run the dialog */
3251 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3252 result = gtk_dialog_run (GTK_DIALOG(dialog));
3253 g_object_ref (tree_view);
3255 if (result == GTK_RESPONSE_ACCEPT) {
3256 TnyFolderStore *folder_store;
3259 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3261 /* Create header list */
3262 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3264 headers = tny_simple_list_new ();
3265 tny_list_prepend (headers, G_OBJECT (header));
3266 g_object_unref (header);
3268 /* Ask user for confirmation. MSG-NOT404 */
3269 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3270 TNY_FOLDER (folder_store),
3273 /* Transfer current msg */
3274 if (response == GTK_RESPONSE_OK) {
3275 ModestMailOperation *mail_op;
3277 /* Create mail op */
3278 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3279 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3282 /* Transfer messages */
3283 modest_mail_operation_xfer_msgs (mail_op,
3285 TNY_FOLDER (folder_store),
3287 transfer_msgs_from_viewer_cb,
3289 g_object_unref (G_OBJECT (mail_op));
3291 g_object_unref (headers);
3292 g_object_unref (folder_store);
3294 gtk_widget_destroy (dialog);
3298 modest_ui_actions_on_move_to (GtkAction *action,
3301 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3302 MODEST_IS_MSG_VIEW_WINDOW (win));
3304 if (MODEST_IS_MAIN_WINDOW (win))
3305 modest_ui_actions_on_main_window_move_to (action,
3306 MODEST_MAIN_WINDOW (win));
3308 modest_ui_actions_on_msg_view_window_move_to (action,
3309 MODEST_MSG_VIEW_WINDOW (win));
3313 * Calls #HeadersFunc for each header already selected in the main
3314 * window or the message currently being shown in the msg view window
3317 do_headers_action (ModestWindow *win,
3321 TnyList *headers_list;
3327 headers_list = get_selected_headers (win);
3331 /* Get the folder */
3332 iter = tny_list_create_iterator (headers_list);
3333 header = TNY_HEADER (tny_iterator_get_current (iter));
3334 folder = tny_header_get_folder (header);
3335 g_object_unref (header);
3337 /* Call the function for each header */
3338 while (!tny_iterator_is_done (iter)) {
3339 header = TNY_HEADER (tny_iterator_get_current (iter));
3340 func (header, win, user_data);
3341 g_object_unref (header);
3342 tny_iterator_next (iter);
3345 /* Trick: do a poke status in order to speed up the signaling
3347 tny_folder_poke_status (folder);
3350 g_object_unref (folder);
3351 g_object_unref (iter);
3352 g_object_unref (headers_list);
3356 modest_ui_actions_view_attachment (GtkAction *action,
3357 ModestWindow *window)
3359 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3360 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3362 /* not supported window for this action */
3363 g_return_if_reached ();
3368 modest_ui_actions_save_attachments (GtkAction *action,
3369 ModestWindow *window)
3371 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3372 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3374 /* not supported window for this action */
3375 g_return_if_reached ();
3380 modest_ui_actions_remove_attachments (GtkAction *action,
3381 ModestWindow *window)
3383 if (MODEST_IS_MAIN_WINDOW (window)) {
3384 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3385 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3386 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3388 /* not supported window for this action */
3389 g_return_if_reached ();
3394 modest_ui_actions_on_settings (GtkAction *action,
3399 dialog = modest_platform_get_global_settings_dialog ();
3400 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3401 gtk_widget_show_all (dialog);
3403 gtk_dialog_run (GTK_DIALOG (dialog));
3405 gtk_widget_destroy (dialog);
3409 modest_ui_actions_on_help (GtkAction *action,
3412 const gchar *help_id = NULL;
3414 if (MODEST_IS_MAIN_WINDOW (win)) {
3415 const gchar *action_name;
3416 action_name = gtk_action_get_name (action);
3418 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3419 !strcmp (action_name, "HeaderViewCSMHelp")) {
3420 GtkWidget *folder_view;
3421 TnyFolderStore *folder_store;
3422 /* Get selected folder */
3423 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3424 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3425 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3427 /* Switch help_id */
3428 if (TNY_IS_FOLDER (folder_store)) {
3429 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3430 case TNY_FOLDER_TYPE_NORMAL:
3431 help_id = "applications_email_userfolder";
3433 case TNY_FOLDER_TYPE_INBOX:
3434 help_id = "applications_email_inbox";
3436 case TNY_FOLDER_TYPE_OUTBOX:
3437 help_id = "applications_email_outbox";
3439 case TNY_FOLDER_TYPE_SENT:
3440 help_id = "applications_email_sent";
3442 case TNY_FOLDER_TYPE_DRAFTS:
3443 help_id = "applications_email_drafts";
3445 case TNY_FOLDER_TYPE_ARCHIVE:
3446 help_id = "applications_email_archive";
3452 g_object_unref (folder_store);
3454 help_id = "applications_email_mainview";
3456 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3457 help_id = "applications_email_viewer";
3458 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3459 help_id = "applications_email_editor";
3461 modest_platform_show_help (GTK_WINDOW (win), help_id);
3465 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3466 ModestWindow *window)
3468 ModestMailOperation *mail_op;
3472 headers = get_selected_headers (window);
3476 /* Create mail operation */
3477 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3479 modest_ui_actions_get_msgs_full_error_handler,
3481 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3482 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3485 g_object_unref (headers);
3486 g_object_unref (mail_op);
3490 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3491 ModestWindow *window)
3493 g_return_if_fail (MODEST_IS_WINDOW (window));
3496 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3500 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3501 ModestWindow *window)
3503 g_return_if_fail (MODEST_IS_WINDOW (window));
3506 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3510 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3511 ModestWindow *window)
3513 g_return_if_fail (MODEST_IS_WINDOW (window));
3516 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3520 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3521 ModestWindow *window)
3523 g_return_if_fail (MODEST_IS_WINDOW (window));
3526 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3530 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3531 ModestWindow *window)
3533 g_return_if_fail (MODEST_IS_WINDOW (window));
3536 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3540 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3541 ModestWindow *window)
3543 g_return_if_fail (MODEST_IS_WINDOW (window));
3546 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3550 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3551 ModestWindow *window)
3553 g_return_if_fail (MODEST_IS_WINDOW (window));
3556 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3560 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3561 ModestWindow *window)
3563 g_return_if_fail (MODEST_IS_WINDOW (window));
3566 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3570 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3572 g_return_if_fail (MODEST_IS_WINDOW (window));
3575 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3579 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3581 g_return_if_fail (MODEST_IS_WINDOW (window));
3583 modest_platform_show_search_messages (GTK_WINDOW (window));
3587 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3589 g_return_if_fail (MODEST_IS_WINDOW (win));
3590 modest_platform_show_addressbook (GTK_WINDOW (win));
3595 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3596 ModestWindow *window)
3598 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3600 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3604 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3605 ModestMailOperationState *state,
3608 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3610 /* Set send/receive operation finished */
3611 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3612 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));