1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _PasteAsAttachmentHelper {
107 ModestMsgEditWindow *window;
109 } PasteAsAttachmentHelper;
113 * The do_headers_action uses this kind of functions to perform some
114 * action to each member of a list of headers
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
118 static void do_headers_action (ModestWindow *win,
122 static void open_msg_cb (ModestMailOperation *mail_op,
127 static void reply_forward_cb (ModestMailOperation *mail_op,
132 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
134 static void folder_refreshed_cb (ModestMailOperation *mail_op,
138 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
139 ModestMailOperationState *state,
143 download_uncached_messages (TnyList *header_list, GtkWindow *win,
148 msgs_move_to_confirmation (GtkWindow *win,
149 TnyFolder *dest_folder,
154 run_account_setup_wizard (ModestWindow *win)
156 ModestEasysetupWizardDialog *wizard;
158 g_return_if_fail (MODEST_IS_WINDOW(win));
160 wizard = modest_easysetup_wizard_dialog_new ();
161 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
163 /* Don't make this a modal window, because secondary windows will then
164 * be unusable, freezing the UI: */
165 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
167 gtk_dialog_run (GTK_DIALOG (wizard));
168 gtk_widget_destroy (GTK_WIDGET (wizard));
173 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
176 const gchar *authors[] = {
177 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
180 about = gtk_about_dialog_new ();
181 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
182 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
183 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
184 _("Copyright (c) 2006, Nokia Corporation\n"
185 "All rights reserved."));
186 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
187 _("a modest e-mail client\n\n"
188 "design and implementation: Dirk-Jan C. Binnema\n"
189 "contributions from the fine people at KC and Ig\n"
190 "uses the tinymail email framework written by Philip van Hoof"));
191 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
192 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
193 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
194 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
196 gtk_dialog_run (GTK_DIALOG (about));
197 gtk_widget_destroy(about);
201 * Gets the list of currently selected messages. If the win is the
202 * main window, then it returns a newly allocated list of the headers
203 * selected in the header view. If win is the msg view window, then
204 * the value returned is a list with just a single header.
206 * The caller of this funcion must free the list.
209 get_selected_headers (ModestWindow *win)
211 if (MODEST_IS_MAIN_WINDOW(win)) {
212 GtkWidget *header_view;
214 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
215 MODEST_WIDGET_TYPE_HEADER_VIEW);
216 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
218 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
219 /* for MsgViewWindows, we simply return a list with one element */
221 TnyList *list = NULL;
223 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
224 if (header != NULL) {
225 list = tny_simple_list_new ();
226 tny_list_prepend (list, G_OBJECT(header));
227 g_object_unref (G_OBJECT(header));
237 headers_action_mark_as_read (TnyHeader *header,
241 TnyHeaderFlags flags;
243 g_return_if_fail (TNY_IS_HEADER(header));
245 flags = tny_header_get_flags (header);
246 if (flags & TNY_HEADER_FLAG_SEEN) return;
247 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
251 headers_action_mark_as_unread (TnyHeader *header,
255 TnyHeaderFlags flags;
257 g_return_if_fail (TNY_IS_HEADER(header));
259 flags = tny_header_get_flags (header);
260 if (flags & TNY_HEADER_FLAG_SEEN) {
261 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
265 /** A convenience method, because deleting a message is
266 * otherwise complicated, and it's best to change it in one place
269 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
271 ModestMailOperation *mail_op = NULL;
272 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
273 win ? G_OBJECT(win) : NULL);
274 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
277 /* Always delete. TODO: Move to trash still not supported */
278 modest_mail_operation_remove_msg (mail_op, header, FALSE);
279 g_object_unref (G_OBJECT (mail_op));
283 headers_action_delete (TnyHeader *header,
287 modest_do_message_delete (header, win);
290 /** After deleing a message that is currently visible in a window,
291 * show the next message from the list, or close the window if there are no more messages.
293 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
295 /* Close msg view window or select next */
296 if (modest_msg_view_window_last_message_selected (win) &&
297 modest_msg_view_window_first_message_selected (win)) {
298 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
300 if (!modest_msg_view_window_select_next_message (win)) {
302 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
308 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
310 TnyList *header_list = NULL;
311 TnyIterator *iter = NULL;
312 TnyHeader *header = NULL;
313 gchar *message = NULL;
316 ModestWindowMgr *mgr;
317 GtkWidget *header_view = NULL;
319 g_return_if_fail (MODEST_IS_WINDOW(win));
321 /* Check first if the header view has the focus */
322 if (MODEST_IS_MAIN_WINDOW (win)) {
324 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
325 MODEST_WIDGET_TYPE_HEADER_VIEW);
326 if (!gtk_widget_is_focus (header_view))
330 /* Get the headers, either from the header view (if win is the main window),
331 * or from the message view window: */
332 header_list = get_selected_headers (win);
333 if (!header_list) return;
335 /* Check if any of the headers are already opened, or in the process of being opened */
336 if (MODEST_IS_MAIN_WINDOW (win)) {
338 iter = tny_list_create_iterator (header_list);
340 mgr = modest_runtime_get_window_mgr ();
341 while (!tny_iterator_is_done (iter) && !found) {
342 header = TNY_HEADER (tny_iterator_get_current (iter));
344 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
345 g_object_unref (header);
348 tny_iterator_next (iter);
350 g_object_unref (iter);
355 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
356 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
358 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
362 g_object_unref (header_list);
368 if (tny_list_get_length(header_list) == 1) {
369 iter = tny_list_create_iterator (header_list);
370 header = TNY_HEADER (tny_iterator_get_current (iter));
372 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
373 g_object_unref (header);
376 g_object_unref (iter);
378 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
379 tny_list_get_length(header_list)), desc);
381 /* Confirmation dialog */
382 printf("DEBUG: %s\n", __FUNCTION__);
383 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
387 if (response == GTK_RESPONSE_OK) {
388 ModestWindow *main_window = NULL;
389 ModestWindowMgr *mgr = NULL;
390 GtkTreeModel *model = NULL;
391 GtkTreeSelection *sel = NULL;
392 GList *sel_list = NULL, *tmp = NULL;
393 GtkTreeRowReference *row_reference = NULL;
394 GtkTreePath *next_path = NULL;
395 TnyFolder *folder = NULL;
398 /* Find last selected row */
399 if (MODEST_IS_MAIN_WINDOW (win)) {
400 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
401 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
402 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
403 for (tmp=sel_list; tmp; tmp=tmp->next) {
404 if (tmp->next == NULL) {
405 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
406 gtk_tree_path_next (next_path);
407 row_reference = gtk_tree_row_reference_new (model, next_path);
408 gtk_tree_path_free (next_path);
413 /* Remove each header. If it's a view window header_view == NULL */
414 do_headers_action (win, headers_action_delete, header_view);
416 /* refresh the header view (removing marked-as-deleted)*/
417 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
419 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
420 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
422 /* Get main window */
423 mgr = modest_runtime_get_window_mgr ();
424 main_window = modest_window_mgr_get_main_window (mgr);
427 /* Move cursor to next row */
430 /* Select next row */
431 if (gtk_tree_row_reference_valid (row_reference)) {
432 next_path = gtk_tree_row_reference_get_path (row_reference);
433 gtk_tree_selection_select_path (sel, next_path);
434 gtk_tree_path_free (next_path);
436 if (row_reference != NULL)
437 gtk_tree_row_reference_free (row_reference);
440 /* Get folder from first header and sync it */
441 iter = tny_list_create_iterator (header_list);
442 header = TNY_HEADER (tny_iterator_get_current (iter));
443 folder = tny_header_get_folder (header);
444 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
445 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
446 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
447 /* else if (TNY_IS_CAMEL_POP_FOLDER (folder)) */
448 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
449 /* tny_folder_sync (folder, TRUE, &err); /\* TRUE --> expunge *\/ */
452 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
453 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
456 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
460 g_object_unref (header);
461 g_object_unref (iter);
462 g_object_unref (folder);
464 /* Update toolbar dimming state */
465 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
468 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
469 g_list_free (sel_list);
475 g_object_unref (header_list);
481 /* delete either message or folder, based on where we are */
483 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
485 g_return_if_fail (MODEST_IS_WINDOW(win));
487 /* Check first if the header view has the focus */
488 if (MODEST_IS_MAIN_WINDOW (win)) {
490 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
491 MODEST_WIDGET_TYPE_FOLDER_VIEW);
492 if (gtk_widget_is_focus (w)) {
493 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
497 modest_ui_actions_on_delete_message (action, win);
503 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
505 #ifdef MODEST_PLATFORM_MAEMO
506 modest_osso_save_state();
507 #endif /* MODEST_PLATFORM_MAEMO */
509 g_debug ("closing down, clearing %d item(s) from operation queue",
510 modest_mail_operation_queue_num_elements
511 (modest_runtime_get_mail_operation_queue()));
513 /* cancel all outstanding operations */
514 modest_mail_operation_queue_cancel_all
515 (modest_runtime_get_mail_operation_queue());
517 g_debug ("queue has been cleared");
519 /* note: when modest-tny-account-store is finalized,
520 it will automatically set all network connections
527 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
531 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
533 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
534 /* gtk_widget_destroy (GTK_WIDGET (win)); */
535 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
536 /* gboolean ret_value; */
537 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
538 /* } else if (MODEST_IS_WINDOW (win)) { */
539 /* gtk_widget_destroy (GTK_WIDGET (win)); */
541 /* g_return_if_reached (); */
546 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
548 GtkClipboard *clipboard = NULL;
549 gchar *selection = NULL;
551 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
552 selection = gtk_clipboard_wait_for_text (clipboard);
554 /* Question: why is the clipboard being used here?
555 * It doesn't really make a lot of sense. */
559 modest_address_book_add_address (selection);
565 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
567 /* This is currently only implemented for Maemo */
568 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
569 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
570 run_account_setup_wizard (win);
573 /* Show the list of accounts: */
574 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
575 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
577 /* Don't make this a modal window, because secondary windows will then
578 * be unusable, freezing the UI: */
579 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
580 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
583 GtkWidget *dialog, *label;
585 /* Create the widgets */
587 dialog = gtk_dialog_new_with_buttons ("Message",
589 GTK_DIALOG_DESTROY_WITH_PARENT,
593 label = gtk_label_new ("Hello World!");
595 /* Ensure that the dialog box is destroyed when the user responds. */
597 g_signal_connect_swapped (dialog, "response",
598 G_CALLBACK (gtk_widget_destroy),
601 /* Add the label, and show everything we've added to the dialog. */
603 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
605 gtk_widget_show_all (dialog);
606 #endif /* MODEST_PLATFORM_MAEMO */
610 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
612 ModestWindow *main_window = MODEST_WINDOW (user_data);
614 /* Save any changes. */
615 modest_connection_specific_smtp_window_save_server_accounts (
616 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
617 modest_window_get_active_account (main_window));
618 gtk_widget_destroy (GTK_WIDGET (window));
624 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
626 /* This is currently only implemented for Maemo,
627 * because it requires an API (libconic) to detect different connection
630 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
632 /* Create the window if necessary: */
633 const gchar *active_account_name = modest_window_get_active_account (win);
635 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
636 * or show the default account?
637 * If we show the default account then the account name should be shown in
638 * the window when we show it. */
639 if (!active_account_name) {
640 g_warning ("%s: No account is active.", __FUNCTION__);
644 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
645 modest_connection_specific_smtp_window_fill_with_connections (
646 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
647 modest_runtime_get_account_mgr(),
648 active_account_name);
650 /* Show the window: */
651 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
652 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
653 gtk_widget_show (specific_window);
655 /* Save changes when the window is hidden: */
656 g_signal_connect (specific_window, "hide",
657 G_CALLBACK (on_smtp_servers_window_hide), win);
658 #endif /* MODEST_PLATFORM_MAEMO */
662 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
664 ModestWindow *msg_win = NULL;
666 TnyFolder *folder = NULL;
667 gchar *account_name = NULL;
668 gchar *from_str = NULL;
669 /* GError *err = NULL; */
670 TnyAccount *account = NULL;
671 ModestWindowMgr *mgr;
672 gchar *signature = NULL, *blank_and_signature = NULL;
674 /* if there are no accounts yet, just show the wizard */
675 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
676 run_account_setup_wizard (win);
680 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
682 account_name = g_strdup (modest_window_get_active_account (win));
684 g_printerr ("modest: no account found\n");
688 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
690 TNY_ACCOUNT_TYPE_STORE);
692 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
696 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
698 g_printerr ("modest: failed get from string for '%s'\n", account_name);
702 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
703 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
704 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
705 MODEST_ACCOUNT_SIGNATURE, FALSE);
706 blank_and_signature = g_strconcat ("\n", signature, NULL);
709 blank_and_signature = g_strdup ("");
712 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
714 g_printerr ("modest: failed to create new msg\n");
718 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
720 g_printerr ("modest: failed to find Drafts folder\n");
725 /* Create and register edit window */
726 /* This is destroyed by TOOD. */
727 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
728 mgr = modest_runtime_get_window_mgr ();
729 modest_window_mgr_register_window (mgr, msg_win);
732 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
734 gtk_widget_show_all (GTK_WIDGET (msg_win));
737 g_free (account_name);
739 g_free (blank_and_signature);
741 g_object_unref (msg_win);
743 g_object_unref (G_OBJECT(account));
745 g_object_unref (G_OBJECT(msg));
747 g_object_unref (G_OBJECT(folder));
751 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
755 ModestMailOperationStatus status;
757 /* If there is no message or the operation was not successful */
758 status = modest_mail_operation_get_status (mail_op);
759 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
761 /* Remove the header from the preregistered uids */
762 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
772 open_msg_cb (ModestMailOperation *mail_op,
777 ModestWindowMgr *mgr = NULL;
778 ModestWindow *parent_win = NULL;
779 ModestWindow *win = NULL;
780 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
781 gchar *account = NULL;
784 /* Do nothing if there was any problem with the mail
785 operation. The error will be shown by the error_handler of
786 the mail operation */
787 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
791 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
792 folder = tny_header_get_folder (header);
794 /* Mark header as read */
795 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
798 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
800 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
802 /* Gets folder type (OUTBOX headers will be opened in edit window */
803 if (modest_tny_folder_is_local_folder (folder))
804 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
806 /* If the header is in the drafts folder then open the editor,
807 else the message view window */
808 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
809 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
810 /* we cannot edit without a valid account... */
811 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
812 run_account_setup_wizard(parent_win);
815 win = modest_msg_edit_window_new (msg, account, TRUE);
818 gchar *uid = modest_tny_folder_get_header_unique_id (header);
820 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
821 GtkWidget *header_view;
822 GtkTreeSelection *sel;
823 GList *sel_list = NULL;
826 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
827 MODEST_WIDGET_TYPE_HEADER_VIEW);
829 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
830 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
832 if (sel_list != NULL) {
833 GtkTreeRowReference *row_reference;
835 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
836 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
837 g_list_free (sel_list);
839 win = modest_msg_view_window_new_with_header_model (msg,
844 gtk_tree_row_reference_free (row_reference);
846 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
849 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
854 /* Register and show new window */
856 mgr = modest_runtime_get_window_mgr ();
857 modest_window_mgr_register_window (mgr, win);
858 g_object_unref (win);
859 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
860 gtk_widget_show_all (GTK_WIDGET(win));
863 /* Update toolbar dimming state */
864 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
865 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
871 g_object_unref (parent_win);
872 g_object_unref (folder);
876 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
880 GObject *win = modest_mail_operation_get_source (mail_op);
882 error = modest_mail_operation_get_error (mail_op);
883 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
885 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
887 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
890 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
891 _("mail_ni_ui_folder_get_msg_folder_error"));
895 g_object_unref (win);
899 * This function is used by both modest_ui_actions_on_open and
900 * modest_ui_actions_on_header_activated. This way we always do the
901 * same when trying to open messages.
904 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
906 ModestWindowMgr *mgr = NULL;
907 TnyIterator *iter = NULL;
908 ModestMailOperation *mail_op = NULL;
909 TnyList *not_opened_headers = NULL;
910 TnyHeaderFlags flags = 0;
912 /* Look if we already have a message view for each header. If
913 true, then remove the header from the list of headers to
915 mgr = modest_runtime_get_window_mgr ();
916 iter = tny_list_create_iterator (headers);
917 not_opened_headers = tny_simple_list_new ();
919 while (!tny_iterator_is_done (iter)) {
921 ModestWindow *window = NULL;
922 TnyHeader *header = NULL;
923 gboolean found = FALSE;
925 header = TNY_HEADER (tny_iterator_get_current (iter));
927 flags = tny_header_get_flags (header);
930 found = modest_window_mgr_find_registered_header (mgr, header, &window);
932 /* Do not open again the message and present the
933 window to the user */
936 gtk_window_present (GTK_WINDOW (window));
938 /* the header has been registered already, we don't do
939 * anything but wait for the window to come up*/
940 g_debug ("header %p already registered, waiting for window", header);
942 tny_list_append (not_opened_headers, G_OBJECT (header));
946 g_object_unref (header);
948 tny_iterator_next (iter);
950 g_object_unref (iter);
953 /* If some messages would have to be downloaded, ask the user to
954 * make a connection. It's generally easier to do this here (in the mainloop)
955 * than later in a thread:
957 if (tny_list_get_length (not_opened_headers) > 0) {
959 gboolean found = FALSE;
961 iter = tny_list_create_iterator (not_opened_headers);
962 while (!tny_iterator_is_done (iter) && !found) {
963 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
964 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
967 tny_iterator_next (iter);
969 g_object_unref (header);
971 g_object_unref (iter);
973 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
974 g_object_unref (not_opened_headers);
979 /* Register the headers before actually creating the windows: */
980 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
981 while (!tny_iterator_is_done (iter_not_opened)) {
982 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
984 modest_window_mgr_register_header (mgr, header);
985 g_object_unref (header);
988 tny_iterator_next (iter_not_opened);
990 g_object_unref (iter_not_opened);
991 iter_not_opened = NULL;
993 /* Open each message */
994 if (tny_list_get_length (not_opened_headers) > 0) {
995 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
997 modest_ui_actions_get_msgs_full_error_handler,
999 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1000 if (tny_list_get_length (not_opened_headers) > 1) {
1001 modest_mail_operation_get_msgs_full (mail_op,
1007 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1008 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1009 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1010 g_object_unref (header);
1011 g_object_unref (iter);
1013 g_object_unref (mail_op);
1017 if (not_opened_headers != NULL)
1018 g_object_unref (not_opened_headers);
1022 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1027 headers = get_selected_headers (win);
1032 _modest_ui_actions_open (headers, win);
1034 g_object_unref(headers);
1039 free_reply_forward_helper (gpointer data)
1041 ReplyForwardHelper *helper;
1043 helper = (ReplyForwardHelper *) data;
1044 g_free (helper->account_name);
1045 g_slice_free (ReplyForwardHelper, helper);
1049 reply_forward_cb (ModestMailOperation *mail_op,
1055 ReplyForwardHelper *rf_helper;
1056 ModestWindow *msg_win = NULL;
1057 ModestEditType edit_type;
1059 TnyAccount *account = NULL;
1060 ModestWindowMgr *mgr = NULL;
1061 gchar *signature = NULL;
1063 /* If there was any error. The mail operation could be NULL,
1064 this means that we already have the message downloaded and
1065 that we didn't do a mail operation to retrieve it */
1066 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1069 g_return_if_fail (user_data != NULL);
1070 rf_helper = (ReplyForwardHelper *) user_data;
1072 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1073 rf_helper->account_name);
1074 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1075 rf_helper->account_name,
1076 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1077 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1078 rf_helper->account_name,
1079 MODEST_ACCOUNT_SIGNATURE, FALSE);
1082 /* Create reply mail */
1083 switch (rf_helper->action) {
1086 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1087 rf_helper->reply_forward_type,
1088 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1090 case ACTION_REPLY_TO_ALL:
1092 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1093 MODEST_TNY_MSG_REPLY_MODE_ALL);
1094 edit_type = MODEST_EDIT_TYPE_REPLY;
1096 case ACTION_FORWARD:
1098 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1099 edit_type = MODEST_EDIT_TYPE_FORWARD;
1102 g_return_if_reached ();
1109 g_printerr ("modest: failed to create message\n");
1113 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1114 rf_helper->account_name,
1115 TNY_ACCOUNT_TYPE_STORE);
1117 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1121 /* Create and register the windows */
1122 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1123 mgr = modest_runtime_get_window_mgr ();
1124 modest_window_mgr_register_window (mgr, msg_win);
1126 if (rf_helper->parent_window != NULL) {
1127 gdouble parent_zoom;
1129 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1130 modest_window_set_zoom (msg_win, parent_zoom);
1133 /* Show edit window */
1134 gtk_widget_show_all (GTK_WIDGET (msg_win));
1138 g_object_unref (msg_win);
1140 g_object_unref (G_OBJECT (new_msg));
1142 g_object_unref (G_OBJECT (account));
1143 /* g_object_unref (msg); */
1144 free_reply_forward_helper (rf_helper);
1148 * Checks a list of headers. If any of them are not currently
1149 * downloaded (CACHED) then it asks the user for permission to
1152 * Returns FALSE if the user does not want to download the
1153 * messages. Returns TRUE if the user allowed the download or if all
1154 * of them are currently downloaded
1157 download_uncached_messages (TnyList *header_list,
1163 gint uncached_messages = 0;
1165 iter = tny_list_create_iterator (header_list);
1166 while (!tny_iterator_is_done (iter)) {
1169 header = TNY_HEADER (tny_iterator_get_current (iter));
1171 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1172 uncached_messages ++;
1173 g_object_unref (header);
1176 tny_iterator_next (iter);
1178 g_object_unref (iter);
1180 /* Ask for user permission to download the messages */
1182 if (uncached_messages > 0) {
1183 GtkResponseType response;
1185 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1186 _("emev_nc_include_original"));
1189 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1190 ngettext("mcen_nc_get_msg",
1192 uncached_messages));
1193 if (response == GTK_RESPONSE_CANCEL)
1196 /* If a download will be necessary, make sure that we have a connection: */
1197 retval = modest_platform_connect_and_wait(win, NULL);
1205 * Common code for the reply and forward actions
1208 reply_forward (ReplyForwardAction action, ModestWindow *win)
1210 ModestMailOperation *mail_op = NULL;
1211 TnyList *header_list = NULL;
1212 ReplyForwardHelper *rf_helper = NULL;
1213 guint reply_forward_type;
1214 gboolean continue_download = TRUE;
1215 gboolean do_retrieve = TRUE;
1217 g_return_if_fail (MODEST_IS_WINDOW(win));
1219 /* we need an account when editing */
1220 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1221 run_account_setup_wizard (win);
1225 header_list = get_selected_headers (win);
1229 reply_forward_type =
1230 modest_conf_get_int (modest_runtime_get_conf (),
1231 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1234 /* Check that the messages have been previously downloaded */
1235 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1237 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1238 if (!continue_download) {
1239 g_object_unref (header_list);
1243 /* We assume that we can only select messages of the
1244 same folder and that we reply all of them from the
1245 same account. In fact the interface currently only
1246 allows single selection */
1249 rf_helper = g_slice_new0 (ReplyForwardHelper);
1250 rf_helper->reply_forward_type = reply_forward_type;
1251 rf_helper->action = action;
1252 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1254 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1255 rf_helper->parent_window = GTK_WIDGET (win);
1256 if (!rf_helper->account_name)
1257 rf_helper->account_name =
1258 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1260 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1263 /* Get header and message. Do not free them here, the
1264 reply_forward_cb must do it */
1265 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1266 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1267 if (!msg || !header) {
1269 g_object_unref (msg);
1270 g_printerr ("modest: no message found\n");
1273 reply_forward_cb (NULL, header, msg, rf_helper);
1276 g_object_unref (header);
1281 /* Only reply/forward to one message */
1282 iter = tny_list_create_iterator (header_list);
1283 header = TNY_HEADER (tny_iterator_get_current (iter));
1284 g_object_unref (iter);
1287 /* Retrieve messages */
1289 mail_op = modest_mail_operation_new_with_error_handling (
1290 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1292 modest_ui_actions_get_msgs_full_error_handler,
1294 modest_mail_operation_queue_add (
1295 modest_runtime_get_mail_operation_queue (), mail_op);
1297 modest_mail_operation_get_msg (mail_op,
1302 g_object_unref(mail_op);
1304 /* we put a ref here to prevent double unref as the reply
1305 * forward callback unrefs the header at its end */
1306 reply_forward_cb (NULL, header, NULL, rf_helper);
1310 g_object_unref (header);
1316 g_object_unref (header_list);
1320 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1322 g_return_if_fail (MODEST_IS_WINDOW(win));
1324 reply_forward (ACTION_REPLY, win);
1328 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1330 g_return_if_fail (MODEST_IS_WINDOW(win));
1332 reply_forward (ACTION_FORWARD, win);
1336 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1338 g_return_if_fail (MODEST_IS_WINDOW(win));
1340 reply_forward (ACTION_REPLY_TO_ALL, win);
1344 modest_ui_actions_on_next (GtkAction *action,
1345 ModestWindow *window)
1347 if (MODEST_IS_MAIN_WINDOW (window)) {
1348 GtkWidget *header_view;
1350 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1351 MODEST_WIDGET_TYPE_HEADER_VIEW);
1355 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1356 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1357 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1359 g_return_if_reached ();
1364 modest_ui_actions_on_prev (GtkAction *action,
1365 ModestWindow *window)
1367 g_return_if_fail (MODEST_IS_WINDOW(window));
1369 if (MODEST_IS_MAIN_WINDOW (window)) {
1370 GtkWidget *header_view;
1371 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1372 MODEST_WIDGET_TYPE_HEADER_VIEW);
1376 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1377 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1378 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1380 g_return_if_reached ();
1385 modest_ui_actions_on_sort (GtkAction *action,
1386 ModestWindow *window)
1388 g_return_if_fail (MODEST_IS_WINDOW(window));
1390 if (MODEST_IS_MAIN_WINDOW (window)) {
1391 GtkWidget *header_view;
1392 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1393 MODEST_WIDGET_TYPE_HEADER_VIEW);
1395 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1400 /* Show sorting dialog */
1401 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1406 new_messages_arrived (ModestMailOperation *self,
1410 if (new_messages == 0)
1413 modest_platform_on_new_msg ();
1417 * This function performs the send & receive required actions. The
1418 * window is used to create the mail operation. Typically it should
1419 * always be the main window, but we pass it as argument in order to
1423 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1425 gchar *acc_name = NULL;
1426 ModestMailOperation *mail_op;
1428 /* If no account name was provided then get the current account, and if
1429 there is no current account then pick the default one: */
1430 if (!account_name) {
1431 acc_name = g_strdup (modest_window_get_active_account(win));
1433 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1435 g_printerr ("modest: cannot get default account\n");
1439 acc_name = g_strdup (account_name);
1442 /* Set send/receive operation in progress */
1443 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1445 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1447 modest_ui_actions_send_receive_error_handler,
1450 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1451 G_CALLBACK (_on_send_receive_progress_changed),
1454 /* Send & receive. */
1455 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1456 /* Receive and then send. The operation is tagged initially as
1457 a receive operation because the account update performs a
1458 receive and then a send. The operation changes its type
1459 internally, so the progress objects will receive the proper
1460 progress information */
1461 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1462 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1463 g_object_unref (G_OBJECT (mail_op));
1471 modest_ui_actions_do_cancel_send (const gchar *account_name,
1474 TnyTransportAccount *transport_account;
1475 TnySendQueue *send_queue = NULL;
1476 GError *error = NULL;
1478 /* Get transport account */
1480 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1481 (modest_runtime_get_account_store(),
1483 TNY_ACCOUNT_TYPE_TRANSPORT));
1484 if (!transport_account) {
1485 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1490 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1491 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1492 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1493 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1494 "modest: could not find send queue for account\n");
1496 /* Keeep messages in outbox folder */
1497 tny_send_queue_cancel (send_queue, FALSE, &error);
1501 if (transport_account != NULL)
1502 g_object_unref (G_OBJECT (transport_account));
1506 modest_ui_actions_cancel_send_all (ModestWindow *win)
1508 GSList *account_names, *iter;
1510 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1513 iter = account_names;
1515 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1516 iter = g_slist_next (iter);
1519 modest_account_mgr_free_account_names (account_names);
1520 account_names = NULL;
1524 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1527 /* Check if accounts exist */
1528 gboolean accounts_exist =
1529 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1531 /* If not, allow the user to create an account before trying to send/receive. */
1532 if (!accounts_exist)
1533 modest_ui_actions_on_accounts (NULL, win);
1535 /* Cancel all sending operaitons */
1536 modest_ui_actions_cancel_send_all (win);
1540 * Refreshes all accounts. This function will be used by automatic
1544 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1546 GSList *account_names, *iter;
1548 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1551 iter = account_names;
1553 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1554 iter = g_slist_next (iter);
1557 modest_account_mgr_free_account_names (account_names);
1558 account_names = NULL;
1562 modest_do_refresh_current_folder(ModestWindow *win)
1564 /* Refresh currently selected folder. Note that if we only
1565 want to retreive the headers, then the refresh only will
1566 invoke a poke_status over all folders, i.e., only the
1567 total/unread count will be updated */
1568 if (MODEST_IS_MAIN_WINDOW (win)) {
1569 GtkWidget *header_view, *folder_view;
1570 TnyFolderStore *folder_store;
1572 /* Get folder and header view */
1574 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1575 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1577 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1579 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1581 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1582 MODEST_WIDGET_TYPE_HEADER_VIEW);
1584 /* We do not need to set the contents style
1585 because it hasn't changed. We also do not
1586 need to save the widget status. Just force
1588 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1589 TNY_FOLDER (folder_store),
1590 folder_refreshed_cb,
1591 MODEST_MAIN_WINDOW (win));
1595 g_object_unref (folder_store);
1601 * Handler of the click on Send&Receive button in the main toolbar
1604 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1606 /* Check if accounts exist */
1607 gboolean accounts_exist =
1608 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1610 /* If not, allow the user to create an account before trying to send/receive. */
1611 if (!accounts_exist)
1612 modest_ui_actions_on_accounts (NULL, win);
1614 modest_do_refresh_current_folder (win);
1616 /* Refresh the active account */
1617 modest_ui_actions_do_send_receive (NULL, win);
1622 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1625 GtkWidget *header_view;
1627 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1629 header_view = modest_main_window_get_child_widget (main_window,
1630 MODEST_WIDGET_TYPE_HEADER_VIEW);
1634 conf = modest_runtime_get_conf ();
1636 /* what is saved/restored is depending on the style; thus; we save with
1637 * old style, then update the style, and restore for this new style
1639 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1641 if (modest_header_view_get_style
1642 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1643 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1644 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1646 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1647 MODEST_HEADER_VIEW_STYLE_DETAILS);
1649 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1650 MODEST_CONF_HEADER_VIEW_KEY);
1655 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1657 ModestMainWindow *main_window)
1659 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1660 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1662 /* in the case the folder is empty, show the empty folder message and focus
1664 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1665 if (modest_header_view_is_empty (header_view)) {
1666 TnyFolder *folder = modest_header_view_get_folder (header_view);
1667 GtkWidget *folder_view =
1668 modest_main_window_get_child_widget (main_window,
1669 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1671 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1672 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1676 /* If no header has been selected then exit */
1681 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1682 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1684 /* Update Main window title */
1685 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1686 const gchar *subject = tny_header_get_subject (header);
1687 if (subject && strlen(subject) > 0)
1688 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1690 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1693 /* Update toolbar dimming state */
1694 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1698 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1700 ModestMainWindow *main_window)
1704 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1709 headers = tny_simple_list_new ();
1710 tny_list_prepend (headers, G_OBJECT (header));
1712 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1714 g_object_unref (headers);
1718 set_active_account_from_tny_account (TnyAccount *account,
1719 ModestWindow *window)
1721 const gchar *server_acc_name = tny_account_get_id (account);
1723 /* We need the TnyAccount provided by the
1724 account store because that is the one that
1725 knows the name of the Modest account */
1726 TnyAccount *modest_server_account = modest_server_account =
1727 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1728 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1731 const gchar *modest_acc_name =
1732 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1733 modest_window_set_active_account (window, modest_acc_name);
1734 g_object_unref (modest_server_account);
1739 folder_refreshed_cb (ModestMailOperation *mail_op,
1743 ModestMainWindow *win = NULL;
1744 GtkWidget *header_view;
1745 TnyFolder *current_folder;
1747 g_return_if_fail (TNY_IS_FOLDER (folder));
1749 win = MODEST_MAIN_WINDOW (user_data);
1751 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1754 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1755 if (current_folder != NULL && folder != current_folder) {
1760 /* Check if folder is empty and set headers view contents style */
1761 if (tny_folder_get_all_count (folder) == 0) {
1762 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1763 modest_main_window_set_contents_style (win,
1764 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1766 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1771 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1772 TnyFolderStore *folder_store,
1774 ModestMainWindow *main_window)
1777 GtkWidget *header_view;
1779 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1781 header_view = modest_main_window_get_child_widget(main_window,
1782 MODEST_WIDGET_TYPE_HEADER_VIEW);
1786 conf = modest_runtime_get_conf ();
1788 if (TNY_IS_ACCOUNT (folder_store)) {
1790 /* Update active account */
1791 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1792 /* Show account details */
1793 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1796 if (TNY_IS_FOLDER (folder_store) && selected) {
1798 /* Update the active account */
1799 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1801 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1802 g_object_unref (account);
1806 /* Set the header style by default, it could
1807 be changed later by the refresh callback to
1809 modest_main_window_set_contents_style (main_window,
1810 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1812 /* Set folder on header view. This function
1813 will call tny_folder_refresh_async so we
1814 pass a callback that will be called when
1815 finished. We use that callback to set the
1816 empty view if there are no messages */
1817 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1818 TNY_FOLDER (folder_store),
1819 folder_refreshed_cb,
1822 /* Restore configuration. We need to do this
1823 *after* the set_folder because the widget
1824 memory asks the header view about its
1826 modest_widget_memory_restore (modest_runtime_get_conf (),
1827 G_OBJECT(header_view),
1828 MODEST_CONF_HEADER_VIEW_KEY);
1830 /* Update the active account */
1831 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1832 /* Save only if we're seeing headers */
1833 if (modest_main_window_get_contents_style (main_window) ==
1834 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1835 modest_widget_memory_save (conf, G_OBJECT (header_view),
1836 MODEST_CONF_HEADER_VIEW_KEY);
1837 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1841 /* Update toolbar dimming state */
1842 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1846 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1853 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1855 online = tny_device_is_online (modest_runtime_get_device());
1858 /* already online -- the item is simply not there... */
1859 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1861 GTK_MESSAGE_WARNING,
1863 _("The %s you selected cannot be found"),
1865 gtk_dialog_run (GTK_DIALOG(dialog));
1867 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1871 GTK_RESPONSE_REJECT,
1873 GTK_RESPONSE_ACCEPT,
1875 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1876 "Do you want to get online?"), item);
1877 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1878 gtk_label_new (txt), FALSE, FALSE, 0);
1879 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1882 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1883 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1884 /* TODO: Comment about why is this commented out: */
1885 /* modest_platform_connect_and_wait (); */
1888 gtk_widget_destroy (dialog);
1892 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1895 /* g_message ("%s %s", __FUNCTION__, link); */
1900 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1903 modest_platform_activate_uri (link);
1907 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1910 modest_platform_show_uri_popup (link);
1914 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1917 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1921 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1922 const gchar *address,
1925 /* g_message ("%s %s", __FUNCTION__, address); */
1929 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1931 TnyTransportAccount *transport_account;
1932 ModestMailOperation *mail_operation;
1934 gchar *account_name, *from;
1935 ModestAccountMgr *account_mgr;
1936 gchar *info_text = NULL;
1938 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1940 data = modest_msg_edit_window_get_msg_data (edit_window);
1942 account_mgr = modest_runtime_get_account_mgr();
1943 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1945 account_name = modest_account_mgr_get_default_account (account_mgr);
1946 if (!account_name) {
1947 g_printerr ("modest: no account found\n");
1948 modest_msg_edit_window_free_msg_data (edit_window, data);
1952 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1953 account_name = g_strdup (data->account_name);
1957 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1958 (modest_runtime_get_account_store(),
1960 TNY_ACCOUNT_TYPE_TRANSPORT));
1961 if (!transport_account) {
1962 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1963 g_free (account_name);
1964 modest_msg_edit_window_free_msg_data (edit_window, data);
1967 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1969 /* Create the mail operation */
1970 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1971 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1973 modest_mail_operation_save_to_drafts (mail_operation,
1985 data->priority_flags);
1988 g_free (account_name);
1989 g_object_unref (G_OBJECT (transport_account));
1990 g_object_unref (G_OBJECT (mail_operation));
1992 modest_msg_edit_window_free_msg_data (edit_window, data);
1994 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1995 modest_platform_information_banner (NULL, NULL, info_text);
1999 /* For instance, when clicking the Send toolbar button when editing a message: */
2001 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2003 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2005 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2008 /* Offer the connection dialog, if necessary: */
2009 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2012 /* FIXME: Code added just for testing. The final version will
2013 use the send queue provided by tinymail and some
2015 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2016 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2018 account_name = modest_account_mgr_get_default_account (account_mgr);
2020 if (!account_name) {
2021 /* Run account setup wizard */
2022 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2026 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2028 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2029 account_name = g_strdup (data->account_name);
2032 /* Get the currently-active transport account for this modest account: */
2033 TnyTransportAccount *transport_account =
2034 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2035 (modest_runtime_get_account_store(),
2037 if (!transport_account) {
2038 /* Run account setup wizard */
2039 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2043 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2045 /* mail content checks and dialogs */
2046 if (data->subject == NULL || data->subject[0] == '\0') {
2047 GtkResponseType response;
2048 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2049 _("mcen_nc_subject_is_empty_send"));
2050 if (response == GTK_RESPONSE_CANCEL) {
2051 g_free (account_name);
2056 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2057 GtkResponseType response;
2058 gchar *note_message;
2059 gchar *note_subject = data->subject;
2060 if (note_subject == NULL || note_subject[0] == '\0')
2061 note_subject = _("mail_va_no_subject");
2062 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2063 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2065 g_free (note_message);
2066 if (response == GTK_RESPONSE_CANCEL) {
2067 g_free (account_name);
2072 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2074 /* Create the mail operation */
2075 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2076 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2078 modest_mail_operation_send_new_mail (mail_operation,
2089 data->priority_flags);
2093 g_free (account_name);
2094 g_object_unref (G_OBJECT (transport_account));
2095 g_object_unref (G_OBJECT (mail_operation));
2097 modest_msg_edit_window_free_msg_data (edit_window, data);
2098 modest_msg_edit_window_set_sent (edit_window, TRUE);
2100 /* Save settings and close the window: */
2101 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2105 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2106 ModestMsgEditWindow *window)
2108 ModestMsgEditFormatState *format_state = NULL;
2110 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2111 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2113 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2116 format_state = modest_msg_edit_window_get_format_state (window);
2117 g_return_if_fail (format_state != NULL);
2119 format_state->bold = gtk_toggle_action_get_active (action);
2120 modest_msg_edit_window_set_format_state (window, format_state);
2121 g_free (format_state);
2126 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2127 ModestMsgEditWindow *window)
2129 ModestMsgEditFormatState *format_state = NULL;
2131 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2132 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2134 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2137 format_state = modest_msg_edit_window_get_format_state (window);
2138 g_return_if_fail (format_state != NULL);
2140 format_state->italics = gtk_toggle_action_get_active (action);
2141 modest_msg_edit_window_set_format_state (window, format_state);
2142 g_free (format_state);
2147 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2148 ModestMsgEditWindow *window)
2150 ModestMsgEditFormatState *format_state = NULL;
2152 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2153 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2155 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2158 format_state = modest_msg_edit_window_get_format_state (window);
2159 g_return_if_fail (format_state != NULL);
2161 format_state->bullet = gtk_toggle_action_get_active (action);
2162 modest_msg_edit_window_set_format_state (window, format_state);
2163 g_free (format_state);
2168 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2169 GtkRadioAction *selected,
2170 ModestMsgEditWindow *window)
2172 ModestMsgEditFormatState *format_state = NULL;
2173 GtkJustification value;
2175 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2177 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2180 value = gtk_radio_action_get_current_value (selected);
2182 format_state = modest_msg_edit_window_get_format_state (window);
2183 g_return_if_fail (format_state != NULL);
2185 format_state->justification = value;
2186 modest_msg_edit_window_set_format_state (window, format_state);
2187 g_free (format_state);
2191 modest_ui_actions_on_select_editor_color (GtkAction *action,
2192 ModestMsgEditWindow *window)
2194 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2195 g_return_if_fail (GTK_IS_ACTION (action));
2197 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2200 modest_msg_edit_window_select_color (window);
2204 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2205 ModestMsgEditWindow *window)
2207 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2208 g_return_if_fail (GTK_IS_ACTION (action));
2210 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2213 modest_msg_edit_window_select_background_color (window);
2217 modest_ui_actions_on_insert_image (GtkAction *action,
2218 ModestMsgEditWindow *window)
2220 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2221 g_return_if_fail (GTK_IS_ACTION (action));
2223 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2226 modest_msg_edit_window_insert_image (window);
2230 modest_ui_actions_on_attach_file (GtkAction *action,
2231 ModestMsgEditWindow *window)
2233 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2234 g_return_if_fail (GTK_IS_ACTION (action));
2236 modest_msg_edit_window_offer_attach_file (window);
2240 modest_ui_actions_on_remove_attachments (GtkAction *action,
2241 ModestMsgEditWindow *window)
2243 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2244 g_return_if_fail (GTK_IS_ACTION (action));
2246 modest_msg_edit_window_remove_attachments (window, NULL);
2250 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2253 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2254 const GError *error = modest_mail_operation_get_error (mail_op);
2258 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2259 modest_mail_operation_get_error (mail_op)->message);
2264 modest_ui_actions_create_folder(GtkWidget *parent_window,
2265 GtkWidget *folder_view)
2267 TnyFolderStore *parent_folder;
2269 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2271 if (parent_folder) {
2272 gboolean finished = FALSE;
2274 gchar *folder_name = NULL, *suggested_name = NULL;
2275 const gchar *proto_str = NULL;
2276 TnyAccount *account;
2278 if (TNY_IS_ACCOUNT (parent_folder))
2279 account = g_object_ref (parent_folder);
2281 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2282 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2284 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2285 MODEST_PROTOCOL_STORE_POP) {
2287 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2289 g_object_unref (account);
2291 /* Run the new folder dialog */
2293 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2298 g_free (suggested_name);
2299 suggested_name = NULL;
2301 if (result == GTK_RESPONSE_REJECT) {
2304 ModestMailOperation *mail_op;
2305 TnyFolder *new_folder = NULL;
2307 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2308 G_OBJECT(parent_window),
2309 modest_ui_actions_new_folder_error_handler,
2312 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2314 new_folder = modest_mail_operation_create_folder (mail_op,
2316 (const gchar *) folder_name);
2318 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2321 g_object_unref (new_folder);
2324 g_object_unref (mail_op);
2327 suggested_name = folder_name;
2331 g_object_unref (parent_folder);
2336 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2338 GtkWidget *folder_view;
2340 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2342 folder_view = modest_main_window_get_child_widget (main_window,
2343 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2347 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2351 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2354 GObject *win = modest_mail_operation_get_source (mail_op);
2355 const GError *error = NULL;
2356 const gchar *message = NULL;
2358 /* Get error message */
2359 error = modest_mail_operation_get_error (mail_op);
2360 if (error != NULL && error->message != NULL) {
2361 message = error->message;
2363 message = _("!!! FIXME: Unable to rename");
2366 /* Show notification dialog */
2367 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2368 g_object_unref (win);
2372 modest_ui_actions_on_rename_folder (GtkAction *action,
2373 ModestMainWindow *main_window)
2375 TnyFolderStore *folder;
2376 GtkWidget *folder_view;
2377 GtkWidget *header_view;
2379 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2381 folder_view = modest_main_window_get_child_widget (main_window,
2382 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2386 header_view = modest_main_window_get_child_widget (main_window,
2387 MODEST_WIDGET_TYPE_HEADER_VIEW);
2392 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2396 /* Offer the connection dialog if necessary: */
2397 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2398 g_object_unref (G_OBJECT (folder));
2403 if (TNY_IS_FOLDER (folder)) {
2406 const gchar *current_name;
2408 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2409 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2410 current_name, &folder_name);
2412 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2413 ModestMailOperation *mail_op;
2416 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2417 G_OBJECT(main_window),
2418 modest_ui_actions_rename_folder_error_handler,
2422 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2425 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2427 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2428 TNY_FOLDER(folder), TRUE);
2431 modest_header_view_clear ((ModestHeaderView *) header_view);
2433 modest_mail_operation_rename_folder (mail_op,
2434 TNY_FOLDER (folder),
2435 (const gchar *) folder_name);
2437 g_object_unref (mail_op);
2438 g_free (folder_name);
2441 g_object_unref (folder);
2445 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2448 GObject *win = modest_mail_operation_get_source (mail_op);
2450 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2451 _("mail_in_ui_folder_delete_error"));
2452 g_object_unref (win);
2456 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2458 TnyFolderStore *folder;
2459 GtkWidget *folder_view;
2463 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2465 folder_view = modest_main_window_get_child_widget (main_window,
2466 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2470 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2472 /* Show an error if it's an account */
2473 if (!TNY_IS_FOLDER (folder)) {
2474 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2475 _("mail_in_ui_folder_delete_error"));
2476 g_object_unref (G_OBJECT (folder));
2480 /* Offer the connection dialog if necessary: */
2481 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2482 g_object_unref (G_OBJECT (folder));
2487 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2488 tny_folder_get_name (TNY_FOLDER (folder)));
2489 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2490 (const gchar *) message);
2493 if (response == GTK_RESPONSE_OK) {
2494 ModestMailOperation *mail_op =
2495 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2496 G_OBJECT(main_window),
2497 modest_ui_actions_delete_folder_error_handler,
2500 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2502 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2503 g_object_unref (G_OBJECT (mail_op));
2506 g_object_unref (G_OBJECT (folder));
2510 modest_ui_actions_on_delete_folder (GtkAction *action,
2511 ModestMainWindow *main_window)
2513 GtkWidget *folder_view;
2514 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2516 delete_folder (main_window, FALSE);
2517 folder_view = modest_main_window_get_child_widget (main_window,
2518 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2521 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2525 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2527 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2529 delete_folder (main_window, TRUE);
2534 show_error (GtkWidget *parent_widget, const gchar* text)
2536 hildon_banner_show_information(parent_widget, NULL, text);
2539 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2541 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2548 gtk_dialog_run (dialog);
2549 gtk_widget_destroy (GTK_WIDGET (dialog));
2554 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2555 const gchar* server_account_name,
2560 ModestMainWindow *main_window)
2562 g_return_if_fail(server_account_name);
2563 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2565 /* Initalize output parameters: */
2572 #ifdef MODEST_PLATFORM_MAEMO
2573 /* Maemo uses a different (awkward) button order,
2574 * It should probably just use gtk_alternative_dialog_button_order ().
2576 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2580 GTK_RESPONSE_ACCEPT,
2582 GTK_RESPONSE_REJECT,
2585 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2589 GTK_RESPONSE_REJECT,
2591 GTK_RESPONSE_ACCEPT,
2593 #endif /* MODEST_PLATFORM_MAEMO */
2595 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2597 gchar *server_name = modest_server_account_get_hostname (
2598 modest_runtime_get_account_mgr(), server_account_name);
2599 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2600 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2605 /* This causes a warning because the logical ID has no %s in it,
2606 * though the translation does, but there is not much we can do about that: */
2607 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2608 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2611 g_free (server_name);
2615 gchar *initial_username = modest_server_account_get_username (
2616 modest_runtime_get_account_mgr(), server_account_name);
2618 GtkWidget *entry_username = gtk_entry_new ();
2619 if (initial_username)
2620 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2621 /* Dim this if a connection has ever succeeded with this username,
2622 * as per the UI spec: */
2623 const gboolean username_known =
2624 modest_server_account_get_username_has_succeeded(
2625 modest_runtime_get_account_mgr(), server_account_name);
2626 gtk_widget_set_sensitive (entry_username, !username_known);
2628 #ifdef MODEST_PLATFORM_MAEMO
2629 /* Auto-capitalization is the default, so let's turn it off: */
2630 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2632 /* Create a size group to be used by all captions.
2633 * Note that HildonCaption does not create a default size group if we do not specify one.
2634 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2635 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2637 GtkWidget *caption = hildon_caption_new (sizegroup,
2638 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2639 gtk_widget_show (entry_username);
2640 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2641 FALSE, FALSE, MODEST_MARGIN_HALF);
2642 gtk_widget_show (caption);
2644 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2646 #endif /* MODEST_PLATFORM_MAEMO */
2649 GtkWidget *entry_password = gtk_entry_new ();
2650 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2651 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2653 #ifdef MODEST_PLATFORM_MAEMO
2654 /* Auto-capitalization is the default, so let's turn it off: */
2655 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2656 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2658 caption = hildon_caption_new (sizegroup,
2659 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2660 gtk_widget_show (entry_password);
2661 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2662 FALSE, FALSE, MODEST_MARGIN_HALF);
2663 gtk_widget_show (caption);
2664 g_object_unref (sizegroup);
2666 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2668 #endif /* MODEST_PLATFORM_MAEMO */
2670 /* This is not in the Maemo UI spec:
2671 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2672 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2676 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2678 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2680 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2682 modest_server_account_set_username (
2683 modest_runtime_get_account_mgr(), server_account_name,
2686 const gboolean username_was_changed =
2687 (strcmp (*username, initial_username) != 0);
2688 if (username_was_changed) {
2689 g_warning ("%s: tinymail does not yet support changing the "
2690 "username in the get_password() callback.\n", __FUNCTION__);
2695 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2697 /* We do not save the password in the configuration,
2698 * because this function is only called for passwords that should
2699 * not be remembered:
2700 modest_server_account_set_password (
2701 modest_runtime_get_account_mgr(), server_account_name,
2710 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2722 /* This is not in the Maemo UI spec:
2723 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2729 gtk_widget_destroy (dialog);
2731 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2735 modest_ui_actions_on_cut (GtkAction *action,
2736 ModestWindow *window)
2738 GtkWidget *focused_widget;
2739 GtkClipboard *clipboard;
2741 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2742 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2743 if (GTK_IS_EDITABLE (focused_widget)) {
2744 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2745 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2746 gtk_clipboard_store (clipboard);
2747 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2748 GtkTextBuffer *buffer;
2750 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2751 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2752 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2753 gtk_clipboard_store (clipboard);
2754 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2755 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2756 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2757 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2762 modest_ui_actions_on_copy (GtkAction *action,
2763 ModestWindow *window)
2765 GtkClipboard *clipboard;
2766 GtkWidget *focused_widget;
2768 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2769 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2771 if (GTK_IS_LABEL (focused_widget)) {
2772 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2773 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2774 gtk_clipboard_store (clipboard);
2775 } else if (GTK_IS_EDITABLE (focused_widget)) {
2776 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2777 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2778 gtk_clipboard_store (clipboard);
2779 } else if (GTK_IS_HTML (focused_widget)) {
2780 gtk_html_copy (GTK_HTML (focused_widget));
2781 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2782 gtk_clipboard_store (clipboard);
2783 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2784 GtkTextBuffer *buffer;
2785 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2786 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2787 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2788 gtk_clipboard_store (clipboard);
2789 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2790 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2791 TnyIterator *iter = tny_list_create_iterator (header_list);
2792 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2794 gboolean ask = FALSE;
2796 TnyFolder *folder = tny_header_get_folder (header);
2797 TnyAccount *account = tny_folder_get_account (folder);
2798 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2799 /* If it's POP then ask */
2800 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2801 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2802 g_object_unref (account);
2803 g_object_unref (folder);
2804 g_object_unref (header);
2807 g_object_unref (iter);
2809 /* Check that the messages have been previously downloaded */
2810 gboolean continue_download = TRUE;
2812 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2813 if (continue_download)
2814 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2815 g_object_unref (header_list);
2816 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2817 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2820 /* Show information banner */
2821 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2826 modest_ui_actions_on_undo (GtkAction *action,
2827 ModestWindow *window)
2829 ModestEmailClipboard *clipboard = NULL;
2831 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2832 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2833 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2834 /* Clear clipboard source */
2835 clipboard = modest_runtime_get_email_clipboard ();
2836 modest_email_clipboard_clear (clipboard);
2839 g_return_if_reached ();
2844 modest_ui_actions_on_redo (GtkAction *action,
2845 ModestWindow *window)
2847 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2848 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2851 g_return_if_reached ();
2857 paste_msgs_cb (const GObject *object, gpointer user_data)
2859 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2860 g_return_if_fail (GTK_IS_WIDGET (user_data));
2862 /* destroy information note */
2863 gtk_widget_destroy (GTK_WIDGET(user_data));
2867 paste_as_attachment_free (gpointer data)
2869 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2871 gtk_widget_destroy (helper->banner);
2872 g_object_unref (helper->banner);
2877 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2882 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2883 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2888 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2893 modest_ui_actions_on_paste (GtkAction *action,
2894 ModestWindow *window)
2896 GtkWidget *focused_widget = NULL;
2897 GtkWidget *inf_note = NULL;
2898 ModestMailOperation *mail_op = NULL;
2900 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2901 if (GTK_IS_EDITABLE (focused_widget)) {
2902 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2903 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2904 ModestEmailClipboard *e_clipboard = NULL;
2905 e_clipboard = modest_runtime_get_email_clipboard ();
2906 if (modest_email_clipboard_cleared (e_clipboard)) {
2907 GtkTextBuffer *buffer;
2908 GtkClipboard *clipboard;
2910 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2911 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2912 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2913 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2914 ModestMailOperation *mail_op;
2915 TnyFolder *src_folder;
2918 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2919 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2920 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2921 _CS("ckct_nw_pasting"));
2922 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2923 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2925 if (helper->banner != NULL) {
2926 g_object_ref (G_OBJECT (helper->banner));
2927 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2928 gtk_widget_show (GTK_WIDGET (helper->banner));
2932 modest_mail_operation_get_msgs_full (mail_op,
2934 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2936 paste_as_attachment_free);
2939 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2940 ModestEmailClipboard *clipboard = NULL;
2941 TnyFolder *src_folder = NULL;
2942 TnyFolderStore *folder_store = NULL;
2943 TnyList *data = NULL;
2944 gboolean delete = FALSE;
2946 /* Check clipboard source */
2947 clipboard = modest_runtime_get_email_clipboard ();
2948 if (modest_email_clipboard_cleared (clipboard))
2951 /* Get elements to paste */
2952 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2954 /* Create a new mail operation */
2955 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2957 /* Get destination folder */
2958 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2960 /* transfer messages */
2964 /* Ask for user confirmation */
2965 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2966 TNY_FOLDER (folder_store),
2969 if (response == GTK_RESPONSE_OK) {
2970 /* Launch notification */
2971 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2972 _CS("ckct_nw_pasting"));
2973 if (inf_note != NULL) {
2974 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2975 gtk_widget_show (GTK_WIDGET(inf_note));
2978 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2979 modest_mail_operation_xfer_msgs (mail_op,
2981 TNY_FOLDER (folder_store),
2986 g_object_unref (mail_op);
2989 } else if (src_folder != NULL) {
2990 /* Launch notification */
2991 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2992 _CS("ckct_nw_pasting"));
2993 if (inf_note != NULL) {
2994 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2995 gtk_widget_show (GTK_WIDGET(inf_note));
2998 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2999 modest_mail_operation_xfer_folder (mail_op,
3009 g_object_unref (data);
3010 if (src_folder != NULL)
3011 g_object_unref (src_folder);
3012 if (folder_store != NULL)
3013 g_object_unref (folder_store);
3019 modest_ui_actions_on_select_all (GtkAction *action,
3020 ModestWindow *window)
3022 GtkWidget *focused_widget;
3024 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3025 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3026 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3027 } else if (GTK_IS_LABEL (focused_widget)) {
3028 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3029 } else if (GTK_IS_EDITABLE (focused_widget)) {
3030 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3031 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3032 GtkTextBuffer *buffer;
3033 GtkTextIter start, end;
3035 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3036 gtk_text_buffer_get_start_iter (buffer, &start);
3037 gtk_text_buffer_get_end_iter (buffer, &end);
3038 gtk_text_buffer_select_range (buffer, &start, &end);
3039 } else if (GTK_IS_HTML (focused_widget)) {
3040 gtk_html_select_all (GTK_HTML (focused_widget));
3041 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3042 GtkWidget *header_view = focused_widget;
3043 GtkTreeSelection *selection = NULL;
3045 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3046 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3047 MODEST_WIDGET_TYPE_HEADER_VIEW);
3049 /* Select all messages */
3050 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3051 gtk_tree_selection_select_all (selection);
3053 /* Set focuse on header view */
3054 gtk_widget_grab_focus (header_view);
3060 modest_ui_actions_on_mark_as_read (GtkAction *action,
3061 ModestWindow *window)
3063 g_return_if_fail (MODEST_IS_WINDOW(window));
3065 /* Mark each header as read */
3066 do_headers_action (window, headers_action_mark_as_read, NULL);
3070 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3071 ModestWindow *window)
3073 g_return_if_fail (MODEST_IS_WINDOW(window));
3075 /* Mark each header as read */
3076 do_headers_action (window, headers_action_mark_as_unread, NULL);
3080 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3081 GtkRadioAction *selected,
3082 ModestWindow *window)
3086 value = gtk_radio_action_get_current_value (selected);
3087 if (MODEST_IS_WINDOW (window)) {
3088 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3092 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3093 GtkRadioAction *selected,
3094 ModestWindow *window)
3096 TnyHeaderFlags flags;
3097 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3099 flags = gtk_radio_action_get_current_value (selected);
3100 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3103 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3104 GtkRadioAction *selected,
3105 ModestWindow *window)
3109 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3111 file_format = gtk_radio_action_get_current_value (selected);
3112 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3117 modest_ui_actions_on_zoom_plus (GtkAction *action,
3118 ModestWindow *window)
3120 g_return_if_fail (MODEST_IS_WINDOW (window));
3122 modest_window_zoom_plus (MODEST_WINDOW (window));
3126 modest_ui_actions_on_zoom_minus (GtkAction *action,
3127 ModestWindow *window)
3129 g_return_if_fail (MODEST_IS_WINDOW (window));
3131 modest_window_zoom_minus (MODEST_WINDOW (window));
3135 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3136 ModestWindow *window)
3138 ModestWindowMgr *mgr;
3139 gboolean fullscreen, active;
3140 g_return_if_fail (MODEST_IS_WINDOW (window));
3142 mgr = modest_runtime_get_window_mgr ();
3144 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3145 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3147 if (active != fullscreen) {
3148 modest_window_mgr_set_fullscreen_mode (mgr, active);
3149 gtk_window_present (GTK_WINDOW (window));
3154 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3155 ModestWindow *window)
3157 ModestWindowMgr *mgr;
3158 gboolean fullscreen;
3160 g_return_if_fail (MODEST_IS_WINDOW (window));
3162 mgr = modest_runtime_get_window_mgr ();
3163 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3164 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3166 gtk_window_present (GTK_WINDOW (window));
3170 * Used by modest_ui_actions_on_details to call do_headers_action
3173 headers_action_show_details (TnyHeader *header,
3174 ModestWindow *window,
3181 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3184 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3185 gtk_widget_show_all (dialog);
3186 gtk_dialog_run (GTK_DIALOG (dialog));
3188 gtk_widget_destroy (dialog);
3192 * Show the folder details in a ModestDetailsDialog widget
3195 show_folder_details (TnyFolder *folder,
3201 dialog = modest_details_dialog_new_with_folder (window, folder);
3204 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3205 gtk_widget_show_all (dialog);
3206 gtk_dialog_run (GTK_DIALOG (dialog));
3208 gtk_widget_destroy (dialog);
3212 * Show the header details in a ModestDetailsDialog widget
3215 modest_ui_actions_on_details (GtkAction *action,
3218 TnyList * headers_list;
3222 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3225 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3228 g_object_unref (msg);
3230 headers_list = get_selected_headers (win);
3234 iter = tny_list_create_iterator (headers_list);
3236 header = TNY_HEADER (tny_iterator_get_current (iter));
3238 headers_action_show_details (header, win, NULL);
3239 g_object_unref (header);
3242 g_object_unref (iter);
3243 g_object_unref (headers_list);
3245 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3246 GtkWidget *folder_view, *header_view;
3248 /* Check which widget has the focus */
3249 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3250 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3251 if (gtk_widget_is_focus (folder_view)) {
3252 TnyFolderStore *folder_store
3253 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3254 if (!folder_store) {
3255 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3258 /* Show only when it's a folder */
3259 /* This function should not be called for account items,
3260 * because we dim the menu item for them. */
3261 if (TNY_IS_FOLDER (folder_store)) {
3262 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3265 g_object_unref (folder_store);
3268 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3269 MODEST_WIDGET_TYPE_HEADER_VIEW);
3270 /* Show details of each header */
3271 do_headers_action (win, headers_action_show_details, header_view);
3277 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3278 ModestMsgEditWindow *window)
3280 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3282 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3286 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3287 ModestMsgEditWindow *window)
3289 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3291 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3295 modest_ui_actions_toggle_folders_view (GtkAction *action,
3296 ModestMainWindow *main_window)
3298 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3300 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3301 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3303 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3307 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3308 ModestWindow *window)
3310 gboolean active, fullscreen = FALSE;
3311 ModestWindowMgr *mgr;
3313 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3315 /* Check if we want to toggle the toolbar vuew in fullscreen
3317 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3318 "ViewShowToolbarFullScreen")) {
3322 /* Toggle toolbar */
3323 mgr = modest_runtime_get_window_mgr ();
3324 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3328 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3329 ModestMsgEditWindow *window)
3331 modest_msg_edit_window_select_font (window);
3335 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3336 const gchar *display_name,
3339 /* Do not change the application name if the widget has not
3340 the focus. This callback could be called even if the folder
3341 view has not the focus, because the handled signal could be
3342 emitted when the folder view is redrawn */
3343 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3345 gtk_window_set_title (window, display_name);
3347 gtk_window_set_title (window, " ");
3352 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3354 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3355 modest_msg_edit_window_select_contacts (window);
3359 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3361 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3362 modest_msg_edit_window_check_names (window, FALSE);
3366 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3368 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3369 GTK_WIDGET (user_data));
3373 create_move_to_dialog (GtkWindow *win,
3374 GtkWidget *folder_view,
3375 GtkWidget **tree_view)
3377 GtkWidget *dialog, *scroll;
3378 GtkWidget *new_button;
3380 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3382 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3385 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3386 /* We do this manually so GTK+ does not associate a response ID for
3388 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3389 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3390 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3392 /* Create scrolled window */
3393 scroll = gtk_scrolled_window_new (NULL, NULL);
3394 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3395 GTK_POLICY_AUTOMATIC,
3396 GTK_POLICY_AUTOMATIC);
3398 /* Create folder view */
3399 *tree_view = modest_platform_create_folder_view (NULL);
3401 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3403 /* It could happen that we're trying to move a message from a
3404 window (msg window for example) after the main window was
3405 closed, so we can not just get the model of the folder
3407 if (MODEST_IS_FOLDER_VIEW (folder_view))
3408 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3409 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3411 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3412 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3414 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3416 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3418 /* Add scroll to dialog */
3419 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3420 scroll, TRUE, TRUE, 0);
3422 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3423 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3429 * Returns TRUE if at least one of the headers of the list belongs to
3430 * a message that has been fully retrieved.
3433 has_retrieved_msgs (TnyList *list)
3436 gboolean found = FALSE;
3438 iter = tny_list_create_iterator (list);
3439 while (tny_iterator_is_done (iter) && !found) {
3441 TnyHeaderFlags flags = 0;
3443 header = TNY_HEADER (tny_iterator_get_current (iter));
3445 flags = tny_header_get_flags (header);
3446 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3449 g_object_unref (header);
3453 tny_iterator_next (iter);
3455 g_object_unref (iter);
3461 * Shows a confirmation dialog to the user when we're moving messages
3462 * from a remote server to the local storage. Returns the dialog
3463 * response. If it's other kind of movement the it always returns
3467 msgs_move_to_confirmation (GtkWindow *win,
3468 TnyFolder *dest_folder,
3471 gint response = GTK_RESPONSE_OK;
3473 /* If the destination is a local folder */
3474 if (modest_tny_folder_is_local_folder (dest_folder)) {
3475 TnyFolder *src_folder = NULL;
3476 TnyIterator *iter = NULL;
3477 TnyHeader *header = NULL;
3479 /* Get source folder */
3480 iter = tny_list_create_iterator (headers);
3481 header = TNY_HEADER (tny_iterator_get_current (iter));
3483 src_folder = tny_header_get_folder (header);
3484 g_object_unref (header);
3487 g_object_unref (iter);
3489 /* if no src_folder, message may be an attahcment */
3490 if (src_folder == NULL)
3491 return GTK_RESPONSE_CANCEL;
3493 /* If the source is a remote folder */
3494 if (!modest_tny_folder_is_local_folder (src_folder)) {
3495 const gchar *message;
3497 if (has_retrieved_msgs (headers))
3498 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3499 tny_list_get_length (headers));
3501 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3502 tny_list_get_length (headers));
3504 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3505 (const gchar *) message);
3508 g_object_unref (src_folder);
3517 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3519 ModestMsgViewWindow *self = NULL;
3521 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3522 self = MODEST_MSG_VIEW_WINDOW (object);
3524 if (!modest_msg_view_window_select_next_message (self))
3525 if (!modest_msg_view_window_select_previous_message (self))
3526 /* No more messages to view, so close this window */
3527 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3531 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3534 GObject *win = modest_mail_operation_get_source (mail_op);
3535 const GError *error = NULL;
3536 const gchar *message = NULL;
3538 /* Get error message */
3539 error = modest_mail_operation_get_error (mail_op);
3540 if (error != NULL && error->message != NULL) {
3541 message = error->message;
3543 message = _("mail_in_ui_folder_move_target_error");
3546 /* Show notification dialog */
3547 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3548 g_object_unref (win);
3552 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3555 GObject *win = modest_mail_operation_get_source (mail_op);
3556 const GError *error = modest_mail_operation_get_error (mail_op);
3558 g_return_if_fail (error != NULL);
3559 if (error->message != NULL)
3560 g_printerr ("modest: %s\n", error->message);
3562 g_printerr ("modest: unkonw error on send&receive operation");
3564 /* Show error message */
3565 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3566 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3567 /* _CS("sfil_ib_unable_to_receive")); */
3569 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3570 /* _CS("sfil_ib_unable_to_send")); */
3571 g_object_unref (win);
3575 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3582 gint pending_purges = 0;
3583 gboolean some_purged = FALSE;
3584 ModestWindow *win = MODEST_WINDOW (user_data);
3585 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3587 /* If there was any error */
3588 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3589 modest_window_mgr_unregister_header (mgr, header);
3593 /* Once the message has been retrieved for purging, we check if
3594 * it's all ok for purging */
3596 parts = tny_simple_list_new ();
3597 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3598 iter = tny_list_create_iterator (parts);
3600 while (!tny_iterator_is_done (iter)) {
3602 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3603 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3604 if (tny_mime_part_is_purged (part))
3611 g_object_unref (part);
3613 tny_iterator_next (iter);
3616 if (pending_purges>0) {
3618 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3620 if (response == GTK_RESPONSE_OK) {
3621 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3622 tny_iterator_first (iter);
3623 while (!tny_iterator_is_done (iter)) {
3626 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3627 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3628 tny_mime_part_set_purged (part);
3631 g_object_unref (part);
3633 tny_iterator_next (iter);
3636 tny_msg_rewrite_cache (msg);
3639 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3642 /* remove attachments */
3643 tny_iterator_first (iter);
3644 while (!tny_iterator_is_done (iter)) {
3647 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3649 /* One for the reference given by tny_iterator_get_current(): */
3650 g_object_unref (part);
3652 /* TODO: Is this meant to remove the attachment by doing another unref()?
3653 * Otherwise, this seems useless. */
3656 tny_iterator_next (iter);
3658 modest_window_mgr_unregister_header (mgr, header);
3660 g_object_unref (iter);
3661 g_object_unref (parts);
3665 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3666 ModestMainWindow *win)
3668 GtkWidget *header_view;
3669 TnyList *header_list;
3672 TnyHeaderFlags flags;
3673 ModestWindow *msg_view_window = NULL;
3676 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3678 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3679 MODEST_WIDGET_TYPE_HEADER_VIEW);
3681 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3683 if (tny_list_get_length (header_list) == 1) {
3684 iter = tny_list_create_iterator (header_list);
3685 header = TNY_HEADER (tny_iterator_get_current (iter));
3686 g_object_unref (iter);
3691 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3692 header, &msg_view_window);
3693 flags = tny_header_get_flags (header);
3694 if (!(flags & TNY_HEADER_FLAG_CACHED))
3697 if (msg_view_window != NULL)
3698 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3700 /* do nothing; uid was registered before, so window is probably on it's way */
3701 g_warning ("debug: header %p has already been registered", header);
3704 ModestMailOperation *mail_op = NULL;
3705 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3706 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3708 modest_ui_actions_get_msgs_full_error_handler,
3710 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3711 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3713 g_object_unref (mail_op);
3716 g_object_unref (header);
3718 g_object_unref (header_list);
3722 * Utility function that transfer messages from both the main window
3723 * and the msg view window when using the "Move to" dialog
3726 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3729 TnyList *headers = NULL;
3731 TnyAccount *dst_account = NULL;
3732 const gchar *proto_str = NULL;
3733 gboolean dst_is_pop = FALSE;
3735 if (!TNY_IS_FOLDER (dst_folder)) {
3736 modest_platform_information_banner (GTK_WIDGET (win),
3738 _CS("ckdg_ib_unable_to_move_to_current_location"));
3742 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3743 proto_str = tny_account_get_proto (dst_account);
3744 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3745 MODEST_PROTOCOL_STORE_POP);
3746 g_object_unref (dst_account);
3748 /* Get selected headers */
3749 headers = get_selected_headers (MODEST_WINDOW (win));
3752 modest_platform_information_banner (GTK_WIDGET (win),
3754 ngettext("mail_in_ui_folder_move_target_error",
3755 "mail_in_ui_folder_move_targets_error",
3756 tny_list_get_length (headers)));
3757 g_object_unref (headers);
3761 /* Ask for user confirmation */
3762 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3763 TNY_FOLDER (dst_folder),
3766 /* Transfer messages */
3767 if (response == GTK_RESPONSE_OK) {
3768 ModestMailOperation *mail_op =
3769 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3771 modest_ui_actions_move_folder_error_handler,
3773 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3776 modest_mail_operation_xfer_msgs (mail_op,
3778 TNY_FOLDER (dst_folder),
3780 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3783 g_object_unref (G_OBJECT (mail_op));
3785 g_object_unref (headers);
3790 * UI handler for the "Move to" action when invoked from the
3794 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3795 GtkWidget *folder_view,
3796 TnyFolderStore *dst_folder,
3797 ModestMainWindow *win)
3799 GtkWidget *header_view = NULL;
3800 ModestMailOperation *mail_op = NULL;
3801 TnyFolderStore *src_folder;
3803 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3805 /* Get the source folder */
3806 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3808 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3809 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3813 /* Get header view */
3815 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3817 /* Get folder or messages to transfer */
3818 if (gtk_widget_is_focus (folder_view)) {
3820 /* Allow only to transfer folders to the local root folder */
3821 if (TNY_IS_ACCOUNT (dst_folder) &&
3822 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3825 /* Clean folder on header view before moving it */
3826 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3828 if (TNY_IS_FOLDER (src_folder)) {
3830 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3832 modest_ui_actions_move_folder_error_handler,
3834 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3837 modest_mail_operation_xfer_folder (mail_op,
3838 TNY_FOLDER (src_folder),
3841 /* Unref mail operation */
3842 g_object_unref (G_OBJECT (mail_op));
3844 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3846 } else if (gtk_widget_is_focus (header_view)) {
3847 /* Transfer messages */
3848 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3853 g_object_unref (src_folder);
3858 * UI handler for the "Move to" action when invoked from the
3859 * ModestMsgViewWindow
3862 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3863 TnyFolderStore *dst_folder,
3864 ModestMsgViewWindow *win)
3866 TnyHeader *header = NULL;
3867 TnyFolder *src_folder;
3869 /* Create header list */
3870 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3871 src_folder = tny_header_get_folder(header);
3872 g_object_unref (header);
3874 /* Transfer the message */
3875 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3876 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3878 g_object_unref (src_folder);
3882 modest_ui_actions_on_move_to (GtkAction *action,
3885 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3887 TnyFolderStore *dst_folder = NULL;
3888 ModestMainWindow *main_window;
3890 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3891 MODEST_IS_MSG_VIEW_WINDOW (win));
3893 /* Get the main window if exists */
3894 if (MODEST_IS_MAIN_WINDOW (win))
3895 main_window = MODEST_MAIN_WINDOW (win);
3898 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3900 /* Get the folder view widget if exists */
3902 folder_view = modest_main_window_get_child_widget (main_window,
3903 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3907 /* Create and run the dialog */
3908 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3909 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3910 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3911 result = gtk_dialog_run (GTK_DIALOG(dialog));
3912 g_object_ref (tree_view);
3913 gtk_widget_destroy (dialog);
3915 if (result != GTK_RESPONSE_ACCEPT)
3918 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3919 /* Offer the connection dialog if necessary: */
3920 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3923 /* Do window specific stuff */
3924 if (MODEST_IS_MAIN_WINDOW (win))
3925 modest_ui_actions_on_main_window_move_to (action,
3928 MODEST_MAIN_WINDOW (win));
3930 modest_ui_actions_on_msg_view_window_move_to (action,
3932 MODEST_MSG_VIEW_WINDOW (win));
3935 g_object_unref (dst_folder);
3939 * Calls #HeadersFunc for each header already selected in the main
3940 * window or the message currently being shown in the msg view window
3943 do_headers_action (ModestWindow *win,
3947 TnyList *headers_list = NULL;
3948 TnyIterator *iter = NULL;
3949 TnyHeader *header = NULL;
3950 TnyFolder *folder = NULL;
3953 headers_list = get_selected_headers (win);
3957 /* Get the folder */
3958 iter = tny_list_create_iterator (headers_list);
3959 header = TNY_HEADER (tny_iterator_get_current (iter));
3961 folder = tny_header_get_folder (header);
3962 g_object_unref (header);
3965 /* Call the function for each header */
3966 while (!tny_iterator_is_done (iter)) {
3967 header = TNY_HEADER (tny_iterator_get_current (iter));
3968 func (header, win, user_data);
3969 g_object_unref (header);
3970 tny_iterator_next (iter);
3973 /* Trick: do a poke status in order to speed up the signaling
3975 tny_folder_poke_status (folder);
3978 g_object_unref (folder);
3979 g_object_unref (iter);
3980 g_object_unref (headers_list);
3984 modest_ui_actions_view_attachment (GtkAction *action,
3985 ModestWindow *window)
3987 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3988 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3990 /* not supported window for this action */
3991 g_return_if_reached ();
3996 modest_ui_actions_save_attachments (GtkAction *action,
3997 ModestWindow *window)
3999 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4000 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4002 /* not supported window for this action */
4003 g_return_if_reached ();
4008 modest_ui_actions_remove_attachments (GtkAction *action,
4009 ModestWindow *window)
4011 if (MODEST_IS_MAIN_WINDOW (window)) {
4012 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4013 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4014 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4016 /* not supported window for this action */
4017 g_return_if_reached ();
4022 modest_ui_actions_on_settings (GtkAction *action,
4027 dialog = modest_platform_get_global_settings_dialog ();
4028 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4029 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4030 gtk_widget_show_all (dialog);
4032 gtk_dialog_run (GTK_DIALOG (dialog));
4034 gtk_widget_destroy (dialog);
4038 modest_ui_actions_on_help (GtkAction *action,
4041 const gchar *help_id = NULL;
4043 if (MODEST_IS_MAIN_WINDOW (win)) {
4044 const gchar *action_name;
4045 action_name = gtk_action_get_name (action);
4047 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4048 !strcmp (action_name, "HeaderViewCSMHelp")) {
4049 GtkWidget *folder_view;
4050 TnyFolderStore *folder_store;
4051 /* Get selected folder */
4052 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4053 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4054 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4056 /* Switch help_id */
4057 if (TNY_IS_FOLDER (folder_store)) {
4058 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4059 case TNY_FOLDER_TYPE_NORMAL:
4060 help_id = "applications_email_managefolders";
4062 case TNY_FOLDER_TYPE_INBOX:
4063 help_id = "applications_email_inbox";
4065 case TNY_FOLDER_TYPE_OUTBOX:
4066 help_id = "applications_email_outbox";
4068 case TNY_FOLDER_TYPE_SENT:
4069 help_id = "applications_email_sent";
4071 case TNY_FOLDER_TYPE_DRAFTS:
4072 help_id = "applications_email_drafts";
4074 case TNY_FOLDER_TYPE_ARCHIVE:
4075 help_id = "applications_email_managefolders";
4078 help_id = "applications_email_managefolders";
4081 help_id = "applications_email_mainview";
4083 g_object_unref (folder_store);
4085 help_id = "applications_email_mainview";
4087 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4088 help_id = "applications_email_viewer";
4089 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4090 help_id = "applications_email_editor";
4092 modest_platform_show_help (GTK_WINDOW (win), help_id);
4096 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4097 ModestWindow *window)
4099 ModestMailOperation *mail_op;
4103 headers = get_selected_headers (window);
4107 /* Create mail operation */
4108 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4110 modest_ui_actions_get_msgs_full_error_handler,
4112 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4113 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4116 g_object_unref (headers);
4117 g_object_unref (mail_op);
4121 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4122 ModestWindow *window)
4124 g_return_if_fail (MODEST_IS_WINDOW (window));
4127 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4131 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4132 ModestWindow *window)
4134 g_return_if_fail (MODEST_IS_WINDOW (window));
4137 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4141 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4142 ModestWindow *window)
4144 g_return_if_fail (MODEST_IS_WINDOW (window));
4147 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4151 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4152 ModestWindow *window)
4154 g_return_if_fail (MODEST_IS_WINDOW (window));
4157 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4161 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4162 ModestWindow *window)
4164 g_return_if_fail (MODEST_IS_WINDOW (window));
4167 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4171 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4172 ModestWindow *window)
4174 g_return_if_fail (MODEST_IS_WINDOW (window));
4177 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4181 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4182 ModestWindow *window)
4184 g_return_if_fail (MODEST_IS_WINDOW (window));
4187 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4191 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4192 ModestWindow *window)
4194 g_return_if_fail (MODEST_IS_WINDOW (window));
4197 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4201 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4203 g_return_if_fail (MODEST_IS_WINDOW (window));
4206 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4210 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4212 g_return_if_fail (MODEST_IS_WINDOW (window));
4214 modest_platform_show_search_messages (GTK_WINDOW (window));
4218 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4220 g_return_if_fail (MODEST_IS_WINDOW (win));
4221 modest_platform_show_addressbook (GTK_WINDOW (win));
4226 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4227 ModestWindow *window)
4229 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4231 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4235 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4236 ModestMailOperationState *state,
4239 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4241 /* Set send/receive operation finished */
4242 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4243 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));