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, or in the process of being 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 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
287 g_object_unref (header);
288 tny_iterator_next (iter);
290 g_object_unref (iter);
295 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
296 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
298 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
302 g_object_unref (header_list);
307 if (tny_list_get_length(header_list) == 1) {
308 iter = tny_list_create_iterator (header_list);
309 header = TNY_HEADER (tny_iterator_get_current (iter));
310 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
311 g_object_unref (header);
312 g_object_unref (iter);
314 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
315 tny_list_get_length(header_list)), desc);
317 /* Confirmation dialog */
318 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
322 if (response == GTK_RESPONSE_OK) {
323 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
325 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
329 /* Remove each header */
330 do_headers_action (win, headers_action_delete, NULL);
332 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
333 gtk_widget_destroy (GTK_WIDGET(win));
337 /* Update toolbar dimming state */
338 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
343 g_object_unref (header_list);
348 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
350 #ifdef MODEST_PLATFORM_MAEMO
351 modest_osso_save_state();
352 #endif /* MODEST_PLATFORM_MAEMO */
354 /* FIXME: we need to cancel all actions/threads here,
361 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
363 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
364 gtk_widget_destroy (GTK_WIDGET (win));
365 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
367 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
368 } else if (MODEST_IS_WINDOW (win)) {
369 gtk_widget_destroy (GTK_WIDGET (win));
371 g_return_if_reached ();
376 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
378 GtkClipboard *clipboard = NULL;
379 gchar *selection = NULL;
381 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
382 selection = gtk_clipboard_wait_for_text (clipboard);
384 /* Question: why is the clipboard being used here?
385 * It doesn't really make a lot of sense. */
389 modest_address_book_add_address (selection);
395 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
397 /* This is currently only implemented for Maemo */
398 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
399 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
400 run_account_setup_wizard (win);
403 /* Show the list of accounts: */
404 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
405 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
406 gtk_dialog_run (account_win);
407 gtk_widget_destroy (GTK_WIDGET(account_win));
410 GtkWidget *dialog, *label;
412 /* Create the widgets */
414 dialog = gtk_dialog_new_with_buttons ("Message",
416 GTK_DIALOG_DESTROY_WITH_PARENT,
420 label = gtk_label_new ("Hello World!");
422 /* Ensure that the dialog box is destroyed when the user responds. */
424 g_signal_connect_swapped (dialog, "response",
425 G_CALLBACK (gtk_widget_destroy),
428 /* Add the label, and show everything we've added to the dialog. */
430 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
432 gtk_widget_show_all (dialog);
433 #endif /* MODEST_PLATFORM_MAEMO */
437 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
439 ModestWindow *main_window = MODEST_WINDOW (user_data);
441 /* Save any changes. */
442 modest_connection_specific_smtp_window_save_server_accounts (
443 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
444 modest_window_get_active_account (main_window));
445 gtk_widget_destroy (GTK_WIDGET (window));
451 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
453 /* This is currently only implemented for Maemo,
454 * because it requires an API (libconic) to detect different connection
457 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
459 /* Create the window if necessary: */
460 const gchar *active_account_name = modest_window_get_active_account (win);
462 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
463 * or show the default account?
464 * If we show the default account then the account name should be shown in
465 * the window when we show it. */
466 if (!active_account_name) {
467 g_warning ("%s: No account is active.", __FUNCTION__);
471 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
472 modest_connection_specific_smtp_window_fill_with_connections (
473 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
474 modest_runtime_get_account_mgr(),
475 active_account_name);
477 /* Show the window: */
478 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
479 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
480 gtk_widget_show (specific_window);
482 /* Save changes when the window is hidden: */
483 g_signal_connect (specific_window, "hide",
484 G_CALLBACK (on_smtp_servers_window_hide), win);
485 #endif /* MODEST_PLATFORM_MAEMO */
489 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
491 ModestWindow *msg_win = NULL;
493 TnyFolder *folder = NULL;
494 gchar *account_name = NULL;
495 gchar *from_str = NULL;
496 /* GError *err = NULL; */
497 TnyAccount *account = NULL;
498 ModestWindowMgr *mgr;
499 gchar *signature = NULL, *blank_and_signature = NULL;
501 /* if there are no accounts yet, just show the wizard */
502 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
503 run_account_setup_wizard (win);
507 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
509 account_name = g_strdup (modest_window_get_active_account (win));
511 g_printerr ("modest: no account found\n");
515 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
517 TNY_ACCOUNT_TYPE_STORE);
519 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
523 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
525 g_printerr ("modest: failed get from string for '%s'\n", account_name);
529 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
530 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
531 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
532 MODEST_ACCOUNT_SIGNATURE, FALSE);
533 blank_and_signature = g_strconcat ("\n", signature, NULL);
536 blank_and_signature = g_strdup ("");
539 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
541 g_printerr ("modest: failed to create new msg\n");
545 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
547 g_printerr ("modest: failed to find Drafts folder\n");
552 /* Create and register edit window */
553 /* This is destroyed by TOOD. */
554 msg_win = modest_msg_edit_window_new (msg, account_name);
555 mgr = modest_runtime_get_window_mgr ();
556 modest_window_mgr_register_window (mgr, msg_win);
559 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
561 gtk_widget_show_all (GTK_WIDGET (msg_win));
564 g_free (account_name);
566 g_free (blank_and_signature);
568 g_object_unref (msg_win);
570 g_object_unref (G_OBJECT(account));
572 g_object_unref (G_OBJECT(msg));
574 g_object_unref (G_OBJECT(folder));
578 open_msg_cb (ModestMailOperation *mail_op,
583 ModestWindowMgr *mgr = NULL;
584 ModestWindow *parent_win = NULL;
585 ModestWindow *win = NULL;
586 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
587 gchar *account = NULL;
590 /* TODO: Show an error? (review the specs) */
594 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
595 folder = tny_header_get_folder (header);
597 /* Mark header as read */
598 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
601 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
603 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
605 /* Gets folder type (OUTBOX headers will be opened in edit window */
606 if (modest_tny_folder_is_local_folder (folder))
607 folder_type = modest_tny_folder_get_local_folder_type (folder);
609 /* If the header is in the drafts folder then open the editor,
610 else the message view window */
611 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
612 /* we cannot edit without a valid account... */
613 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
614 run_account_setup_wizard(parent_win);
617 win = modest_msg_edit_window_new (msg, account);
619 gchar *uid = modest_tny_folder_get_header_unique_id (header);
621 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
622 GtkWidget *header_view;
623 GtkTreeSelection *sel;
624 GList *sel_list = NULL;
627 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
628 MODEST_WIDGET_TYPE_HEADER_VIEW);
630 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
631 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
633 if (sel_list != NULL) {
634 GtkTreeRowReference *row_reference;
636 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
637 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
638 g_list_free (sel_list);
640 win = modest_msg_view_window_new_with_header_model (msg,
645 gtk_tree_row_reference_free (row_reference);
647 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
650 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
655 /* Register and show new window */
657 mgr = modest_runtime_get_window_mgr ();
658 modest_window_mgr_register_window (mgr, win);
659 g_object_unref (win);
660 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
661 gtk_widget_show_all (GTK_WIDGET(win));
664 /* Update toolbar dimming state */
665 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
666 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
672 g_object_unref (parent_win);
673 /* g_object_unref (msg); */
674 g_object_unref (folder);
678 * This function is the error handler of the
679 * modest_mail_operation_get_msgs_full operation
682 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
687 error = modest_mail_operation_get_error (mail_op);
688 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
689 GObject *win = modest_mail_operation_get_source (mail_op);
691 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
693 g_object_unref (win);
698 * This function is used by both modest_ui_actions_on_open and
699 * modest_ui_actions_on_header_activated. This way we always do the
700 * same when trying to open messages.
703 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
705 ModestWindowMgr *mgr = NULL;
706 TnyIterator *iter = NULL;
707 ModestMailOperation *mail_op1 = NULL;
708 ModestMailOperation *mail_op2 = NULL;
709 TnyList *not_opened_headers = NULL;
710 TnyList *not_opened_cached_headers = NULL;
711 TnyHeaderFlags flags;
713 /* Look if we already have a message view for each header. If
714 true, then remove the header from the list of headers to
716 mgr = modest_runtime_get_window_mgr ();
717 iter = tny_list_create_iterator (headers);
718 not_opened_headers = tny_simple_list_new ();
719 not_opened_cached_headers = tny_simple_list_new ();
720 while (!tny_iterator_is_done (iter)) {
722 ModestWindow *window;
726 header = TNY_HEADER (tny_iterator_get_current (iter));
727 flags = tny_header_get_flags (header);
730 found = modest_window_mgr_find_registered_header (mgr, header, &window);
732 /* Do not open again the message and present the
733 window to the user */
736 gtk_window_present (GTK_WINDOW (window));
738 /* the header has been registered already, we don't do
739 * anything but wait for the window to come up*/
740 g_warning ("debug: header %p already registered, waiting for window",
743 /* register the header before actually creating the window */
744 modest_window_mgr_register_header (mgr, header);
746 if (!(flags & TNY_HEADER_FLAG_CACHED))
747 tny_list_append (not_opened_headers, G_OBJECT (header));
748 /* Check if msg has already been retreived */
750 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
752 g_object_unref (header);
753 tny_iterator_next (iter);
756 /* Open each uncached message */
757 if (tny_list_get_length (not_opened_headers) > 0) {
758 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
760 modest_ui_actions_get_msgs_full_error_handler,
762 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
763 if (tny_list_get_length (not_opened_headers) > 1) {
764 modest_mail_operation_get_msgs_full (mail_op1,
770 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
771 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
772 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
773 g_object_unref (header);
774 g_object_unref (iter);
778 /* Open each cached message */
779 if (tny_list_get_length (not_opened_cached_headers) > 0) {
780 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
782 modest_ui_actions_get_msgs_full_error_handler,
784 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
785 if (tny_list_get_length (not_opened_cached_headers) > 1) {
786 modest_mail_operation_get_msgs_full (mail_op2,
792 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
793 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
794 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
795 g_object_unref (header);
796 g_object_unref (iter);
801 if (not_opened_headers != NULL)
802 g_object_unref (not_opened_headers);
803 if (not_opened_cached_headers != NULL)
804 g_object_unref (not_opened_cached_headers);
806 g_object_unref (iter);
807 if (mail_op1 != NULL)
808 g_object_unref (mail_op1);
809 if (mail_op2 != NULL)
810 g_object_unref (mail_op2);
814 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
819 headers = get_selected_headers (win);
824 _modest_ui_actions_open (headers, win);
826 g_object_unref(headers);
831 free_reply_forward_helper (gpointer data)
833 ReplyForwardHelper *helper;
835 helper = (ReplyForwardHelper *) data;
836 g_free (helper->account_name);
837 g_slice_free (ReplyForwardHelper, helper);
841 reply_forward_cb (ModestMailOperation *mail_op,
847 ReplyForwardHelper *rf_helper;
848 ModestWindow *msg_win = NULL;
849 ModestEditType edit_type;
851 TnyAccount *account = NULL;
852 ModestWindowMgr *mgr = NULL;
853 gchar *signature = NULL;
855 g_return_if_fail (user_data != NULL);
856 rf_helper = (ReplyForwardHelper *) user_data;
858 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
859 rf_helper->account_name);
860 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
861 rf_helper->account_name,
862 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
863 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
864 rf_helper->account_name,
865 MODEST_ACCOUNT_SIGNATURE, FALSE);
868 /* Create reply mail */
869 switch (rf_helper->action) {
872 modest_tny_msg_create_reply_msg (msg, from, signature,
873 rf_helper->reply_forward_type,
874 MODEST_TNY_MSG_REPLY_MODE_SENDER);
876 case ACTION_REPLY_TO_ALL:
878 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
879 MODEST_TNY_MSG_REPLY_MODE_ALL);
880 edit_type = MODEST_EDIT_TYPE_REPLY;
884 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
885 edit_type = MODEST_EDIT_TYPE_FORWARD;
888 g_return_if_reached ();
895 g_printerr ("modest: failed to create message\n");
899 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
900 rf_helper->account_name,
901 TNY_ACCOUNT_TYPE_STORE);
903 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
907 /* Create and register the windows */
908 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
909 mgr = modest_runtime_get_window_mgr ();
910 modest_window_mgr_register_window (mgr, msg_win);
912 if (rf_helper->parent_window != NULL) {
915 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
916 modest_window_set_zoom (msg_win, parent_zoom);
919 /* Show edit window */
920 gtk_widget_show_all (GTK_WIDGET (msg_win));
924 g_object_unref (msg_win);
926 g_object_unref (G_OBJECT (new_msg));
928 g_object_unref (G_OBJECT (account));
929 /* g_object_unref (msg); */
930 g_object_unref (header);
934 * Checks a list of headers. If any of them are not currently
935 * downloaded (CACHED) then it asks the user for permission to
938 * Returns FALSE if the user does not want to download the
939 * messages. Returns TRUE if the user allowed the download or if all
940 * of them are currently downloaded
943 download_uncached_messages (TnyList *header_list, GtkWindow *win)
947 gint uncached_messages = 0;
949 iter = tny_list_create_iterator (header_list);
950 while (!tny_iterator_is_done (iter)) {
952 TnyHeaderFlags flags;
954 header = TNY_HEADER (tny_iterator_get_current (iter));
955 flags = tny_header_get_flags (header);
956 /* TODO: is this the right flag?, it seems that some
957 headers that have been previously downloaded do not
959 if (! (flags & TNY_HEADER_FLAG_CACHED))
960 uncached_messages ++;
961 g_object_unref (header);
962 tny_iterator_next (iter);
964 g_object_unref (iter);
966 /* Ask for user permission to download the messages */
968 if (uncached_messages > 0) {
969 GtkResponseType response;
971 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
972 ngettext("mcen_nc_get_msg",
975 if (response == GTK_RESPONSE_CANCEL)
983 * Common code for the reply and forward actions
986 reply_forward (ReplyForwardAction action, ModestWindow *win)
988 ModestMailOperation *mail_op = NULL;
989 TnyList *header_list = NULL;
990 ReplyForwardHelper *rf_helper = NULL;
991 guint reply_forward_type;
992 gboolean continue_download;
994 g_return_if_fail (MODEST_IS_WINDOW(win));
996 /* we need an account when editing */
997 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
998 run_account_setup_wizard (win);
1002 header_list = get_selected_headers (win);
1006 /* Check that the messages have been previously downloaded */
1007 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1008 if (!continue_download) {
1009 g_object_unref (header_list);
1013 reply_forward_type =
1014 modest_conf_get_int (modest_runtime_get_conf (),
1015 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1017 /* We assume that we can only select messages of the
1018 same folder and that we reply all of them from the
1019 same account. In fact the interface currently only
1020 allows single selection */
1023 rf_helper = g_slice_new0 (ReplyForwardHelper);
1024 rf_helper->reply_forward_type = reply_forward_type;
1025 rf_helper->action = action;
1026 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1027 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1028 rf_helper->parent_window = GTK_WIDGET (win);
1029 if (!rf_helper->account_name)
1030 rf_helper->account_name =
1031 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1033 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1036 /* Get header and message. Do not free them here, the
1037 reply_forward_cb must do it */
1038 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1039 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1040 if (!msg || !header) {
1042 g_object_unref (msg);
1044 g_object_unref (header);
1045 g_printerr ("modest: no message found\n");
1048 reply_forward_cb (NULL, header, msg, rf_helper);
1050 /* Retrieve messages */
1051 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1053 modest_ui_actions_get_msgs_full_error_handler,
1055 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1056 modest_mail_operation_get_msgs_full (mail_op,
1060 free_reply_forward_helper);
1063 g_object_unref(mail_op);
1067 g_object_unref (header_list);
1071 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1073 g_return_if_fail (MODEST_IS_WINDOW(win));
1075 reply_forward (ACTION_REPLY, win);
1079 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1081 g_return_if_fail (MODEST_IS_WINDOW(win));
1083 reply_forward (ACTION_FORWARD, win);
1087 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1089 g_return_if_fail (MODEST_IS_WINDOW(win));
1091 reply_forward (ACTION_REPLY_TO_ALL, win);
1095 modest_ui_actions_on_next (GtkAction *action,
1096 ModestWindow *window)
1098 if (MODEST_IS_MAIN_WINDOW (window)) {
1099 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_next (MODEST_HEADER_VIEW(header_view));
1107 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1108 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1110 g_return_if_reached ();
1115 modest_ui_actions_on_prev (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 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1128 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1129 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1131 g_return_if_reached ();
1136 modest_ui_actions_on_sort (GtkAction *action,
1137 ModestWindow *window)
1139 g_return_if_fail (MODEST_IS_WINDOW(window));
1141 if (MODEST_IS_MAIN_WINDOW (window)) {
1142 GtkWidget *header_view;
1143 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1144 MODEST_WIDGET_TYPE_HEADER_VIEW);
1148 /* Show sorting dialog */
1149 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1154 new_messages_arrived (ModestMailOperation *self,
1158 if (new_messages == 0)
1161 modest_platform_on_new_msg ();
1165 * This function performs the send & receive required actions. The
1166 * window is used to create the mail operation. Typically it should
1167 * always be the main window, but we pass it as argument in order to
1171 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1173 gchar *acc_name = NULL;
1174 ModestMailOperation *mail_op;
1176 /* If no account name was provided then get the current account, and if
1177 there is no current account then pick the default one: */
1178 if (!account_name) {
1179 acc_name = g_strdup (modest_window_get_active_account(win));
1181 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1183 g_printerr ("modest: cannot get default account\n");
1187 acc_name = g_strdup (account_name);
1190 /* Set send/receive operation in progress */
1191 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1193 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1194 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1195 G_CALLBACK (_on_send_receive_progress_changed),
1198 /* Send & receive. */
1199 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1200 /* Receive and then send. The operation is tagged initially as
1201 a receive operation because the account update performs a
1202 receive and then a send. The operation changes its type
1203 internally, so the progress objects will receive the proper
1204 progress information */
1205 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1206 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1207 g_object_unref (G_OBJECT (mail_op));
1214 * Refreshes all accounts. This function will be used by automatic
1218 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1220 GSList *account_names, *iter;
1222 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1225 iter = account_names;
1227 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1228 iter = g_slist_next (iter);
1231 modest_account_mgr_free_account_names (account_names);
1232 account_names = NULL;
1236 * Handler of the click on Send&Receive button in the main toolbar
1239 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1241 /* Check if accounts exist */
1242 gboolean accounts_exist =
1243 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1245 /* If not, allow the user to create an account before trying to send/receive. */
1246 if (!accounts_exist)
1247 modest_ui_actions_on_accounts (NULL, win);
1249 /* Refresh the active account */
1250 modest_ui_actions_do_send_receive (NULL, win);
1255 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1258 GtkWidget *header_view;
1260 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1262 header_view = modest_main_window_get_child_widget (main_window,
1263 MODEST_WIDGET_TYPE_HEADER_VIEW);
1267 conf = modest_runtime_get_conf ();
1269 /* what is saved/restored is depending on the style; thus; we save with
1270 * old style, then update the style, and restore for this new style
1272 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1274 if (modest_header_view_get_style
1275 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1276 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1277 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1279 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1280 MODEST_HEADER_VIEW_STYLE_DETAILS);
1282 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1283 MODEST_CONF_HEADER_VIEW_KEY);
1288 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1290 ModestMainWindow *main_window)
1292 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1293 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1295 /* If no header has been selected then exit */
1300 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1301 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1303 /* Update Main window title */
1304 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1305 const gchar *subject = tny_header_get_subject (header);
1306 if (subject && strlen(subject) > 0)
1307 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1309 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1312 /* Update toolbar dimming state */
1313 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1317 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1319 ModestMainWindow *main_window)
1323 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1328 headers = tny_simple_list_new ();
1329 tny_list_prepend (headers, G_OBJECT (header));
1331 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1333 g_object_unref (headers);
1337 set_active_account_from_tny_account (TnyAccount *account,
1338 ModestWindow *window)
1340 const gchar *server_acc_name = tny_account_get_id (account);
1342 /* We need the TnyAccount provided by the
1343 account store because that is the one that
1344 knows the name of the Modest account */
1345 TnyAccount *modest_server_account = modest_server_account =
1346 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1347 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1350 const gchar *modest_acc_name =
1351 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1352 modest_window_set_active_account (window, modest_acc_name);
1353 g_object_unref (modest_server_account);
1358 folder_refreshed_cb (const GObject *obj,
1362 ModestMainWindow *win = NULL;
1363 GtkWidget *header_view;
1365 g_return_if_fail (TNY_IS_FOLDER (folder));
1367 win = MODEST_MAIN_WINDOW (user_data);
1369 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1371 /* Check if folder is empty and set headers view contents style */
1372 if (tny_folder_get_all_count (folder) == 0) {
1373 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1374 modest_main_window_set_contents_style (win,
1375 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1377 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1382 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1383 TnyFolderStore *folder_store,
1385 ModestMainWindow *main_window)
1388 GtkWidget *header_view;
1390 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1392 header_view = modest_main_window_get_child_widget(main_window,
1393 MODEST_WIDGET_TYPE_HEADER_VIEW);
1397 conf = modest_runtime_get_conf ();
1399 if (TNY_IS_ACCOUNT (folder_store)) {
1401 /* Update active account */
1402 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1403 /* Show account details */
1404 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1407 if (TNY_IS_FOLDER (folder_store) && selected) {
1409 /* Update the active account */
1410 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1412 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1413 g_object_unref (account);
1417 /* Set the header style by default, it could
1418 be changed later by the refresh callback to
1420 modest_main_window_set_contents_style (main_window,
1421 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1423 /* Set folder on header view. This function
1424 will call tny_folder_refresh_async so we
1425 pass a callback that will be called when
1426 finished. We use that callback to set the
1427 empty view if there are no messages */
1428 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1429 TNY_FOLDER (folder_store),
1430 folder_refreshed_cb,
1433 /* Restore configuration. We need to do this
1434 *after* the set_folder because the widget
1435 memory asks the header view about its
1437 modest_widget_memory_restore (modest_runtime_get_conf (),
1438 G_OBJECT(header_view),
1439 MODEST_CONF_HEADER_VIEW_KEY);
1441 /* Update the active account */
1442 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1443 /* Save only if we're seeing headers */
1444 if (modest_main_window_get_contents_style (main_window) ==
1445 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1446 modest_widget_memory_save (conf, G_OBJECT (header_view),
1447 MODEST_CONF_HEADER_VIEW_KEY);
1448 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1452 /* Update toolbar dimming state */
1453 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1457 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1464 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1466 online = tny_device_is_online (modest_runtime_get_device());
1469 /* already online -- the item is simply not there... */
1470 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1472 GTK_MESSAGE_WARNING,
1474 _("The %s you selected cannot be found"),
1476 gtk_dialog_run (GTK_DIALOG(dialog));
1478 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1482 GTK_RESPONSE_REJECT,
1484 GTK_RESPONSE_ACCEPT,
1486 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1487 "Do you want to get online?"), item);
1488 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1489 gtk_label_new (txt), FALSE, FALSE, 0);
1490 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1493 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1494 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1495 // modest_platform_connect_and_wait ();
1498 gtk_widget_destroy (dialog);
1502 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1505 /* g_message ("%s %s", __FUNCTION__, link); */
1510 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1513 modest_platform_activate_uri (link);
1517 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1520 modest_platform_show_uri_popup (link);
1524 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1527 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1531 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1532 const gchar *address,
1535 /* g_message ("%s %s", __FUNCTION__, address); */
1539 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1541 TnyTransportAccount *transport_account;
1542 ModestMailOperation *mail_operation;
1544 gchar *account_name, *from;
1545 ModestAccountMgr *account_mgr;
1546 gchar *info_text = NULL;
1548 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1550 data = modest_msg_edit_window_get_msg_data (edit_window);
1552 account_mgr = modest_runtime_get_account_mgr();
1553 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1555 account_name = modest_account_mgr_get_default_account (account_mgr);
1556 if (!account_name) {
1557 g_printerr ("modest: no account found\n");
1558 modest_msg_edit_window_free_msg_data (edit_window, data);
1562 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1563 account_name = g_strdup (data->account_name);
1567 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1568 (modest_runtime_get_account_store(),
1570 TNY_ACCOUNT_TYPE_TRANSPORT));
1571 if (!transport_account) {
1572 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1573 g_free (account_name);
1574 modest_msg_edit_window_free_msg_data (edit_window, data);
1577 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1579 /* Create the mail operation */
1580 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1581 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1583 modest_mail_operation_save_to_drafts (mail_operation,
1594 data->priority_flags);
1597 g_free (account_name);
1598 g_object_unref (G_OBJECT (transport_account));
1599 g_object_unref (G_OBJECT (mail_operation));
1601 modest_msg_edit_window_free_msg_data (edit_window, data);
1603 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1604 modest_platform_information_banner (NULL, NULL, info_text);
1608 /* For instance, when clicking the Send toolbar button when editing a message: */
1610 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1612 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1614 if (!modest_msg_edit_window_check_names (edit_window))
1617 /* FIXME: Code added just for testing. The final version will
1618 use the send queue provided by tinymail and some
1620 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1621 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1623 account_name = modest_account_mgr_get_default_account (account_mgr);
1625 if (!account_name) {
1626 g_printerr ("modest: no account found\n");
1630 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1632 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1633 account_name = g_strdup (data->account_name);
1636 /* Get the currently-active transport account for this modest account: */
1637 TnyTransportAccount *transport_account =
1638 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1639 (modest_runtime_get_account_store(),
1641 if (!transport_account) {
1642 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1643 g_free (account_name);
1644 modest_msg_edit_window_free_msg_data (edit_window, data);
1648 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1650 /* mail content checks and dialogs */
1651 if (data->subject == NULL || data->subject[0] == '\0') {
1652 GtkResponseType response;
1653 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1654 _("mcen_nc_subject_is_empty_send"));
1655 if (response == GTK_RESPONSE_CANCEL) {
1656 g_free (account_name);
1661 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1662 GtkResponseType response;
1663 gchar *note_message;
1664 gchar *note_subject = data->subject;
1665 if (note_subject == NULL || note_subject[0] == '\0')
1666 note_subject = _("mail_va_no_subject");
1667 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1668 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1670 g_free (note_message);
1671 if (response == GTK_RESPONSE_CANCEL) {
1672 g_free (account_name);
1677 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1679 /* Create the mail operation */
1680 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1681 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1683 modest_mail_operation_send_new_mail (mail_operation,
1694 data->priority_flags);
1698 g_free (account_name);
1699 g_object_unref (G_OBJECT (transport_account));
1700 g_object_unref (G_OBJECT (mail_operation));
1702 modest_msg_edit_window_free_msg_data (edit_window, data);
1703 modest_msg_edit_window_set_sent (edit_window, TRUE);
1705 /* Save settings and close the window: */
1706 gtk_widget_destroy (GTK_WIDGET (edit_window));
1710 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1711 ModestMsgEditWindow *window)
1713 ModestMsgEditFormatState *format_state = NULL;
1715 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1716 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1718 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1721 format_state = modest_msg_edit_window_get_format_state (window);
1722 g_return_if_fail (format_state != NULL);
1724 format_state->bold = gtk_toggle_action_get_active (action);
1725 modest_msg_edit_window_set_format_state (window, format_state);
1726 g_free (format_state);
1731 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1732 ModestMsgEditWindow *window)
1734 ModestMsgEditFormatState *format_state = NULL;
1736 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1737 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1739 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1742 format_state = modest_msg_edit_window_get_format_state (window);
1743 g_return_if_fail (format_state != NULL);
1745 format_state->italics = gtk_toggle_action_get_active (action);
1746 modest_msg_edit_window_set_format_state (window, format_state);
1747 g_free (format_state);
1752 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1753 ModestMsgEditWindow *window)
1755 ModestMsgEditFormatState *format_state = NULL;
1757 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1758 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1760 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1763 format_state = modest_msg_edit_window_get_format_state (window);
1764 g_return_if_fail (format_state != NULL);
1766 format_state->bullet = gtk_toggle_action_get_active (action);
1767 modest_msg_edit_window_set_format_state (window, format_state);
1768 g_free (format_state);
1773 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1774 GtkRadioAction *selected,
1775 ModestMsgEditWindow *window)
1777 ModestMsgEditFormatState *format_state = NULL;
1778 GtkJustification value;
1780 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1782 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1785 value = gtk_radio_action_get_current_value (selected);
1787 format_state = modest_msg_edit_window_get_format_state (window);
1788 g_return_if_fail (format_state != NULL);
1790 format_state->justification = value;
1791 modest_msg_edit_window_set_format_state (window, format_state);
1792 g_free (format_state);
1796 modest_ui_actions_on_select_editor_color (GtkAction *action,
1797 ModestMsgEditWindow *window)
1799 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1800 g_return_if_fail (GTK_IS_ACTION (action));
1802 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1805 modest_msg_edit_window_select_color (window);
1809 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1810 ModestMsgEditWindow *window)
1812 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1813 g_return_if_fail (GTK_IS_ACTION (action));
1815 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1818 modest_msg_edit_window_select_background_color (window);
1822 modest_ui_actions_on_insert_image (GtkAction *action,
1823 ModestMsgEditWindow *window)
1825 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1826 g_return_if_fail (GTK_IS_ACTION (action));
1828 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1831 modest_msg_edit_window_insert_image (window);
1835 modest_ui_actions_on_attach_file (GtkAction *action,
1836 ModestMsgEditWindow *window)
1838 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1839 g_return_if_fail (GTK_IS_ACTION (action));
1841 modest_msg_edit_window_attach_file (window);
1845 modest_ui_actions_on_remove_attachments (GtkAction *action,
1846 ModestMsgEditWindow *window)
1848 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1849 g_return_if_fail (GTK_IS_ACTION (action));
1851 modest_msg_edit_window_remove_attachments (window, NULL);
1855 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1857 TnyFolderStore *parent_folder;
1858 GtkWidget *folder_view;
1860 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1862 folder_view = modest_main_window_get_child_widget (main_window,
1863 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1867 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1869 if (parent_folder) {
1870 gboolean finished = FALSE;
1872 gchar *folder_name = NULL, *suggested_name = NULL;
1874 /* Run the new folder dialog */
1876 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1881 if (result == GTK_RESPONSE_REJECT) {
1884 ModestMailOperation *mail_op;
1885 TnyFolder *new_folder = NULL;
1887 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1888 G_OBJECT(main_window));
1889 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1891 new_folder = modest_mail_operation_create_folder (mail_op,
1893 (const gchar *) folder_name);
1895 g_object_unref (new_folder);
1898 g_object_unref (mail_op);
1900 g_free (folder_name);
1904 g_object_unref (parent_folder);
1909 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1912 GObject *win = modest_mail_operation_get_source (mail_op);
1914 /* TODO: what should we do in case of this error ? */
1915 g_warning ("Invalid folder name");
1917 g_object_unref (win);
1921 modest_ui_actions_on_rename_folder (GtkAction *action,
1922 ModestMainWindow *main_window)
1924 TnyFolderStore *folder;
1925 GtkWidget *folder_view;
1926 GtkWidget *header_view;
1928 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1930 folder_view = modest_main_window_get_child_widget (main_window,
1931 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1935 header_view = modest_main_window_get_child_widget (main_window,
1936 MODEST_WIDGET_TYPE_HEADER_VIEW);
1941 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1943 if (folder && TNY_IS_FOLDER (folder)) {
1946 const gchar *current_name;
1948 current_name = tny_folder_get_name (TNY_FOLDER (folder));
1949 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
1950 current_name, &folder_name);
1952 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
1953 ModestMailOperation *mail_op;
1956 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
1957 G_OBJECT(main_window),
1958 modest_ui_actions_rename_folder_error_handler,
1962 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1965 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
1967 modest_mail_operation_rename_folder (mail_op,
1968 TNY_FOLDER (folder),
1969 (const gchar *) folder_name);
1971 g_object_unref (mail_op);
1972 g_free (folder_name);
1974 g_object_unref (folder);
1979 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1982 GObject *win = modest_mail_operation_get_source (mail_op);
1984 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1985 _("mail_in_ui_folder_delete_error"));
1986 g_object_unref (win);
1990 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1992 TnyFolderStore *folder;
1993 GtkWidget *folder_view;
1997 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1999 folder_view = modest_main_window_get_child_widget (main_window,
2000 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2004 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2006 /* Show an error if it's an account */
2007 if (!TNY_IS_FOLDER (folder)) {
2008 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2009 _("mail_in_ui_folder_delete_error"));
2014 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2015 tny_folder_get_name (TNY_FOLDER (folder)));
2016 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2017 (const gchar *) message);
2020 if (response == GTK_RESPONSE_OK) {
2021 ModestMailOperation *mail_op =
2022 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2023 G_OBJECT(main_window),
2024 modest_ui_actions_delete_folder_error_handler,
2027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2029 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2030 g_object_unref (G_OBJECT (mail_op));
2033 g_object_unref (G_OBJECT (folder));
2037 modest_ui_actions_on_delete_folder (GtkAction *action,
2038 ModestMainWindow *main_window)
2040 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2042 delete_folder (main_window, FALSE);
2046 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2048 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2050 delete_folder (main_window, TRUE);
2054 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2055 const gchar* server_account_name,
2060 ModestMainWindow *main_window)
2062 g_return_if_fail(server_account_name);
2063 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2065 /* Initalize output parameters: */
2072 #ifdef MODEST_PLATFORM_MAEMO
2073 /* Maemo uses a different (awkward) button order,
2074 * It should probably just use gtk_alternative_dialog_button_order ().
2076 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2080 GTK_RESPONSE_ACCEPT,
2082 GTK_RESPONSE_REJECT,
2085 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2089 GTK_RESPONSE_REJECT,
2091 GTK_RESPONSE_ACCEPT,
2093 #endif /* MODEST_PLATFORM_MAEMO */
2095 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2097 gchar *server_name = modest_server_account_get_hostname (
2098 modest_runtime_get_account_mgr(), server_account_name);
2099 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2100 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2105 /* This causes a warning because the logical ID has no %s in it,
2106 * though the translation does, but there is not much we can do about that: */
2107 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2108 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2111 g_free (server_name);
2115 gchar *initial_username = modest_server_account_get_username (
2116 modest_runtime_get_account_mgr(), server_account_name);
2118 GtkWidget *entry_username = gtk_entry_new ();
2119 if (initial_username)
2120 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2121 /* Dim this if a connection has ever succeeded with this username,
2122 * as per the UI spec: */
2123 const gboolean username_known =
2124 modest_server_account_get_username_has_succeeded(
2125 modest_runtime_get_account_mgr(), server_account_name);
2126 gtk_widget_set_sensitive (entry_username, !username_known);
2128 #ifdef MODEST_PLATFORM_MAEMO
2129 /* Auto-capitalization is the default, so let's turn it off: */
2130 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2132 /* Create a size group to be used by all captions.
2133 * Note that HildonCaption does not create a default size group if we do not specify one.
2134 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2135 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2137 GtkWidget *caption = hildon_caption_new (sizegroup,
2138 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2139 gtk_widget_show (entry_username);
2140 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2141 FALSE, FALSE, MODEST_MARGIN_HALF);
2142 gtk_widget_show (caption);
2144 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2146 #endif /* MODEST_PLATFORM_MAEMO */
2149 GtkWidget *entry_password = gtk_entry_new ();
2150 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2151 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2153 #ifdef MODEST_PLATFORM_MAEMO
2154 /* Auto-capitalization is the default, so let's turn it off: */
2155 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2156 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2158 caption = hildon_caption_new (sizegroup,
2159 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2160 gtk_widget_show (entry_password);
2161 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2162 FALSE, FALSE, MODEST_MARGIN_HALF);
2163 gtk_widget_show (caption);
2164 g_object_unref (sizegroup);
2166 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2168 #endif /* MODEST_PLATFORM_MAEMO */
2170 /* This is not in the Maemo UI spec:
2171 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2172 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2176 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2178 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2180 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2182 modest_server_account_set_username (
2183 modest_runtime_get_account_mgr(), server_account_name,
2186 const gboolean username_was_changed =
2187 (strcmp (*username, initial_username) != 0);
2188 if (username_was_changed) {
2189 g_warning ("%s: tinymail does not yet support changing the "
2190 "username in the get_password() callback.\n", __FUNCTION__);
2195 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2197 /* We do not save the password in the configuration,
2198 * because this function is only called for passwords that should
2199 * not be remembered:
2200 modest_server_account_set_password (
2201 modest_runtime_get_account_mgr(), server_account_name,
2220 /* This is not in the Maemo UI spec:
2221 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2227 gtk_widget_destroy (dialog);
2229 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2233 modest_ui_actions_on_cut (GtkAction *action,
2234 ModestWindow *window)
2236 GtkWidget *focused_widget;
2238 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2239 if (GTK_IS_EDITABLE (focused_widget)) {
2240 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2241 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2242 GtkTextBuffer *buffer;
2243 GtkClipboard *clipboard;
2245 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2246 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2247 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2248 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2249 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2250 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2251 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2256 modest_ui_actions_on_copy (GtkAction *action,
2257 ModestWindow *window)
2259 GtkClipboard *clipboard;
2260 GtkWidget *focused_widget;
2262 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2263 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2265 if (GTK_IS_LABEL (focused_widget)) {
2266 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2267 } else if (GTK_IS_EDITABLE (focused_widget)) {
2268 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2269 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2270 GtkTextBuffer *buffer;
2271 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2272 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2273 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2274 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2275 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2276 TnyIterator *iter = tny_list_create_iterator (header_list);
2277 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2278 TnyFolder *folder = tny_header_get_folder (header);
2279 TnyAccount *account = tny_folder_get_account (folder);
2280 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2281 /* If it's POP then ask */
2282 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2283 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2284 g_object_unref (account);
2285 g_object_unref (folder);
2286 g_object_unref (header);
2287 g_object_unref (iter);
2289 /* Check that the messages have been previously downloaded */
2290 gboolean continue_download = TRUE;
2292 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2293 if (continue_download)
2294 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2295 g_object_unref (header_list);
2296 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2297 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2300 /* Show information banner */
2301 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2306 modest_ui_actions_on_undo (GtkAction *action,
2307 ModestWindow *window)
2309 ModestEmailClipboard *clipboard = NULL;
2311 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2312 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2313 } if (MODEST_IS_MAIN_WINDOW (window)) {
2314 /* Clear clipboard source */
2315 clipboard = modest_runtime_get_email_clipboard ();
2316 modest_email_clipboard_clear (clipboard);
2319 g_return_if_reached ();
2324 modest_ui_actions_on_paste (GtkAction *action,
2325 ModestWindow *window)
2327 GtkWidget *focused_widget;
2328 ModestMailOperation *mail_op = NULL;
2330 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2331 if (GTK_IS_EDITABLE (focused_widget)) {
2332 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2333 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2334 GtkTextBuffer *buffer;
2335 GtkClipboard *clipboard;
2337 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2338 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2339 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2340 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2341 ModestEmailClipboard *clipboard = NULL;
2342 TnyFolder *src_folder = NULL;
2343 TnyFolderStore *folder_store = NULL;
2344 TnyList *data = NULL;
2345 gboolean delete = FALSE;
2347 /* Check clipboard source */
2348 clipboard = modest_runtime_get_email_clipboard ();
2349 if (modest_email_clipboard_cleared (clipboard))
2352 /* Get elements to paste */
2353 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2355 /* Create a new mail operation */
2356 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2357 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2360 /* Get destination folder */
2361 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2363 /* transfer messages */
2365 modest_mail_operation_xfer_msgs (mail_op,
2367 TNY_FOLDER (folder_store),
2372 } else if (src_folder != NULL) {
2373 modest_mail_operation_xfer_folder (mail_op,
2381 g_object_unref (data);
2382 if (src_folder != NULL)
2383 g_object_unref (src_folder);
2384 if (folder_store != NULL)
2385 g_object_unref (folder_store);
2390 modest_ui_actions_on_select_all (GtkAction *action,
2391 ModestWindow *window)
2393 GtkWidget *focused_widget;
2395 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2396 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2397 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2398 } else if (GTK_IS_LABEL (focused_widget)) {
2399 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2400 } else if (GTK_IS_EDITABLE (focused_widget)) {
2401 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2402 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2403 GtkTextBuffer *buffer;
2404 GtkTextIter start, end;
2406 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2407 gtk_text_buffer_get_start_iter (buffer, &start);
2408 gtk_text_buffer_get_end_iter (buffer, &end);
2409 gtk_text_buffer_select_range (buffer, &start, &end);
2410 } else if (GTK_IS_HTML (focused_widget)) {
2411 gtk_html_select_all (GTK_HTML (focused_widget));
2412 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2413 GtkWidget *header_view = focused_widget;
2414 GtkTreeSelection *selection = NULL;
2416 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2417 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2418 MODEST_WIDGET_TYPE_HEADER_VIEW);
2420 /* Select all messages */
2421 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2422 gtk_tree_selection_select_all (selection);
2424 /* Set focuse on header view */
2425 gtk_widget_grab_focus (header_view);
2431 modest_ui_actions_on_mark_as_read (GtkAction *action,
2432 ModestWindow *window)
2434 g_return_if_fail (MODEST_IS_WINDOW(window));
2436 /* Mark each header as read */
2437 do_headers_action (window, headers_action_mark_as_read, NULL);
2441 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2442 ModestWindow *window)
2444 g_return_if_fail (MODEST_IS_WINDOW(window));
2446 /* Mark each header as read */
2447 do_headers_action (window, headers_action_mark_as_unread, NULL);
2451 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2452 GtkRadioAction *selected,
2453 ModestWindow *window)
2457 value = gtk_radio_action_get_current_value (selected);
2458 if (MODEST_IS_WINDOW (window)) {
2459 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2463 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2464 GtkRadioAction *selected,
2465 ModestWindow *window)
2467 TnyHeaderFlags flags;
2468 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2470 flags = gtk_radio_action_get_current_value (selected);
2471 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2474 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2475 GtkRadioAction *selected,
2476 ModestWindow *window)
2480 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2482 file_format = gtk_radio_action_get_current_value (selected);
2483 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2488 modest_ui_actions_on_zoom_plus (GtkAction *action,
2489 ModestWindow *window)
2491 g_return_if_fail (MODEST_IS_WINDOW (window));
2493 modest_window_zoom_plus (MODEST_WINDOW (window));
2497 modest_ui_actions_on_zoom_minus (GtkAction *action,
2498 ModestWindow *window)
2500 g_return_if_fail (MODEST_IS_WINDOW (window));
2502 modest_window_zoom_minus (MODEST_WINDOW (window));
2506 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2507 ModestWindow *window)
2509 ModestWindowMgr *mgr;
2510 gboolean fullscreen, active;
2511 g_return_if_fail (MODEST_IS_WINDOW (window));
2513 mgr = modest_runtime_get_window_mgr ();
2515 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2516 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2518 if (active != fullscreen) {
2519 modest_window_mgr_set_fullscreen_mode (mgr, active);
2520 gtk_window_present (GTK_WINDOW (window));
2525 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2526 ModestWindow *window)
2528 ModestWindowMgr *mgr;
2529 gboolean fullscreen;
2531 g_return_if_fail (MODEST_IS_WINDOW (window));
2533 mgr = modest_runtime_get_window_mgr ();
2534 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2535 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2537 gtk_window_present (GTK_WINDOW (window));
2541 * Used by modest_ui_actions_on_details to call do_headers_action
2544 headers_action_show_details (TnyHeader *header,
2545 ModestWindow *window,
2552 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2555 gtk_widget_show_all (dialog);
2556 gtk_dialog_run (GTK_DIALOG (dialog));
2558 gtk_widget_destroy (dialog);
2562 * Show the folder details in a ModestDetailsDialog widget
2565 show_folder_details (TnyFolder *folder,
2571 dialog = modest_details_dialog_new_with_folder (window, folder);
2574 gtk_widget_show_all (dialog);
2575 gtk_dialog_run (GTK_DIALOG (dialog));
2577 gtk_widget_destroy (dialog);
2581 * Show the header details in a ModestDetailsDialog widget
2584 modest_ui_actions_on_details (GtkAction *action,
2587 TnyList * headers_list;
2591 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2594 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2597 g_object_unref (msg);
2599 headers_list = get_selected_headers (win);
2603 iter = tny_list_create_iterator (headers_list);
2605 header = TNY_HEADER (tny_iterator_get_current (iter));
2606 headers_action_show_details (header, win, NULL);
2607 g_object_unref (header);
2609 g_object_unref (iter);
2610 g_object_unref (headers_list);
2612 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2613 GtkWidget *folder_view, *header_view;
2615 /* Check which widget has the focus */
2616 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2617 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2618 if (gtk_widget_is_focus (folder_view)) {
2619 TnyFolderStore *folder_store
2620 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2621 if (!folder_store) {
2622 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2625 /* Show only when it's a folder */
2626 /* This function should not be called for account items,
2627 * because we dim the menu item for them. */
2628 if (TNY_IS_FOLDER (folder_store)) {
2629 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2632 g_object_unref (folder_store);
2635 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2636 MODEST_WIDGET_TYPE_HEADER_VIEW);
2637 /* Show details of each header */
2638 do_headers_action (win, headers_action_show_details, header_view);
2644 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2645 ModestMsgEditWindow *window)
2647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2649 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2653 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2654 ModestMsgEditWindow *window)
2656 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2658 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2662 modest_ui_actions_toggle_folders_view (GtkAction *action,
2663 ModestMainWindow *main_window)
2667 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2669 conf = modest_runtime_get_conf ();
2671 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2672 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2674 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2678 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2679 ModestWindow *window)
2681 gboolean active, fullscreen = FALSE;
2682 ModestWindowMgr *mgr;
2684 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2686 /* Check if we want to toggle the toolbar vuew in fullscreen
2688 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2689 "ViewShowToolbarFullScreen")) {
2693 /* Toggle toolbar */
2694 mgr = modest_runtime_get_window_mgr ();
2695 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2699 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2700 ModestMsgEditWindow *window)
2702 modest_msg_edit_window_select_font (window);
2706 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2707 const gchar *display_name,
2710 /* Do not change the application name if the widget has not
2711 the focus. This callback could be called even if the folder
2712 view has not the focus, because the handled signal could be
2713 emitted when the folder view is redrawn */
2714 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2716 gtk_window_set_title (window, display_name);
2718 gtk_window_set_title (window, " ");
2723 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2725 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2726 modest_msg_edit_window_select_contacts (window);
2730 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2732 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2733 modest_msg_edit_window_check_names (window);
2738 create_move_to_dialog (ModestWindow *win,
2739 GtkWidget *folder_view,
2740 GtkWidget **tree_view)
2742 GtkWidget *dialog, *scroll;
2744 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2746 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2748 GTK_RESPONSE_ACCEPT,
2750 GTK_RESPONSE_REJECT,
2753 /* Create scrolled window */
2754 scroll = gtk_scrolled_window_new (NULL, NULL);
2755 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2756 GTK_POLICY_AUTOMATIC,
2757 GTK_POLICY_AUTOMATIC);
2759 /* Create folder view */
2760 *tree_view = modest_platform_create_folder_view (NULL);
2762 /* It could happen that we're trying to move a message from a
2763 window (msg window for example) after the main window was
2764 closed, so we can not just get the model of the folder
2766 if (MODEST_IS_FOLDER_VIEW (folder_view))
2767 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2768 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2770 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2771 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2773 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2775 /* Add scroll to dialog */
2776 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2777 scroll, FALSE, FALSE, 0);
2779 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2781 /* Select INBOX or local account */
2782 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2788 * Returns TRUE if at least one of the headers of the list belongs to
2789 * a message that has been fully retrieved.
2792 has_retrieved_msgs (TnyList *list)
2795 gboolean found = FALSE;
2797 iter = tny_list_create_iterator (list);
2798 while (tny_iterator_is_done (iter) && !found) {
2800 TnyHeaderFlags flags;
2802 header = TNY_HEADER (tny_iterator_get_current (iter));
2803 flags = tny_header_get_flags (header);
2804 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2808 tny_iterator_next (iter);
2810 g_object_unref (iter);
2816 * Shows a confirmation dialog to the user when we're moving messages
2817 * from a remote server to the local storage. Returns the dialog
2818 * response. If it's other kind of movement the it always returns
2822 msgs_move_to_confirmation (GtkWindow *win,
2823 TnyFolder *dest_folder,
2826 gint response = GTK_RESPONSE_OK;
2828 /* If the destination is a local folder */
2829 if (modest_tny_folder_is_local_folder (dest_folder)) {
2830 TnyFolder *src_folder;
2834 /* Get source folder */
2835 iter = tny_list_create_iterator (headers);
2836 header = TNY_HEADER (tny_iterator_get_current (iter));
2837 src_folder = tny_header_get_folder (header);
2838 g_object_unref (header);
2839 g_object_unref (iter);
2841 /* if no src_folder, message may be an attahcment */
2842 if (src_folder == NULL)
2843 return GTK_RESPONSE_CANCEL;
2845 /* If the source is a remote folder */
2846 if (!modest_tny_folder_is_local_folder (src_folder)) {
2847 const gchar *message;
2849 if (has_retrieved_msgs (headers))
2850 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2851 tny_list_get_length (headers));
2853 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2854 tny_list_get_length (headers));
2856 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2857 (const gchar *) message);
2859 g_object_unref (src_folder);
2866 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2868 ModestMsgViewWindow *self = NULL;
2869 gboolean last, first;
2871 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2872 self = MODEST_MSG_VIEW_WINDOW (object);
2874 last = modest_msg_view_window_last_message_selected (self);
2875 first = modest_msg_view_window_first_message_selected (self);
2877 /* No more messages to view, so close this window */
2878 /* gboolean ret_value; */
2879 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2880 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
2882 modest_msg_view_window_select_previous_message (self);
2884 modest_msg_view_window_select_next_message (self);
2888 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2891 GObject *win = modest_mail_operation_get_source (mail_op);
2893 /* TODO: show error message */
2894 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2895 _("mail_in_ui_folder_move_target_error"));
2896 g_object_unref (win);
2900 open_msg_for_purge_cb (ModestMailOperation *mail_op,
2907 gint pending_purges = 0;
2908 gboolean some_purged = FALSE;
2909 ModestWindow *win = MODEST_WINDOW (user_data);
2913 /* Once the message has been retrieved for purging, we check if
2914 * it's all ok for purging */
2916 parts = tny_simple_list_new ();
2917 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
2918 iter = tny_list_create_iterator (parts);
2920 while (!tny_iterator_is_done (iter)) {
2922 part = TNY_MIME_PART (tny_iterator_get_current (iter));
2923 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
2924 if (tny_mime_part_is_purged (part))
2929 tny_iterator_next (iter);
2932 if (pending_purges>0) {
2934 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
2936 if (response == GTK_RESPONSE_OK) {
2937 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
2938 tny_iterator_first (iter);
2939 while (!tny_iterator_is_done (iter)) {
2942 part = TNY_MIME_PART (tny_iterator_get_current (iter));
2943 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
2944 tny_mime_part_set_purged (part);
2945 tny_iterator_next (iter);
2948 tny_msg_rewrite_cache (msg);
2951 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
2954 /* remove attachments */
2955 tny_iterator_first (iter);
2956 while (!tny_iterator_is_done (iter)) {
2959 part = TNY_MIME_PART (tny_iterator_get_current (iter));
2960 g_object_unref (part);
2961 tny_iterator_next (iter);
2964 g_object_unref (iter);
2965 g_object_unref (parts);
2969 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
2970 ModestMainWindow *win)
2972 GtkWidget *header_view;
2973 TnyList *header_list;
2976 TnyHeaderFlags flags;
2977 ModestWindow *msg_view_window = NULL;
2980 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2982 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2983 MODEST_WIDGET_TYPE_HEADER_VIEW);
2985 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2987 if (tny_list_get_length (header_list) == 1) {
2988 iter = tny_list_create_iterator (header_list);
2989 header = TNY_HEADER (tny_iterator_get_current (iter));
2990 g_object_unref (iter);
2995 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
2996 header, &msg_view_window);
2997 flags = tny_header_get_flags (header);
2998 if (!(flags & TNY_HEADER_FLAG_CACHED))
3001 if (msg_view_window != NULL)
3002 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3004 /* do nothing; uid was registered before, so window is probably on it's way */
3005 g_warning ("debug: header %p has already been registered", header);
3008 ModestMailOperation *mail_op = NULL;
3009 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3010 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
3012 modest_ui_actions_get_msgs_full_error_handler,
3014 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3015 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3017 g_object_unref (mail_op);
3020 g_object_unref (header);
3022 g_object_unref (header_list);
3026 * UI handler for the "Move to" action when invoked from the
3030 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3031 ModestMainWindow *win)
3033 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3034 GtkWidget *header_view = NULL;
3036 TnyFolderStore *folder_store = NULL;
3037 ModestMailOperation *mail_op = NULL;
3039 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3041 /* Get the folder view */
3042 folder_view = modest_main_window_get_child_widget (win,
3043 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3045 /* Get header view */
3046 header_view = modest_main_window_get_child_widget (win,
3047 MODEST_WIDGET_TYPE_HEADER_VIEW);
3049 /* Create and run the dialog */
3050 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3051 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3052 result = gtk_dialog_run (GTK_DIALOG(dialog));
3053 g_object_ref (tree_view);
3055 /* We do this to save an indentation level ;-) */
3056 if (result != GTK_RESPONSE_ACCEPT)
3059 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3061 if (TNY_IS_ACCOUNT (folder_store) &&
3062 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3065 /* Get folder or messages to transfer */
3066 if (gtk_widget_is_focus (folder_view)) {
3067 TnyFolderStore *src_folder;
3068 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3070 /* Clean folder on header view before moving it */
3071 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3073 if (TNY_IS_FOLDER (src_folder)) {
3075 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3077 modest_ui_actions_move_folder_error_handler,
3079 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3081 modest_mail_operation_xfer_folder (mail_op,
3082 TNY_FOLDER (src_folder),
3085 /* Unref mail operation */
3086 g_object_unref (G_OBJECT (mail_op));
3090 g_object_unref (G_OBJECT (src_folder));
3092 if (gtk_widget_is_focus (header_view)) {
3096 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3098 /* Ask for user confirmation */
3099 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3100 TNY_FOLDER (folder_store),
3103 /* Transfer messages */
3104 if (response == GTK_RESPONSE_OK) {
3105 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3106 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3109 modest_mail_operation_xfer_msgs (mail_op,
3111 TNY_FOLDER (folder_store),
3116 g_object_unref (G_OBJECT (mail_op));
3118 g_object_unref (headers);
3122 if (folder_store != NULL)
3123 g_object_unref (folder_store);
3124 gtk_widget_destroy (dialog);
3129 * UI handler for the "Move to" action when invoked from the
3130 * ModestMsgViewWindow
3133 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3134 ModestMsgViewWindow *win)
3136 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3138 ModestMainWindow *main_window;
3142 /* Get the folder view */
3143 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3145 folder_view = modest_main_window_get_child_widget (main_window,
3146 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3150 /* Create and run the dialog */
3151 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3152 result = gtk_dialog_run (GTK_DIALOG(dialog));
3153 g_object_ref (tree_view);
3155 if (result == GTK_RESPONSE_ACCEPT) {
3156 TnyFolderStore *folder_store;
3159 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3161 /* Create header list */
3162 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3164 headers = tny_simple_list_new ();
3165 tny_list_prepend (headers, G_OBJECT (header));
3166 g_object_unref (header);
3168 /* Ask user for confirmation. MSG-NOT404 */
3169 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3170 TNY_FOLDER (folder_store),
3173 /* Transfer current msg */
3174 if (response == GTK_RESPONSE_OK) {
3175 ModestMailOperation *mail_op;
3177 /* Create mail op */
3178 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3179 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3182 /* Transfer messages */
3183 modest_mail_operation_xfer_msgs (mail_op,
3185 TNY_FOLDER (folder_store),
3187 transfer_msgs_from_viewer_cb,
3189 g_object_unref (G_OBJECT (mail_op));
3191 g_object_unref (headers);
3192 g_object_unref (folder_store);
3194 gtk_widget_destroy (dialog);
3198 modest_ui_actions_on_move_to (GtkAction *action,
3201 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3202 MODEST_IS_MSG_VIEW_WINDOW (win));
3204 if (MODEST_IS_MAIN_WINDOW (win))
3205 modest_ui_actions_on_main_window_move_to (action,
3206 MODEST_MAIN_WINDOW (win));
3208 modest_ui_actions_on_msg_view_window_move_to (action,
3209 MODEST_MSG_VIEW_WINDOW (win));
3213 * Calls #HeadersFunc for each header already selected in the main
3214 * window or the message currently being shown in the msg view window
3217 do_headers_action (ModestWindow *win,
3221 TnyList *headers_list;
3227 headers_list = get_selected_headers (win);
3231 /* Get the folder */
3232 iter = tny_list_create_iterator (headers_list);
3233 header = TNY_HEADER (tny_iterator_get_current (iter));
3234 folder = tny_header_get_folder (header);
3235 g_object_unref (header);
3237 /* Call the function for each header */
3238 while (!tny_iterator_is_done (iter)) {
3239 header = TNY_HEADER (tny_iterator_get_current (iter));
3240 func (header, win, user_data);
3241 g_object_unref (header);
3242 tny_iterator_next (iter);
3245 /* Trick: do a poke status in order to speed up the signaling
3247 tny_folder_poke_status (folder);
3250 g_object_unref (folder);
3251 g_object_unref (iter);
3252 g_object_unref (headers_list);
3256 modest_ui_actions_view_attachment (GtkAction *action,
3257 ModestWindow *window)
3259 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3260 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3262 /* not supported window for this action */
3263 g_return_if_reached ();
3268 modest_ui_actions_save_attachments (GtkAction *action,
3269 ModestWindow *window)
3271 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3272 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3274 /* not supported window for this action */
3275 g_return_if_reached ();
3280 modest_ui_actions_remove_attachments (GtkAction *action,
3281 ModestWindow *window)
3283 if (MODEST_IS_MAIN_WINDOW (window)) {
3284 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3285 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3286 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3288 /* not supported window for this action */
3289 g_return_if_reached ();
3294 modest_ui_actions_on_settings (GtkAction *action,
3299 dialog = modest_platform_get_global_settings_dialog ();
3300 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3301 gtk_widget_show_all (dialog);
3303 gtk_dialog_run (GTK_DIALOG (dialog));
3305 gtk_widget_destroy (dialog);
3309 modest_ui_actions_on_help (GtkAction *action,
3312 const gchar *help_id = NULL;
3314 if (MODEST_IS_MAIN_WINDOW (win)) {
3315 const gchar *action_name;
3316 action_name = gtk_action_get_name (action);
3318 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3319 !strcmp (action_name, "HeaderViewCSMHelp")) {
3320 GtkWidget *folder_view;
3321 TnyFolderStore *folder_store;
3322 /* Get selected folder */
3323 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3324 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3325 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3327 /* Switch help_id */
3328 if (TNY_IS_FOLDER (folder_store)) {
3329 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3330 case TNY_FOLDER_TYPE_NORMAL:
3331 help_id = "applications_email_userfolder";
3333 case TNY_FOLDER_TYPE_INBOX:
3334 help_id = "applications_email_inbox";
3336 case TNY_FOLDER_TYPE_OUTBOX:
3337 help_id = "applications_email_outbox";
3339 case TNY_FOLDER_TYPE_SENT:
3340 help_id = "applications_email_sent";
3342 case TNY_FOLDER_TYPE_DRAFTS:
3343 help_id = "applications_email_drafts";
3345 case TNY_FOLDER_TYPE_ARCHIVE:
3346 help_id = "applications_email_archive";
3352 g_object_unref (folder_store);
3354 help_id = "applications_email_mainview";
3356 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3357 help_id = "applications_email_viewer";
3358 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3359 help_id = "applications_email_editor";
3361 modest_platform_show_help (GTK_WINDOW (win), help_id);
3365 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3366 ModestWindow *window)
3368 ModestMailOperation *mail_op;
3372 headers = get_selected_headers (window);
3376 /* Create mail operation */
3377 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3379 modest_ui_actions_get_msgs_full_error_handler,
3381 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3382 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3385 g_object_unref (headers);
3386 g_object_unref (mail_op);
3390 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3391 ModestWindow *window)
3393 g_return_if_fail (MODEST_IS_WINDOW (window));
3396 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3400 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3401 ModestWindow *window)
3403 g_return_if_fail (MODEST_IS_WINDOW (window));
3406 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3410 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3411 ModestWindow *window)
3413 g_return_if_fail (MODEST_IS_WINDOW (window));
3416 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3420 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3421 ModestWindow *window)
3423 g_return_if_fail (MODEST_IS_WINDOW (window));
3426 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3430 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3431 ModestWindow *window)
3433 g_return_if_fail (MODEST_IS_WINDOW (window));
3436 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3440 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3441 ModestWindow *window)
3443 g_return_if_fail (MODEST_IS_WINDOW (window));
3446 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3450 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3451 ModestWindow *window)
3453 g_return_if_fail (MODEST_IS_WINDOW (window));
3456 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3460 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3461 ModestWindow *window)
3463 g_return_if_fail (MODEST_IS_WINDOW (window));
3466 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3470 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3472 g_return_if_fail (MODEST_IS_WINDOW (window));
3475 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3479 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3481 g_return_if_fail (MODEST_IS_WINDOW (window));
3483 modest_platform_show_search_messages (GTK_WINDOW (window));
3487 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3489 g_return_if_fail (MODEST_IS_WINDOW (win));
3490 modest_platform_show_addressbook (GTK_WINDOW (win));
3495 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3496 ModestWindow *window)
3498 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3500 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3504 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3505 ModestMailOperationState *state,
3508 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3510 /* Set send/receive operation finished */
3511 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3512 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));