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"
48 #ifdef MODEST_PLATFORM_MAEMO
49 #include "maemo/modest-osso-state-saving.h"
50 #endif /* MODEST_PLATFORM_MAEMO */
52 #include "widgets/modest-ui-constants.h"
53 #include <widgets/modest-main-window.h>
54 #include <widgets/modest-msg-view-window.h>
55 #include <widgets/modest-account-view-window.h>
56 #include <widgets/modest-details-dialog.h>
57 #include <widgets/modest-attachments-view.h>
58 #include "widgets/modest-folder-view.h"
59 #include "widgets/modest-global-settings-dialog.h"
60 #include "modest-connection-specific-smtp-window.h"
61 #include "modest-account-mgr-helpers.h"
62 #include "modest-mail-operation.h"
63 #include "modest-text-utils.h"
65 #ifdef MODEST_HAVE_EASYSETUP
66 #include "easysetup/modest-easysetup-wizard.h"
67 #endif /* MODEST_HAVE_EASYSETUP */
69 #include <modest-widget-memory.h>
70 #include <tny-error.h>
71 #include <tny-simple-list.h>
72 #include <tny-msg-view.h>
73 #include <tny-device.h>
74 #include <tny-merge-folder.h>
76 #include <gtkhtml/gtkhtml.h>
78 typedef struct _GetMsgAsyncHelper {
80 ModestMailOperation *mail_op;
87 typedef enum _ReplyForwardAction {
93 typedef struct _ReplyForwardHelper {
94 guint reply_forward_type;
95 ReplyForwardAction action;
97 GtkWidget *parent_window;
102 * The do_headers_action uses this kind of functions to perform some
103 * action to each member of a list of headers
105 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
108 do_headers_action (ModestWindow *win,
113 static void open_msg_cb (ModestMailOperation *mail_op,
118 static void reply_forward_cb (ModestMailOperation *mail_op,
123 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
126 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
127 ModestMailOperationState *state,
133 run_account_setup_wizard (ModestWindow *win)
135 ModestEasysetupWizardDialog *wizard;
137 g_return_if_fail (MODEST_IS_WINDOW(win));
139 wizard = modest_easysetup_wizard_dialog_new ();
140 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
141 gtk_dialog_run (GTK_DIALOG (wizard));
142 gtk_widget_destroy (GTK_WIDGET (wizard));
147 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
150 const gchar *authors[] = {
151 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
154 about = gtk_about_dialog_new ();
155 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
156 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
157 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
158 _("Copyright (c) 2006, Nokia Corporation\n"
159 "All rights reserved."));
160 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
161 _("a modest e-mail client\n\n"
162 "design and implementation: Dirk-Jan C. Binnema\n"
163 "contributions from the fine people at KC and Ig\n"
164 "uses the tinymail email framework written by Philip van Hoof"));
165 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
166 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
168 gtk_dialog_run (GTK_DIALOG (about));
169 gtk_widget_destroy(about);
173 * Gets the list of currently selected messages. If the win is the
174 * main window, then it returns a newly allocated list of the headers
175 * selected in the header view. If win is the msg view window, then
176 * the value returned is a list with just a single header.
178 * The caller of this funcion must free the list.
181 get_selected_headers (ModestWindow *win)
183 if (MODEST_IS_MAIN_WINDOW(win)) {
184 GtkWidget *header_view;
186 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
187 MODEST_WIDGET_TYPE_HEADER_VIEW);
188 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
190 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
191 /* for MsgViewWindows, we simply return a list with one element */
193 TnyList *list = NULL;
195 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
196 if (header != NULL) {
197 list = tny_simple_list_new ();
198 tny_list_prepend (list, G_OBJECT(header));
199 g_object_unref (G_OBJECT(header));
209 headers_action_mark_as_read (TnyHeader *header,
213 TnyHeaderFlags flags;
215 g_return_if_fail (TNY_IS_HEADER(header));
217 flags = tny_header_get_flags (header);
218 if (flags & TNY_HEADER_FLAG_SEEN) return;
219 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
223 headers_action_mark_as_unread (TnyHeader *header,
227 TnyHeaderFlags flags;
229 g_return_if_fail (TNY_IS_HEADER(header));
231 flags = tny_header_get_flags (header);
232 if (flags & TNY_HEADER_FLAG_SEEN) {
233 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
239 headers_action_delete (TnyHeader *header,
243 ModestMailOperation *mail_op = NULL;
245 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
246 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
249 /* Always delete. TODO: Move to trash still not supported */
250 modest_mail_operation_remove_msg (mail_op, header, FALSE);
251 g_object_unref (G_OBJECT (mail_op));
255 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
257 TnyList *header_list = NULL;
258 TnyIterator *iter = NULL;
259 TnyHeader *header = NULL;
260 gchar *message = NULL;
264 ModestWindowMgr *mgr;
265 GtkWidget *header_view;
267 g_return_if_fail (MODEST_IS_WINDOW(win));
269 /* Check first if the header view has the focus */
270 if (MODEST_IS_MAIN_WINDOW (win)) {
271 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
272 MODEST_WIDGET_TYPE_HEADER_VIEW);
273 if (!gtk_widget_is_focus (header_view))
277 header_list = get_selected_headers (win);
278 if (!header_list) return;
280 /* Check if any of the headers is already opened */
281 iter = tny_list_create_iterator (header_list);
283 mgr = modest_runtime_get_window_mgr ();
284 while (!tny_iterator_is_done (iter) && !found) {
285 header = TNY_HEADER (tny_iterator_get_current (iter));
286 if (modest_window_mgr_find_window_by_header (mgr, header))
288 g_object_unref (header);
289 tny_iterator_next (iter);
291 g_object_unref (iter);
296 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
297 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
299 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
303 g_object_unref (header_list);
308 if (tny_list_get_length(header_list) == 1) {
309 iter = tny_list_create_iterator (header_list);
310 header = TNY_HEADER (tny_iterator_get_current (iter));
311 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
312 g_object_unref (header);
313 g_object_unref (iter);
315 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
316 tny_list_get_length(header_list)), desc);
318 /* Confirmation dialog */
319 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
323 if (response == GTK_RESPONSE_OK) {
324 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
326 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
330 /* Remove each header */
331 do_headers_action (win, headers_action_delete, NULL);
333 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
334 gtk_widget_destroy (GTK_WIDGET(win));
341 g_object_unref (header_list);
346 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
348 #ifdef MODEST_PLATFORM_MAEMO
349 modest_osso_save_state();
350 #endif /* MODEST_PLATFORM_MAEMO */
352 /* FIXME: we need to cancel all actions/threads here,
359 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
361 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
362 gtk_widget_destroy (GTK_WIDGET (win));
363 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
365 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
366 } else if (MODEST_IS_WINDOW (win)) {
367 gtk_widget_destroy (GTK_WIDGET (win));
369 g_return_if_reached ();
374 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
376 GtkClipboard *clipboard = NULL;
377 gchar *selection = NULL;
379 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
380 selection = gtk_clipboard_wait_for_text (clipboard);
382 /* Question: why is the clipboard being used here?
383 * It doesn't really make a lot of sense. */
387 modest_address_book_add_address (selection);
393 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
395 /* This is currently only implemented for Maemo */
396 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
397 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
398 run_account_setup_wizard (win);
401 /* Show the list of accounts: */
402 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
403 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
404 gtk_dialog_run (account_win);
405 gtk_widget_destroy (GTK_WIDGET(account_win));
408 GtkWidget *dialog, *label;
410 /* Create the widgets */
412 dialog = gtk_dialog_new_with_buttons ("Message",
414 GTK_DIALOG_DESTROY_WITH_PARENT,
418 label = gtk_label_new ("Hello World!");
420 /* Ensure that the dialog box is destroyed when the user responds. */
422 g_signal_connect_swapped (dialog, "response",
423 G_CALLBACK (gtk_widget_destroy),
426 /* Add the label, and show everything we've added to the dialog. */
428 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
430 gtk_widget_show_all (dialog);
431 #endif /* MODEST_PLATFORM_MAEMO */
435 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
437 ModestWindow *main_window = MODEST_WINDOW (user_data);
439 /* Save any changes. */
440 modest_connection_specific_smtp_window_save_server_accounts (
441 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
442 modest_window_get_active_account (main_window));
443 gtk_widget_destroy (GTK_WIDGET (window));
449 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
451 /* This is currently only implemented for Maemo,
452 * because it requires an API (libconic) to detect different connection
455 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
457 /* Create the window if necessary: */
458 const gchar *active_account_name = modest_window_get_active_account (win);
460 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
461 * or show the default account?
462 * If we show the default account then the account name should be shown in
463 * the window when we show it. */
464 if (!active_account_name) {
465 g_warning ("%s: No account is active.", __FUNCTION__);
469 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
470 modest_connection_specific_smtp_window_fill_with_connections (
471 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
472 modest_runtime_get_account_mgr(),
473 active_account_name);
475 /* Show the window: */
476 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
477 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
478 gtk_widget_show (specific_window);
480 /* Save changes when the window is hidden: */
481 g_signal_connect (specific_window, "hide",
482 G_CALLBACK (on_smtp_servers_window_hide), win);
483 #endif /* MODEST_PLATFORM_MAEMO */
487 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
489 ModestWindow *msg_win = NULL;
491 TnyFolder *folder = NULL;
492 gchar *account_name = NULL;
493 gchar *from_str = NULL;
494 /* GError *err = NULL; */
495 TnyAccount *account = NULL;
496 ModestWindowMgr *mgr;
497 gchar *signature = NULL, *blank_and_signature = NULL;
499 /* if there are no accounts yet, just show the wizard */
500 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
501 run_account_setup_wizard (win);
505 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
507 account_name = g_strdup (modest_window_get_active_account (win));
509 g_printerr ("modest: no account found\n");
513 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
515 TNY_ACCOUNT_TYPE_STORE);
517 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
521 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
523 g_printerr ("modest: failed get from string for '%s'\n", account_name);
527 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
528 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
529 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
530 MODEST_ACCOUNT_SIGNATURE, FALSE);
531 blank_and_signature = g_strconcat ("\n", signature, NULL);
534 blank_and_signature = g_strdup ("");
537 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
539 g_printerr ("modest: failed to create new msg\n");
543 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
545 g_printerr ("modest: failed to find Drafts folder\n");
550 /* Create and register edit window */
551 /* This is destroyed by TOOD. */
552 msg_win = modest_msg_edit_window_new (msg, account_name);
553 mgr = modest_runtime_get_window_mgr ();
554 modest_window_mgr_register_window (mgr, msg_win);
557 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
559 gtk_widget_show_all (GTK_WIDGET (msg_win));
562 g_free (account_name);
564 g_free (blank_and_signature);
566 g_object_unref (msg_win);
568 g_object_unref (G_OBJECT(account));
570 g_object_unref (G_OBJECT(msg));
572 g_object_unref (G_OBJECT(folder));
576 open_msg_cb (ModestMailOperation *mail_op,
581 ModestWindowMgr *mgr = NULL;
582 ModestWindow *parent_win = NULL;
583 ModestWindow *win = NULL;
584 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
585 gchar *account = NULL;
588 /* TODO: Show an error? (review the specs) */
592 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
593 folder = tny_header_get_folder (header);
595 /* Mark header as read */
596 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
599 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
601 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
603 /* Gets folder type (OUTBOX headers will be opened in edit window */
604 if (modest_tny_folder_is_local_folder (folder))
605 folder_type = modest_tny_folder_get_local_folder_type (folder);
607 /* If the header is in the drafts folder then open the editor,
608 else the message view window */
609 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
610 /* we cannot edit without a valid account... */
611 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
612 run_account_setup_wizard(parent_win);
615 win = modest_msg_edit_window_new (msg, account);
617 gchar *uid = modest_tny_folder_get_header_unique_id (header);
619 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
620 GtkWidget *header_view;
621 GtkTreeSelection *sel;
622 GList *sel_list = NULL;
625 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
626 MODEST_WIDGET_TYPE_HEADER_VIEW);
628 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
629 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
631 if (sel_list != NULL) {
632 GtkTreeRowReference *row_reference;
634 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
635 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
636 g_list_free (sel_list);
638 win = modest_msg_view_window_new_with_header_model (msg,
643 gtk_tree_row_reference_free (row_reference);
645 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
648 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
653 /* Register and show new window */
655 mgr = modest_runtime_get_window_mgr ();
656 modest_window_mgr_register_window (mgr, win);
657 g_object_unref (win);
658 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
659 gtk_widget_show_all (GTK_WIDGET(win));
665 g_object_unref (parent_win);
666 g_object_unref (msg);
667 g_object_unref (folder);
671 * This function is the error handler of the
672 * modest_mail_operation_get_msgs_full operation
675 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
680 error = modest_mail_operation_get_error (mail_op);
681 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
682 GObject *win = modest_mail_operation_get_source (mail_op);
684 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
686 g_object_unref (win);
691 * This function is used by both modest_ui_actions_on_open and
692 * modest_ui_actions_on_header_activated. This way we always do the
693 * same when trying to open messages.
696 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
698 ModestWindowMgr *mgr = NULL;
699 TnyIterator *iter = NULL;
700 ModestMailOperation *mail_op1 = NULL;
701 ModestMailOperation *mail_op2 = NULL;
702 TnyList *not_opened_headers = NULL;
703 TnyList *not_opened_cached_headers = NULL;
704 TnyHeaderFlags flags;
706 /* Look if we already have a message view for each header. If
707 true, then remove the header from the list of headers to
709 mgr = modest_runtime_get_window_mgr ();
710 iter = tny_list_create_iterator (headers);
711 not_opened_headers = tny_simple_list_new ();
712 not_opened_cached_headers = tny_simple_list_new ();
713 while (!tny_iterator_is_done (iter)) {
714 ModestWindow *window;
717 header = TNY_HEADER (tny_iterator_get_current (iter));
718 flags = tny_header_get_flags (header);
719 window = modest_window_mgr_find_window_by_header (mgr, header);
721 /* Do not open again the message and present the
722 window to the user */
724 gtk_window_present (GTK_WINDOW (window));
725 else if (!(flags & TNY_HEADER_FLAG_CACHED))
726 tny_list_append (not_opened_headers, G_OBJECT (header));
727 /* Check if msg has already been retreived */
729 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
731 g_object_unref (header);
732 tny_iterator_next (iter);
735 /* Open each uncached message */
736 if (tny_list_get_length (not_opened_headers) > 0) {
737 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
739 modest_ui_actions_get_msgs_full_error_handler,
741 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
742 if (tny_list_get_length (not_opened_headers) > 1) {
743 modest_mail_operation_get_msgs_full (mail_op1,
749 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
750 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
751 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
752 g_object_unref (header);
753 g_object_unref (iter);
757 /* Open each cached message */
758 if (tny_list_get_length (not_opened_cached_headers) > 0) {
759 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
761 modest_ui_actions_get_msgs_full_error_handler,
763 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
764 if (tny_list_get_length (not_opened_cached_headers) > 1) {
765 modest_mail_operation_get_msgs_full (mail_op2,
771 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
772 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
773 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
774 g_object_unref (header);
775 g_object_unref (iter);
780 if (not_opened_headers != NULL)
781 g_object_unref (not_opened_headers);
782 if (not_opened_cached_headers != NULL)
783 g_object_unref (not_opened_cached_headers);
785 g_object_unref (iter);
786 if (mail_op1 != NULL)
787 g_object_unref (mail_op1);
788 if (mail_op2 != NULL)
789 g_object_unref (mail_op2);
793 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
798 headers = get_selected_headers (win);
803 _modest_ui_actions_open (headers, win);
805 g_object_unref(headers);
810 free_reply_forward_helper (gpointer data)
812 ReplyForwardHelper *helper;
814 helper = (ReplyForwardHelper *) data;
815 g_free (helper->account_name);
816 g_slice_free (ReplyForwardHelper, helper);
820 reply_forward_cb (ModestMailOperation *mail_op,
826 ReplyForwardHelper *rf_helper;
827 ModestWindow *msg_win = NULL;
828 ModestEditType edit_type;
830 TnyAccount *account = NULL;
831 ModestWindowMgr *mgr = NULL;
832 gchar *signature = NULL;
834 g_return_if_fail (user_data != NULL);
835 rf_helper = (ReplyForwardHelper *) user_data;
837 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
838 rf_helper->account_name);
839 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
840 rf_helper->account_name,
841 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
842 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
843 rf_helper->account_name,
844 MODEST_ACCOUNT_SIGNATURE, FALSE);
847 /* Create reply mail */
848 switch (rf_helper->action) {
851 modest_tny_msg_create_reply_msg (msg, from, signature,
852 rf_helper->reply_forward_type,
853 MODEST_TNY_MSG_REPLY_MODE_SENDER);
855 case ACTION_REPLY_TO_ALL:
857 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
858 MODEST_TNY_MSG_REPLY_MODE_ALL);
859 edit_type = MODEST_EDIT_TYPE_REPLY;
863 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
864 edit_type = MODEST_EDIT_TYPE_FORWARD;
867 g_return_if_reached ();
874 g_printerr ("modest: failed to create message\n");
878 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
879 rf_helper->account_name,
880 TNY_ACCOUNT_TYPE_STORE);
882 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
886 /* Create and register the windows */
887 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
888 mgr = modest_runtime_get_window_mgr ();
889 modest_window_mgr_register_window (mgr, msg_win);
891 if (rf_helper->parent_window != NULL) {
894 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
895 modest_window_set_zoom (msg_win, parent_zoom);
898 /* Show edit window */
899 gtk_widget_show_all (GTK_WIDGET (msg_win));
903 g_object_unref (msg_win);
905 g_object_unref (G_OBJECT (new_msg));
907 g_object_unref (G_OBJECT (account));
908 g_object_unref (msg);
909 g_object_unref (header);
913 * Checks a list of headers. If any of them are not currently
914 * downloaded (CACHED) then it asks the user for permission to
917 * Returns FALSE if the user does not want to download the
918 * messages. Returns TRUE if the user allowed the download or if all
919 * of them are currently downloaded
922 download_uncached_messages (TnyList *header_list, GtkWindow *win)
926 gint uncached_messages = 0;
928 iter = tny_list_create_iterator (header_list);
929 while (!tny_iterator_is_done (iter)) {
931 TnyHeaderFlags flags;
933 header = TNY_HEADER (tny_iterator_get_current (iter));
934 flags = tny_header_get_flags (header);
935 /* TODO: is this the right flag?, it seems that some
936 headers that have been previously downloaded do not
938 if (! (flags & TNY_HEADER_FLAG_CACHED))
939 uncached_messages ++;
940 g_object_unref (header);
941 tny_iterator_next (iter);
943 g_object_unref (iter);
945 /* Ask for user permission to download the messages */
947 if (uncached_messages > 0) {
948 GtkResponseType response;
950 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
951 ngettext("mcen_nc_get_msg",
954 if (response == GTK_RESPONSE_CANCEL)
962 * Common code for the reply and forward actions
965 reply_forward (ReplyForwardAction action, ModestWindow *win)
967 ModestMailOperation *mail_op = NULL;
968 TnyList *header_list = NULL;
969 ReplyForwardHelper *rf_helper = NULL;
970 guint reply_forward_type;
971 gboolean continue_download;
973 g_return_if_fail (MODEST_IS_WINDOW(win));
975 /* we need an account when editing */
976 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
977 run_account_setup_wizard (win);
981 header_list = get_selected_headers (win);
985 /* Check that the messages have been previously downloaded */
986 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
987 if (!continue_download) {
988 g_object_unref (header_list);
993 modest_conf_get_int (modest_runtime_get_conf (),
994 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
996 /* We assume that we can only select messages of the
997 same folder and that we reply all of them from the
998 same account. In fact the interface currently only
999 allows single selection */
1002 rf_helper = g_slice_new0 (ReplyForwardHelper);
1003 rf_helper->reply_forward_type = reply_forward_type;
1004 rf_helper->action = action;
1005 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1006 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1007 rf_helper->parent_window = GTK_WIDGET (win);
1008 if (!rf_helper->account_name)
1009 rf_helper->account_name =
1010 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1012 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1015 /* Get header and message. Do not free them here, the
1016 reply_forward_cb must do it */
1017 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1018 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1019 if (!msg || !header) {
1021 g_object_unref (msg);
1023 g_object_unref (header);
1024 g_printerr ("modest: no message found\n");
1027 reply_forward_cb (NULL, header, msg, rf_helper);
1029 /* Retrieve messages */
1030 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1032 modest_ui_actions_get_msgs_full_error_handler,
1034 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1035 modest_mail_operation_get_msgs_full (mail_op,
1039 free_reply_forward_helper);
1042 g_object_unref(mail_op);
1046 g_object_unref (header_list);
1050 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1052 g_return_if_fail (MODEST_IS_WINDOW(win));
1054 reply_forward (ACTION_REPLY, win);
1058 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1060 g_return_if_fail (MODEST_IS_WINDOW(win));
1062 reply_forward (ACTION_FORWARD, win);
1066 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1068 g_return_if_fail (MODEST_IS_WINDOW(win));
1070 reply_forward (ACTION_REPLY_TO_ALL, win);
1074 modest_ui_actions_on_next (GtkAction *action,
1075 ModestWindow *window)
1077 if (MODEST_IS_MAIN_WINDOW (window)) {
1078 GtkWidget *header_view;
1080 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1081 MODEST_WIDGET_TYPE_HEADER_VIEW);
1085 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1086 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1087 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1089 g_return_if_reached ();
1094 modest_ui_actions_on_prev (GtkAction *action,
1095 ModestWindow *window)
1097 g_return_if_fail (MODEST_IS_WINDOW(window));
1099 if (MODEST_IS_MAIN_WINDOW (window)) {
1100 GtkWidget *header_view;
1101 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1102 MODEST_WIDGET_TYPE_HEADER_VIEW);
1106 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1107 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1108 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1110 g_return_if_reached ();
1115 modest_ui_actions_on_sort (GtkAction *action,
1116 ModestWindow *window)
1118 g_return_if_fail (MODEST_IS_WINDOW(window));
1120 if (MODEST_IS_MAIN_WINDOW (window)) {
1121 GtkWidget *header_view;
1122 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1123 MODEST_WIDGET_TYPE_HEADER_VIEW);
1127 /* Show sorting dialog */
1128 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1133 new_messages_arrived (ModestMailOperation *self,
1137 if (new_messages == 0)
1140 modest_platform_on_new_msg ();
1144 * This function performs the send & receive required actions. The
1145 * window is used to create the mail operation. Typically it should
1146 * always be the main window, but we pass it as argument in order to
1150 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1152 gchar *acc_name = NULL;
1153 ModestMailOperation *mail_op;
1155 /* If no account name was provided then get the current account, and if
1156 there is no current account then pick the default one: */
1157 if (!account_name) {
1158 acc_name = g_strdup (modest_window_get_active_account(win));
1160 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1162 g_printerr ("modest: cannot get default account\n");
1166 acc_name = g_strdup (account_name);
1169 /* Set send/receive operation in progress */
1170 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1172 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1173 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1174 G_CALLBACK (_on_send_receive_progress_changed),
1177 /* Send & receive. */
1178 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1179 /* Receive and then send. The operation is tagged initially as
1180 a receive operation because the account update performs a
1181 receive and then a send. The operation changes its type
1182 internally, so the progress objects will receive the proper
1183 progress information */
1184 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1185 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1186 g_object_unref (G_OBJECT (mail_op));
1193 * Refreshes all accounts. This function will be used by automatic
1197 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1199 GSList *account_names, *iter;
1201 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1204 iter = account_names;
1206 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1207 iter = g_slist_next (iter);
1210 modest_account_mgr_free_account_names (account_names);
1211 account_names = NULL;
1215 * Handler of the click on Send&Receive button in the main toolbar
1218 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1220 /* Check if accounts exist */
1221 gboolean accounts_exist =
1222 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1224 /* If not, allow the user to create an account before trying to send/receive. */
1225 if (!accounts_exist)
1226 modest_ui_actions_on_accounts (NULL, win);
1228 /* Refresh the active account */
1229 modest_ui_actions_do_send_receive (NULL, win);
1234 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1237 GtkWidget *header_view;
1239 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1241 header_view = modest_main_window_get_child_widget (main_window,
1242 MODEST_WIDGET_TYPE_HEADER_VIEW);
1246 conf = modest_runtime_get_conf ();
1248 /* what is saved/restored is depending on the style; thus; we save with
1249 * old style, then update the style, and restore for this new style
1251 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1253 if (modest_header_view_get_style
1254 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1255 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1256 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1258 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1259 MODEST_HEADER_VIEW_STYLE_DETAILS);
1261 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1262 MODEST_CONF_HEADER_VIEW_KEY);
1267 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1269 ModestMainWindow *main_window)
1271 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1272 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1274 /* If no header has been selected then exit */
1279 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1280 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1282 /* Update Main window title */
1283 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1284 const gchar *subject = tny_header_get_subject (header);
1285 if (subject && strlen(subject) > 0)
1286 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1288 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1291 /* Update toolbar dimming state */
1292 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1296 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1298 ModestMainWindow *main_window)
1302 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1307 headers = tny_simple_list_new ();
1308 tny_list_prepend (headers, G_OBJECT (header));
1310 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1312 g_object_unref (headers);
1316 set_active_account_from_tny_account (TnyAccount *account,
1317 ModestWindow *window)
1319 const gchar *server_acc_name = tny_account_get_id (account);
1321 /* We need the TnyAccount provided by the
1322 account store because that is the one that
1323 knows the name of the Modest account */
1324 TnyAccount *modest_server_account = modest_server_account =
1325 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1326 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1329 const gchar *modest_acc_name =
1330 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1331 modest_window_set_active_account (window, modest_acc_name);
1332 g_object_unref (modest_server_account);
1337 folder_refreshed_cb (const GObject *obj,
1341 ModestMainWindow *win = NULL;
1342 GtkWidget *header_view;
1344 g_return_if_fail (TNY_IS_FOLDER (folder));
1346 win = MODEST_MAIN_WINDOW (user_data);
1348 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1350 /* Check if folder is empty and set headers view contents style */
1351 if (tny_folder_get_all_count (folder) == 0) {
1352 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1353 modest_main_window_set_contents_style (win,
1354 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1356 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1361 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1362 TnyFolderStore *folder_store,
1364 ModestMainWindow *main_window)
1367 GtkWidget *header_view;
1369 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1371 header_view = modest_main_window_get_child_widget(main_window,
1372 MODEST_WIDGET_TYPE_HEADER_VIEW);
1376 conf = modest_runtime_get_conf ();
1378 if (TNY_IS_ACCOUNT (folder_store)) {
1380 /* Update active account */
1381 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1382 /* Show account details */
1383 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1386 if (TNY_IS_FOLDER (folder_store) && selected) {
1388 /* Update the active account */
1389 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1391 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1392 g_object_unref (account);
1396 /* Set the header style by default, it could
1397 be changed later by the refresh callback to
1399 modest_main_window_set_contents_style (main_window,
1400 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1402 /* Set folder on header view. This function
1403 will call tny_folder_refresh_async so we
1404 pass a callback that will be called when
1405 finished. We use that callback to set the
1406 empty view if there are no messages */
1407 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1408 TNY_FOLDER (folder_store),
1409 folder_refreshed_cb,
1412 /* Restore configuration. We need to do this
1413 *after* the set_folder because the widget
1414 memory asks the header view about its
1416 modest_widget_memory_restore (modest_runtime_get_conf (),
1417 G_OBJECT(header_view),
1418 MODEST_CONF_HEADER_VIEW_KEY);
1420 /* Update the active account */
1421 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1422 /* Save only if we're seeing headers */
1423 if (modest_main_window_get_contents_style (main_window) ==
1424 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1425 modest_widget_memory_save (conf, G_OBJECT (header_view),
1426 MODEST_CONF_HEADER_VIEW_KEY);
1427 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1431 /* Update toolbar dimming state */
1432 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1436 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1443 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1445 if (g_main_depth > 0)
1446 gdk_threads_enter ();
1447 online = tny_device_is_online (modest_runtime_get_device());
1450 /* already online -- the item is simply not there... */
1451 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1453 GTK_MESSAGE_WARNING,
1455 _("The %s you selected cannot be found"),
1457 gtk_dialog_run (GTK_DIALOG(dialog));
1459 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1463 GTK_RESPONSE_REJECT,
1465 GTK_RESPONSE_ACCEPT,
1467 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1468 "Do you want to get online?"), item);
1469 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1470 gtk_label_new (txt), FALSE, FALSE, 0);
1471 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1474 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1475 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1476 // modest_platform_connect_and_wait ();
1479 gtk_widget_destroy (dialog);
1480 if (g_main_depth > 0)
1481 gdk_threads_leave ();
1485 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1488 /* g_message ("%s %s", __FUNCTION__, link); */
1493 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1496 modest_platform_activate_uri (link);
1500 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1503 modest_platform_show_uri_popup (link);
1507 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1510 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1514 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1515 const gchar *address,
1518 /* g_message ("%s %s", __FUNCTION__, address); */
1522 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1524 TnyTransportAccount *transport_account;
1525 ModestMailOperation *mail_operation;
1527 gchar *account_name, *from;
1528 ModestAccountMgr *account_mgr;
1529 gchar *info_text = NULL;
1531 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1533 data = modest_msg_edit_window_get_msg_data (edit_window);
1535 account_mgr = modest_runtime_get_account_mgr();
1536 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1538 account_name = modest_account_mgr_get_default_account (account_mgr);
1539 if (!account_name) {
1540 g_printerr ("modest: no account found\n");
1541 modest_msg_edit_window_free_msg_data (edit_window, data);
1545 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1546 account_name = g_strdup (data->account_name);
1550 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1551 (modest_runtime_get_account_store(),
1553 TNY_ACCOUNT_TYPE_TRANSPORT));
1554 if (!transport_account) {
1555 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1556 g_free (account_name);
1557 modest_msg_edit_window_free_msg_data (edit_window, data);
1560 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1562 /* Create the mail operation */
1563 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1564 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1566 modest_mail_operation_save_to_drafts (mail_operation,
1577 data->priority_flags);
1580 g_free (account_name);
1581 g_object_unref (G_OBJECT (transport_account));
1582 g_object_unref (G_OBJECT (mail_operation));
1584 modest_msg_edit_window_free_msg_data (edit_window, data);
1586 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1587 modest_platform_information_banner (NULL, NULL, info_text);
1591 /* For instance, when clicking the Send toolbar button when editing a message: */
1593 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1595 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1597 if (!modest_msg_edit_window_check_names (edit_window))
1600 /* FIXME: Code added just for testing. The final version will
1601 use the send queue provided by tinymail and some
1603 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1604 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1606 account_name = modest_account_mgr_get_default_account (account_mgr);
1608 if (!account_name) {
1609 g_printerr ("modest: no account found\n");
1613 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1615 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1616 account_name = g_strdup (data->account_name);
1619 /* Get the currently-active transport account for this modest account: */
1620 TnyTransportAccount *transport_account =
1621 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1622 (modest_runtime_get_account_store(),
1624 if (!transport_account) {
1625 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1626 g_free (account_name);
1627 modest_msg_edit_window_free_msg_data (edit_window, data);
1631 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1633 /* mail content checks and dialogs */
1634 if (data->subject == NULL || data->subject[0] == '\0') {
1635 GtkResponseType response;
1636 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1637 _("mcen_nc_subject_is_empty_send"));
1638 if (response == GTK_RESPONSE_CANCEL) {
1639 g_free (account_name);
1644 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1645 GtkResponseType response;
1646 gchar *note_message;
1647 gchar *note_subject = data->subject;
1648 if (note_subject == NULL || note_subject[0] == '\0')
1649 note_subject = _("mail_va_no_subject");
1650 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1651 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1653 g_free (note_message);
1654 if (response == GTK_RESPONSE_CANCEL) {
1655 g_free (account_name);
1660 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1662 /* Create the mail operation */
1663 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1664 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1666 modest_mail_operation_send_new_mail (mail_operation,
1677 data->priority_flags);
1681 g_free (account_name);
1682 g_object_unref (G_OBJECT (transport_account));
1683 g_object_unref (G_OBJECT (mail_operation));
1685 modest_msg_edit_window_free_msg_data (edit_window, data);
1686 modest_msg_edit_window_set_sent (edit_window, TRUE);
1688 /* Save settings and close the window: */
1689 gtk_widget_destroy (GTK_WIDGET (edit_window));
1693 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1694 ModestMsgEditWindow *window)
1696 ModestMsgEditFormatState *format_state = NULL;
1698 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1699 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1701 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1704 format_state = modest_msg_edit_window_get_format_state (window);
1705 g_return_if_fail (format_state != NULL);
1707 format_state->bold = gtk_toggle_action_get_active (action);
1708 modest_msg_edit_window_set_format_state (window, format_state);
1709 g_free (format_state);
1714 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1715 ModestMsgEditWindow *window)
1717 ModestMsgEditFormatState *format_state = NULL;
1719 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1720 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1722 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1725 format_state = modest_msg_edit_window_get_format_state (window);
1726 g_return_if_fail (format_state != NULL);
1728 format_state->italics = gtk_toggle_action_get_active (action);
1729 modest_msg_edit_window_set_format_state (window, format_state);
1730 g_free (format_state);
1735 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1736 ModestMsgEditWindow *window)
1738 ModestMsgEditFormatState *format_state = NULL;
1740 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1741 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1743 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1746 format_state = modest_msg_edit_window_get_format_state (window);
1747 g_return_if_fail (format_state != NULL);
1749 format_state->bullet = gtk_toggle_action_get_active (action);
1750 modest_msg_edit_window_set_format_state (window, format_state);
1751 g_free (format_state);
1756 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1757 GtkRadioAction *selected,
1758 ModestMsgEditWindow *window)
1760 ModestMsgEditFormatState *format_state = NULL;
1761 GtkJustification value;
1763 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1765 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1768 value = gtk_radio_action_get_current_value (selected);
1770 format_state = modest_msg_edit_window_get_format_state (window);
1771 g_return_if_fail (format_state != NULL);
1773 format_state->justification = value;
1774 modest_msg_edit_window_set_format_state (window, format_state);
1775 g_free (format_state);
1779 modest_ui_actions_on_select_editor_color (GtkAction *action,
1780 ModestMsgEditWindow *window)
1782 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1783 g_return_if_fail (GTK_IS_ACTION (action));
1785 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1788 modest_msg_edit_window_select_color (window);
1792 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1793 ModestMsgEditWindow *window)
1795 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1796 g_return_if_fail (GTK_IS_ACTION (action));
1798 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1801 modest_msg_edit_window_select_background_color (window);
1805 modest_ui_actions_on_insert_image (GtkAction *action,
1806 ModestMsgEditWindow *window)
1808 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1809 g_return_if_fail (GTK_IS_ACTION (action));
1811 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1814 modest_msg_edit_window_insert_image (window);
1818 modest_ui_actions_on_attach_file (GtkAction *action,
1819 ModestMsgEditWindow *window)
1821 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1822 g_return_if_fail (GTK_IS_ACTION (action));
1824 modest_msg_edit_window_attach_file (window);
1828 modest_ui_actions_on_remove_attachments (GtkAction *action,
1829 ModestMsgEditWindow *window)
1831 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1832 g_return_if_fail (GTK_IS_ACTION (action));
1834 modest_msg_edit_window_remove_attachments (window, NULL);
1838 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1840 TnyFolderStore *parent_folder;
1841 GtkWidget *folder_view;
1843 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1845 folder_view = modest_main_window_get_child_widget (main_window,
1846 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1850 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1852 if (parent_folder) {
1853 gboolean finished = FALSE;
1855 gchar *folder_name = NULL, *suggested_name = NULL;
1857 /* Run the new folder dialog */
1859 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1864 if (result == GTK_RESPONSE_REJECT) {
1867 ModestMailOperation *mail_op;
1868 TnyFolder *new_folder = NULL;
1870 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1871 G_OBJECT(main_window));
1872 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1874 new_folder = modest_mail_operation_create_folder (mail_op,
1876 (const gchar *) folder_name);
1878 g_object_unref (new_folder);
1881 g_object_unref (mail_op);
1883 g_free (folder_name);
1887 g_object_unref (parent_folder);
1892 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1895 GObject *win = modest_mail_operation_get_source (mail_op);
1897 /* TODO: what should we do in case of this error ? */
1898 g_warning ("Invalid folder name");
1900 g_object_unref (win);
1904 modest_ui_actions_on_rename_folder (GtkAction *action,
1905 ModestMainWindow *main_window)
1907 TnyFolderStore *folder;
1908 GtkWidget *folder_view;
1909 GtkWidget *header_view;
1911 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1913 folder_view = modest_main_window_get_child_widget (main_window,
1914 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1918 header_view = modest_main_window_get_child_widget (main_window,
1919 MODEST_WIDGET_TYPE_HEADER_VIEW);
1924 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1926 if (folder && TNY_IS_FOLDER (folder)) {
1929 const gchar *current_name;
1931 current_name = tny_folder_get_name (TNY_FOLDER (folder));
1932 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
1933 current_name, &folder_name);
1935 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
1936 ModestMailOperation *mail_op;
1939 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
1940 G_OBJECT(main_window),
1941 modest_ui_actions_rename_folder_error_handler,
1945 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1948 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
1950 modest_mail_operation_rename_folder (mail_op,
1951 TNY_FOLDER (folder),
1952 (const gchar *) folder_name);
1954 g_object_unref (mail_op);
1955 g_free (folder_name);
1957 g_object_unref (folder);
1962 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1965 GObject *win = modest_mail_operation_get_source (mail_op);
1967 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1968 _("mail_in_ui_folder_delete_error"));
1969 g_object_unref (win);
1973 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1975 TnyFolderStore *folder;
1976 GtkWidget *folder_view;
1980 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1982 folder_view = modest_main_window_get_child_widget (main_window,
1983 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1987 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1989 /* Show an error if it's an account */
1990 if (!TNY_IS_FOLDER (folder)) {
1991 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1992 _("mail_in_ui_folder_delete_error"));
1997 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1998 tny_folder_get_name (TNY_FOLDER (folder)));
1999 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2000 (const gchar *) message);
2003 if (response == GTK_RESPONSE_OK) {
2004 ModestMailOperation *mail_op =
2005 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2006 G_OBJECT(main_window),
2007 modest_ui_actions_delete_folder_error_handler,
2010 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2012 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2013 g_object_unref (G_OBJECT (mail_op));
2016 g_object_unref (G_OBJECT (folder));
2020 modest_ui_actions_on_delete_folder (GtkAction *action,
2021 ModestMainWindow *main_window)
2023 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2025 delete_folder (main_window, FALSE);
2029 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2031 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2033 delete_folder (main_window, TRUE);
2037 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2038 const gchar* server_account_name,
2043 ModestMainWindow *main_window)
2045 g_return_if_fail(server_account_name);
2046 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2048 /* Initalize output parameters: */
2055 #ifdef MODEST_PLATFORM_MAEMO
2056 /* Maemo uses a different (awkward) button order,
2057 * It should probably just use gtk_alternative_dialog_button_order ().
2059 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2063 GTK_RESPONSE_ACCEPT,
2065 GTK_RESPONSE_REJECT,
2068 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2072 GTK_RESPONSE_REJECT,
2074 GTK_RESPONSE_ACCEPT,
2076 #endif /* MODEST_PLATFORM_MAEMO */
2078 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2080 gchar *server_name = modest_server_account_get_hostname (
2081 modest_runtime_get_account_mgr(), server_account_name);
2082 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2083 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2088 /* This causes a warning because the logical ID has no %s in it,
2089 * though the translation does, but there is not much we can do about that: */
2090 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2091 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2094 g_free (server_name);
2098 gchar *initial_username = modest_server_account_get_username (
2099 modest_runtime_get_account_mgr(), server_account_name);
2101 GtkWidget *entry_username = gtk_entry_new ();
2102 if (initial_username)
2103 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2104 /* Dim this if a connection has ever succeeded with this username,
2105 * as per the UI spec: */
2106 const gboolean username_known =
2107 modest_server_account_get_username_has_succeeded(
2108 modest_runtime_get_account_mgr(), server_account_name);
2109 gtk_widget_set_sensitive (entry_username, !username_known);
2111 #ifdef MODEST_PLATFORM_MAEMO
2112 /* Auto-capitalization is the default, so let's turn it off: */
2113 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2115 /* Create a size group to be used by all captions.
2116 * Note that HildonCaption does not create a default size group if we do not specify one.
2117 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2118 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2120 GtkWidget *caption = hildon_caption_new (sizegroup,
2121 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2122 gtk_widget_show (entry_username);
2123 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2124 FALSE, FALSE, MODEST_MARGIN_HALF);
2125 gtk_widget_show (caption);
2127 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2129 #endif /* MODEST_PLATFORM_MAEMO */
2132 GtkWidget *entry_password = gtk_entry_new ();
2133 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2134 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2136 #ifdef MODEST_PLATFORM_MAEMO
2137 /* Auto-capitalization is the default, so let's turn it off: */
2138 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2139 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2141 caption = hildon_caption_new (sizegroup,
2142 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2143 gtk_widget_show (entry_password);
2144 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2145 FALSE, FALSE, MODEST_MARGIN_HALF);
2146 gtk_widget_show (caption);
2147 g_object_unref (sizegroup);
2149 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2151 #endif /* MODEST_PLATFORM_MAEMO */
2153 /* This is not in the Maemo UI spec:
2154 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2155 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2159 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2161 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2163 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2165 modest_server_account_set_username (
2166 modest_runtime_get_account_mgr(), server_account_name,
2169 const gboolean username_was_changed =
2170 (strcmp (*username, initial_username) != 0);
2171 if (username_was_changed) {
2172 g_warning ("%s: tinymail does not yet support changing the "
2173 "username in the get_password() callback.\n", __FUNCTION__);
2178 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2180 /* We do not save the password in the configuration,
2181 * because this function is only called for passwords that should
2182 * not be remembered:
2183 modest_server_account_set_password (
2184 modest_runtime_get_account_mgr(), server_account_name,
2203 /* This is not in the Maemo UI spec:
2204 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2210 gtk_widget_destroy (dialog);
2212 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2216 modest_ui_actions_on_cut (GtkAction *action,
2217 ModestWindow *window)
2219 GtkWidget *focused_widget;
2221 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2222 if (GTK_IS_EDITABLE (focused_widget)) {
2223 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2224 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2225 GtkTextBuffer *buffer;
2226 GtkClipboard *clipboard;
2228 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2229 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2230 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2231 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2232 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2233 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2234 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2239 modest_ui_actions_on_copy (GtkAction *action,
2240 ModestWindow *window)
2242 GtkClipboard *clipboard;
2243 GtkWidget *focused_widget;
2245 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2246 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2248 if (GTK_IS_LABEL (focused_widget)) {
2249 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2250 } else if (GTK_IS_EDITABLE (focused_widget)) {
2251 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2252 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2253 GtkTextBuffer *buffer;
2254 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2255 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2256 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2257 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2258 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2259 TnyIterator *iter = tny_list_create_iterator (header_list);
2260 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2261 TnyFolder *folder = tny_header_get_folder (header);
2262 TnyAccount *account = tny_folder_get_account (folder);
2263 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2264 /* If it's POP then ask */
2265 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2266 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2267 g_object_unref (account);
2268 g_object_unref (folder);
2269 g_object_unref (header);
2270 g_object_unref (iter);
2272 /* Check that the messages have been previously downloaded */
2273 gboolean continue_download = TRUE;
2275 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2276 if (continue_download)
2277 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2278 g_object_unref (header_list);
2279 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2280 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2283 /* Show information banner */
2284 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2289 modest_ui_actions_on_undo (GtkAction *action,
2290 ModestWindow *window)
2292 ModestEmailClipboard *clipboard = NULL;
2294 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2295 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2296 } if (MODEST_IS_MAIN_WINDOW (window)) {
2297 /* Clear clipboard source */
2298 clipboard = modest_runtime_get_email_clipboard ();
2299 modest_email_clipboard_clear (clipboard);
2302 g_return_if_reached ();
2307 modest_ui_actions_on_paste (GtkAction *action,
2308 ModestWindow *window)
2310 GtkWidget *focused_widget;
2311 ModestMailOperation *mail_op = NULL;
2313 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2314 if (GTK_IS_EDITABLE (focused_widget)) {
2315 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2316 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2317 GtkTextBuffer *buffer;
2318 GtkClipboard *clipboard;
2320 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2321 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2322 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2323 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2324 ModestEmailClipboard *clipboard = NULL;
2325 TnyFolder *src_folder = NULL;
2326 TnyFolderStore *folder_store = NULL;
2327 TnyList *data = NULL;
2328 gboolean delete = FALSE;
2330 /* Check clipboard source */
2331 clipboard = modest_runtime_get_email_clipboard ();
2332 if (modest_email_clipboard_cleared (clipboard))
2335 /* Get elements to paste */
2336 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2338 /* Create a new mail operation */
2339 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2340 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2343 /* Get destination folder */
2344 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2346 /* transfer messages */
2348 modest_mail_operation_xfer_msgs (mail_op,
2350 TNY_FOLDER (folder_store),
2355 } else if (src_folder != NULL) {
2356 modest_mail_operation_xfer_folder (mail_op,
2364 g_object_unref (data);
2365 if (src_folder != NULL)
2366 g_object_unref (src_folder);
2367 if (folder_store != NULL)
2368 g_object_unref (folder_store);
2373 modest_ui_actions_on_select_all (GtkAction *action,
2374 ModestWindow *window)
2376 GtkWidget *focused_widget;
2378 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2379 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2380 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2381 } else if (GTK_IS_LABEL (focused_widget)) {
2382 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2383 } else if (GTK_IS_EDITABLE (focused_widget)) {
2384 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2385 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2386 GtkTextBuffer *buffer;
2387 GtkTextIter start, end;
2389 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2390 gtk_text_buffer_get_start_iter (buffer, &start);
2391 gtk_text_buffer_get_end_iter (buffer, &end);
2392 gtk_text_buffer_select_range (buffer, &start, &end);
2393 } else if (GTK_IS_HTML (focused_widget)) {
2394 gtk_html_select_all (GTK_HTML (focused_widget));
2395 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2396 GtkWidget *header_view = focused_widget;
2397 GtkTreeSelection *selection = NULL;
2399 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2400 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2401 MODEST_WIDGET_TYPE_HEADER_VIEW);
2403 /* Select all messages */
2404 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2405 gtk_tree_selection_select_all (selection);
2407 /* Set focuse on header view */
2408 gtk_widget_grab_focus (header_view);
2414 modest_ui_actions_on_mark_as_read (GtkAction *action,
2415 ModestWindow *window)
2417 g_return_if_fail (MODEST_IS_WINDOW(window));
2419 /* Mark each header as read */
2420 do_headers_action (window, headers_action_mark_as_read, NULL);
2424 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2425 ModestWindow *window)
2427 g_return_if_fail (MODEST_IS_WINDOW(window));
2429 /* Mark each header as read */
2430 do_headers_action (window, headers_action_mark_as_unread, NULL);
2434 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2435 GtkRadioAction *selected,
2436 ModestWindow *window)
2440 value = gtk_radio_action_get_current_value (selected);
2441 if (MODEST_IS_WINDOW (window)) {
2442 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2446 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2447 GtkRadioAction *selected,
2448 ModestWindow *window)
2450 TnyHeaderFlags flags;
2451 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2453 flags = gtk_radio_action_get_current_value (selected);
2454 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2457 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2458 GtkRadioAction *selected,
2459 ModestWindow *window)
2463 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2465 file_format = gtk_radio_action_get_current_value (selected);
2466 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2471 modest_ui_actions_on_zoom_plus (GtkAction *action,
2472 ModestWindow *window)
2474 g_return_if_fail (MODEST_IS_WINDOW (window));
2476 modest_window_zoom_plus (MODEST_WINDOW (window));
2480 modest_ui_actions_on_zoom_minus (GtkAction *action,
2481 ModestWindow *window)
2483 g_return_if_fail (MODEST_IS_WINDOW (window));
2485 modest_window_zoom_minus (MODEST_WINDOW (window));
2489 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2490 ModestWindow *window)
2492 ModestWindowMgr *mgr;
2493 gboolean fullscreen, active;
2494 g_return_if_fail (MODEST_IS_WINDOW (window));
2496 mgr = modest_runtime_get_window_mgr ();
2498 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2499 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2501 if (active != fullscreen) {
2502 modest_window_mgr_set_fullscreen_mode (mgr, active);
2503 gtk_window_present (GTK_WINDOW (window));
2508 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2509 ModestWindow *window)
2511 ModestWindowMgr *mgr;
2512 gboolean fullscreen;
2514 g_return_if_fail (MODEST_IS_WINDOW (window));
2516 mgr = modest_runtime_get_window_mgr ();
2517 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2518 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2520 gtk_window_present (GTK_WINDOW (window));
2524 * Used by modest_ui_actions_on_details to call do_headers_action
2527 headers_action_show_details (TnyHeader *header,
2528 ModestWindow *window,
2535 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2538 gtk_widget_show_all (dialog);
2539 gtk_dialog_run (GTK_DIALOG (dialog));
2541 gtk_widget_destroy (dialog);
2545 * Show the folder details in a ModestDetailsDialog widget
2548 show_folder_details (TnyFolder *folder,
2554 dialog = modest_details_dialog_new_with_folder (window, folder);
2557 gtk_widget_show_all (dialog);
2558 gtk_dialog_run (GTK_DIALOG (dialog));
2560 gtk_widget_destroy (dialog);
2564 * Show the header details in a ModestDetailsDialog widget
2567 modest_ui_actions_on_details (GtkAction *action,
2570 TnyList * headers_list;
2574 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2577 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2580 g_object_unref (msg);
2582 headers_list = get_selected_headers (win);
2586 iter = tny_list_create_iterator (headers_list);
2588 header = TNY_HEADER (tny_iterator_get_current (iter));
2589 headers_action_show_details (header, win, NULL);
2590 g_object_unref (header);
2592 g_object_unref (iter);
2593 g_object_unref (headers_list);
2595 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2596 GtkWidget *folder_view, *header_view;
2598 /* Check which widget has the focus */
2599 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2600 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2601 if (gtk_widget_is_focus (folder_view)) {
2602 TnyFolderStore *folder_store
2603 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2604 if (!folder_store) {
2605 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2608 /* Show only when it's a folder */
2609 /* This function should not be called for account items,
2610 * because we dim the menu item for them. */
2611 if (TNY_IS_FOLDER (folder_store)) {
2612 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2615 g_object_unref (folder_store);
2618 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2619 MODEST_WIDGET_TYPE_HEADER_VIEW);
2620 /* Show details of each header */
2621 do_headers_action (win, headers_action_show_details, header_view);
2627 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2628 ModestMsgEditWindow *window)
2630 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2632 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2636 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2637 ModestMsgEditWindow *window)
2639 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2641 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2645 modest_ui_actions_toggle_folders_view (GtkAction *action,
2646 ModestMainWindow *main_window)
2650 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2652 conf = modest_runtime_get_conf ();
2654 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2655 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2657 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2661 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2662 ModestWindow *window)
2664 gboolean active, fullscreen = FALSE;
2665 ModestWindowMgr *mgr;
2667 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2669 /* Check if we want to toggle the toolbar vuew in fullscreen
2671 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2672 "ViewShowToolbarFullScreen")) {
2676 /* Toggle toolbar */
2677 mgr = modest_runtime_get_window_mgr ();
2678 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2682 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2683 ModestMsgEditWindow *window)
2685 modest_msg_edit_window_select_font (window);
2689 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2690 const gchar *display_name,
2693 /* Do not change the application name if the widget has not
2694 the focus. This callback could be called even if the folder
2695 view has not the focus, because the handled signal could be
2696 emitted when the folder view is redrawn */
2697 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2699 gtk_window_set_title (window, display_name);
2701 gtk_window_set_title (window, " ");
2706 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2708 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2709 modest_msg_edit_window_select_contacts (window);
2713 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2715 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2716 modest_msg_edit_window_check_names (window);
2721 create_move_to_dialog (ModestWindow *win,
2722 GtkWidget *folder_view,
2723 GtkWidget **tree_view)
2725 GtkWidget *dialog, *scroll;
2727 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2729 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2731 GTK_RESPONSE_ACCEPT,
2733 GTK_RESPONSE_REJECT,
2736 /* Create scrolled window */
2737 scroll = gtk_scrolled_window_new (NULL, NULL);
2738 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2739 GTK_POLICY_AUTOMATIC,
2740 GTK_POLICY_AUTOMATIC);
2742 /* Create folder view */
2743 *tree_view = modest_platform_create_folder_view (NULL);
2745 /* It could happen that we're trying to move a message from a
2746 window (msg window for example) after the main window was
2747 closed, so we can not just get the model of the folder
2749 if (MODEST_IS_FOLDER_VIEW (folder_view))
2750 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2751 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2753 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2754 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2756 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2758 /* Add scroll to dialog */
2759 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2760 scroll, FALSE, FALSE, 0);
2762 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2764 /* Select INBOX or local account */
2765 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2771 * Returns TRUE if at least one of the headers of the list belongs to
2772 * a message that has been fully retrieved.
2775 has_retrieved_msgs (TnyList *list)
2778 gboolean found = FALSE;
2780 iter = tny_list_create_iterator (list);
2781 while (tny_iterator_is_done (iter) && !found) {
2783 TnyHeaderFlags flags;
2785 header = TNY_HEADER (tny_iterator_get_current (iter));
2786 flags = tny_header_get_flags (header);
2787 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2791 tny_iterator_next (iter);
2793 g_object_unref (iter);
2799 * Shows a confirmation dialog to the user when we're moving messages
2800 * from a remote server to the local storage. Returns the dialog
2801 * response. If it's other kind of movement the it always returns
2805 msgs_move_to_confirmation (GtkWindow *win,
2806 TnyFolder *dest_folder,
2809 gint response = GTK_RESPONSE_OK;
2811 /* If the destination is a local folder */
2812 if (modest_tny_folder_is_local_folder (dest_folder)) {
2813 TnyFolder *src_folder;
2817 /* Get source folder */
2818 iter = tny_list_create_iterator (headers);
2819 header = TNY_HEADER (tny_iterator_get_current (iter));
2820 src_folder = tny_header_get_folder (header);
2821 g_object_unref (header);
2822 g_object_unref (iter);
2824 /* if no src_folder, message may be an attahcment */
2825 if (src_folder == NULL)
2826 return GTK_RESPONSE_CANCEL;
2828 /* If the source is a remote folder */
2829 if (!modest_tny_folder_is_local_folder (src_folder)) {
2830 const gchar *message;
2832 if (has_retrieved_msgs (headers))
2833 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2834 tny_list_get_length (headers));
2836 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2837 tny_list_get_length (headers));
2839 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2840 (const gchar *) message);
2842 g_object_unref (src_folder);
2849 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2851 ModestMsgViewWindow *self = NULL;
2853 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2854 self = MODEST_MSG_VIEW_WINDOW (object);
2856 /* If there are not more messages don't do anything. The
2857 viewer will show the same message */
2858 if (!modest_msg_view_window_select_first_message (self))
2863 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2866 GObject *win = modest_mail_operation_get_source (mail_op);
2868 /* TODO: show error message */
2869 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2870 _("mail_in_ui_folder_move_target_error"));
2871 g_object_unref (win);
2875 * UI handler for the "Move to" action when invoked from the
2879 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2880 ModestMainWindow *win)
2882 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2883 GtkWidget *header_view = NULL;
2885 TnyFolderStore *folder_store = NULL;
2886 ModestMailOperation *mail_op = NULL;
2888 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2890 /* Get the folder view */
2891 folder_view = modest_main_window_get_child_widget (win,
2892 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2894 /* Get header view */
2895 header_view = modest_main_window_get_child_widget (win,
2896 MODEST_WIDGET_TYPE_HEADER_VIEW);
2898 /* Create and run the dialog */
2899 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2900 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2901 result = gtk_dialog_run (GTK_DIALOG(dialog));
2902 g_object_ref (tree_view);
2904 /* We do this to save an indentation level ;-) */
2905 if (result != GTK_RESPONSE_ACCEPT)
2908 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2910 if (TNY_IS_ACCOUNT (folder_store))
2913 /* Get folder or messages to transfer */
2914 if (gtk_widget_is_focus (folder_view)) {
2915 TnyFolderStore *src_folder;
2916 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2918 /* Clean folder on header view before moving it */
2919 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2921 if (TNY_IS_FOLDER (src_folder)) {
2923 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2925 modest_ui_actions_move_folder_error_handler,
2927 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2929 modest_mail_operation_xfer_folder (mail_op,
2930 TNY_FOLDER (src_folder),
2933 /* Unref mail operation */
2934 g_object_unref (G_OBJECT (mail_op));
2938 g_object_unref (G_OBJECT (src_folder));
2940 if (gtk_widget_is_focus (header_view)) {
2944 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2946 /* Ask for user confirmation */
2947 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2948 TNY_FOLDER (folder_store),
2951 /* Transfer messages */
2952 if (response == GTK_RESPONSE_OK) {
2953 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2954 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2957 modest_mail_operation_xfer_msgs (mail_op,
2959 TNY_FOLDER (folder_store),
2964 g_object_unref (G_OBJECT (mail_op));
2966 g_object_unref (headers);
2970 if (folder_store != NULL)
2971 g_object_unref (folder_store);
2972 gtk_widget_destroy (dialog);
2977 * UI handler for the "Move to" action when invoked from the
2978 * ModestMsgViewWindow
2981 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2982 ModestMsgViewWindow *win)
2984 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2986 ModestMainWindow *main_window;
2990 /* Get the folder view */
2991 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2993 folder_view = modest_main_window_get_child_widget (main_window,
2994 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2998 /* Create and run the dialog */
2999 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3000 result = gtk_dialog_run (GTK_DIALOG(dialog));
3001 g_object_ref (tree_view);
3003 if (result == GTK_RESPONSE_ACCEPT) {
3004 TnyFolderStore *folder_store;
3007 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3009 /* Create header list */
3010 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3012 headers = tny_simple_list_new ();
3013 tny_list_prepend (headers, G_OBJECT (header));
3014 g_object_unref (header);
3016 /* Ask user for confirmation. MSG-NOT404 */
3017 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3018 TNY_FOLDER (folder_store),
3021 /* Transfer current msg */
3022 if (response == GTK_RESPONSE_OK) {
3023 ModestMailOperation *mail_op;
3025 /* Create mail op */
3026 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3030 /* Transfer messages */
3031 modest_mail_operation_xfer_msgs (mail_op,
3033 TNY_FOLDER (folder_store),
3035 transfer_msgs_from_viewer_cb,
3037 g_object_unref (G_OBJECT (mail_op));
3039 g_object_unref (headers);
3040 g_object_unref (folder_store);
3042 gtk_widget_destroy (dialog);
3046 modest_ui_actions_on_move_to (GtkAction *action,
3049 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3050 MODEST_IS_MSG_VIEW_WINDOW (win));
3052 if (MODEST_IS_MAIN_WINDOW (win))
3053 modest_ui_actions_on_main_window_move_to (action,
3054 MODEST_MAIN_WINDOW (win));
3056 modest_ui_actions_on_msg_view_window_move_to (action,
3057 MODEST_MSG_VIEW_WINDOW (win));
3061 * Calls #HeadersFunc for each header already selected in the main
3062 * window or the message currently being shown in the msg view window
3065 do_headers_action (ModestWindow *win,
3069 TnyList *headers_list;
3075 headers_list = get_selected_headers (win);
3079 /* Get the folder */
3080 iter = tny_list_create_iterator (headers_list);
3081 header = TNY_HEADER (tny_iterator_get_current (iter));
3082 folder = tny_header_get_folder (header);
3083 g_object_unref (header);
3085 /* Call the function for each header */
3086 while (!tny_iterator_is_done (iter)) {
3087 header = TNY_HEADER (tny_iterator_get_current (iter));
3088 func (header, win, user_data);
3089 g_object_unref (header);
3090 tny_iterator_next (iter);
3093 /* Trick: do a poke status in order to speed up the signaling
3095 tny_folder_poke_status (folder);
3098 g_object_unref (folder);
3099 g_object_unref (iter);
3100 g_object_unref (headers_list);
3104 modest_ui_actions_view_attachment (GtkAction *action,
3105 ModestWindow *window)
3107 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3108 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3110 /* not supported window for this action */
3111 g_return_if_reached ();
3116 modest_ui_actions_save_attachments (GtkAction *action,
3117 ModestWindow *window)
3119 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3120 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3122 /* not supported window for this action */
3123 g_return_if_reached ();
3128 modest_ui_actions_remove_attachments (GtkAction *action,
3129 ModestWindow *window)
3131 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3132 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window));
3134 /* not supported window for this action */
3135 g_return_if_reached ();
3140 modest_ui_actions_on_settings (GtkAction *action,
3145 dialog = modest_platform_get_global_settings_dialog ();
3146 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3147 gtk_widget_show_all (dialog);
3149 gtk_dialog_run (GTK_DIALOG (dialog));
3151 gtk_widget_destroy (dialog);
3155 modest_ui_actions_on_help (GtkAction *action,
3158 const gchar *help_id = NULL;
3160 if (MODEST_IS_MAIN_WINDOW (win)) {
3161 const gchar *action_name;
3162 action_name = gtk_action_get_name (action);
3164 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3165 !strcmp (action_name, "HeaderViewCSMHelp")) {
3166 GtkWidget *folder_view;
3167 TnyFolderStore *folder_store;
3168 /* Get selected folder */
3169 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3170 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3171 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3173 /* Switch help_id */
3174 if (TNY_IS_FOLDER (folder_store)) {
3175 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3176 case TNY_FOLDER_TYPE_NORMAL:
3177 help_id = "applications_email_userfolder";
3179 case TNY_FOLDER_TYPE_INBOX:
3180 help_id = "applications_email_inbox";
3182 case TNY_FOLDER_TYPE_OUTBOX:
3183 help_id = "applications_email_outbox";
3185 case TNY_FOLDER_TYPE_SENT:
3186 help_id = "applications_email_sent";
3188 case TNY_FOLDER_TYPE_DRAFTS:
3189 help_id = "applications_email_drafts";
3191 case TNY_FOLDER_TYPE_ARCHIVE:
3192 help_id = "applications_email_archive";
3198 g_object_unref (folder_store);
3200 help_id = "applications_email_mainview";
3202 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3203 help_id = "applications_email_viewer";
3204 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3205 help_id = "applications_email_editor";
3207 modest_platform_show_help (GTK_WINDOW (win), help_id);
3211 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3212 ModestWindow *window)
3214 ModestMailOperation *mail_op;
3218 headers = get_selected_headers (window);
3222 /* Create mail operation */
3223 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3225 modest_ui_actions_get_msgs_full_error_handler,
3227 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3228 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3231 g_object_unref (headers);
3232 g_object_unref (mail_op);
3236 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3237 ModestWindow *window)
3239 g_return_if_fail (MODEST_IS_WINDOW (window));
3242 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3246 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3247 ModestWindow *window)
3249 g_return_if_fail (MODEST_IS_WINDOW (window));
3252 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3256 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3257 ModestWindow *window)
3259 g_return_if_fail (MODEST_IS_WINDOW (window));
3262 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3266 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3267 ModestWindow *window)
3269 g_return_if_fail (MODEST_IS_WINDOW (window));
3272 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3276 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3277 ModestWindow *window)
3279 g_return_if_fail (MODEST_IS_WINDOW (window));
3282 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3286 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3287 ModestWindow *window)
3289 g_return_if_fail (MODEST_IS_WINDOW (window));
3292 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3296 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3297 ModestWindow *window)
3299 g_return_if_fail (MODEST_IS_WINDOW (window));
3302 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3306 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3307 ModestWindow *window)
3309 g_return_if_fail (MODEST_IS_WINDOW (window));
3312 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3316 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3318 g_return_if_fail (MODEST_IS_WINDOW (window));
3321 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3325 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3327 g_return_if_fail (MODEST_IS_WINDOW (window));
3329 modest_platform_show_search_messages (GTK_WINDOW (window));
3333 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3335 g_return_if_fail (MODEST_IS_WINDOW (win));
3336 modest_platform_show_addressbook (GTK_WINDOW (win));
3341 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3342 ModestWindow *window)
3344 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3346 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3350 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3351 ModestMailOperationState *state,
3354 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3356 /* Set send/receive operation finished */
3357 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3358 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));