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));
662 /* Update toolbar dimming state */
663 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
668 g_object_unref (parent_win);
669 /* g_object_unref (msg); */
670 g_object_unref (folder);
674 * This function is the error handler of the
675 * modest_mail_operation_get_msgs_full operation
678 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
683 error = modest_mail_operation_get_error (mail_op);
684 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
685 GObject *win = modest_mail_operation_get_source (mail_op);
687 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
689 g_object_unref (win);
694 * This function is used by both modest_ui_actions_on_open and
695 * modest_ui_actions_on_header_activated. This way we always do the
696 * same when trying to open messages.
699 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
701 ModestWindowMgr *mgr = NULL;
702 TnyIterator *iter = NULL;
703 ModestMailOperation *mail_op1 = NULL;
704 ModestMailOperation *mail_op2 = NULL;
705 TnyList *not_opened_headers = NULL;
706 TnyList *not_opened_cached_headers = NULL;
707 TnyHeaderFlags flags;
709 /* Look if we already have a message view for each header. If
710 true, then remove the header from the list of headers to
712 mgr = modest_runtime_get_window_mgr ();
713 iter = tny_list_create_iterator (headers);
714 not_opened_headers = tny_simple_list_new ();
715 not_opened_cached_headers = tny_simple_list_new ();
716 while (!tny_iterator_is_done (iter)) {
717 ModestWindow *window;
720 header = TNY_HEADER (tny_iterator_get_current (iter));
721 flags = tny_header_get_flags (header);
722 window = modest_window_mgr_find_window_by_header (mgr, header);
724 /* Do not open again the message and present the
725 window to the user */
727 gtk_window_present (GTK_WINDOW (window));
728 else if (!(flags & TNY_HEADER_FLAG_CACHED))
729 tny_list_append (not_opened_headers, G_OBJECT (header));
730 /* Check if msg has already been retreived */
732 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
734 g_object_unref (header);
735 tny_iterator_next (iter);
738 /* Open each uncached message */
739 if (tny_list_get_length (not_opened_headers) > 0) {
740 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
742 modest_ui_actions_get_msgs_full_error_handler,
744 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
745 if (tny_list_get_length (not_opened_headers) > 1) {
746 modest_mail_operation_get_msgs_full (mail_op1,
752 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
753 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
754 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
755 g_object_unref (header);
756 g_object_unref (iter);
760 /* Open each cached message */
761 if (tny_list_get_length (not_opened_cached_headers) > 0) {
762 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
764 modest_ui_actions_get_msgs_full_error_handler,
766 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
767 if (tny_list_get_length (not_opened_cached_headers) > 1) {
768 modest_mail_operation_get_msgs_full (mail_op2,
774 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
775 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
776 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
777 g_object_unref (header);
778 g_object_unref (iter);
783 if (not_opened_headers != NULL)
784 g_object_unref (not_opened_headers);
785 if (not_opened_cached_headers != NULL)
786 g_object_unref (not_opened_cached_headers);
788 g_object_unref (iter);
789 if (mail_op1 != NULL)
790 g_object_unref (mail_op1);
791 if (mail_op2 != NULL)
792 g_object_unref (mail_op2);
796 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
801 headers = get_selected_headers (win);
806 _modest_ui_actions_open (headers, win);
808 g_object_unref(headers);
813 free_reply_forward_helper (gpointer data)
815 ReplyForwardHelper *helper;
817 helper = (ReplyForwardHelper *) data;
818 g_free (helper->account_name);
819 g_slice_free (ReplyForwardHelper, helper);
823 reply_forward_cb (ModestMailOperation *mail_op,
829 ReplyForwardHelper *rf_helper;
830 ModestWindow *msg_win = NULL;
831 ModestEditType edit_type;
833 TnyAccount *account = NULL;
834 ModestWindowMgr *mgr = NULL;
835 gchar *signature = NULL;
837 g_return_if_fail (user_data != NULL);
838 rf_helper = (ReplyForwardHelper *) user_data;
840 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
841 rf_helper->account_name);
842 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
843 rf_helper->account_name,
844 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
845 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
846 rf_helper->account_name,
847 MODEST_ACCOUNT_SIGNATURE, FALSE);
850 /* Create reply mail */
851 switch (rf_helper->action) {
854 modest_tny_msg_create_reply_msg (msg, from, signature,
855 rf_helper->reply_forward_type,
856 MODEST_TNY_MSG_REPLY_MODE_SENDER);
858 case ACTION_REPLY_TO_ALL:
860 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
861 MODEST_TNY_MSG_REPLY_MODE_ALL);
862 edit_type = MODEST_EDIT_TYPE_REPLY;
866 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
867 edit_type = MODEST_EDIT_TYPE_FORWARD;
870 g_return_if_reached ();
877 g_printerr ("modest: failed to create message\n");
881 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
882 rf_helper->account_name,
883 TNY_ACCOUNT_TYPE_STORE);
885 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
889 /* Create and register the windows */
890 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
891 mgr = modest_runtime_get_window_mgr ();
892 modest_window_mgr_register_window (mgr, msg_win);
894 if (rf_helper->parent_window != NULL) {
897 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
898 modest_window_set_zoom (msg_win, parent_zoom);
901 /* Show edit window */
902 gtk_widget_show_all (GTK_WIDGET (msg_win));
906 g_object_unref (msg_win);
908 g_object_unref (G_OBJECT (new_msg));
910 g_object_unref (G_OBJECT (account));
911 /* g_object_unref (msg); */
912 g_object_unref (header);
916 * Checks a list of headers. If any of them are not currently
917 * downloaded (CACHED) then it asks the user for permission to
920 * Returns FALSE if the user does not want to download the
921 * messages. Returns TRUE if the user allowed the download or if all
922 * of them are currently downloaded
925 download_uncached_messages (TnyList *header_list, GtkWindow *win)
929 gint uncached_messages = 0;
931 iter = tny_list_create_iterator (header_list);
932 while (!tny_iterator_is_done (iter)) {
934 TnyHeaderFlags flags;
936 header = TNY_HEADER (tny_iterator_get_current (iter));
937 flags = tny_header_get_flags (header);
938 /* TODO: is this the right flag?, it seems that some
939 headers that have been previously downloaded do not
941 if (! (flags & TNY_HEADER_FLAG_CACHED))
942 uncached_messages ++;
943 g_object_unref (header);
944 tny_iterator_next (iter);
946 g_object_unref (iter);
948 /* Ask for user permission to download the messages */
950 if (uncached_messages > 0) {
951 GtkResponseType response;
953 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
954 ngettext("mcen_nc_get_msg",
957 if (response == GTK_RESPONSE_CANCEL)
965 * Common code for the reply and forward actions
968 reply_forward (ReplyForwardAction action, ModestWindow *win)
970 ModestMailOperation *mail_op = NULL;
971 TnyList *header_list = NULL;
972 ReplyForwardHelper *rf_helper = NULL;
973 guint reply_forward_type;
974 gboolean continue_download;
976 g_return_if_fail (MODEST_IS_WINDOW(win));
978 /* we need an account when editing */
979 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
980 run_account_setup_wizard (win);
984 header_list = get_selected_headers (win);
988 /* Check that the messages have been previously downloaded */
989 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
990 if (!continue_download) {
991 g_object_unref (header_list);
996 modest_conf_get_int (modest_runtime_get_conf (),
997 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
999 /* We assume that we can only select messages of the
1000 same folder and that we reply all of them from the
1001 same account. In fact the interface currently only
1002 allows single selection */
1005 rf_helper = g_slice_new0 (ReplyForwardHelper);
1006 rf_helper->reply_forward_type = reply_forward_type;
1007 rf_helper->action = action;
1008 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1009 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1010 rf_helper->parent_window = GTK_WIDGET (win);
1011 if (!rf_helper->account_name)
1012 rf_helper->account_name =
1013 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1015 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1018 /* Get header and message. Do not free them here, the
1019 reply_forward_cb must do it */
1020 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1021 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1022 if (!msg || !header) {
1024 g_object_unref (msg);
1026 g_object_unref (header);
1027 g_printerr ("modest: no message found\n");
1030 reply_forward_cb (NULL, header, msg, rf_helper);
1032 /* Retrieve messages */
1033 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1035 modest_ui_actions_get_msgs_full_error_handler,
1037 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1038 modest_mail_operation_get_msgs_full (mail_op,
1042 free_reply_forward_helper);
1045 g_object_unref(mail_op);
1049 g_object_unref (header_list);
1053 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1055 g_return_if_fail (MODEST_IS_WINDOW(win));
1057 reply_forward (ACTION_REPLY, win);
1061 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1063 g_return_if_fail (MODEST_IS_WINDOW(win));
1065 reply_forward (ACTION_FORWARD, win);
1069 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1071 g_return_if_fail (MODEST_IS_WINDOW(win));
1073 reply_forward (ACTION_REPLY_TO_ALL, win);
1077 modest_ui_actions_on_next (GtkAction *action,
1078 ModestWindow *window)
1080 if (MODEST_IS_MAIN_WINDOW (window)) {
1081 GtkWidget *header_view;
1083 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1084 MODEST_WIDGET_TYPE_HEADER_VIEW);
1088 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1089 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1090 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1092 g_return_if_reached ();
1097 modest_ui_actions_on_prev (GtkAction *action,
1098 ModestWindow *window)
1100 g_return_if_fail (MODEST_IS_WINDOW(window));
1102 if (MODEST_IS_MAIN_WINDOW (window)) {
1103 GtkWidget *header_view;
1104 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1105 MODEST_WIDGET_TYPE_HEADER_VIEW);
1109 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1110 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1111 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1113 g_return_if_reached ();
1118 modest_ui_actions_on_sort (GtkAction *action,
1119 ModestWindow *window)
1121 g_return_if_fail (MODEST_IS_WINDOW(window));
1123 if (MODEST_IS_MAIN_WINDOW (window)) {
1124 GtkWidget *header_view;
1125 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1126 MODEST_WIDGET_TYPE_HEADER_VIEW);
1130 /* Show sorting dialog */
1131 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1136 new_messages_arrived (ModestMailOperation *self,
1140 if (new_messages == 0)
1143 modest_platform_on_new_msg ();
1147 * This function performs the send & receive required actions. The
1148 * window is used to create the mail operation. Typically it should
1149 * always be the main window, but we pass it as argument in order to
1153 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1155 gchar *acc_name = NULL;
1156 ModestMailOperation *mail_op;
1158 /* If no account name was provided then get the current account, and if
1159 there is no current account then pick the default one: */
1160 if (!account_name) {
1161 acc_name = g_strdup (modest_window_get_active_account(win));
1163 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1165 g_printerr ("modest: cannot get default account\n");
1169 acc_name = g_strdup (account_name);
1172 /* Set send/receive operation in progress */
1173 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1175 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1176 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1177 G_CALLBACK (_on_send_receive_progress_changed),
1180 /* Send & receive. */
1181 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1182 /* Receive and then send. The operation is tagged initially as
1183 a receive operation because the account update performs a
1184 receive and then a send. The operation changes its type
1185 internally, so the progress objects will receive the proper
1186 progress information */
1187 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1188 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1189 g_object_unref (G_OBJECT (mail_op));
1196 * Refreshes all accounts. This function will be used by automatic
1200 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1202 GSList *account_names, *iter;
1204 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1207 iter = account_names;
1209 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1210 iter = g_slist_next (iter);
1213 modest_account_mgr_free_account_names (account_names);
1214 account_names = NULL;
1218 * Handler of the click on Send&Receive button in the main toolbar
1221 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1223 /* Check if accounts exist */
1224 gboolean accounts_exist =
1225 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1227 /* If not, allow the user to create an account before trying to send/receive. */
1228 if (!accounts_exist)
1229 modest_ui_actions_on_accounts (NULL, win);
1231 /* Refresh the active account */
1232 modest_ui_actions_do_send_receive (NULL, win);
1237 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1240 GtkWidget *header_view;
1242 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1244 header_view = modest_main_window_get_child_widget (main_window,
1245 MODEST_WIDGET_TYPE_HEADER_VIEW);
1249 conf = modest_runtime_get_conf ();
1251 /* what is saved/restored is depending on the style; thus; we save with
1252 * old style, then update the style, and restore for this new style
1254 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1256 if (modest_header_view_get_style
1257 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1258 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1259 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1261 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1262 MODEST_HEADER_VIEW_STYLE_DETAILS);
1264 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1265 MODEST_CONF_HEADER_VIEW_KEY);
1270 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1272 ModestMainWindow *main_window)
1274 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1275 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1277 /* If no header has been selected then exit */
1282 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1283 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1285 /* Update Main window title */
1286 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1287 const gchar *subject = tny_header_get_subject (header);
1288 if (subject && strlen(subject) > 0)
1289 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1291 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1294 /* Update toolbar dimming state */
1295 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1299 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1301 ModestMainWindow *main_window)
1305 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1310 headers = tny_simple_list_new ();
1311 tny_list_prepend (headers, G_OBJECT (header));
1313 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1315 g_object_unref (headers);
1319 set_active_account_from_tny_account (TnyAccount *account,
1320 ModestWindow *window)
1322 const gchar *server_acc_name = tny_account_get_id (account);
1324 /* We need the TnyAccount provided by the
1325 account store because that is the one that
1326 knows the name of the Modest account */
1327 TnyAccount *modest_server_account = modest_server_account =
1328 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1329 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1332 const gchar *modest_acc_name =
1333 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1334 modest_window_set_active_account (window, modest_acc_name);
1335 g_object_unref (modest_server_account);
1340 folder_refreshed_cb (const GObject *obj,
1344 ModestMainWindow *win = NULL;
1345 GtkWidget *header_view;
1347 g_return_if_fail (TNY_IS_FOLDER (folder));
1349 win = MODEST_MAIN_WINDOW (user_data);
1351 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1353 /* Check if folder is empty and set headers view contents style */
1354 if (tny_folder_get_all_count (folder) == 0) {
1355 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1356 modest_main_window_set_contents_style (win,
1357 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1359 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1364 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1365 TnyFolderStore *folder_store,
1367 ModestMainWindow *main_window)
1370 GtkWidget *header_view;
1372 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1374 header_view = modest_main_window_get_child_widget(main_window,
1375 MODEST_WIDGET_TYPE_HEADER_VIEW);
1379 conf = modest_runtime_get_conf ();
1381 if (TNY_IS_ACCOUNT (folder_store)) {
1383 /* Update active account */
1384 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1385 /* Show account details */
1386 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1389 if (TNY_IS_FOLDER (folder_store) && selected) {
1391 /* Update the active account */
1392 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1394 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1395 g_object_unref (account);
1399 /* Set the header style by default, it could
1400 be changed later by the refresh callback to
1402 modest_main_window_set_contents_style (main_window,
1403 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1405 /* Set folder on header view. This function
1406 will call tny_folder_refresh_async so we
1407 pass a callback that will be called when
1408 finished. We use that callback to set the
1409 empty view if there are no messages */
1410 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1411 TNY_FOLDER (folder_store),
1412 folder_refreshed_cb,
1415 /* Restore configuration. We need to do this
1416 *after* the set_folder because the widget
1417 memory asks the header view about its
1419 modest_widget_memory_restore (modest_runtime_get_conf (),
1420 G_OBJECT(header_view),
1421 MODEST_CONF_HEADER_VIEW_KEY);
1423 /* Update the active account */
1424 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1425 /* Save only if we're seeing headers */
1426 if (modest_main_window_get_contents_style (main_window) ==
1427 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1428 modest_widget_memory_save (conf, G_OBJECT (header_view),
1429 MODEST_CONF_HEADER_VIEW_KEY);
1430 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1434 /* Update toolbar dimming state */
1435 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1439 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1446 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1448 if (g_main_depth > 0)
1449 gdk_threads_enter ();
1450 online = tny_device_is_online (modest_runtime_get_device());
1453 /* already online -- the item is simply not there... */
1454 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1456 GTK_MESSAGE_WARNING,
1458 _("The %s you selected cannot be found"),
1460 gtk_dialog_run (GTK_DIALOG(dialog));
1462 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1466 GTK_RESPONSE_REJECT,
1468 GTK_RESPONSE_ACCEPT,
1470 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1471 "Do you want to get online?"), item);
1472 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1473 gtk_label_new (txt), FALSE, FALSE, 0);
1474 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1477 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1478 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1479 // modest_platform_connect_and_wait ();
1482 gtk_widget_destroy (dialog);
1483 if (g_main_depth > 0)
1484 gdk_threads_leave ();
1488 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1491 /* g_message ("%s %s", __FUNCTION__, link); */
1496 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1499 modest_platform_activate_uri (link);
1503 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1506 modest_platform_show_uri_popup (link);
1510 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1513 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1517 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1518 const gchar *address,
1521 /* g_message ("%s %s", __FUNCTION__, address); */
1525 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1527 TnyTransportAccount *transport_account;
1528 ModestMailOperation *mail_operation;
1530 gchar *account_name, *from;
1531 ModestAccountMgr *account_mgr;
1532 gchar *info_text = NULL;
1534 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1536 data = modest_msg_edit_window_get_msg_data (edit_window);
1538 account_mgr = modest_runtime_get_account_mgr();
1539 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1541 account_name = modest_account_mgr_get_default_account (account_mgr);
1542 if (!account_name) {
1543 g_printerr ("modest: no account found\n");
1544 modest_msg_edit_window_free_msg_data (edit_window, data);
1548 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1549 account_name = g_strdup (data->account_name);
1553 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1554 (modest_runtime_get_account_store(),
1556 TNY_ACCOUNT_TYPE_TRANSPORT));
1557 if (!transport_account) {
1558 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1559 g_free (account_name);
1560 modest_msg_edit_window_free_msg_data (edit_window, data);
1563 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1565 /* Create the mail operation */
1566 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1567 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1569 modest_mail_operation_save_to_drafts (mail_operation,
1580 data->priority_flags);
1583 g_free (account_name);
1584 g_object_unref (G_OBJECT (transport_account));
1585 g_object_unref (G_OBJECT (mail_operation));
1587 modest_msg_edit_window_free_msg_data (edit_window, data);
1589 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1590 modest_platform_information_banner (NULL, NULL, info_text);
1594 /* For instance, when clicking the Send toolbar button when editing a message: */
1596 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1598 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1600 if (!modest_msg_edit_window_check_names (edit_window))
1603 /* FIXME: Code added just for testing. The final version will
1604 use the send queue provided by tinymail and some
1606 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1607 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1609 account_name = modest_account_mgr_get_default_account (account_mgr);
1611 if (!account_name) {
1612 g_printerr ("modest: no account found\n");
1616 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1618 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1619 account_name = g_strdup (data->account_name);
1622 /* Get the currently-active transport account for this modest account: */
1623 TnyTransportAccount *transport_account =
1624 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1625 (modest_runtime_get_account_store(),
1627 if (!transport_account) {
1628 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1629 g_free (account_name);
1630 modest_msg_edit_window_free_msg_data (edit_window, data);
1634 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1636 /* mail content checks and dialogs */
1637 if (data->subject == NULL || data->subject[0] == '\0') {
1638 GtkResponseType response;
1639 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1640 _("mcen_nc_subject_is_empty_send"));
1641 if (response == GTK_RESPONSE_CANCEL) {
1642 g_free (account_name);
1647 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1648 GtkResponseType response;
1649 gchar *note_message;
1650 gchar *note_subject = data->subject;
1651 if (note_subject == NULL || note_subject[0] == '\0')
1652 note_subject = _("mail_va_no_subject");
1653 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1654 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1656 g_free (note_message);
1657 if (response == GTK_RESPONSE_CANCEL) {
1658 g_free (account_name);
1663 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1665 /* Create the mail operation */
1666 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1667 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1669 modest_mail_operation_send_new_mail (mail_operation,
1680 data->priority_flags);
1684 g_free (account_name);
1685 g_object_unref (G_OBJECT (transport_account));
1686 g_object_unref (G_OBJECT (mail_operation));
1688 modest_msg_edit_window_free_msg_data (edit_window, data);
1689 modest_msg_edit_window_set_sent (edit_window, TRUE);
1691 /* Save settings and close the window: */
1692 gtk_widget_destroy (GTK_WIDGET (edit_window));
1696 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1697 ModestMsgEditWindow *window)
1699 ModestMsgEditFormatState *format_state = NULL;
1701 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1702 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1704 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1707 format_state = modest_msg_edit_window_get_format_state (window);
1708 g_return_if_fail (format_state != NULL);
1710 format_state->bold = gtk_toggle_action_get_active (action);
1711 modest_msg_edit_window_set_format_state (window, format_state);
1712 g_free (format_state);
1717 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1718 ModestMsgEditWindow *window)
1720 ModestMsgEditFormatState *format_state = NULL;
1722 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1723 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1725 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1728 format_state = modest_msg_edit_window_get_format_state (window);
1729 g_return_if_fail (format_state != NULL);
1731 format_state->italics = gtk_toggle_action_get_active (action);
1732 modest_msg_edit_window_set_format_state (window, format_state);
1733 g_free (format_state);
1738 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1739 ModestMsgEditWindow *window)
1741 ModestMsgEditFormatState *format_state = NULL;
1743 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1744 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1746 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1749 format_state = modest_msg_edit_window_get_format_state (window);
1750 g_return_if_fail (format_state != NULL);
1752 format_state->bullet = gtk_toggle_action_get_active (action);
1753 modest_msg_edit_window_set_format_state (window, format_state);
1754 g_free (format_state);
1759 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1760 GtkRadioAction *selected,
1761 ModestMsgEditWindow *window)
1763 ModestMsgEditFormatState *format_state = NULL;
1764 GtkJustification value;
1766 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1768 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1771 value = gtk_radio_action_get_current_value (selected);
1773 format_state = modest_msg_edit_window_get_format_state (window);
1774 g_return_if_fail (format_state != NULL);
1776 format_state->justification = value;
1777 modest_msg_edit_window_set_format_state (window, format_state);
1778 g_free (format_state);
1782 modest_ui_actions_on_select_editor_color (GtkAction *action,
1783 ModestMsgEditWindow *window)
1785 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1786 g_return_if_fail (GTK_IS_ACTION (action));
1788 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1791 modest_msg_edit_window_select_color (window);
1795 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1796 ModestMsgEditWindow *window)
1798 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1799 g_return_if_fail (GTK_IS_ACTION (action));
1801 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1804 modest_msg_edit_window_select_background_color (window);
1808 modest_ui_actions_on_insert_image (GtkAction *action,
1809 ModestMsgEditWindow *window)
1811 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1812 g_return_if_fail (GTK_IS_ACTION (action));
1814 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1817 modest_msg_edit_window_insert_image (window);
1821 modest_ui_actions_on_attach_file (GtkAction *action,
1822 ModestMsgEditWindow *window)
1824 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1825 g_return_if_fail (GTK_IS_ACTION (action));
1827 modest_msg_edit_window_attach_file (window);
1831 modest_ui_actions_on_remove_attachments (GtkAction *action,
1832 ModestMsgEditWindow *window)
1834 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1835 g_return_if_fail (GTK_IS_ACTION (action));
1837 modest_msg_edit_window_remove_attachments (window, NULL);
1841 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1843 TnyFolderStore *parent_folder;
1844 GtkWidget *folder_view;
1846 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1848 folder_view = modest_main_window_get_child_widget (main_window,
1849 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1853 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1855 if (parent_folder) {
1856 gboolean finished = FALSE;
1858 gchar *folder_name = NULL, *suggested_name = NULL;
1860 /* Run the new folder dialog */
1862 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1867 if (result == GTK_RESPONSE_REJECT) {
1870 ModestMailOperation *mail_op;
1871 TnyFolder *new_folder = NULL;
1873 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1874 G_OBJECT(main_window));
1875 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1877 new_folder = modest_mail_operation_create_folder (mail_op,
1879 (const gchar *) folder_name);
1881 g_object_unref (new_folder);
1884 g_object_unref (mail_op);
1886 g_free (folder_name);
1890 g_object_unref (parent_folder);
1895 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1898 GObject *win = modest_mail_operation_get_source (mail_op);
1900 /* TODO: what should we do in case of this error ? */
1901 g_warning ("Invalid folder name");
1903 g_object_unref (win);
1907 modest_ui_actions_on_rename_folder (GtkAction *action,
1908 ModestMainWindow *main_window)
1910 TnyFolderStore *folder;
1911 GtkWidget *folder_view;
1912 GtkWidget *header_view;
1914 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1916 folder_view = modest_main_window_get_child_widget (main_window,
1917 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1921 header_view = modest_main_window_get_child_widget (main_window,
1922 MODEST_WIDGET_TYPE_HEADER_VIEW);
1927 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1929 if (folder && TNY_IS_FOLDER (folder)) {
1932 const gchar *current_name;
1934 current_name = tny_folder_get_name (TNY_FOLDER (folder));
1935 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
1936 current_name, &folder_name);
1938 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
1939 ModestMailOperation *mail_op;
1942 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
1943 G_OBJECT(main_window),
1944 modest_ui_actions_rename_folder_error_handler,
1948 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1951 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
1953 modest_mail_operation_rename_folder (mail_op,
1954 TNY_FOLDER (folder),
1955 (const gchar *) folder_name);
1957 g_object_unref (mail_op);
1958 g_free (folder_name);
1960 g_object_unref (folder);
1965 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1968 GObject *win = modest_mail_operation_get_source (mail_op);
1970 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1971 _("mail_in_ui_folder_delete_error"));
1972 g_object_unref (win);
1976 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1978 TnyFolderStore *folder;
1979 GtkWidget *folder_view;
1983 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1985 folder_view = modest_main_window_get_child_widget (main_window,
1986 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1990 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1992 /* Show an error if it's an account */
1993 if (!TNY_IS_FOLDER (folder)) {
1994 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1995 _("mail_in_ui_folder_delete_error"));
2000 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2001 tny_folder_get_name (TNY_FOLDER (folder)));
2002 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2003 (const gchar *) message);
2006 if (response == GTK_RESPONSE_OK) {
2007 ModestMailOperation *mail_op =
2008 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2009 G_OBJECT(main_window),
2010 modest_ui_actions_delete_folder_error_handler,
2013 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2015 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2016 g_object_unref (G_OBJECT (mail_op));
2019 g_object_unref (G_OBJECT (folder));
2023 modest_ui_actions_on_delete_folder (GtkAction *action,
2024 ModestMainWindow *main_window)
2026 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2028 delete_folder (main_window, FALSE);
2032 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2034 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2036 delete_folder (main_window, TRUE);
2040 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2041 const gchar* server_account_name,
2046 ModestMainWindow *main_window)
2048 g_return_if_fail(server_account_name);
2049 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2051 /* Initalize output parameters: */
2058 #ifdef MODEST_PLATFORM_MAEMO
2059 /* Maemo uses a different (awkward) button order,
2060 * It should probably just use gtk_alternative_dialog_button_order ().
2062 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2066 GTK_RESPONSE_ACCEPT,
2068 GTK_RESPONSE_REJECT,
2071 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2075 GTK_RESPONSE_REJECT,
2077 GTK_RESPONSE_ACCEPT,
2079 #endif /* MODEST_PLATFORM_MAEMO */
2081 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2083 gchar *server_name = modest_server_account_get_hostname (
2084 modest_runtime_get_account_mgr(), server_account_name);
2085 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2086 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2091 /* This causes a warning because the logical ID has no %s in it,
2092 * though the translation does, but there is not much we can do about that: */
2093 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2094 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2097 g_free (server_name);
2101 gchar *initial_username = modest_server_account_get_username (
2102 modest_runtime_get_account_mgr(), server_account_name);
2104 GtkWidget *entry_username = gtk_entry_new ();
2105 if (initial_username)
2106 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2107 /* Dim this if a connection has ever succeeded with this username,
2108 * as per the UI spec: */
2109 const gboolean username_known =
2110 modest_server_account_get_username_has_succeeded(
2111 modest_runtime_get_account_mgr(), server_account_name);
2112 gtk_widget_set_sensitive (entry_username, !username_known);
2114 #ifdef MODEST_PLATFORM_MAEMO
2115 /* Auto-capitalization is the default, so let's turn it off: */
2116 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2118 /* Create a size group to be used by all captions.
2119 * Note that HildonCaption does not create a default size group if we do not specify one.
2120 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2121 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2123 GtkWidget *caption = hildon_caption_new (sizegroup,
2124 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2125 gtk_widget_show (entry_username);
2126 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2127 FALSE, FALSE, MODEST_MARGIN_HALF);
2128 gtk_widget_show (caption);
2130 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2132 #endif /* MODEST_PLATFORM_MAEMO */
2135 GtkWidget *entry_password = gtk_entry_new ();
2136 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2137 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2139 #ifdef MODEST_PLATFORM_MAEMO
2140 /* Auto-capitalization is the default, so let's turn it off: */
2141 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2142 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2144 caption = hildon_caption_new (sizegroup,
2145 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2146 gtk_widget_show (entry_password);
2147 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2148 FALSE, FALSE, MODEST_MARGIN_HALF);
2149 gtk_widget_show (caption);
2150 g_object_unref (sizegroup);
2152 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2154 #endif /* MODEST_PLATFORM_MAEMO */
2156 /* This is not in the Maemo UI spec:
2157 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2158 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2162 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2164 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2166 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2168 modest_server_account_set_username (
2169 modest_runtime_get_account_mgr(), server_account_name,
2172 const gboolean username_was_changed =
2173 (strcmp (*username, initial_username) != 0);
2174 if (username_was_changed) {
2175 g_warning ("%s: tinymail does not yet support changing the "
2176 "username in the get_password() callback.\n", __FUNCTION__);
2181 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2183 /* We do not save the password in the configuration,
2184 * because this function is only called for passwords that should
2185 * not be remembered:
2186 modest_server_account_set_password (
2187 modest_runtime_get_account_mgr(), server_account_name,
2206 /* This is not in the Maemo UI spec:
2207 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2213 gtk_widget_destroy (dialog);
2215 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2219 modest_ui_actions_on_cut (GtkAction *action,
2220 ModestWindow *window)
2222 GtkWidget *focused_widget;
2224 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2225 if (GTK_IS_EDITABLE (focused_widget)) {
2226 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2227 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2228 GtkTextBuffer *buffer;
2229 GtkClipboard *clipboard;
2231 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2232 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2233 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2234 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2235 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2236 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2237 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2242 modest_ui_actions_on_copy (GtkAction *action,
2243 ModestWindow *window)
2245 GtkClipboard *clipboard;
2246 GtkWidget *focused_widget;
2248 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2249 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2251 if (GTK_IS_LABEL (focused_widget)) {
2252 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2253 } else if (GTK_IS_EDITABLE (focused_widget)) {
2254 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2255 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2256 GtkTextBuffer *buffer;
2257 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2258 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2259 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2260 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2261 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2262 TnyIterator *iter = tny_list_create_iterator (header_list);
2263 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2264 TnyFolder *folder = tny_header_get_folder (header);
2265 TnyAccount *account = tny_folder_get_account (folder);
2266 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2267 /* If it's POP then ask */
2268 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2269 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2270 g_object_unref (account);
2271 g_object_unref (folder);
2272 g_object_unref (header);
2273 g_object_unref (iter);
2275 /* Check that the messages have been previously downloaded */
2276 gboolean continue_download = TRUE;
2278 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2279 if (continue_download)
2280 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2281 g_object_unref (header_list);
2282 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2283 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2286 /* Show information banner */
2287 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2292 modest_ui_actions_on_undo (GtkAction *action,
2293 ModestWindow *window)
2295 ModestEmailClipboard *clipboard = NULL;
2297 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2298 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2299 } if (MODEST_IS_MAIN_WINDOW (window)) {
2300 /* Clear clipboard source */
2301 clipboard = modest_runtime_get_email_clipboard ();
2302 modest_email_clipboard_clear (clipboard);
2305 g_return_if_reached ();
2310 modest_ui_actions_on_paste (GtkAction *action,
2311 ModestWindow *window)
2313 GtkWidget *focused_widget;
2314 ModestMailOperation *mail_op = NULL;
2316 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2317 if (GTK_IS_EDITABLE (focused_widget)) {
2318 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2319 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2320 GtkTextBuffer *buffer;
2321 GtkClipboard *clipboard;
2323 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2324 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2325 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2326 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2327 ModestEmailClipboard *clipboard = NULL;
2328 TnyFolder *src_folder = NULL;
2329 TnyFolderStore *folder_store = NULL;
2330 TnyList *data = NULL;
2331 gboolean delete = FALSE;
2333 /* Check clipboard source */
2334 clipboard = modest_runtime_get_email_clipboard ();
2335 if (modest_email_clipboard_cleared (clipboard))
2338 /* Get elements to paste */
2339 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2341 /* Create a new mail operation */
2342 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2343 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2346 /* Get destination folder */
2347 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2349 /* transfer messages */
2351 modest_mail_operation_xfer_msgs (mail_op,
2353 TNY_FOLDER (folder_store),
2358 } else if (src_folder != NULL) {
2359 modest_mail_operation_xfer_folder (mail_op,
2367 g_object_unref (data);
2368 if (src_folder != NULL)
2369 g_object_unref (src_folder);
2370 if (folder_store != NULL)
2371 g_object_unref (folder_store);
2376 modest_ui_actions_on_select_all (GtkAction *action,
2377 ModestWindow *window)
2379 GtkWidget *focused_widget;
2381 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2382 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2383 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2384 } else if (GTK_IS_LABEL (focused_widget)) {
2385 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2386 } else if (GTK_IS_EDITABLE (focused_widget)) {
2387 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2388 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2389 GtkTextBuffer *buffer;
2390 GtkTextIter start, end;
2392 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2393 gtk_text_buffer_get_start_iter (buffer, &start);
2394 gtk_text_buffer_get_end_iter (buffer, &end);
2395 gtk_text_buffer_select_range (buffer, &start, &end);
2396 } else if (GTK_IS_HTML (focused_widget)) {
2397 gtk_html_select_all (GTK_HTML (focused_widget));
2398 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2399 GtkWidget *header_view = focused_widget;
2400 GtkTreeSelection *selection = NULL;
2402 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2403 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2404 MODEST_WIDGET_TYPE_HEADER_VIEW);
2406 /* Select all messages */
2407 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2408 gtk_tree_selection_select_all (selection);
2410 /* Set focuse on header view */
2411 gtk_widget_grab_focus (header_view);
2417 modest_ui_actions_on_mark_as_read (GtkAction *action,
2418 ModestWindow *window)
2420 g_return_if_fail (MODEST_IS_WINDOW(window));
2422 /* Mark each header as read */
2423 do_headers_action (window, headers_action_mark_as_read, NULL);
2427 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2428 ModestWindow *window)
2430 g_return_if_fail (MODEST_IS_WINDOW(window));
2432 /* Mark each header as read */
2433 do_headers_action (window, headers_action_mark_as_unread, NULL);
2437 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2438 GtkRadioAction *selected,
2439 ModestWindow *window)
2443 value = gtk_radio_action_get_current_value (selected);
2444 if (MODEST_IS_WINDOW (window)) {
2445 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2449 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2450 GtkRadioAction *selected,
2451 ModestWindow *window)
2453 TnyHeaderFlags flags;
2454 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2456 flags = gtk_radio_action_get_current_value (selected);
2457 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2460 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2461 GtkRadioAction *selected,
2462 ModestWindow *window)
2466 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2468 file_format = gtk_radio_action_get_current_value (selected);
2469 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2474 modest_ui_actions_on_zoom_plus (GtkAction *action,
2475 ModestWindow *window)
2477 g_return_if_fail (MODEST_IS_WINDOW (window));
2479 modest_window_zoom_plus (MODEST_WINDOW (window));
2483 modest_ui_actions_on_zoom_minus (GtkAction *action,
2484 ModestWindow *window)
2486 g_return_if_fail (MODEST_IS_WINDOW (window));
2488 modest_window_zoom_minus (MODEST_WINDOW (window));
2492 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2493 ModestWindow *window)
2495 ModestWindowMgr *mgr;
2496 gboolean fullscreen, active;
2497 g_return_if_fail (MODEST_IS_WINDOW (window));
2499 mgr = modest_runtime_get_window_mgr ();
2501 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2502 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2504 if (active != fullscreen) {
2505 modest_window_mgr_set_fullscreen_mode (mgr, active);
2506 gtk_window_present (GTK_WINDOW (window));
2511 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2512 ModestWindow *window)
2514 ModestWindowMgr *mgr;
2515 gboolean fullscreen;
2517 g_return_if_fail (MODEST_IS_WINDOW (window));
2519 mgr = modest_runtime_get_window_mgr ();
2520 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2521 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2523 gtk_window_present (GTK_WINDOW (window));
2527 * Used by modest_ui_actions_on_details to call do_headers_action
2530 headers_action_show_details (TnyHeader *header,
2531 ModestWindow *window,
2538 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2541 gtk_widget_show_all (dialog);
2542 gtk_dialog_run (GTK_DIALOG (dialog));
2544 gtk_widget_destroy (dialog);
2548 * Show the folder details in a ModestDetailsDialog widget
2551 show_folder_details (TnyFolder *folder,
2557 dialog = modest_details_dialog_new_with_folder (window, folder);
2560 gtk_widget_show_all (dialog);
2561 gtk_dialog_run (GTK_DIALOG (dialog));
2563 gtk_widget_destroy (dialog);
2567 * Show the header details in a ModestDetailsDialog widget
2570 modest_ui_actions_on_details (GtkAction *action,
2573 TnyList * headers_list;
2577 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2580 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2583 g_object_unref (msg);
2585 headers_list = get_selected_headers (win);
2589 iter = tny_list_create_iterator (headers_list);
2591 header = TNY_HEADER (tny_iterator_get_current (iter));
2592 headers_action_show_details (header, win, NULL);
2593 g_object_unref (header);
2595 g_object_unref (iter);
2596 g_object_unref (headers_list);
2598 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2599 GtkWidget *folder_view, *header_view;
2601 /* Check which widget has the focus */
2602 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2603 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2604 if (gtk_widget_is_focus (folder_view)) {
2605 TnyFolderStore *folder_store
2606 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2607 if (!folder_store) {
2608 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2611 /* Show only when it's a folder */
2612 /* This function should not be called for account items,
2613 * because we dim the menu item for them. */
2614 if (TNY_IS_FOLDER (folder_store)) {
2615 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2618 g_object_unref (folder_store);
2621 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2622 MODEST_WIDGET_TYPE_HEADER_VIEW);
2623 /* Show details of each header */
2624 do_headers_action (win, headers_action_show_details, header_view);
2630 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2631 ModestMsgEditWindow *window)
2633 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2635 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2639 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2640 ModestMsgEditWindow *window)
2642 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2644 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2648 modest_ui_actions_toggle_folders_view (GtkAction *action,
2649 ModestMainWindow *main_window)
2653 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2655 conf = modest_runtime_get_conf ();
2657 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2658 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2660 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2664 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2665 ModestWindow *window)
2667 gboolean active, fullscreen = FALSE;
2668 ModestWindowMgr *mgr;
2670 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2672 /* Check if we want to toggle the toolbar vuew in fullscreen
2674 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2675 "ViewShowToolbarFullScreen")) {
2679 /* Toggle toolbar */
2680 mgr = modest_runtime_get_window_mgr ();
2681 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2685 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2686 ModestMsgEditWindow *window)
2688 modest_msg_edit_window_select_font (window);
2692 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2693 const gchar *display_name,
2696 /* Do not change the application name if the widget has not
2697 the focus. This callback could be called even if the folder
2698 view has not the focus, because the handled signal could be
2699 emitted when the folder view is redrawn */
2700 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2702 gtk_window_set_title (window, display_name);
2704 gtk_window_set_title (window, " ");
2709 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2711 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2712 modest_msg_edit_window_select_contacts (window);
2716 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2718 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2719 modest_msg_edit_window_check_names (window);
2724 create_move_to_dialog (ModestWindow *win,
2725 GtkWidget *folder_view,
2726 GtkWidget **tree_view)
2728 GtkWidget *dialog, *scroll;
2730 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2732 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2734 GTK_RESPONSE_ACCEPT,
2736 GTK_RESPONSE_REJECT,
2739 /* Create scrolled window */
2740 scroll = gtk_scrolled_window_new (NULL, NULL);
2741 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2742 GTK_POLICY_AUTOMATIC,
2743 GTK_POLICY_AUTOMATIC);
2745 /* Create folder view */
2746 *tree_view = modest_platform_create_folder_view (NULL);
2748 /* It could happen that we're trying to move a message from a
2749 window (msg window for example) after the main window was
2750 closed, so we can not just get the model of the folder
2752 if (MODEST_IS_FOLDER_VIEW (folder_view))
2753 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2754 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2756 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2757 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2759 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2761 /* Add scroll to dialog */
2762 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2763 scroll, FALSE, FALSE, 0);
2765 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2767 /* Select INBOX or local account */
2768 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2774 * Returns TRUE if at least one of the headers of the list belongs to
2775 * a message that has been fully retrieved.
2778 has_retrieved_msgs (TnyList *list)
2781 gboolean found = FALSE;
2783 iter = tny_list_create_iterator (list);
2784 while (tny_iterator_is_done (iter) && !found) {
2786 TnyHeaderFlags flags;
2788 header = TNY_HEADER (tny_iterator_get_current (iter));
2789 flags = tny_header_get_flags (header);
2790 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2794 tny_iterator_next (iter);
2796 g_object_unref (iter);
2802 * Shows a confirmation dialog to the user when we're moving messages
2803 * from a remote server to the local storage. Returns the dialog
2804 * response. If it's other kind of movement the it always returns
2808 msgs_move_to_confirmation (GtkWindow *win,
2809 TnyFolder *dest_folder,
2812 gint response = GTK_RESPONSE_OK;
2814 /* If the destination is a local folder */
2815 if (modest_tny_folder_is_local_folder (dest_folder)) {
2816 TnyFolder *src_folder;
2820 /* Get source folder */
2821 iter = tny_list_create_iterator (headers);
2822 header = TNY_HEADER (tny_iterator_get_current (iter));
2823 src_folder = tny_header_get_folder (header);
2824 g_object_unref (header);
2825 g_object_unref (iter);
2827 /* if no src_folder, message may be an attahcment */
2828 if (src_folder == NULL)
2829 return GTK_RESPONSE_CANCEL;
2831 /* If the source is a remote folder */
2832 if (!modest_tny_folder_is_local_folder (src_folder)) {
2833 const gchar *message;
2835 if (has_retrieved_msgs (headers))
2836 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2837 tny_list_get_length (headers));
2839 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2840 tny_list_get_length (headers));
2842 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2843 (const gchar *) message);
2845 g_object_unref (src_folder);
2852 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2854 ModestMsgViewWindow *self = NULL;
2856 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2857 self = MODEST_MSG_VIEW_WINDOW (object);
2859 /* If there are not more messages don't do anything. The
2860 viewer will show the same message */
2861 if (!modest_msg_view_window_select_first_message (self))
2866 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2869 GObject *win = modest_mail_operation_get_source (mail_op);
2871 /* TODO: show error message */
2872 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2873 _("mail_in_ui_folder_move_target_error"));
2874 g_object_unref (win);
2878 * UI handler for the "Move to" action when invoked from the
2882 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2883 ModestMainWindow *win)
2885 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2886 GtkWidget *header_view = NULL;
2888 TnyFolderStore *folder_store = NULL;
2889 ModestMailOperation *mail_op = NULL;
2891 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2893 /* Get the folder view */
2894 folder_view = modest_main_window_get_child_widget (win,
2895 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2897 /* Get header view */
2898 header_view = modest_main_window_get_child_widget (win,
2899 MODEST_WIDGET_TYPE_HEADER_VIEW);
2901 /* Create and run the dialog */
2902 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2903 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2904 result = gtk_dialog_run (GTK_DIALOG(dialog));
2905 g_object_ref (tree_view);
2907 /* We do this to save an indentation level ;-) */
2908 if (result != GTK_RESPONSE_ACCEPT)
2911 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2913 if (TNY_IS_ACCOUNT (folder_store))
2916 /* Get folder or messages to transfer */
2917 if (gtk_widget_is_focus (folder_view)) {
2918 TnyFolderStore *src_folder;
2919 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2921 /* Clean folder on header view before moving it */
2922 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2924 if (TNY_IS_FOLDER (src_folder)) {
2926 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2928 modest_ui_actions_move_folder_error_handler,
2930 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2932 modest_mail_operation_xfer_folder (mail_op,
2933 TNY_FOLDER (src_folder),
2936 /* Unref mail operation */
2937 g_object_unref (G_OBJECT (mail_op));
2941 g_object_unref (G_OBJECT (src_folder));
2943 if (gtk_widget_is_focus (header_view)) {
2947 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2949 /* Ask for user confirmation */
2950 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2951 TNY_FOLDER (folder_store),
2954 /* Transfer messages */
2955 if (response == GTK_RESPONSE_OK) {
2956 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2957 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2960 modest_mail_operation_xfer_msgs (mail_op,
2962 TNY_FOLDER (folder_store),
2967 g_object_unref (G_OBJECT (mail_op));
2969 g_object_unref (headers);
2973 if (folder_store != NULL)
2974 g_object_unref (folder_store);
2975 gtk_widget_destroy (dialog);
2980 * UI handler for the "Move to" action when invoked from the
2981 * ModestMsgViewWindow
2984 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2985 ModestMsgViewWindow *win)
2987 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2989 ModestMainWindow *main_window;
2993 /* Get the folder view */
2994 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2996 folder_view = modest_main_window_get_child_widget (main_window,
2997 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3001 /* Create and run the dialog */
3002 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3003 result = gtk_dialog_run (GTK_DIALOG(dialog));
3004 g_object_ref (tree_view);
3006 if (result == GTK_RESPONSE_ACCEPT) {
3007 TnyFolderStore *folder_store;
3010 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3012 /* Create header list */
3013 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3015 headers = tny_simple_list_new ();
3016 tny_list_prepend (headers, G_OBJECT (header));
3017 g_object_unref (header);
3019 /* Ask user for confirmation. MSG-NOT404 */
3020 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3021 TNY_FOLDER (folder_store),
3024 /* Transfer current msg */
3025 if (response == GTK_RESPONSE_OK) {
3026 ModestMailOperation *mail_op;
3028 /* Create mail op */
3029 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3030 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3033 /* Transfer messages */
3034 modest_mail_operation_xfer_msgs (mail_op,
3036 TNY_FOLDER (folder_store),
3038 transfer_msgs_from_viewer_cb,
3040 g_object_unref (G_OBJECT (mail_op));
3042 g_object_unref (headers);
3043 g_object_unref (folder_store);
3045 gtk_widget_destroy (dialog);
3049 modest_ui_actions_on_move_to (GtkAction *action,
3052 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3053 MODEST_IS_MSG_VIEW_WINDOW (win));
3055 if (MODEST_IS_MAIN_WINDOW (win))
3056 modest_ui_actions_on_main_window_move_to (action,
3057 MODEST_MAIN_WINDOW (win));
3059 modest_ui_actions_on_msg_view_window_move_to (action,
3060 MODEST_MSG_VIEW_WINDOW (win));
3064 * Calls #HeadersFunc for each header already selected in the main
3065 * window or the message currently being shown in the msg view window
3068 do_headers_action (ModestWindow *win,
3072 TnyList *headers_list;
3078 headers_list = get_selected_headers (win);
3082 /* Get the folder */
3083 iter = tny_list_create_iterator (headers_list);
3084 header = TNY_HEADER (tny_iterator_get_current (iter));
3085 folder = tny_header_get_folder (header);
3086 g_object_unref (header);
3088 /* Call the function for each header */
3089 while (!tny_iterator_is_done (iter)) {
3090 header = TNY_HEADER (tny_iterator_get_current (iter));
3091 func (header, win, user_data);
3092 g_object_unref (header);
3093 tny_iterator_next (iter);
3096 /* Trick: do a poke status in order to speed up the signaling
3098 tny_folder_poke_status (folder);
3101 g_object_unref (folder);
3102 g_object_unref (iter);
3103 g_object_unref (headers_list);
3107 modest_ui_actions_view_attachment (GtkAction *action,
3108 ModestWindow *window)
3110 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3111 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3113 /* not supported window for this action */
3114 g_return_if_reached ();
3119 modest_ui_actions_save_attachments (GtkAction *action,
3120 ModestWindow *window)
3122 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3123 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3125 /* not supported window for this action */
3126 g_return_if_reached ();
3131 modest_ui_actions_remove_attachments (GtkAction *action,
3132 ModestWindow *window)
3134 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3135 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window));
3137 /* not supported window for this action */
3138 g_return_if_reached ();
3143 modest_ui_actions_on_settings (GtkAction *action,
3148 dialog = modest_platform_get_global_settings_dialog ();
3149 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3150 gtk_widget_show_all (dialog);
3152 gtk_dialog_run (GTK_DIALOG (dialog));
3154 gtk_widget_destroy (dialog);
3158 modest_ui_actions_on_help (GtkAction *action,
3161 const gchar *help_id = NULL;
3163 if (MODEST_IS_MAIN_WINDOW (win)) {
3164 const gchar *action_name;
3165 action_name = gtk_action_get_name (action);
3167 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3168 !strcmp (action_name, "HeaderViewCSMHelp")) {
3169 GtkWidget *folder_view;
3170 TnyFolderStore *folder_store;
3171 /* Get selected folder */
3172 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3173 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3174 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3176 /* Switch help_id */
3177 if (TNY_IS_FOLDER (folder_store)) {
3178 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3179 case TNY_FOLDER_TYPE_NORMAL:
3180 help_id = "applications_email_userfolder";
3182 case TNY_FOLDER_TYPE_INBOX:
3183 help_id = "applications_email_inbox";
3185 case TNY_FOLDER_TYPE_OUTBOX:
3186 help_id = "applications_email_outbox";
3188 case TNY_FOLDER_TYPE_SENT:
3189 help_id = "applications_email_sent";
3191 case TNY_FOLDER_TYPE_DRAFTS:
3192 help_id = "applications_email_drafts";
3194 case TNY_FOLDER_TYPE_ARCHIVE:
3195 help_id = "applications_email_archive";
3201 g_object_unref (folder_store);
3203 help_id = "applications_email_mainview";
3205 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3206 help_id = "applications_email_viewer";
3207 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3208 help_id = "applications_email_editor";
3210 modest_platform_show_help (GTK_WINDOW (win), help_id);
3214 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3215 ModestWindow *window)
3217 ModestMailOperation *mail_op;
3221 headers = get_selected_headers (window);
3225 /* Create mail operation */
3226 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3228 modest_ui_actions_get_msgs_full_error_handler,
3230 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3231 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3234 g_object_unref (headers);
3235 g_object_unref (mail_op);
3239 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3240 ModestWindow *window)
3242 g_return_if_fail (MODEST_IS_WINDOW (window));
3245 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3249 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3250 ModestWindow *window)
3252 g_return_if_fail (MODEST_IS_WINDOW (window));
3255 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3259 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3260 ModestWindow *window)
3262 g_return_if_fail (MODEST_IS_WINDOW (window));
3265 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3269 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3270 ModestWindow *window)
3272 g_return_if_fail (MODEST_IS_WINDOW (window));
3275 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3279 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3280 ModestWindow *window)
3282 g_return_if_fail (MODEST_IS_WINDOW (window));
3285 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3289 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3290 ModestWindow *window)
3292 g_return_if_fail (MODEST_IS_WINDOW (window));
3295 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3299 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3300 ModestWindow *window)
3302 g_return_if_fail (MODEST_IS_WINDOW (window));
3305 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3309 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3310 ModestWindow *window)
3312 g_return_if_fail (MODEST_IS_WINDOW (window));
3315 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3319 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3321 g_return_if_fail (MODEST_IS_WINDOW (window));
3324 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3328 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3330 g_return_if_fail (MODEST_IS_WINDOW (window));
3332 modest_platform_show_search_messages (GTK_WINDOW (window));
3336 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3338 g_return_if_fail (MODEST_IS_WINDOW (win));
3339 modest_platform_show_addressbook (GTK_WINDOW (win));
3344 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3345 ModestWindow *window)
3347 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3349 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3353 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3354 ModestMailOperationState *state,
3357 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3359 /* Set send/receive operation finished */
3360 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3361 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));