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,
142 static gboolean download_uncached_messages (TnyList *header_list,
146 /* static gint msgs_move_to_confirmation (GtkWindow *win, */
147 /* TnyFolder *dest_folder, */
148 /* gboolean delete, */
149 /* TnyList *headers); */
152 /* Show the account creation wizard dialog.
153 * returns: TRUE if an account was created. FALSE if the user cancelled.
156 modest_run_account_setup_wizard (ModestWindow *win)
158 gboolean result = FALSE;
159 ModestEasysetupWizardDialog *wizard;
162 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
164 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
166 wizard = modest_easysetup_wizard_dialog_new_or_present ();
168 /* if wizard == NULL it means there is already a easy setup thingy running;
169 * in that case, don't do anything here; the call above will present it instead */
171 g_message ("%s: easysetup wizard already running", __FUNCTION__);
175 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
177 /* Don't make this a modal window, because secondary windows will then
178 * be unusable, freezing the UI: */
179 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
181 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
182 if (dialog_response == GTK_RESPONSE_CANCEL)
185 /* Check whether an account was created: */
186 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
189 gtk_widget_destroy (GTK_WIDGET (wizard));
196 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
199 const gchar *authors[] = {
200 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
203 about = gtk_about_dialog_new ();
204 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
205 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
206 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
207 _("Copyright (c) 2006, Nokia Corporation\n"
208 "All rights reserved."));
209 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
210 _("a modest e-mail client\n\n"
211 "design and implementation: Dirk-Jan C. Binnema\n"
212 "contributions from the fine people at KC and Ig\n"
213 "uses the tinymail email framework written by Philip van Hoof"));
214 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
215 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
216 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
217 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
219 gtk_dialog_run (GTK_DIALOG (about));
220 gtk_widget_destroy(about);
224 * Gets the list of currently selected messages. If the win is the
225 * main window, then it returns a newly allocated list of the headers
226 * selected in the header view. If win is the msg view window, then
227 * the value returned is a list with just a single header.
229 * The caller of this funcion must free the list.
232 get_selected_headers (ModestWindow *win)
234 if (MODEST_IS_MAIN_WINDOW(win)) {
235 GtkWidget *header_view;
237 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
238 MODEST_WIDGET_TYPE_HEADER_VIEW);
239 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
241 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
242 /* for MsgViewWindows, we simply return a list with one element */
244 TnyList *list = NULL;
246 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
247 if (header != NULL) {
248 list = tny_simple_list_new ();
249 tny_list_prepend (list, G_OBJECT(header));
250 g_object_unref (G_OBJECT(header));
260 headers_action_mark_as_read (TnyHeader *header,
264 TnyHeaderFlags flags;
266 g_return_if_fail (TNY_IS_HEADER(header));
268 flags = tny_header_get_flags (header);
269 if (flags & TNY_HEADER_FLAG_SEEN) return;
270 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
274 headers_action_mark_as_unread (TnyHeader *header,
278 TnyHeaderFlags flags;
280 g_return_if_fail (TNY_IS_HEADER(header));
282 flags = tny_header_get_flags (header);
283 if (flags & TNY_HEADER_FLAG_SEEN) {
284 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
288 /** A convenience method, because deleting a message is
289 * otherwise complicated, and it's best to change it in one place
292 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
294 ModestMailOperation *mail_op = NULL;
295 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
296 win ? G_OBJECT(win) : NULL);
297 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
300 /* Always delete. TODO: Move to trash still not supported */
301 modest_mail_operation_remove_msg (mail_op, header, FALSE);
302 g_object_unref (G_OBJECT (mail_op));
306 headers_action_delete (TnyHeader *header,
310 modest_do_message_delete (header, win);
313 /** After deleing a message that is currently visible in a window,
314 * show the next message from the list, or close the window if there are no more messages.
316 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
318 /* Close msg view window or select next */
319 if (modest_msg_view_window_last_message_selected (win) &&
320 modest_msg_view_window_first_message_selected (win)) {
321 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
323 if (!modest_msg_view_window_select_next_message (win)) {
325 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
331 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
333 TnyList *header_list = NULL;
334 TnyIterator *iter = NULL;
335 TnyHeader *header = NULL;
336 gchar *message = NULL;
339 ModestWindowMgr *mgr;
340 GtkWidget *header_view = NULL;
342 g_return_if_fail (MODEST_IS_WINDOW(win));
344 /* Check first if the header view has the focus */
345 if (MODEST_IS_MAIN_WINDOW (win)) {
347 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
348 MODEST_WIDGET_TYPE_HEADER_VIEW);
349 if (!gtk_widget_is_focus (header_view))
353 /* Get the headers, either from the header view (if win is the main window),
354 * or from the message view window: */
355 header_list = get_selected_headers (win);
356 if (!header_list) return;
358 /* Check if any of the headers are already opened, or in the process of being opened */
359 if (MODEST_IS_MAIN_WINDOW (win)) {
361 iter = tny_list_create_iterator (header_list);
363 mgr = modest_runtime_get_window_mgr ();
364 while (!tny_iterator_is_done (iter) && !found) {
365 header = TNY_HEADER (tny_iterator_get_current (iter));
367 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
368 g_object_unref (header);
371 tny_iterator_next (iter);
373 g_object_unref (iter);
378 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
379 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
381 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
385 g_object_unref (header_list);
391 if (tny_list_get_length(header_list) == 1) {
392 iter = tny_list_create_iterator (header_list);
393 header = TNY_HEADER (tny_iterator_get_current (iter));
395 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
396 g_object_unref (header);
399 g_object_unref (iter);
401 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
402 tny_list_get_length(header_list)), desc);
404 /* Confirmation dialog */
405 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
409 if (response == GTK_RESPONSE_OK) {
410 ModestWindow *main_window = NULL;
411 ModestWindowMgr *mgr = NULL;
412 GtkTreeModel *model = NULL;
413 GtkTreeSelection *sel = NULL;
414 GList *sel_list = NULL, *tmp = NULL;
415 GtkTreeRowReference *row_reference = NULL;
416 GtkTreePath *next_path = NULL;
417 TnyFolder *folder = NULL;
420 /* Find last selected row */
421 if (MODEST_IS_MAIN_WINDOW (win)) {
422 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
423 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
424 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
425 for (tmp=sel_list; tmp; tmp=tmp->next) {
426 if (tmp->next == NULL) {
427 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
428 gtk_tree_path_next (next_path);
429 row_reference = gtk_tree_row_reference_new (model, next_path);
430 gtk_tree_path_free (next_path);
435 /* Remove each header. If it's a view window header_view == NULL */
436 do_headers_action (win, headers_action_delete, header_view);
438 /* refresh the header view (removing marked-as-deleted)*/
439 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
441 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
442 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
444 /* Get main window */
445 mgr = modest_runtime_get_window_mgr ();
446 main_window = modest_window_mgr_get_main_window (mgr);
449 /* Move cursor to next row */
452 /* Select next row */
453 if (gtk_tree_row_reference_valid (row_reference)) {
454 next_path = gtk_tree_row_reference_get_path (row_reference);
455 gtk_tree_selection_select_path (sel, next_path);
456 gtk_tree_path_free (next_path);
458 if (row_reference != NULL)
459 gtk_tree_row_reference_free (row_reference);
462 /* Get folder from first header and sync it */
463 iter = tny_list_create_iterator (header_list);
464 header = TNY_HEADER (tny_iterator_get_current (iter));
465 folder = tny_header_get_folder (header);
466 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
467 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
468 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
469 else if (TNY_IS_CAMEL_POP_FOLDER (folder))
470 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
471 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
474 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
475 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
478 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
482 g_object_unref (header);
483 g_object_unref (iter);
484 g_object_unref (folder);
486 /* Update toolbar dimming state */
487 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
490 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
491 g_list_free (sel_list);
497 g_object_unref (header_list);
503 /* delete either message or folder, based on where we are */
505 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
507 g_return_if_fail (MODEST_IS_WINDOW(win));
509 /* Check first if the header view has the focus */
510 if (MODEST_IS_MAIN_WINDOW (win)) {
512 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
513 MODEST_WIDGET_TYPE_FOLDER_VIEW);
514 if (gtk_widget_is_focus (w)) {
515 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
519 modest_ui_actions_on_delete_message (action, win);
525 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
527 #ifdef MODEST_PLATFORM_MAEMO
528 modest_osso_save_state();
529 #endif /* MODEST_PLATFORM_MAEMO */
531 g_debug ("closing down, clearing %d item(s) from operation queue",
532 modest_mail_operation_queue_num_elements
533 (modest_runtime_get_mail_operation_queue()));
535 /* cancel all outstanding operations */
536 modest_mail_operation_queue_cancel_all
537 (modest_runtime_get_mail_operation_queue());
539 g_debug ("queue has been cleared");
541 /* note: when modest-tny-account-store is finalized,
542 it will automatically set all network connections
549 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
553 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
555 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
556 /* gtk_widget_destroy (GTK_WIDGET (win)); */
557 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
558 /* gboolean ret_value; */
559 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
560 /* } else if (MODEST_IS_WINDOW (win)) { */
561 /* gtk_widget_destroy (GTK_WIDGET (win)); */
563 /* g_return_if_reached (); */
568 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
570 GtkClipboard *clipboard = NULL;
571 gchar *selection = NULL;
573 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
574 selection = gtk_clipboard_wait_for_text (clipboard);
576 /* Question: why is the clipboard being used here?
577 * It doesn't really make a lot of sense. */
581 modest_address_book_add_address (selection);
587 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
589 /* This is currently only implemented for Maemo */
590 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
591 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
592 modest_run_account_setup_wizard (win);
595 /* Show the list of accounts: */
596 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
597 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
599 /* Don't make this a modal window, because secondary windows will then
600 * be unusable, freezing the UI: */
601 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
602 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
605 GtkWidget *dialog, *label;
607 /* Create the widgets */
609 dialog = gtk_dialog_new_with_buttons ("Message",
611 GTK_DIALOG_DESTROY_WITH_PARENT,
615 label = gtk_label_new ("Hello World!");
617 /* Ensure that the dialog box is destroyed when the user responds. */
619 g_signal_connect_swapped (dialog, "response",
620 G_CALLBACK (gtk_widget_destroy),
623 /* Add the label, and show everything we've added to the dialog. */
625 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
627 gtk_widget_show_all (dialog);
628 #endif /* MODEST_PLATFORM_MAEMO */
632 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
634 ModestWindow *main_window = MODEST_WINDOW (user_data);
636 /* Save any changes. */
637 modest_connection_specific_smtp_window_save_server_accounts (
638 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
639 modest_window_get_active_account (main_window));
640 gtk_widget_destroy (GTK_WIDGET (window));
646 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
648 /* This is currently only implemented for Maemo,
649 * because it requires an API (libconic) to detect different connection
652 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
654 /* Create the window if necessary: */
655 const gchar *active_account_name = modest_window_get_active_account (win);
657 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
658 * or show the default account?
659 * If we show the default account then the account name should be shown in
660 * the window when we show it. */
661 if (!active_account_name) {
662 g_warning ("%s: No account is active.", __FUNCTION__);
666 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
667 modest_connection_specific_smtp_window_fill_with_connections (
668 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
669 modest_runtime_get_account_mgr(),
670 active_account_name);
672 /* Show the window: */
673 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
674 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
675 gtk_widget_show (specific_window);
677 /* Save changes when the window is hidden: */
678 g_signal_connect (specific_window, "hide",
679 G_CALLBACK (on_smtp_servers_window_hide), win);
680 #endif /* MODEST_PLATFORM_MAEMO */
684 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
686 ModestWindow *msg_win = NULL;
688 TnyFolder *folder = NULL;
689 gchar *account_name = NULL;
690 gchar *from_str = NULL;
691 /* GError *err = NULL; */
692 TnyAccount *account = NULL;
693 ModestWindowMgr *mgr;
694 gchar *signature = NULL, *blank_and_signature = NULL;
696 /* if there are no accounts yet, just show the wizard */
697 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
698 const gboolean created = modest_run_account_setup_wizard (win);
703 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
705 account_name = g_strdup (modest_window_get_active_account (win));
707 g_printerr ("modest: no account found\n");
711 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
713 TNY_ACCOUNT_TYPE_STORE);
715 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
719 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
721 g_printerr ("modest: failed get from string for '%s'\n", account_name);
725 gboolean use_signature = FALSE;
726 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
729 blank_and_signature = g_strconcat ("\n", signature, NULL);
731 blank_and_signature = g_strdup ("");
736 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
738 g_printerr ("modest: failed to create new msg\n");
742 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
744 g_printerr ("modest: failed to find Drafts folder\n");
749 /* Create and register edit window */
750 /* This is destroyed by TODO. */
751 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
752 mgr = modest_runtime_get_window_mgr ();
753 modest_window_mgr_register_window (mgr, msg_win);
756 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
758 gtk_widget_show_all (GTK_WIDGET (msg_win));
761 g_free (account_name);
763 g_free (blank_and_signature);
765 g_object_unref (msg_win);
767 g_object_unref (G_OBJECT(account));
769 g_object_unref (G_OBJECT(msg));
771 g_object_unref (G_OBJECT(folder));
775 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
779 ModestMailOperationStatus status;
781 /* If there is no message or the operation was not successful */
782 status = modest_mail_operation_get_status (mail_op);
783 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
785 /* Remove the header from the preregistered uids */
786 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
796 open_msg_cb (ModestMailOperation *mail_op,
801 ModestWindowMgr *mgr = NULL;
802 ModestWindow *parent_win = NULL;
803 ModestWindow *win = NULL;
804 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
805 gchar *account = NULL;
808 /* Do nothing if there was any problem with the mail
809 operation. The error will be shown by the error_handler of
810 the mail operation */
811 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
815 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
816 folder = tny_header_get_folder (header);
818 /* Mark header as read */
819 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
822 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
824 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
826 /* Gets folder type (OUTBOX headers will be opened in edit window */
827 if (modest_tny_folder_is_local_folder (folder))
828 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
830 /* If the header is in the drafts folder then open the editor,
831 else the message view window */
832 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
833 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
834 /* we cannot edit without a valid account... */
835 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
836 const gboolean created = modest_run_account_setup_wizard(parent_win);
840 win = modest_msg_edit_window_new (msg, account, TRUE);
843 gchar *uid = modest_tny_folder_get_header_unique_id (header);
845 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
846 GtkWidget *header_view;
847 GtkTreeSelection *sel;
848 GList *sel_list = NULL;
851 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
852 MODEST_WIDGET_TYPE_HEADER_VIEW);
854 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
855 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
857 if (sel_list != NULL) {
858 GtkTreeRowReference *row_reference;
860 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
861 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
862 g_list_free (sel_list);
864 win = modest_msg_view_window_new_with_header_model (
865 msg, account, (const gchar*) uid,
866 model, row_reference);
867 gtk_tree_row_reference_free (row_reference);
869 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
872 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
877 /* Register and show new window */
879 mgr = modest_runtime_get_window_mgr ();
880 modest_window_mgr_register_window (mgr, win);
881 g_object_unref (win);
882 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
883 gtk_widget_show_all (GTK_WIDGET(win));
886 /* Update toolbar dimming state */
887 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
888 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
894 g_object_unref (parent_win);
895 g_object_unref (folder);
899 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
903 GObject *win = modest_mail_operation_get_source (mail_op);
905 error = modest_mail_operation_get_error (mail_op);
906 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
908 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
910 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
913 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
914 _("mail_ni_ui_folder_get_msg_folder_error"));
918 g_object_unref (win);
922 * This function is used by both modest_ui_actions_on_open and
923 * modest_ui_actions_on_header_activated. This way we always do the
924 * same when trying to open messages.
927 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
929 ModestWindowMgr *mgr = NULL;
930 TnyIterator *iter = NULL;
931 ModestMailOperation *mail_op = NULL;
932 TnyList *not_opened_headers = NULL;
933 TnyHeaderFlags flags = 0;
935 g_return_if_fail (headers != NULL);
937 /* Check that only one message is selected for opening */
938 if (tny_list_get_length (headers) != 1) {
939 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
940 _("mcen_ib_select_one_message"));
945 /* Look if we already have a message view for each header. If
946 true, then remove the header from the list of headers to
948 mgr = modest_runtime_get_window_mgr ();
949 iter = tny_list_create_iterator (headers);
950 not_opened_headers = tny_simple_list_new ();
952 while (!tny_iterator_is_done (iter)) {
954 ModestWindow *window = NULL;
955 TnyHeader *header = NULL;
956 gboolean found = FALSE;
958 header = TNY_HEADER (tny_iterator_get_current (iter));
960 flags = tny_header_get_flags (header);
963 found = modest_window_mgr_find_registered_header (mgr, header, &window);
965 /* Do not open again the message and present the
966 window to the user */
969 gtk_window_present (GTK_WINDOW (window));
971 /* the header has been registered already, we don't do
972 * anything but wait for the window to come up*/
973 g_debug ("header %p already registered, waiting for window", header);
975 tny_list_append (not_opened_headers, G_OBJECT (header));
979 g_object_unref (header);
981 tny_iterator_next (iter);
983 g_object_unref (iter);
986 /* If some messages would have to be downloaded, ask the user to
987 * make a connection. It's generally easier to do this here (in the mainloop)
988 * than later in a thread:
990 if (tny_list_get_length (not_opened_headers) > 0) {
992 gboolean found = FALSE;
994 iter = tny_list_create_iterator (not_opened_headers);
995 while (!tny_iterator_is_done (iter) && !found) {
996 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
997 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1000 tny_iterator_next (iter);
1002 g_object_unref (header);
1004 g_object_unref (iter);
1006 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1007 g_object_unref (not_opened_headers);
1012 /* Register the headers before actually creating the windows: */
1013 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1014 while (!tny_iterator_is_done (iter_not_opened)) {
1015 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1017 modest_window_mgr_register_header (mgr, header);
1018 g_object_unref (header);
1021 tny_iterator_next (iter_not_opened);
1023 g_object_unref (iter_not_opened);
1024 iter_not_opened = NULL;
1026 /* Open each message */
1027 if (tny_list_get_length (not_opened_headers) > 0) {
1028 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1030 modest_ui_actions_get_msgs_full_error_handler,
1032 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1033 if (tny_list_get_length (not_opened_headers) > 1) {
1034 modest_mail_operation_get_msgs_full (mail_op,
1040 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1041 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1042 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1043 g_object_unref (header);
1044 g_object_unref (iter);
1046 g_object_unref (mail_op);
1050 if (not_opened_headers != NULL)
1051 g_object_unref (not_opened_headers);
1055 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1060 headers = get_selected_headers (win);
1065 _modest_ui_actions_open (headers, win);
1067 g_object_unref(headers);
1072 free_reply_forward_helper (gpointer data)
1074 ReplyForwardHelper *helper;
1076 helper = (ReplyForwardHelper *) data;
1077 g_free (helper->account_name);
1078 g_slice_free (ReplyForwardHelper, helper);
1082 reply_forward_cb (ModestMailOperation *mail_op,
1088 ReplyForwardHelper *rf_helper;
1089 ModestWindow *msg_win = NULL;
1090 ModestEditType edit_type;
1092 TnyAccount *account = NULL;
1093 ModestWindowMgr *mgr = NULL;
1094 gchar *signature = NULL;
1096 /* If there was any error. The mail operation could be NULL,
1097 this means that we already have the message downloaded and
1098 that we didn't do a mail operation to retrieve it */
1099 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1102 g_return_if_fail (user_data != NULL);
1103 rf_helper = (ReplyForwardHelper *) user_data;
1105 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1106 rf_helper->account_name);
1107 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1108 rf_helper->account_name,
1109 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1110 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1111 rf_helper->account_name,
1112 MODEST_ACCOUNT_SIGNATURE, FALSE);
1115 /* Create reply mail */
1116 switch (rf_helper->action) {
1119 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1120 rf_helper->reply_forward_type,
1121 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1123 case ACTION_REPLY_TO_ALL:
1125 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1126 MODEST_TNY_MSG_REPLY_MODE_ALL);
1127 edit_type = MODEST_EDIT_TYPE_REPLY;
1129 case ACTION_FORWARD:
1131 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1132 edit_type = MODEST_EDIT_TYPE_FORWARD;
1135 g_return_if_reached ();
1142 g_printerr ("modest: failed to create message\n");
1146 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1147 rf_helper->account_name,
1148 TNY_ACCOUNT_TYPE_STORE);
1150 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1154 /* Create and register the windows */
1155 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1156 mgr = modest_runtime_get_window_mgr ();
1157 modest_window_mgr_register_window (mgr, msg_win);
1159 if (rf_helper->parent_window != NULL) {
1160 gdouble parent_zoom;
1162 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1163 modest_window_set_zoom (msg_win, parent_zoom);
1166 /* Show edit window */
1167 gtk_widget_show_all (GTK_WIDGET (msg_win));
1171 g_object_unref (msg_win);
1173 g_object_unref (G_OBJECT (new_msg));
1175 g_object_unref (G_OBJECT (account));
1176 /* g_object_unref (msg); */
1177 free_reply_forward_helper (rf_helper);
1181 * Checks a list of headers. If any of them are not currently
1182 * downloaded (CACHED) then it asks the user for permission to
1185 * Returns FALSE if the user does not want to download the
1186 * messages. Returns TRUE if the user allowed the download or if all
1187 * of them are currently downloaded
1190 download_uncached_messages (TnyList *header_list,
1195 gint uncached_messages = 0;
1197 iter = tny_list_create_iterator (header_list);
1198 while (!tny_iterator_is_done (iter)) {
1201 header = TNY_HEADER (tny_iterator_get_current (iter));
1203 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1204 uncached_messages ++;
1205 g_object_unref (header);
1208 tny_iterator_next (iter);
1210 g_object_unref (iter);
1212 /* Ask for user permission to download the messages */
1214 if (uncached_messages > 0) {
1215 gboolean download = TRUE;
1216 if (!tny_device_is_online (modest_runtime_get_device())) {
1217 GtkResponseType response =
1218 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1219 ngettext("mcen_nc_get_msg",
1221 uncached_messages));
1222 if (response == GTK_RESPONSE_CANCEL) download = FALSE;
1225 /* If a download will be necessary, make sure that we have a connection: */
1226 retval = modest_platform_connect_and_wait(win, NULL);
1236 * Common code for the reply and forward actions
1239 reply_forward (ReplyForwardAction action, ModestWindow *win)
1241 ModestMailOperation *mail_op = NULL;
1242 TnyList *header_list = NULL;
1243 ReplyForwardHelper *rf_helper = NULL;
1244 guint reply_forward_type;
1245 gboolean continue_download = TRUE;
1246 gboolean do_retrieve = TRUE;
1248 g_return_if_fail (MODEST_IS_WINDOW(win));
1250 /* we need an account when editing */
1251 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1252 const gboolean created = modest_run_account_setup_wizard (win);
1257 header_list = get_selected_headers (win);
1261 reply_forward_type =
1262 modest_conf_get_int (modest_runtime_get_conf (),
1263 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1266 /* Check that the messages have been previously downloaded */
1267 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1269 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1270 if (!continue_download) {
1271 g_object_unref (header_list);
1275 /* We assume that we can only select messages of the
1276 same folder and that we reply all of them from the
1277 same account. In fact the interface currently only
1278 allows single selection */
1281 rf_helper = g_slice_new0 (ReplyForwardHelper);
1282 rf_helper->reply_forward_type = reply_forward_type;
1283 rf_helper->action = action;
1284 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1286 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1287 rf_helper->parent_window = GTK_WIDGET (win);
1288 if (!rf_helper->account_name)
1289 rf_helper->account_name =
1290 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1292 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1295 /* Get header and message. Do not free them here, the
1296 reply_forward_cb must do it */
1297 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1298 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1299 if (!msg || !header) {
1301 g_object_unref (msg);
1302 g_printerr ("modest: no message found\n");
1305 reply_forward_cb (NULL, header, msg, rf_helper);
1308 g_object_unref (header);
1313 /* Only reply/forward to one message */
1314 iter = tny_list_create_iterator (header_list);
1315 header = TNY_HEADER (tny_iterator_get_current (iter));
1316 g_object_unref (iter);
1319 /* Retrieve messages */
1321 mail_op = modest_mail_operation_new_with_error_handling (
1322 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1324 modest_ui_actions_get_msgs_full_error_handler,
1326 modest_mail_operation_queue_add (
1327 modest_runtime_get_mail_operation_queue (), mail_op);
1329 modest_mail_operation_get_msg (mail_op,
1334 g_object_unref(mail_op);
1336 /* we put a ref here to prevent double unref as the reply
1337 * forward callback unrefs the header at its end */
1338 reply_forward_cb (NULL, header, NULL, rf_helper);
1342 g_object_unref (header);
1348 g_object_unref (header_list);
1352 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1354 g_return_if_fail (MODEST_IS_WINDOW(win));
1356 reply_forward (ACTION_REPLY, win);
1360 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1362 g_return_if_fail (MODEST_IS_WINDOW(win));
1364 reply_forward (ACTION_FORWARD, win);
1368 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1370 g_return_if_fail (MODEST_IS_WINDOW(win));
1372 reply_forward (ACTION_REPLY_TO_ALL, win);
1376 modest_ui_actions_on_next (GtkAction *action,
1377 ModestWindow *window)
1379 if (MODEST_IS_MAIN_WINDOW (window)) {
1380 GtkWidget *header_view;
1382 header_view = modest_main_window_get_child_widget (
1383 MODEST_MAIN_WINDOW(window),
1384 MODEST_WIDGET_TYPE_HEADER_VIEW);
1388 modest_header_view_select_next (
1389 MODEST_HEADER_VIEW(header_view));
1390 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1391 modest_msg_view_window_select_next_message (
1392 MODEST_MSG_VIEW_WINDOW (window));
1394 g_return_if_reached ();
1399 modest_ui_actions_on_prev (GtkAction *action,
1400 ModestWindow *window)
1402 g_return_if_fail (MODEST_IS_WINDOW(window));
1404 if (MODEST_IS_MAIN_WINDOW (window)) {
1405 GtkWidget *header_view;
1406 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1407 MODEST_WIDGET_TYPE_HEADER_VIEW);
1411 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1412 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1413 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1415 g_return_if_reached ();
1420 modest_ui_actions_on_sort (GtkAction *action,
1421 ModestWindow *window)
1423 g_return_if_fail (MODEST_IS_WINDOW(window));
1425 if (MODEST_IS_MAIN_WINDOW (window)) {
1426 GtkWidget *header_view;
1427 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1428 MODEST_WIDGET_TYPE_HEADER_VIEW);
1430 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1435 /* Show sorting dialog */
1436 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1441 new_messages_arrived (ModestMailOperation *self,
1445 ModestMainWindow *win = NULL;
1446 GtkWidget *folder_view = NULL;
1447 TnyFolderStore *folder = NULL;
1448 gboolean folder_empty = FALSE;
1450 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1451 win = MODEST_MAIN_WINDOW (user_data);
1453 /* Set contents style of headers view */
1454 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1455 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1456 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1457 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1460 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1463 modest_main_window_set_contents_style (win,
1464 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1467 /* Notify new messages have been downloaded */
1468 if (new_messages > 0)
1469 modest_platform_on_new_msg ();
1473 * This function performs the send & receive required actions. The
1474 * window is used to create the mail operation. Typically it should
1475 * always be the main window, but we pass it as argument in order to
1479 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1481 gchar *acc_name = NULL;
1482 ModestMailOperation *mail_op;
1484 /* If no account name was provided then get the current account, and if
1485 there is no current account then pick the default one: */
1486 if (!account_name) {
1487 acc_name = g_strdup (modest_window_get_active_account(win));
1489 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1491 g_printerr ("modest: cannot get default account\n");
1495 acc_name = g_strdup (account_name);
1498 /* Set send/receive operation in progress */
1499 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1501 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1503 modest_ui_actions_send_receive_error_handler,
1506 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1507 G_CALLBACK (_on_send_receive_progress_changed),
1510 /* Send & receive. */
1511 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1512 /* Receive and then send. The operation is tagged initially as
1513 a receive operation because the account update performs a
1514 receive and then a send. The operation changes its type
1515 internally, so the progress objects will receive the proper
1516 progress information */
1517 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1518 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1519 g_object_unref (G_OBJECT (mail_op));
1527 modest_ui_actions_do_cancel_send (const gchar *account_name,
1530 TnyTransportAccount *transport_account;
1531 TnySendQueue *send_queue = NULL;
1532 GError *error = NULL;
1534 /* Get transport account */
1536 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1537 (modest_runtime_get_account_store(),
1539 TNY_ACCOUNT_TYPE_TRANSPORT));
1540 if (!transport_account) {
1541 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1546 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1547 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1548 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1549 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1550 "modest: could not find send queue for account\n");
1552 /* Keeep messages in outbox folder */
1553 tny_send_queue_cancel (send_queue, FALSE, &error);
1557 if (transport_account != NULL)
1558 g_object_unref (G_OBJECT (transport_account));
1562 modest_ui_actions_cancel_send_all (ModestWindow *win)
1564 GSList *account_names, *iter;
1566 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1569 iter = account_names;
1571 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1572 iter = g_slist_next (iter);
1575 modest_account_mgr_free_account_names (account_names);
1576 account_names = NULL;
1580 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1583 /* Check if accounts exist */
1584 gboolean accounts_exist =
1585 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1587 /* If not, allow the user to create an account before trying to send/receive. */
1588 if (!accounts_exist)
1589 modest_ui_actions_on_accounts (NULL, win);
1591 /* Cancel all sending operaitons */
1592 modest_ui_actions_cancel_send_all (win);
1596 * Refreshes all accounts. This function will be used by automatic
1600 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1602 GSList *account_names, *iter;
1604 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1607 iter = account_names;
1609 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1610 iter = g_slist_next (iter);
1613 modest_account_mgr_free_account_names (account_names);
1614 account_names = NULL;
1618 modest_do_refresh_current_folder(ModestWindow *win)
1620 /* Refresh currently selected folder. Note that if we only
1621 want to retreive the headers, then the refresh only will
1622 invoke a poke_status over all folders, i.e., only the
1623 total/unread count will be updated */
1624 if (MODEST_IS_MAIN_WINDOW (win)) {
1625 GtkWidget *header_view, *folder_view;
1626 TnyFolderStore *folder_store;
1628 /* Get folder and header view */
1630 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1631 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1633 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1635 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1637 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1638 MODEST_WIDGET_TYPE_HEADER_VIEW);
1640 /* We do not need to set the contents style
1641 because it hasn't changed. We also do not
1642 need to save the widget status. Just force
1644 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1645 TNY_FOLDER (folder_store),
1646 folder_refreshed_cb,
1647 MODEST_MAIN_WINDOW (win));
1651 g_object_unref (folder_store);
1657 * Handler of the click on Send&Receive button in the main toolbar
1660 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1662 /* Check if accounts exist */
1663 gboolean accounts_exist =
1664 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1666 /* If not, allow the user to create an account before trying to send/receive. */
1667 if (!accounts_exist)
1668 modest_ui_actions_on_accounts (NULL, win);
1670 modest_do_refresh_current_folder (win);
1672 /* Refresh the active account */
1673 modest_ui_actions_do_send_receive (NULL, win);
1678 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1681 GtkWidget *header_view;
1683 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1685 header_view = modest_main_window_get_child_widget (main_window,
1686 MODEST_WIDGET_TYPE_HEADER_VIEW);
1690 conf = modest_runtime_get_conf ();
1692 /* what is saved/restored is depending on the style; thus; we save with
1693 * old style, then update the style, and restore for this new style
1695 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1697 if (modest_header_view_get_style
1698 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1699 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1700 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1702 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1703 MODEST_HEADER_VIEW_STYLE_DETAILS);
1705 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1706 MODEST_CONF_HEADER_VIEW_KEY);
1711 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1713 ModestMainWindow *main_window)
1715 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1716 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1718 /* in the case the folder is empty, show the empty folder message and focus
1720 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1721 if (modest_header_view_is_empty (header_view)) {
1722 TnyFolder *folder = modest_header_view_get_folder (header_view);
1723 GtkWidget *folder_view =
1724 modest_main_window_get_child_widget (main_window,
1725 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1727 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1728 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1732 /* If no header has been selected then exit */
1737 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1738 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1740 /* Update toolbar dimming state */
1741 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1745 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1747 ModestMainWindow *main_window)
1751 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1757 /* headers = tny_simple_list_new (); */
1758 /* tny_list_prepend (headers, G_OBJECT (header)); */
1759 headers = modest_header_view_get_selected_headers (header_view);
1761 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1763 g_object_unref (headers);
1767 set_active_account_from_tny_account (TnyAccount *account,
1768 ModestWindow *window)
1770 const gchar *server_acc_name = tny_account_get_id (account);
1772 /* We need the TnyAccount provided by the
1773 account store because that is the one that
1774 knows the name of the Modest account */
1775 TnyAccount *modest_server_account = modest_server_account =
1776 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1777 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1780 const gchar *modest_acc_name =
1781 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1782 modest_window_set_active_account (window, modest_acc_name);
1783 g_object_unref (modest_server_account);
1788 folder_refreshed_cb (ModestMailOperation *mail_op,
1792 ModestMainWindow *win = NULL;
1793 GtkWidget *header_view;
1794 TnyFolder *current_folder;
1795 gboolean folder_empty = FALSE;
1796 gboolean all_marked_as_deleted = FALSE;
1798 g_return_if_fail (TNY_IS_FOLDER (folder));
1800 win = MODEST_MAIN_WINDOW (user_data);
1802 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1805 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1806 if (current_folder != NULL && folder != current_folder) {
1811 /* Check if folder is empty and set headers view contents style */
1812 folder_empty = (tny_folder_get_all_count (folder) == 0);
1813 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1814 folder_empty = folder_empty || all_marked_as_deleted ;
1817 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1818 modest_main_window_set_contents_style (win,
1819 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1821 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1826 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1827 TnyFolderStore *folder_store,
1829 ModestMainWindow *main_window)
1832 GtkWidget *header_view;
1834 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1836 header_view = modest_main_window_get_child_widget(main_window,
1837 MODEST_WIDGET_TYPE_HEADER_VIEW);
1841 conf = modest_runtime_get_conf ();
1843 if (TNY_IS_ACCOUNT (folder_store)) {
1845 /* Update active account */
1846 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1847 /* Show account details */
1848 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1851 if (TNY_IS_FOLDER (folder_store) && selected) {
1853 /* Update the active account */
1854 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1856 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1857 g_object_unref (account);
1861 /* Set the header style by default, it could
1862 be changed later by the refresh callback to
1864 modest_main_window_set_contents_style (main_window,
1865 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1867 /* Set folder on header view. This function
1868 will call tny_folder_refresh_async so we
1869 pass a callback that will be called when
1870 finished. We use that callback to set the
1871 empty view if there are no messages */
1872 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1873 TNY_FOLDER (folder_store),
1874 folder_refreshed_cb,
1877 /* Restore configuration. We need to do this
1878 *after* the set_folder because the widget
1879 memory asks the header view about its
1881 modest_widget_memory_restore (modest_runtime_get_conf (),
1882 G_OBJECT(header_view),
1883 MODEST_CONF_HEADER_VIEW_KEY);
1885 /* Update the active account */
1886 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1887 /* Save only if we're seeing headers */
1888 if (modest_main_window_get_contents_style (main_window) ==
1889 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1890 modest_widget_memory_save (conf, G_OBJECT (header_view),
1891 MODEST_CONF_HEADER_VIEW_KEY);
1892 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1896 /* Update toolbar dimming state */
1897 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1901 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1908 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1910 online = tny_device_is_online (modest_runtime_get_device());
1913 /* already online -- the item is simply not there... */
1914 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1916 GTK_MESSAGE_WARNING,
1918 _("The %s you selected cannot be found"),
1920 gtk_dialog_run (GTK_DIALOG(dialog));
1922 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1926 GTK_RESPONSE_REJECT,
1928 GTK_RESPONSE_ACCEPT,
1930 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1931 "Do you want to get online?"), item);
1932 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1933 gtk_label_new (txt), FALSE, FALSE, 0);
1934 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1937 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1938 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1939 /* TODO: Comment about why is this commented out: */
1940 /* modest_platform_connect_and_wait (); */
1943 gtk_widget_destroy (dialog);
1947 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1950 /* g_message ("%s %s", __FUNCTION__, link); */
1955 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1958 modest_platform_activate_uri (link);
1962 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1965 modest_platform_show_uri_popup (link);
1969 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1972 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1976 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1977 const gchar *address,
1980 /* g_message ("%s %s", __FUNCTION__, address); */
1984 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1986 TnyTransportAccount *transport_account;
1987 ModestMailOperation *mail_operation;
1989 gchar *account_name, *from;
1990 ModestAccountMgr *account_mgr;
1991 gchar *info_text = NULL;
1993 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1995 data = modest_msg_edit_window_get_msg_data (edit_window);
1997 account_mgr = modest_runtime_get_account_mgr();
1998 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2000 account_name = modest_account_mgr_get_default_account (account_mgr);
2001 if (!account_name) {
2002 g_printerr ("modest: no account found\n");
2003 modest_msg_edit_window_free_msg_data (edit_window, data);
2007 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2008 account_name = g_strdup (data->account_name);
2012 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2013 (modest_runtime_get_account_store(),
2015 TNY_ACCOUNT_TYPE_TRANSPORT));
2016 if (!transport_account) {
2017 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2018 g_free (account_name);
2019 modest_msg_edit_window_free_msg_data (edit_window, data);
2022 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2024 /* Create the mail operation */
2025 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2026 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2028 modest_mail_operation_save_to_drafts (mail_operation,
2040 data->priority_flags);
2043 g_free (account_name);
2044 g_object_unref (G_OBJECT (transport_account));
2045 g_object_unref (G_OBJECT (mail_operation));
2047 modest_msg_edit_window_free_msg_data (edit_window, data);
2049 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2050 modest_platform_information_banner (NULL, NULL, info_text);
2054 /* For instance, when clicking the Send toolbar button when editing a message: */
2056 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2058 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2060 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2063 /* Offer the connection dialog, if necessary: */
2064 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2067 /* FIXME: Code added just for testing. The final version will
2068 use the send queue provided by tinymail and some
2070 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2071 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2073 account_name = modest_account_mgr_get_default_account (account_mgr);
2075 if (!account_name) {
2076 /* Run account setup wizard */
2077 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2082 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2084 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2085 account_name = g_strdup (data->account_name);
2088 /* Get the currently-active transport account for this modest account: */
2089 TnyTransportAccount *transport_account =
2090 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2091 (modest_runtime_get_account_store(),
2093 if (!transport_account) {
2094 /* Run account setup wizard */
2095 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2100 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2102 /* modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent")); */
2104 /* Create the mail operation */
2105 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2106 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2108 modest_mail_operation_send_new_mail (mail_operation,
2119 data->priority_flags);
2123 g_free (account_name);
2124 g_object_unref (G_OBJECT (transport_account));
2125 g_object_unref (G_OBJECT (mail_operation));
2127 modest_msg_edit_window_free_msg_data (edit_window, data);
2128 modest_msg_edit_window_set_sent (edit_window, TRUE);
2130 /* Save settings and close the window: */
2131 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2135 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2136 ModestMsgEditWindow *window)
2138 ModestMsgEditFormatState *format_state = NULL;
2140 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2141 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2143 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2146 format_state = modest_msg_edit_window_get_format_state (window);
2147 g_return_if_fail (format_state != NULL);
2149 format_state->bold = gtk_toggle_action_get_active (action);
2150 modest_msg_edit_window_set_format_state (window, format_state);
2151 g_free (format_state);
2156 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2157 ModestMsgEditWindow *window)
2159 ModestMsgEditFormatState *format_state = NULL;
2161 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2162 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2164 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2167 format_state = modest_msg_edit_window_get_format_state (window);
2168 g_return_if_fail (format_state != NULL);
2170 format_state->italics = gtk_toggle_action_get_active (action);
2171 modest_msg_edit_window_set_format_state (window, format_state);
2172 g_free (format_state);
2177 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2178 ModestMsgEditWindow *window)
2180 ModestMsgEditFormatState *format_state = NULL;
2182 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2183 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2185 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2188 format_state = modest_msg_edit_window_get_format_state (window);
2189 g_return_if_fail (format_state != NULL);
2191 format_state->bullet = gtk_toggle_action_get_active (action);
2192 modest_msg_edit_window_set_format_state (window, format_state);
2193 g_free (format_state);
2198 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2199 GtkRadioAction *selected,
2200 ModestMsgEditWindow *window)
2202 ModestMsgEditFormatState *format_state = NULL;
2203 GtkJustification value;
2205 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2207 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2210 value = gtk_radio_action_get_current_value (selected);
2212 format_state = modest_msg_edit_window_get_format_state (window);
2213 g_return_if_fail (format_state != NULL);
2215 format_state->justification = value;
2216 modest_msg_edit_window_set_format_state (window, format_state);
2217 g_free (format_state);
2221 modest_ui_actions_on_select_editor_color (GtkAction *action,
2222 ModestMsgEditWindow *window)
2224 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2225 g_return_if_fail (GTK_IS_ACTION (action));
2227 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2230 modest_msg_edit_window_select_color (window);
2234 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2235 ModestMsgEditWindow *window)
2237 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2238 g_return_if_fail (GTK_IS_ACTION (action));
2240 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2243 modest_msg_edit_window_select_background_color (window);
2247 modest_ui_actions_on_insert_image (GtkAction *action,
2248 ModestMsgEditWindow *window)
2250 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2251 g_return_if_fail (GTK_IS_ACTION (action));
2253 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2256 modest_msg_edit_window_insert_image (window);
2260 modest_ui_actions_on_attach_file (GtkAction *action,
2261 ModestMsgEditWindow *window)
2263 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2264 g_return_if_fail (GTK_IS_ACTION (action));
2266 modest_msg_edit_window_offer_attach_file (window);
2270 modest_ui_actions_on_remove_attachments (GtkAction *action,
2271 ModestMsgEditWindow *window)
2273 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2274 g_return_if_fail (GTK_IS_ACTION (action));
2276 modest_msg_edit_window_remove_attachments (window, NULL);
2280 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2283 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2284 const GError *error = modest_mail_operation_get_error (mail_op);
2288 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2289 modest_mail_operation_get_error (mail_op)->message);
2294 modest_ui_actions_create_folder(GtkWidget *parent_window,
2295 GtkWidget *folder_view)
2297 TnyFolderStore *parent_folder;
2299 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2301 if (parent_folder) {
2302 gboolean finished = FALSE;
2304 gchar *folder_name = NULL, *suggested_name = NULL;
2305 const gchar *proto_str = NULL;
2306 TnyAccount *account;
2308 if (TNY_IS_ACCOUNT (parent_folder))
2309 account = g_object_ref (parent_folder);
2311 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2312 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2314 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2315 MODEST_PROTOCOL_STORE_POP) {
2317 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2319 g_object_unref (account);
2321 /* Run the new folder dialog */
2323 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2328 g_free (suggested_name);
2329 suggested_name = NULL;
2331 if (result == GTK_RESPONSE_REJECT) {
2334 ModestMailOperation *mail_op;
2335 TnyFolder *new_folder = NULL;
2337 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2338 G_OBJECT(parent_window),
2339 modest_ui_actions_new_folder_error_handler,
2342 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2344 new_folder = modest_mail_operation_create_folder (mail_op,
2346 (const gchar *) folder_name);
2348 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2351 g_object_unref (new_folder);
2354 g_object_unref (mail_op);
2357 suggested_name = folder_name;
2361 g_object_unref (parent_folder);
2366 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2368 GtkWidget *folder_view;
2370 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2372 folder_view = modest_main_window_get_child_widget (main_window,
2373 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2377 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2381 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2384 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2385 const GError *error = NULL;
2386 const gchar *message = NULL;
2388 /* Get error message */
2389 error = modest_mail_operation_get_error (mail_op);
2390 if (error != NULL && error->message != NULL) {
2391 message = error->message;
2393 message = _("!!! FIXME: Unable to rename");
2396 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2401 modest_ui_actions_on_rename_folder (GtkAction *action,
2402 ModestMainWindow *main_window)
2404 TnyFolderStore *folder;
2405 GtkWidget *folder_view;
2406 GtkWidget *header_view;
2408 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2410 folder_view = modest_main_window_get_child_widget (main_window,
2411 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2415 header_view = modest_main_window_get_child_widget (main_window,
2416 MODEST_WIDGET_TYPE_HEADER_VIEW);
2421 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2425 /* Offer the connection dialog if necessary: */
2426 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2427 g_object_unref (G_OBJECT (folder));
2432 if (TNY_IS_FOLDER (folder)) {
2435 const gchar *current_name;
2436 TnyFolderStore *parent;
2438 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2439 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2440 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2441 parent, current_name,
2443 g_object_unref (parent);
2445 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2446 ModestMailOperation *mail_op;
2449 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2450 G_OBJECT(main_window),
2451 modest_ui_actions_rename_folder_error_handler,
2455 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2458 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2460 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2461 TNY_FOLDER(folder), TRUE);
2463 modest_header_view_clear ((ModestHeaderView *) header_view);
2465 modest_mail_operation_rename_folder (mail_op,
2466 TNY_FOLDER (folder),
2467 (const gchar *) folder_name);
2469 g_object_unref (mail_op);
2470 g_free (folder_name);
2473 g_object_unref (folder);
2477 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2480 GObject *win = modest_mail_operation_get_source (mail_op);
2482 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2483 _("mail_in_ui_folder_delete_error"));
2484 g_object_unref (win);
2488 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2490 TnyFolderStore *folder;
2491 GtkWidget *folder_view;
2495 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2497 folder_view = modest_main_window_get_child_widget (main_window,
2498 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2502 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2504 /* Show an error if it's an account */
2505 if (!TNY_IS_FOLDER (folder)) {
2506 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2507 _("mail_in_ui_folder_delete_error"));
2508 g_object_unref (G_OBJECT (folder));
2512 /* Offer the connection dialog if necessary: */
2513 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2514 g_object_unref (G_OBJECT (folder));
2519 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2520 tny_folder_get_name (TNY_FOLDER (folder)));
2521 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2522 (const gchar *) message);
2525 if (response == GTK_RESPONSE_OK) {
2526 ModestMailOperation *mail_op =
2527 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2528 G_OBJECT(main_window),
2529 modest_ui_actions_delete_folder_error_handler,
2532 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2534 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2535 g_object_unref (G_OBJECT (mail_op));
2538 g_object_unref (G_OBJECT (folder));
2542 modest_ui_actions_on_delete_folder (GtkAction *action,
2543 ModestMainWindow *main_window)
2545 GtkWidget *folder_view;
2546 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2548 delete_folder (main_window, FALSE);
2549 folder_view = modest_main_window_get_child_widget (main_window,
2550 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2553 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2557 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2559 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2561 delete_folder (main_window, TRUE);
2566 show_error (GtkWidget *parent_widget, const gchar* text)
2568 hildon_banner_show_information(parent_widget, NULL, text);
2571 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2573 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2580 gtk_dialog_run (dialog);
2581 gtk_widget_destroy (GTK_WIDGET (dialog));
2586 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2587 const gchar* server_account_name,
2592 ModestMainWindow *main_window)
2594 g_return_if_fail(server_account_name);
2595 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2597 /* Initalize output parameters: */
2604 #ifdef MODEST_PLATFORM_MAEMO
2605 /* Maemo uses a different (awkward) button order,
2606 * It should probably just use gtk_alternative_dialog_button_order ().
2608 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2612 GTK_RESPONSE_ACCEPT,
2614 GTK_RESPONSE_REJECT,
2617 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2621 GTK_RESPONSE_REJECT,
2623 GTK_RESPONSE_ACCEPT,
2625 #endif /* MODEST_PLATFORM_MAEMO */
2627 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2629 gchar *server_name = modest_server_account_get_hostname (
2630 modest_runtime_get_account_mgr(), server_account_name);
2631 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2632 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2637 /* This causes a warning because the logical ID has no %s in it,
2638 * though the translation does, but there is not much we can do about that: */
2639 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2640 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2643 g_free (server_name);
2647 gchar *initial_username = modest_server_account_get_username (
2648 modest_runtime_get_account_mgr(), server_account_name);
2650 GtkWidget *entry_username = gtk_entry_new ();
2651 if (initial_username)
2652 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2653 /* Dim this if a connection has ever succeeded with this username,
2654 * as per the UI spec: */
2655 const gboolean username_known =
2656 modest_server_account_get_username_has_succeeded(
2657 modest_runtime_get_account_mgr(), server_account_name);
2658 gtk_widget_set_sensitive (entry_username, !username_known);
2660 #ifdef MODEST_PLATFORM_MAEMO
2661 /* Auto-capitalization is the default, so let's turn it off: */
2662 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2664 /* Create a size group to be used by all captions.
2665 * Note that HildonCaption does not create a default size group if we do not specify one.
2666 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2667 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2669 GtkWidget *caption = hildon_caption_new (sizegroup,
2670 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2671 gtk_widget_show (entry_username);
2672 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2673 FALSE, FALSE, MODEST_MARGIN_HALF);
2674 gtk_widget_show (caption);
2676 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2678 #endif /* MODEST_PLATFORM_MAEMO */
2681 GtkWidget *entry_password = gtk_entry_new ();
2682 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2683 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2685 #ifdef MODEST_PLATFORM_MAEMO
2686 /* Auto-capitalization is the default, so let's turn it off: */
2687 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2688 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2690 caption = hildon_caption_new (sizegroup,
2691 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2692 gtk_widget_show (entry_password);
2693 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2694 FALSE, FALSE, MODEST_MARGIN_HALF);
2695 gtk_widget_show (caption);
2696 g_object_unref (sizegroup);
2698 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2700 #endif /* MODEST_PLATFORM_MAEMO */
2702 /* This is not in the Maemo UI spec:
2703 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2704 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2708 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2710 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2712 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2714 modest_server_account_set_username (
2715 modest_runtime_get_account_mgr(), server_account_name,
2718 const gboolean username_was_changed =
2719 (strcmp (*username, initial_username) != 0);
2720 if (username_was_changed) {
2721 g_warning ("%s: tinymail does not yet support changing the "
2722 "username in the get_password() callback.\n", __FUNCTION__);
2727 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2729 /* We do not save the password in the configuration,
2730 * because this function is only called for passwords that should
2731 * not be remembered:
2732 modest_server_account_set_password (
2733 modest_runtime_get_account_mgr(), server_account_name,
2742 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2754 /* This is not in the Maemo UI spec:
2755 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2761 gtk_widget_destroy (dialog);
2763 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2767 modest_ui_actions_on_cut (GtkAction *action,
2768 ModestWindow *window)
2770 GtkWidget *focused_widget;
2771 GtkClipboard *clipboard;
2773 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2774 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2775 if (GTK_IS_EDITABLE (focused_widget)) {
2776 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2777 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2778 gtk_clipboard_store (clipboard);
2779 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2780 GtkTextBuffer *buffer;
2782 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2783 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2784 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2785 gtk_clipboard_store (clipboard);
2786 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2787 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2788 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2789 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2794 modest_ui_actions_on_copy (GtkAction *action,
2795 ModestWindow *window)
2797 GtkClipboard *clipboard;
2798 GtkWidget *focused_widget;
2800 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2801 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2803 if (GTK_IS_LABEL (focused_widget)) {
2804 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2805 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2806 gtk_clipboard_store (clipboard);
2807 } else if (GTK_IS_EDITABLE (focused_widget)) {
2808 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2809 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2810 gtk_clipboard_store (clipboard);
2811 } else if (GTK_IS_HTML (focused_widget)) {
2812 gtk_html_copy (GTK_HTML (focused_widget));
2813 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2814 gtk_clipboard_store (clipboard);
2815 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2816 GtkTextBuffer *buffer;
2817 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2818 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2819 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2820 gtk_clipboard_store (clipboard);
2821 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2822 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2823 TnyIterator *iter = tny_list_create_iterator (header_list);
2824 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2826 gboolean ask = FALSE;
2828 TnyFolder *folder = tny_header_get_folder (header);
2829 TnyAccount *account = tny_folder_get_account (folder);
2830 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2831 /* If it's POP then ask */
2832 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2833 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2834 g_object_unref (account);
2835 g_object_unref (folder);
2836 g_object_unref (header);
2839 g_object_unref (iter);
2841 /* Check that the messages have been previously downloaded */
2842 gboolean continue_download = TRUE;
2844 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2845 if (continue_download)
2846 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2847 g_object_unref (header_list);
2848 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2849 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2852 /* Show information banner */
2853 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2858 modest_ui_actions_on_undo (GtkAction *action,
2859 ModestWindow *window)
2861 ModestEmailClipboard *clipboard = NULL;
2863 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2864 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2865 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2866 /* Clear clipboard source */
2867 clipboard = modest_runtime_get_email_clipboard ();
2868 modest_email_clipboard_clear (clipboard);
2871 g_return_if_reached ();
2876 modest_ui_actions_on_redo (GtkAction *action,
2877 ModestWindow *window)
2879 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2880 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2883 g_return_if_reached ();
2889 paste_msgs_cb (const GObject *object, gpointer user_data)
2891 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2892 g_return_if_fail (GTK_IS_WIDGET (user_data));
2894 /* destroy information note */
2895 gtk_widget_destroy (GTK_WIDGET(user_data));
2899 paste_as_attachment_free (gpointer data)
2901 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2903 gtk_widget_destroy (helper->banner);
2904 g_object_unref (helper->banner);
2909 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2914 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2915 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2920 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2925 modest_ui_actions_on_paste (GtkAction *action,
2926 ModestWindow *window)
2928 GtkWidget *focused_widget = NULL;
2929 GtkWidget *inf_note = NULL;
2930 ModestMailOperation *mail_op = NULL;
2932 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2933 if (GTK_IS_EDITABLE (focused_widget)) {
2934 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2935 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2936 ModestEmailClipboard *e_clipboard = NULL;
2937 e_clipboard = modest_runtime_get_email_clipboard ();
2938 if (modest_email_clipboard_cleared (e_clipboard)) {
2939 GtkTextBuffer *buffer;
2940 GtkClipboard *clipboard;
2942 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2943 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2944 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2945 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2946 ModestMailOperation *mail_op;
2947 TnyFolder *src_folder;
2950 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2951 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2952 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2953 _CS("ckct_nw_pasting"));
2954 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2955 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2957 if (helper->banner != NULL) {
2958 g_object_ref (G_OBJECT (helper->banner));
2959 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2960 gtk_widget_show (GTK_WIDGET (helper->banner));
2964 modest_mail_operation_get_msgs_full (mail_op,
2966 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2968 paste_as_attachment_free);
2971 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2972 ModestEmailClipboard *clipboard = NULL;
2973 TnyFolder *src_folder = NULL;
2974 TnyFolderStore *folder_store = NULL;
2975 TnyList *data = NULL;
2976 gboolean delete = FALSE;
2978 /* Check clipboard source */
2979 clipboard = modest_runtime_get_email_clipboard ();
2980 if (modest_email_clipboard_cleared (clipboard))
2983 /* Get elements to paste */
2984 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2986 /* Create a new mail operation */
2987 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2989 /* Get destination folder */
2990 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2992 /* transfer messages */
2996 /* Ask for user confirmation */
2997 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2998 TNY_FOLDER (folder_store),
3002 if (response == GTK_RESPONSE_OK) {
3003 /* Launch notification */
3004 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3005 _CS("ckct_nw_pasting"));
3006 if (inf_note != NULL) {
3007 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3008 gtk_widget_show (GTK_WIDGET(inf_note));
3011 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3012 modest_mail_operation_xfer_msgs (mail_op,
3014 TNY_FOLDER (folder_store),
3019 g_object_unref (mail_op);
3022 } else if (src_folder != NULL) {
3023 /* Launch notification */
3024 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3025 _CS("ckct_nw_pasting"));
3026 if (inf_note != NULL) {
3027 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3028 gtk_widget_show (GTK_WIDGET(inf_note));
3031 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3032 modest_mail_operation_xfer_folder (mail_op,
3042 g_object_unref (data);
3043 if (src_folder != NULL)
3044 g_object_unref (src_folder);
3045 if (folder_store != NULL)
3046 g_object_unref (folder_store);
3052 modest_ui_actions_on_select_all (GtkAction *action,
3053 ModestWindow *window)
3055 GtkWidget *focused_widget;
3057 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3058 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3059 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3060 } else if (GTK_IS_LABEL (focused_widget)) {
3061 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3062 } else if (GTK_IS_EDITABLE (focused_widget)) {
3063 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3064 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3065 GtkTextBuffer *buffer;
3066 GtkTextIter start, end;
3068 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3069 gtk_text_buffer_get_start_iter (buffer, &start);
3070 gtk_text_buffer_get_end_iter (buffer, &end);
3071 gtk_text_buffer_select_range (buffer, &start, &end);
3072 } else if (GTK_IS_HTML (focused_widget)) {
3073 gtk_html_select_all (GTK_HTML (focused_widget));
3074 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3075 GtkWidget *header_view = focused_widget;
3076 GtkTreeSelection *selection = NULL;
3078 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3079 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3080 MODEST_WIDGET_TYPE_HEADER_VIEW);
3082 /* Select all messages */
3083 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3084 gtk_tree_selection_select_all (selection);
3086 /* Set focuse on header view */
3087 gtk_widget_grab_focus (header_view);
3093 modest_ui_actions_on_mark_as_read (GtkAction *action,
3094 ModestWindow *window)
3096 g_return_if_fail (MODEST_IS_WINDOW(window));
3098 /* Mark each header as read */
3099 do_headers_action (window, headers_action_mark_as_read, NULL);
3103 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3104 ModestWindow *window)
3106 g_return_if_fail (MODEST_IS_WINDOW(window));
3108 /* Mark each header as read */
3109 do_headers_action (window, headers_action_mark_as_unread, NULL);
3113 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3114 GtkRadioAction *selected,
3115 ModestWindow *window)
3119 value = gtk_radio_action_get_current_value (selected);
3120 if (MODEST_IS_WINDOW (window)) {
3121 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3125 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3126 GtkRadioAction *selected,
3127 ModestWindow *window)
3129 TnyHeaderFlags flags;
3130 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3132 flags = gtk_radio_action_get_current_value (selected);
3133 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3136 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3137 GtkRadioAction *selected,
3138 ModestWindow *window)
3142 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3144 file_format = gtk_radio_action_get_current_value (selected);
3145 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3150 modest_ui_actions_on_zoom_plus (GtkAction *action,
3151 ModestWindow *window)
3153 g_return_if_fail (MODEST_IS_WINDOW (window));
3155 modest_window_zoom_plus (MODEST_WINDOW (window));
3159 modest_ui_actions_on_zoom_minus (GtkAction *action,
3160 ModestWindow *window)
3162 g_return_if_fail (MODEST_IS_WINDOW (window));
3164 modest_window_zoom_minus (MODEST_WINDOW (window));
3168 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3169 ModestWindow *window)
3171 ModestWindowMgr *mgr;
3172 gboolean fullscreen, active;
3173 g_return_if_fail (MODEST_IS_WINDOW (window));
3175 mgr = modest_runtime_get_window_mgr ();
3177 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3178 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3180 if (active != fullscreen) {
3181 modest_window_mgr_set_fullscreen_mode (mgr, active);
3182 gtk_window_present (GTK_WINDOW (window));
3187 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3188 ModestWindow *window)
3190 ModestWindowMgr *mgr;
3191 gboolean fullscreen;
3193 g_return_if_fail (MODEST_IS_WINDOW (window));
3195 mgr = modest_runtime_get_window_mgr ();
3196 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3197 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3199 gtk_window_present (GTK_WINDOW (window));
3203 * Used by modest_ui_actions_on_details to call do_headers_action
3206 headers_action_show_details (TnyHeader *header,
3207 ModestWindow *window,
3214 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3217 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3218 gtk_widget_show_all (dialog);
3219 gtk_dialog_run (GTK_DIALOG (dialog));
3221 gtk_widget_destroy (dialog);
3225 * Show the folder details in a ModestDetailsDialog widget
3228 show_folder_details (TnyFolder *folder,
3234 dialog = modest_details_dialog_new_with_folder (window, folder);
3237 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3238 gtk_widget_show_all (dialog);
3239 gtk_dialog_run (GTK_DIALOG (dialog));
3241 gtk_widget_destroy (dialog);
3245 * Show the header details in a ModestDetailsDialog widget
3248 modest_ui_actions_on_details (GtkAction *action,
3251 TnyList * headers_list;
3255 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3258 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3261 g_object_unref (msg);
3263 headers_list = get_selected_headers (win);
3267 iter = tny_list_create_iterator (headers_list);
3269 header = TNY_HEADER (tny_iterator_get_current (iter));
3271 headers_action_show_details (header, win, NULL);
3272 g_object_unref (header);
3275 g_object_unref (iter);
3276 g_object_unref (headers_list);
3278 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3279 GtkWidget *folder_view, *header_view;
3281 /* Check which widget has the focus */
3282 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3283 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3284 if (gtk_widget_is_focus (folder_view)) {
3285 TnyFolderStore *folder_store
3286 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3287 if (!folder_store) {
3288 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3291 /* Show only when it's a folder */
3292 /* This function should not be called for account items,
3293 * because we dim the menu item for them. */
3294 if (TNY_IS_FOLDER (folder_store)) {
3295 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3298 g_object_unref (folder_store);
3301 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3302 MODEST_WIDGET_TYPE_HEADER_VIEW);
3303 /* Show details of each header */
3304 do_headers_action (win, headers_action_show_details, header_view);
3310 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3311 ModestMsgEditWindow *window)
3313 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3315 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3319 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3320 ModestMsgEditWindow *window)
3322 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3324 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3328 modest_ui_actions_toggle_folders_view (GtkAction *action,
3329 ModestMainWindow *main_window)
3331 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3333 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3334 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3336 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3340 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3341 ModestWindow *window)
3343 gboolean active, fullscreen = FALSE;
3344 ModestWindowMgr *mgr;
3346 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3348 /* Check if we want to toggle the toolbar vuew in fullscreen
3350 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3351 "ViewShowToolbarFullScreen")) {
3355 /* Toggle toolbar */
3356 mgr = modest_runtime_get_window_mgr ();
3357 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3361 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3362 ModestMsgEditWindow *window)
3364 modest_msg_edit_window_select_font (window);
3368 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3369 const gchar *display_name,
3372 /* Do not change the application name if the widget has not
3373 the focus. This callback could be called even if the folder
3374 view has not the focus, because the handled signal could be
3375 emitted when the folder view is redrawn */
3376 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3378 gtk_window_set_title (window, display_name);
3380 gtk_window_set_title (window, " ");
3385 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3388 modest_msg_edit_window_select_contacts (window);
3392 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3394 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3395 modest_msg_edit_window_check_names (window, FALSE);
3399 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3401 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3402 GTK_WIDGET (user_data));
3406 create_move_to_dialog (GtkWindow *win,
3407 GtkWidget *folder_view,
3408 GtkWidget **tree_view)
3410 GtkWidget *dialog, *scroll;
3411 GtkWidget *new_button;
3413 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3415 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3418 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3419 /* We do this manually so GTK+ does not associate a response ID for
3421 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3422 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3423 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3425 /* Create scrolled window */
3426 scroll = gtk_scrolled_window_new (NULL, NULL);
3427 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3428 GTK_POLICY_AUTOMATIC,
3429 GTK_POLICY_AUTOMATIC);
3431 /* Create folder view */
3432 *tree_view = modest_platform_create_folder_view (NULL);
3434 g_signal_connect (G_OBJECT (new_button),
3436 G_CALLBACK(create_move_to_dialog_on_new_folder),
3439 /* It could happen that we're trying to move a message from a
3440 window (msg window for example) after the main window was
3441 closed, so we can not just get the model of the folder
3443 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3444 const gchar *visible_id = NULL;
3446 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3447 MODEST_FOLDER_VIEW(*tree_view));
3450 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3452 /* Show the same account than the one that is shown in the main window */
3453 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3456 const gchar *active_account_name = NULL;
3457 ModestAccountMgr *mgr = NULL;
3458 ModestAccountData *acc_data = NULL;
3460 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3461 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3463 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3464 mgr = modest_runtime_get_account_mgr ();
3465 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3467 /* Set the new visible & active account */
3468 if (acc_data && acc_data->store_account) {
3469 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3470 acc_data->store_account->account_name);
3471 modest_account_mgr_free_account_data (mgr, acc_data);
3475 /* Hide special folders */
3476 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3478 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3480 /* Add scroll to dialog */
3481 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3482 scroll, TRUE, TRUE, 0);
3484 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3485 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3491 * Returns TRUE if at least one of the headers of the list belongs to
3492 * a message that has been fully retrieved.
3494 #if 0 /* no longer in use. delete in 2007.10 */
3496 has_retrieved_msgs (TnyList *list)
3499 gboolean found = FALSE;
3501 iter = tny_list_create_iterator (list);
3502 while (!tny_iterator_is_done (iter) && !found) {
3504 TnyHeaderFlags flags = 0;
3506 header = TNY_HEADER (tny_iterator_get_current (iter));
3508 flags = tny_header_get_flags (header);
3509 if (flags & TNY_HEADER_FLAG_CACHED)
3510 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3513 g_object_unref (header);
3517 tny_iterator_next (iter);
3519 g_object_unref (iter);
3527 * Shows a confirmation dialog to the user when we're moving messages
3528 * from a remote server to the local storage. Returns the dialog
3529 * response. If it's other kind of movement the it always returns
3533 msgs_move_to_confirmation (GtkWindow *win,
3534 TnyFolder *dest_folder,
3538 gint response = GTK_RESPONSE_OK;
3540 /* If the destination is a local folder (or MMC folder )*/
3541 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3546 TnyFolder *src_folder = NULL;
3547 TnyIterator *iter = NULL;
3548 TnyHeader *header = NULL;
3550 /* get the device */
3552 device = modest_runtime_get_device ();
3554 is_online = tny_device_is_online (device);
3556 g_warning ("failed to get tny device"); /* should not happend */
3560 /* Get source folder */
3561 iter = tny_list_create_iterator (headers);
3562 header = TNY_HEADER (tny_iterator_get_current (iter));
3564 src_folder = tny_header_get_folder (header);
3565 g_object_unref (header);
3568 g_object_unref (iter);
3570 /* if no src_folder, message may be an attahcment */
3571 if (src_folder == NULL)
3572 return GTK_RESPONSE_CANCEL;
3574 /* If the source is a remote folder */
3575 if (!is_online && modest_tny_folder_is_remote_folder (src_folder)) {
3577 const gchar *message = NULL;
3578 message = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs",
3579 tny_list_get_length (headers));
3580 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3581 (const gchar *) message);
3583 response = GTK_RESPONSE_OK;
3585 g_object_unref (src_folder);
3594 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3596 ModestMsgViewWindow *self = NULL;
3598 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3599 self = MODEST_MSG_VIEW_WINDOW (object);
3601 if (!modest_msg_view_window_select_next_message (self))
3602 if (!modest_msg_view_window_select_previous_message (self))
3603 /* No more messages to view, so close this window */
3604 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3608 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3611 GObject *win = modest_mail_operation_get_source (mail_op);
3612 const GError *error = NULL;
3613 const gchar *message = NULL;
3615 /* Get error message */
3616 error = modest_mail_operation_get_error (mail_op);
3617 if (error != NULL && error->message != NULL) {
3618 message = error->message;
3620 message = _("mail_in_ui_folder_move_target_error");
3623 /* Show notification dialog */
3624 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3625 g_object_unref (win);
3629 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3632 GObject *win = modest_mail_operation_get_source (mail_op);
3633 const GError *error = modest_mail_operation_get_error (mail_op);
3635 g_return_if_fail (error != NULL);
3636 if (error->message != NULL)
3637 g_printerr ("modest: %s\n", error->message);
3639 g_printerr ("modest: unkonw error on send&receive operation");
3641 /* Show error message */
3642 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3643 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3644 /* _CS("sfil_ib_unable_to_receive")); */
3646 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3647 /* _CS("sfil_ib_unable_to_send")); */
3648 g_object_unref (win);
3652 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3659 gint pending_purges = 0;
3660 gboolean some_purged = FALSE;
3661 ModestWindow *win = MODEST_WINDOW (user_data);
3662 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3664 /* If there was any error */
3665 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3666 modest_window_mgr_unregister_header (mgr, header);
3670 /* Once the message has been retrieved for purging, we check if
3671 * it's all ok for purging */
3673 parts = tny_simple_list_new ();
3674 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3675 iter = tny_list_create_iterator (parts);
3677 while (!tny_iterator_is_done (iter)) {
3679 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3680 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3681 if (tny_mime_part_is_purged (part))
3688 g_object_unref (part);
3690 tny_iterator_next (iter);
3693 if (pending_purges>0) {
3695 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3697 if (response == GTK_RESPONSE_OK) {
3698 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3699 tny_iterator_first (iter);
3700 while (!tny_iterator_is_done (iter)) {
3703 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3704 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3705 tny_mime_part_set_purged (part);
3708 g_object_unref (part);
3710 tny_iterator_next (iter);
3713 tny_msg_rewrite_cache (msg);
3716 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3719 /* remove attachments */
3720 tny_iterator_first (iter);
3721 while (!tny_iterator_is_done (iter)) {
3724 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3726 /* One for the reference given by tny_iterator_get_current(): */
3727 g_object_unref (part);
3729 /* TODO: Is this meant to remove the attachment by doing another unref()?
3730 * Otherwise, this seems useless. */
3733 tny_iterator_next (iter);
3735 modest_window_mgr_unregister_header (mgr, header);
3737 g_object_unref (iter);
3738 g_object_unref (parts);
3742 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3743 ModestMainWindow *win)
3745 GtkWidget *header_view;
3746 TnyList *header_list;
3749 TnyHeaderFlags flags;
3750 ModestWindow *msg_view_window = NULL;
3753 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3755 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3756 MODEST_WIDGET_TYPE_HEADER_VIEW);
3758 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3760 if (tny_list_get_length (header_list) == 1) {
3761 iter = tny_list_create_iterator (header_list);
3762 header = TNY_HEADER (tny_iterator_get_current (iter));
3763 g_object_unref (iter);
3768 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3769 header, &msg_view_window);
3770 flags = tny_header_get_flags (header);
3771 if (!(flags & TNY_HEADER_FLAG_CACHED))
3774 if (msg_view_window != NULL)
3775 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3777 /* do nothing; uid was registered before, so window is probably on it's way */
3778 g_warning ("debug: header %p has already been registered", header);
3781 ModestMailOperation *mail_op = NULL;
3782 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3783 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3785 modest_ui_actions_get_msgs_full_error_handler,
3787 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3788 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3790 g_object_unref (mail_op);
3793 g_object_unref (header);
3795 g_object_unref (header_list);
3799 * Utility function that transfer messages from both the main window
3800 * and the msg view window when using the "Move to" dialog
3803 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3806 TnyList *headers = NULL;
3808 TnyAccount *dst_account = NULL;
3809 const gchar *proto_str = NULL;
3810 gboolean dst_is_pop = FALSE;
3812 if (!TNY_IS_FOLDER (dst_folder)) {
3813 modest_platform_information_banner (GTK_WIDGET (win),
3815 _CS("ckdg_ib_unable_to_move_to_current_location"));
3819 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3820 proto_str = tny_account_get_proto (dst_account);
3822 /* tinymail will return NULL for local folders it seems */
3823 dst_is_pop = proto_str &&
3824 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3825 MODEST_PROTOCOL_STORE_POP);
3827 g_object_unref (dst_account);
3829 /* Get selected headers */
3830 headers = get_selected_headers (MODEST_WINDOW (win));
3833 modest_platform_information_banner (GTK_WIDGET (win),
3835 ngettext("mail_in_ui_folder_move_target_error",
3836 "mail_in_ui_folder_move_targets_error",
3837 tny_list_get_length (headers)));
3838 g_object_unref (headers);
3842 /* Ask for user confirmation */
3843 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3844 TNY_FOLDER (dst_folder),
3848 /* Transfer messages */
3849 if (response == GTK_RESPONSE_OK) {
3850 ModestMailOperation *mail_op =
3851 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3853 modest_ui_actions_move_folder_error_handler,
3855 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3858 modest_mail_operation_xfer_msgs (mail_op,
3860 TNY_FOLDER (dst_folder),
3862 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3865 g_object_unref (G_OBJECT (mail_op));
3867 g_object_unref (headers);
3871 * UI handler for the "Move to" action when invoked from the
3875 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3876 GtkWidget *folder_view,
3877 TnyFolderStore *dst_folder,
3878 ModestMainWindow *win)
3880 GtkWidget *header_view = NULL;
3881 ModestMailOperation *mail_op = NULL;
3882 TnyFolderStore *src_folder;
3884 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3886 /* Get the source folder */
3887 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3889 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3890 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3894 /* Get header view */
3896 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3898 /* Get folder or messages to transfer */
3899 if (gtk_widget_is_focus (folder_view)) {
3900 GtkTreeSelection *sel;
3902 /* Allow only to transfer folders to the local root folder */
3903 if (TNY_IS_ACCOUNT (dst_folder) &&
3904 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3907 /* Clean folder on header view before moving it */
3908 /* modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); */
3909 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3910 gtk_tree_selection_unselect_all (sel);
3912 if (TNY_IS_FOLDER (src_folder)) {
3914 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3916 modest_ui_actions_move_folder_error_handler,
3918 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3921 modest_mail_operation_xfer_folder (mail_op,
3922 TNY_FOLDER (src_folder),
3925 /* Unref mail operation */
3926 g_object_unref (G_OBJECT (mail_op));
3928 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3930 } else if (gtk_widget_is_focus (header_view)) {
3931 /* Transfer messages */
3932 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3937 g_object_unref (src_folder);
3942 * UI handler for the "Move to" action when invoked from the
3943 * ModestMsgViewWindow
3946 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3947 TnyFolderStore *dst_folder,
3948 ModestMsgViewWindow *win)
3950 TnyHeader *header = NULL;
3951 TnyFolder *src_folder;
3953 /* Create header list */
3954 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3955 src_folder = tny_header_get_folder(header);
3956 g_object_unref (header);
3958 /* Transfer the message */
3959 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3960 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3962 g_object_unref (src_folder);
3966 modest_ui_actions_on_move_to (GtkAction *action,
3969 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3971 TnyFolderStore *dst_folder = NULL;
3972 ModestMainWindow *main_window;
3974 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3975 MODEST_IS_MSG_VIEW_WINDOW (win));
3977 /* Get the main window if exists */
3978 if (MODEST_IS_MAIN_WINDOW (win))
3979 main_window = MODEST_MAIN_WINDOW (win);
3982 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3984 /* Get the folder view widget if exists */
3986 folder_view = modest_main_window_get_child_widget (main_window,
3987 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3991 /* Create and run the dialog */
3992 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3993 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3994 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3995 result = gtk_dialog_run (GTK_DIALOG(dialog));
3996 g_object_ref (tree_view);
3997 gtk_widget_destroy (dialog);
3999 if (result != GTK_RESPONSE_ACCEPT)
4002 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4003 /* Offer the connection dialog if necessary: */
4004 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
4007 /* Do window specific stuff */
4008 if (MODEST_IS_MAIN_WINDOW (win))
4009 modest_ui_actions_on_main_window_move_to (action,
4012 MODEST_MAIN_WINDOW (win));
4014 modest_ui_actions_on_msg_view_window_move_to (action,
4016 MODEST_MSG_VIEW_WINDOW (win));
4019 g_object_unref (dst_folder);
4023 * Calls #HeadersFunc for each header already selected in the main
4024 * window or the message currently being shown in the msg view window
4027 do_headers_action (ModestWindow *win,
4031 TnyList *headers_list = NULL;
4032 TnyIterator *iter = NULL;
4033 TnyHeader *header = NULL;
4034 TnyFolder *folder = NULL;
4037 headers_list = get_selected_headers (win);
4041 /* Get the folder */
4042 iter = tny_list_create_iterator (headers_list);
4043 header = TNY_HEADER (tny_iterator_get_current (iter));
4045 folder = tny_header_get_folder (header);
4046 g_object_unref (header);
4049 /* Call the function for each header */
4050 while (!tny_iterator_is_done (iter)) {
4051 header = TNY_HEADER (tny_iterator_get_current (iter));
4052 func (header, win, user_data);
4053 g_object_unref (header);
4054 tny_iterator_next (iter);
4057 /* Trick: do a poke status in order to speed up the signaling
4059 tny_folder_poke_status (folder);
4062 g_object_unref (folder);
4063 g_object_unref (iter);
4064 g_object_unref (headers_list);
4068 modest_ui_actions_view_attachment (GtkAction *action,
4069 ModestWindow *window)
4071 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4072 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4074 /* not supported window for this action */
4075 g_return_if_reached ();
4080 modest_ui_actions_save_attachments (GtkAction *action,
4081 ModestWindow *window)
4083 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4084 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4086 /* not supported window for this action */
4087 g_return_if_reached ();
4092 modest_ui_actions_remove_attachments (GtkAction *action,
4093 ModestWindow *window)
4095 if (MODEST_IS_MAIN_WINDOW (window)) {
4096 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4097 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4098 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4100 /* not supported window for this action */
4101 g_return_if_reached ();
4106 modest_ui_actions_on_settings (GtkAction *action,
4111 dialog = modest_platform_get_global_settings_dialog ();
4112 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4113 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4114 gtk_widget_show_all (dialog);
4116 gtk_dialog_run (GTK_DIALOG (dialog));
4118 gtk_widget_destroy (dialog);
4122 modest_ui_actions_on_help (GtkAction *action,
4125 const gchar *help_id = NULL;
4127 if (MODEST_IS_MAIN_WINDOW (win)) {
4128 const gchar *action_name;
4129 action_name = gtk_action_get_name (action);
4131 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4132 !strcmp (action_name, "HeaderViewCSMHelp")) {
4133 GtkWidget *folder_view;
4134 TnyFolderStore *folder_store;
4135 /* Get selected folder */
4136 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4137 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4138 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4140 /* Switch help_id */
4141 if (TNY_IS_FOLDER (folder_store)) {
4142 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4143 case TNY_FOLDER_TYPE_NORMAL:
4144 help_id = "applications_email_managefolders";
4146 case TNY_FOLDER_TYPE_INBOX:
4147 help_id = "applications_email_inbox";
4149 case TNY_FOLDER_TYPE_OUTBOX:
4150 help_id = "applications_email_outbox";
4152 case TNY_FOLDER_TYPE_SENT:
4153 help_id = "applications_email_sent";
4155 case TNY_FOLDER_TYPE_DRAFTS:
4156 help_id = "applications_email_drafts";
4158 case TNY_FOLDER_TYPE_ARCHIVE:
4159 help_id = "applications_email_managefolders";
4162 help_id = "applications_email_managefolders";
4165 help_id = "applications_email_mainview";
4167 g_object_unref (folder_store);
4169 help_id = "applications_email_mainview";
4171 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4172 help_id = "applications_email_viewer";
4173 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4174 help_id = "applications_email_editor";
4176 modest_platform_show_help (GTK_WINDOW (win), help_id);
4180 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4181 ModestWindow *window)
4183 ModestMailOperation *mail_op;
4187 headers = get_selected_headers (window);
4191 /* Create mail operation */
4192 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4194 modest_ui_actions_get_msgs_full_error_handler,
4196 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4197 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4200 g_object_unref (headers);
4201 g_object_unref (mail_op);
4205 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4206 ModestWindow *window)
4208 g_return_if_fail (MODEST_IS_WINDOW (window));
4211 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4215 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4216 ModestWindow *window)
4218 g_return_if_fail (MODEST_IS_WINDOW (window));
4221 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4225 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4226 ModestWindow *window)
4228 g_return_if_fail (MODEST_IS_WINDOW (window));
4231 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4235 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4236 ModestWindow *window)
4238 g_return_if_fail (MODEST_IS_WINDOW (window));
4241 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4245 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4246 ModestWindow *window)
4248 g_return_if_fail (MODEST_IS_WINDOW (window));
4251 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4255 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4256 ModestWindow *window)
4258 g_return_if_fail (MODEST_IS_WINDOW (window));
4261 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4265 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4266 ModestWindow *window)
4268 g_return_if_fail (MODEST_IS_WINDOW (window));
4271 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4275 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4276 ModestWindow *window)
4278 g_return_if_fail (MODEST_IS_WINDOW (window));
4281 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4285 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4287 g_return_if_fail (MODEST_IS_WINDOW (window));
4290 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4294 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4296 g_return_if_fail (MODEST_IS_WINDOW (window));
4298 modest_platform_show_search_messages (GTK_WINDOW (window));
4302 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4304 g_return_if_fail (MODEST_IS_WINDOW (win));
4305 modest_platform_show_addressbook (GTK_WINDOW (win));
4310 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4311 ModestWindow *window)
4313 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4315 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4319 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4320 ModestMailOperationState *state,
4323 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4325 /* Set send/receive operation finished */
4326 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4327 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));