1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _PasteAsAttachmentHelper {
107 ModestMsgEditWindow *window;
109 } PasteAsAttachmentHelper;
113 * The do_headers_action uses this kind of functions to perform some
114 * action to each member of a list of headers
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
118 static void do_headers_action (ModestWindow *win,
122 static void open_msg_cb (ModestMailOperation *mail_op,
127 static void reply_forward_cb (ModestMailOperation *mail_op,
132 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
134 static void folder_refreshed_cb (ModestMailOperation *mail_op,
138 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
139 ModestMailOperationState *state,
143 download_uncached_messages (TnyList *header_list, GtkWindow *win,
148 msgs_move_to_confirmation (GtkWindow *win,
149 TnyFolder *dest_folder,
155 run_account_setup_wizard (ModestWindow *win)
157 ModestEasysetupWizardDialog *wizard;
159 g_return_if_fail (MODEST_IS_WINDOW(win));
161 wizard = modest_easysetup_wizard_dialog_new ();
162 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
164 /* Don't make this a modal window, because secondary windows will then
165 * be unusable, freezing the UI: */
166 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
168 gtk_dialog_run (GTK_DIALOG (wizard));
169 gtk_widget_destroy (GTK_WIDGET (wizard));
174 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
177 const gchar *authors[] = {
178 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
181 about = gtk_about_dialog_new ();
182 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
183 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
184 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
185 _("Copyright (c) 2006, Nokia Corporation\n"
186 "All rights reserved."));
187 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
188 _("a modest e-mail client\n\n"
189 "design and implementation: Dirk-Jan C. Binnema\n"
190 "contributions from the fine people at KC and Ig\n"
191 "uses the tinymail email framework written by Philip van Hoof"));
192 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
193 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
194 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
195 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
197 gtk_dialog_run (GTK_DIALOG (about));
198 gtk_widget_destroy(about);
202 * Gets the list of currently selected messages. If the win is the
203 * main window, then it returns a newly allocated list of the headers
204 * selected in the header view. If win is the msg view window, then
205 * the value returned is a list with just a single header.
207 * The caller of this funcion must free the list.
210 get_selected_headers (ModestWindow *win)
212 if (MODEST_IS_MAIN_WINDOW(win)) {
213 GtkWidget *header_view;
215 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
216 MODEST_WIDGET_TYPE_HEADER_VIEW);
217 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
219 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
220 /* for MsgViewWindows, we simply return a list with one element */
222 TnyList *list = NULL;
224 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
225 if (header != NULL) {
226 list = tny_simple_list_new ();
227 tny_list_prepend (list, G_OBJECT(header));
228 g_object_unref (G_OBJECT(header));
238 headers_action_mark_as_read (TnyHeader *header,
242 TnyHeaderFlags flags;
244 g_return_if_fail (TNY_IS_HEADER(header));
246 flags = tny_header_get_flags (header);
247 if (flags & TNY_HEADER_FLAG_SEEN) return;
248 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
252 headers_action_mark_as_unread (TnyHeader *header,
256 TnyHeaderFlags flags;
258 g_return_if_fail (TNY_IS_HEADER(header));
260 flags = tny_header_get_flags (header);
261 if (flags & TNY_HEADER_FLAG_SEEN) {
262 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
266 /** A convenience method, because deleting a message is
267 * otherwise complicated, and it's best to change it in one place
270 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
272 ModestMailOperation *mail_op = NULL;
273 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
274 win ? G_OBJECT(win) : NULL);
275 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
278 /* Always delete. TODO: Move to trash still not supported */
279 modest_mail_operation_remove_msg (mail_op, header, FALSE);
280 g_object_unref (G_OBJECT (mail_op));
284 headers_action_delete (TnyHeader *header,
288 modest_do_message_delete (header, win);
291 /** After deleing a message that is currently visible in a window,
292 * show the next message from the list, or close the window if there are no more messages.
294 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
296 /* Close msg view window or select next */
297 if (modest_msg_view_window_last_message_selected (win) &&
298 modest_msg_view_window_first_message_selected (win)) {
299 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
301 if (!modest_msg_view_window_select_next_message (win)) {
303 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
309 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
311 TnyList *header_list = NULL;
312 TnyIterator *iter = NULL;
313 TnyHeader *header = NULL;
314 gchar *message = NULL;
317 ModestWindowMgr *mgr;
318 GtkWidget *header_view = NULL;
320 g_return_if_fail (MODEST_IS_WINDOW(win));
322 /* Check first if the header view has the focus */
323 if (MODEST_IS_MAIN_WINDOW (win)) {
325 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
326 MODEST_WIDGET_TYPE_HEADER_VIEW);
327 if (!gtk_widget_is_focus (header_view))
331 /* Get the headers, either from the header view (if win is the main window),
332 * or from the message view window: */
333 header_list = get_selected_headers (win);
334 if (!header_list) return;
336 /* Check if any of the headers are already opened, or in the process of being opened */
337 if (MODEST_IS_MAIN_WINDOW (win)) {
339 iter = tny_list_create_iterator (header_list);
341 mgr = modest_runtime_get_window_mgr ();
342 while (!tny_iterator_is_done (iter) && !found) {
343 header = TNY_HEADER (tny_iterator_get_current (iter));
345 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
346 g_object_unref (header);
349 tny_iterator_next (iter);
351 g_object_unref (iter);
356 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
357 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
359 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
363 g_object_unref (header_list);
369 if (tny_list_get_length(header_list) == 1) {
370 iter = tny_list_create_iterator (header_list);
371 header = TNY_HEADER (tny_iterator_get_current (iter));
373 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
374 g_object_unref (header);
377 g_object_unref (iter);
379 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
380 tny_list_get_length(header_list)), desc);
382 /* Confirmation dialog */
383 printf("DEBUG: %s\n", __FUNCTION__);
384 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
388 if (response == GTK_RESPONSE_OK) {
389 ModestWindow *main_window = NULL;
390 ModestWindowMgr *mgr = NULL;
391 GtkTreeModel *model = NULL;
392 GtkTreeSelection *sel = NULL;
393 GList *sel_list = NULL, *tmp = NULL;
394 GtkTreeRowReference *row_reference = NULL;
395 GtkTreePath *next_path = NULL;
396 TnyFolder *folder = NULL;
399 /* Find last selected row */
400 if (MODEST_IS_MAIN_WINDOW (win)) {
401 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
402 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
403 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
404 for (tmp=sel_list; tmp; tmp=tmp->next) {
405 if (tmp->next == NULL) {
406 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
407 gtk_tree_path_next (next_path);
408 row_reference = gtk_tree_row_reference_new (model, next_path);
409 gtk_tree_path_free (next_path);
414 /* Remove each header. If it's a view window header_view == NULL */
415 do_headers_action (win, headers_action_delete, header_view);
417 /* refresh the header view (removing marked-as-deleted)*/
418 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
420 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
421 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
423 /* Get main window */
424 mgr = modest_runtime_get_window_mgr ();
425 main_window = modest_window_mgr_get_main_window (mgr);
428 /* Move cursor to next row */
431 /* Select next row */
432 if (gtk_tree_row_reference_valid (row_reference)) {
433 next_path = gtk_tree_row_reference_get_path (row_reference);
434 gtk_tree_selection_select_path (sel, next_path);
435 gtk_tree_path_free (next_path);
437 if (row_reference != NULL)
438 gtk_tree_row_reference_free (row_reference);
441 /* Get folder from first header and sync it */
442 iter = tny_list_create_iterator (header_list);
443 header = TNY_HEADER (tny_iterator_get_current (iter));
444 folder = tny_header_get_folder (header);
445 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
446 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
447 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
448 /* else if (TNY_IS_CAMEL_POP_FOLDER (folder)) */
449 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
450 /* tny_folder_sync (folder, TRUE, &err); /\* TRUE --> expunge *\/ */
453 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
454 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
457 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
461 g_object_unref (header);
462 g_object_unref (iter);
463 g_object_unref (folder);
465 /* Update toolbar dimming state */
466 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
469 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
470 g_list_free (sel_list);
476 g_object_unref (header_list);
482 /* delete either message or folder, based on where we are */
484 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
486 g_return_if_fail (MODEST_IS_WINDOW(win));
488 /* Check first if the header view has the focus */
489 if (MODEST_IS_MAIN_WINDOW (win)) {
491 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
492 MODEST_WIDGET_TYPE_FOLDER_VIEW);
493 if (gtk_widget_is_focus (w)) {
494 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
498 modest_ui_actions_on_delete_message (action, win);
504 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
506 #ifdef MODEST_PLATFORM_MAEMO
507 modest_osso_save_state();
508 #endif /* MODEST_PLATFORM_MAEMO */
510 g_debug ("closing down, clearing %d item(s) from operation queue",
511 modest_mail_operation_queue_num_elements
512 (modest_runtime_get_mail_operation_queue()));
514 /* cancel all outstanding operations */
515 modest_mail_operation_queue_cancel_all
516 (modest_runtime_get_mail_operation_queue());
518 g_debug ("queue has been cleared");
520 /* note: when modest-tny-account-store is finalized,
521 it will automatically set all network connections
528 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
532 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
534 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
535 /* gtk_widget_destroy (GTK_WIDGET (win)); */
536 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
537 /* gboolean ret_value; */
538 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
539 /* } else if (MODEST_IS_WINDOW (win)) { */
540 /* gtk_widget_destroy (GTK_WIDGET (win)); */
542 /* g_return_if_reached (); */
547 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
549 GtkClipboard *clipboard = NULL;
550 gchar *selection = NULL;
552 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
553 selection = gtk_clipboard_wait_for_text (clipboard);
555 /* Question: why is the clipboard being used here?
556 * It doesn't really make a lot of sense. */
560 modest_address_book_add_address (selection);
566 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
568 /* This is currently only implemented for Maemo */
569 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
570 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
571 run_account_setup_wizard (win);
574 /* Show the list of accounts: */
575 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
576 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
578 /* Don't make this a modal window, because secondary windows will then
579 * be unusable, freezing the UI: */
580 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
581 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
584 GtkWidget *dialog, *label;
586 /* Create the widgets */
588 dialog = gtk_dialog_new_with_buttons ("Message",
590 GTK_DIALOG_DESTROY_WITH_PARENT,
594 label = gtk_label_new ("Hello World!");
596 /* Ensure that the dialog box is destroyed when the user responds. */
598 g_signal_connect_swapped (dialog, "response",
599 G_CALLBACK (gtk_widget_destroy),
602 /* Add the label, and show everything we've added to the dialog. */
604 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
606 gtk_widget_show_all (dialog);
607 #endif /* MODEST_PLATFORM_MAEMO */
611 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
613 ModestWindow *main_window = MODEST_WINDOW (user_data);
615 /* Save any changes. */
616 modest_connection_specific_smtp_window_save_server_accounts (
617 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
618 modest_window_get_active_account (main_window));
619 gtk_widget_destroy (GTK_WIDGET (window));
625 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
627 /* This is currently only implemented for Maemo,
628 * because it requires an API (libconic) to detect different connection
631 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
633 /* Create the window if necessary: */
634 const gchar *active_account_name = modest_window_get_active_account (win);
636 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
637 * or show the default account?
638 * If we show the default account then the account name should be shown in
639 * the window when we show it. */
640 if (!active_account_name) {
641 g_warning ("%s: No account is active.", __FUNCTION__);
645 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
646 modest_connection_specific_smtp_window_fill_with_connections (
647 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
648 modest_runtime_get_account_mgr(),
649 active_account_name);
651 /* Show the window: */
652 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
653 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
654 gtk_widget_show (specific_window);
656 /* Save changes when the window is hidden: */
657 g_signal_connect (specific_window, "hide",
658 G_CALLBACK (on_smtp_servers_window_hide), win);
659 #endif /* MODEST_PLATFORM_MAEMO */
663 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
665 ModestWindow *msg_win = NULL;
667 TnyFolder *folder = NULL;
668 gchar *account_name = NULL;
669 gchar *from_str = NULL;
670 /* GError *err = NULL; */
671 TnyAccount *account = NULL;
672 ModestWindowMgr *mgr;
673 gchar *signature = NULL, *blank_and_signature = NULL;
675 /* if there are no accounts yet, just show the wizard */
676 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
677 run_account_setup_wizard (win);
681 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
683 account_name = g_strdup (modest_window_get_active_account (win));
685 g_printerr ("modest: no account found\n");
689 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
691 TNY_ACCOUNT_TYPE_STORE);
693 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
697 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
699 g_printerr ("modest: failed get from string for '%s'\n", account_name);
703 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
704 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
705 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
706 MODEST_ACCOUNT_SIGNATURE, FALSE);
707 blank_and_signature = g_strconcat ("\n", signature, NULL);
710 blank_and_signature = g_strdup ("");
713 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
715 g_printerr ("modest: failed to create new msg\n");
719 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
721 g_printerr ("modest: failed to find Drafts folder\n");
726 /* Create and register edit window */
727 /* This is destroyed by TOOD. */
728 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
729 mgr = modest_runtime_get_window_mgr ();
730 modest_window_mgr_register_window (mgr, msg_win);
733 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
735 gtk_widget_show_all (GTK_WIDGET (msg_win));
738 g_free (account_name);
740 g_free (blank_and_signature);
742 g_object_unref (msg_win);
744 g_object_unref (G_OBJECT(account));
746 g_object_unref (G_OBJECT(msg));
748 g_object_unref (G_OBJECT(folder));
752 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
756 ModestMailOperationStatus status;
758 /* If there is no message or the operation was not successful */
759 status = modest_mail_operation_get_status (mail_op);
760 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
762 /* Remove the header from the preregistered uids */
763 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
773 open_msg_cb (ModestMailOperation *mail_op,
778 ModestWindowMgr *mgr = NULL;
779 ModestWindow *parent_win = NULL;
780 ModestWindow *win = NULL;
781 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
782 gchar *account = NULL;
785 /* Do nothing if there was any problem with the mail
786 operation. The error will be shown by the error_handler of
787 the mail operation */
788 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
792 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
793 folder = tny_header_get_folder (header);
795 /* Mark header as read */
796 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
799 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
801 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
803 /* Gets folder type (OUTBOX headers will be opened in edit window */
804 if (modest_tny_folder_is_local_folder (folder))
805 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
807 /* If the header is in the drafts folder then open the editor,
808 else the message view window */
809 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
810 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
811 /* we cannot edit without a valid account... */
812 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
813 run_account_setup_wizard(parent_win);
816 win = modest_msg_edit_window_new (msg, account, TRUE);
819 gchar *uid = modest_tny_folder_get_header_unique_id (header);
821 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
822 GtkWidget *header_view;
823 GtkTreeSelection *sel;
824 GList *sel_list = NULL;
827 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
828 MODEST_WIDGET_TYPE_HEADER_VIEW);
830 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
831 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
833 if (sel_list != NULL) {
834 GtkTreeRowReference *row_reference;
836 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
837 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
838 g_list_free (sel_list);
840 win = modest_msg_view_window_new_with_header_model (msg,
845 gtk_tree_row_reference_free (row_reference);
847 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
850 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
855 /* Register and show new window */
857 mgr = modest_runtime_get_window_mgr ();
858 modest_window_mgr_register_window (mgr, win);
859 g_object_unref (win);
860 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
861 gtk_widget_show_all (GTK_WIDGET(win));
864 /* Update toolbar dimming state */
865 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
866 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
872 g_object_unref (parent_win);
873 g_object_unref (folder);
877 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
881 GObject *win = modest_mail_operation_get_source (mail_op);
883 error = modest_mail_operation_get_error (mail_op);
884 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
886 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
888 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
891 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
892 _("mail_ni_ui_folder_get_msg_folder_error"));
896 g_object_unref (win);
900 * This function is used by both modest_ui_actions_on_open and
901 * modest_ui_actions_on_header_activated. This way we always do the
902 * same when trying to open messages.
905 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
907 ModestWindowMgr *mgr = NULL;
908 TnyIterator *iter = NULL;
909 ModestMailOperation *mail_op = NULL;
910 TnyList *not_opened_headers = NULL;
911 TnyHeaderFlags flags = 0;
913 /* Look if we already have a message view for each header. If
914 true, then remove the header from the list of headers to
916 mgr = modest_runtime_get_window_mgr ();
917 iter = tny_list_create_iterator (headers);
918 not_opened_headers = tny_simple_list_new ();
920 while (!tny_iterator_is_done (iter)) {
922 ModestWindow *window = NULL;
923 TnyHeader *header = NULL;
924 gboolean found = FALSE;
926 header = TNY_HEADER (tny_iterator_get_current (iter));
928 flags = tny_header_get_flags (header);
931 found = modest_window_mgr_find_registered_header (mgr, header, &window);
933 /* Do not open again the message and present the
934 window to the user */
937 gtk_window_present (GTK_WINDOW (window));
939 /* the header has been registered already, we don't do
940 * anything but wait for the window to come up*/
941 g_debug ("header %p already registered, waiting for window", header);
943 tny_list_append (not_opened_headers, G_OBJECT (header));
947 g_object_unref (header);
949 tny_iterator_next (iter);
951 g_object_unref (iter);
954 /* If some messages would have to be downloaded, ask the user to
955 * make a connection. It's generally easier to do this here (in the mainloop)
956 * than later in a thread:
958 if (tny_list_get_length (not_opened_headers) > 0) {
960 gboolean found = FALSE;
962 iter = tny_list_create_iterator (not_opened_headers);
963 while (!tny_iterator_is_done (iter) && !found) {
964 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
965 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
968 tny_iterator_next (iter);
970 g_object_unref (header);
972 g_object_unref (iter);
974 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
975 g_object_unref (not_opened_headers);
980 /* Register the headers before actually creating the windows: */
981 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
982 while (!tny_iterator_is_done (iter_not_opened)) {
983 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
985 modest_window_mgr_register_header (mgr, header);
986 g_object_unref (header);
989 tny_iterator_next (iter_not_opened);
991 g_object_unref (iter_not_opened);
992 iter_not_opened = NULL;
994 /* Open each message */
995 if (tny_list_get_length (not_opened_headers) > 0) {
996 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
998 modest_ui_actions_get_msgs_full_error_handler,
1000 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1001 if (tny_list_get_length (not_opened_headers) > 1) {
1002 modest_mail_operation_get_msgs_full (mail_op,
1008 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1009 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1010 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1011 g_object_unref (header);
1012 g_object_unref (iter);
1014 g_object_unref (mail_op);
1018 if (not_opened_headers != NULL)
1019 g_object_unref (not_opened_headers);
1023 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1028 headers = get_selected_headers (win);
1033 _modest_ui_actions_open (headers, win);
1035 g_object_unref(headers);
1040 free_reply_forward_helper (gpointer data)
1042 ReplyForwardHelper *helper;
1044 helper = (ReplyForwardHelper *) data;
1045 g_free (helper->account_name);
1046 g_slice_free (ReplyForwardHelper, helper);
1050 reply_forward_cb (ModestMailOperation *mail_op,
1056 ReplyForwardHelper *rf_helper;
1057 ModestWindow *msg_win = NULL;
1058 ModestEditType edit_type;
1060 TnyAccount *account = NULL;
1061 ModestWindowMgr *mgr = NULL;
1062 gchar *signature = NULL;
1064 /* If there was any error. The mail operation could be NULL,
1065 this means that we already have the message downloaded and
1066 that we didn't do a mail operation to retrieve it */
1067 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1070 g_return_if_fail (user_data != NULL);
1071 rf_helper = (ReplyForwardHelper *) user_data;
1073 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1074 rf_helper->account_name);
1075 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1076 rf_helper->account_name,
1077 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1078 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1079 rf_helper->account_name,
1080 MODEST_ACCOUNT_SIGNATURE, FALSE);
1083 /* Create reply mail */
1084 switch (rf_helper->action) {
1087 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1088 rf_helper->reply_forward_type,
1089 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1091 case ACTION_REPLY_TO_ALL:
1093 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1094 MODEST_TNY_MSG_REPLY_MODE_ALL);
1095 edit_type = MODEST_EDIT_TYPE_REPLY;
1097 case ACTION_FORWARD:
1099 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1100 edit_type = MODEST_EDIT_TYPE_FORWARD;
1103 g_return_if_reached ();
1110 g_printerr ("modest: failed to create message\n");
1114 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1115 rf_helper->account_name,
1116 TNY_ACCOUNT_TYPE_STORE);
1118 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1122 /* Create and register the windows */
1123 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1124 mgr = modest_runtime_get_window_mgr ();
1125 modest_window_mgr_register_window (mgr, msg_win);
1127 if (rf_helper->parent_window != NULL) {
1128 gdouble parent_zoom;
1130 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1131 modest_window_set_zoom (msg_win, parent_zoom);
1134 /* Show edit window */
1135 gtk_widget_show_all (GTK_WIDGET (msg_win));
1139 g_object_unref (msg_win);
1141 g_object_unref (G_OBJECT (new_msg));
1143 g_object_unref (G_OBJECT (account));
1144 /* g_object_unref (msg); */
1145 free_reply_forward_helper (rf_helper);
1149 * Checks a list of headers. If any of them are not currently
1150 * downloaded (CACHED) then it asks the user for permission to
1153 * Returns FALSE if the user does not want to download the
1154 * messages. Returns TRUE if the user allowed the download or if all
1155 * of them are currently downloaded
1158 download_uncached_messages (TnyList *header_list,
1164 gint uncached_messages = 0;
1166 iter = tny_list_create_iterator (header_list);
1167 while (!tny_iterator_is_done (iter)) {
1170 header = TNY_HEADER (tny_iterator_get_current (iter));
1172 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1173 uncached_messages ++;
1174 g_object_unref (header);
1177 tny_iterator_next (iter);
1179 g_object_unref (iter);
1181 /* Ask for user permission to download the messages */
1183 if (uncached_messages > 0) {
1184 GtkResponseType response;
1186 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1187 _("emev_nc_include_original"));
1190 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1191 ngettext("mcen_nc_get_msg",
1193 uncached_messages));
1194 if (response == GTK_RESPONSE_CANCEL)
1197 /* If a download will be necessary, make sure that we have a connection: */
1198 retval = modest_platform_connect_and_wait(win, NULL);
1206 * Common code for the reply and forward actions
1209 reply_forward (ReplyForwardAction action, ModestWindow *win)
1211 ModestMailOperation *mail_op = NULL;
1212 TnyList *header_list = NULL;
1213 ReplyForwardHelper *rf_helper = NULL;
1214 guint reply_forward_type;
1215 gboolean continue_download = TRUE;
1216 gboolean do_retrieve = TRUE;
1218 g_return_if_fail (MODEST_IS_WINDOW(win));
1220 /* we need an account when editing */
1221 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1222 run_account_setup_wizard (win);
1226 header_list = get_selected_headers (win);
1230 reply_forward_type =
1231 modest_conf_get_int (modest_runtime_get_conf (),
1232 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1235 /* Check that the messages have been previously downloaded */
1236 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1238 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1239 if (!continue_download) {
1240 g_object_unref (header_list);
1244 /* We assume that we can only select messages of the
1245 same folder and that we reply all of them from the
1246 same account. In fact the interface currently only
1247 allows single selection */
1250 rf_helper = g_slice_new0 (ReplyForwardHelper);
1251 rf_helper->reply_forward_type = reply_forward_type;
1252 rf_helper->action = action;
1253 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1255 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1256 rf_helper->parent_window = GTK_WIDGET (win);
1257 if (!rf_helper->account_name)
1258 rf_helper->account_name =
1259 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1261 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1264 /* Get header and message. Do not free them here, the
1265 reply_forward_cb must do it */
1266 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1267 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1268 if (!msg || !header) {
1270 g_object_unref (msg);
1271 g_printerr ("modest: no message found\n");
1274 reply_forward_cb (NULL, header, msg, rf_helper);
1277 g_object_unref (header);
1282 /* Only reply/forward to one message */
1283 iter = tny_list_create_iterator (header_list);
1284 header = TNY_HEADER (tny_iterator_get_current (iter));
1285 g_object_unref (iter);
1288 /* Retrieve messages */
1290 mail_op = modest_mail_operation_new_with_error_handling (
1291 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1293 modest_ui_actions_get_msgs_full_error_handler,
1295 modest_mail_operation_queue_add (
1296 modest_runtime_get_mail_operation_queue (), mail_op);
1298 modest_mail_operation_get_msg (mail_op,
1303 g_object_unref(mail_op);
1305 /* we put a ref here to prevent double unref as the reply
1306 * forward callback unrefs the header at its end */
1307 reply_forward_cb (NULL, header, NULL, rf_helper);
1311 g_object_unref (header);
1317 g_object_unref (header_list);
1321 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1323 g_return_if_fail (MODEST_IS_WINDOW(win));
1325 reply_forward (ACTION_REPLY, win);
1329 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1331 g_return_if_fail (MODEST_IS_WINDOW(win));
1333 reply_forward (ACTION_FORWARD, win);
1337 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1339 g_return_if_fail (MODEST_IS_WINDOW(win));
1341 reply_forward (ACTION_REPLY_TO_ALL, win);
1345 modest_ui_actions_on_next (GtkAction *action,
1346 ModestWindow *window)
1348 if (MODEST_IS_MAIN_WINDOW (window)) {
1349 GtkWidget *header_view;
1351 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1352 MODEST_WIDGET_TYPE_HEADER_VIEW);
1356 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1357 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1358 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1360 g_return_if_reached ();
1365 modest_ui_actions_on_prev (GtkAction *action,
1366 ModestWindow *window)
1368 g_return_if_fail (MODEST_IS_WINDOW(window));
1370 if (MODEST_IS_MAIN_WINDOW (window)) {
1371 GtkWidget *header_view;
1372 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1373 MODEST_WIDGET_TYPE_HEADER_VIEW);
1377 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1378 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1379 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1381 g_return_if_reached ();
1386 modest_ui_actions_on_sort (GtkAction *action,
1387 ModestWindow *window)
1389 g_return_if_fail (MODEST_IS_WINDOW(window));
1391 if (MODEST_IS_MAIN_WINDOW (window)) {
1392 GtkWidget *header_view;
1393 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1394 MODEST_WIDGET_TYPE_HEADER_VIEW);
1396 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1401 /* Show sorting dialog */
1402 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1407 new_messages_arrived (ModestMailOperation *self,
1411 if (new_messages == 0)
1414 modest_platform_on_new_msg ();
1418 * This function performs the send & receive required actions. The
1419 * window is used to create the mail operation. Typically it should
1420 * always be the main window, but we pass it as argument in order to
1424 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1426 gchar *acc_name = NULL;
1427 ModestMailOperation *mail_op;
1429 /* If no account name was provided then get the current account, and if
1430 there is no current account then pick the default one: */
1431 if (!account_name) {
1432 acc_name = g_strdup (modest_window_get_active_account(win));
1434 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1436 g_printerr ("modest: cannot get default account\n");
1440 acc_name = g_strdup (account_name);
1443 /* Set send/receive operation in progress */
1444 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1446 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1448 modest_ui_actions_send_receive_error_handler,
1451 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1452 G_CALLBACK (_on_send_receive_progress_changed),
1455 /* Send & receive. */
1456 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1457 /* Receive and then send. The operation is tagged initially as
1458 a receive operation because the account update performs a
1459 receive and then a send. The operation changes its type
1460 internally, so the progress objects will receive the proper
1461 progress information */
1462 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1463 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1464 g_object_unref (G_OBJECT (mail_op));
1472 modest_ui_actions_do_cancel_send (const gchar *account_name,
1475 TnyTransportAccount *transport_account;
1476 TnySendQueue *send_queue = NULL;
1477 GError *error = NULL;
1479 /* Get transport account */
1481 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1482 (modest_runtime_get_account_store(),
1484 TNY_ACCOUNT_TYPE_TRANSPORT));
1485 if (!transport_account) {
1486 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1491 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1492 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1493 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1494 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1495 "modest: could not find send queue for account\n");
1497 /* Keeep messages in outbox folder */
1498 tny_send_queue_cancel (send_queue, FALSE, &error);
1502 if (transport_account != NULL)
1503 g_object_unref (G_OBJECT (transport_account));
1507 modest_ui_actions_cancel_send_all (ModestWindow *win)
1509 GSList *account_names, *iter;
1511 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1514 iter = account_names;
1516 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1517 iter = g_slist_next (iter);
1520 modest_account_mgr_free_account_names (account_names);
1521 account_names = NULL;
1525 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1528 /* Check if accounts exist */
1529 gboolean accounts_exist =
1530 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1532 /* If not, allow the user to create an account before trying to send/receive. */
1533 if (!accounts_exist)
1534 modest_ui_actions_on_accounts (NULL, win);
1536 /* Cancel all sending operaitons */
1537 modest_ui_actions_cancel_send_all (win);
1541 * Refreshes all accounts. This function will be used by automatic
1545 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1547 GSList *account_names, *iter;
1549 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1552 iter = account_names;
1554 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1555 iter = g_slist_next (iter);
1558 modest_account_mgr_free_account_names (account_names);
1559 account_names = NULL;
1563 modest_do_refresh_current_folder(ModestWindow *win)
1565 /* Refresh currently selected folder. Note that if we only
1566 want to retreive the headers, then the refresh only will
1567 invoke a poke_status over all folders, i.e., only the
1568 total/unread count will be updated */
1569 if (MODEST_IS_MAIN_WINDOW (win)) {
1570 GtkWidget *header_view, *folder_view;
1571 TnyFolderStore *folder_store;
1573 /* Get folder and header view */
1575 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1576 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1578 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1580 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1582 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1583 MODEST_WIDGET_TYPE_HEADER_VIEW);
1585 /* We do not need to set the contents style
1586 because it hasn't changed. We also do not
1587 need to save the widget status. Just force
1589 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1590 TNY_FOLDER (folder_store),
1591 folder_refreshed_cb,
1592 MODEST_MAIN_WINDOW (win));
1596 g_object_unref (folder_store);
1602 * Handler of the click on Send&Receive button in the main toolbar
1605 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1607 /* Check if accounts exist */
1608 gboolean accounts_exist =
1609 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1611 /* If not, allow the user to create an account before trying to send/receive. */
1612 if (!accounts_exist)
1613 modest_ui_actions_on_accounts (NULL, win);
1615 modest_do_refresh_current_folder (win);
1617 /* Refresh the active account */
1618 modest_ui_actions_do_send_receive (NULL, win);
1623 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1626 GtkWidget *header_view;
1628 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1630 header_view = modest_main_window_get_child_widget (main_window,
1631 MODEST_WIDGET_TYPE_HEADER_VIEW);
1635 conf = modest_runtime_get_conf ();
1637 /* what is saved/restored is depending on the style; thus; we save with
1638 * old style, then update the style, and restore for this new style
1640 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1642 if (modest_header_view_get_style
1643 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1644 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1645 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1647 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1648 MODEST_HEADER_VIEW_STYLE_DETAILS);
1650 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1651 MODEST_CONF_HEADER_VIEW_KEY);
1656 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1658 ModestMainWindow *main_window)
1660 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1661 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1663 /* in the case the folder is empty, show the empty folder message and focus
1665 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1666 if (modest_header_view_is_empty (header_view)) {
1667 TnyFolder *folder = modest_header_view_get_folder (header_view);
1668 GtkWidget *folder_view =
1669 modest_main_window_get_child_widget (main_window,
1670 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1672 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1673 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1677 /* If no header has been selected then exit */
1682 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1683 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1685 /* Update Main window title */
1686 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1687 const gchar *subject = tny_header_get_subject (header);
1688 if (subject && strlen(subject) > 0)
1689 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1691 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1694 /* Update toolbar dimming state */
1695 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1699 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1701 ModestMainWindow *main_window)
1705 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1710 headers = tny_simple_list_new ();
1711 tny_list_prepend (headers, G_OBJECT (header));
1713 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1715 g_object_unref (headers);
1719 set_active_account_from_tny_account (TnyAccount *account,
1720 ModestWindow *window)
1722 const gchar *server_acc_name = tny_account_get_id (account);
1724 /* We need the TnyAccount provided by the
1725 account store because that is the one that
1726 knows the name of the Modest account */
1727 TnyAccount *modest_server_account = modest_server_account =
1728 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1729 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1732 const gchar *modest_acc_name =
1733 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1734 modest_window_set_active_account (window, modest_acc_name);
1735 g_object_unref (modest_server_account);
1740 folder_refreshed_cb (ModestMailOperation *mail_op,
1744 ModestMainWindow *win = NULL;
1745 GtkWidget *header_view;
1746 TnyFolder *current_folder;
1748 g_return_if_fail (TNY_IS_FOLDER (folder));
1750 win = MODEST_MAIN_WINDOW (user_data);
1752 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1755 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1756 if (current_folder != NULL && folder != current_folder) {
1761 /* Check if folder is empty and set headers view contents style */
1762 if (tny_folder_get_all_count (folder) == 0) {
1763 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1764 modest_main_window_set_contents_style (win,
1765 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1767 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1772 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1773 TnyFolderStore *folder_store,
1775 ModestMainWindow *main_window)
1778 GtkWidget *header_view;
1780 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1782 header_view = modest_main_window_get_child_widget(main_window,
1783 MODEST_WIDGET_TYPE_HEADER_VIEW);
1787 conf = modest_runtime_get_conf ();
1789 if (TNY_IS_ACCOUNT (folder_store)) {
1791 /* Update active account */
1792 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1793 /* Show account details */
1794 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1797 if (TNY_IS_FOLDER (folder_store) && selected) {
1799 /* Update the active account */
1800 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1802 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1803 g_object_unref (account);
1807 /* Set the header style by default, it could
1808 be changed later by the refresh callback to
1810 modest_main_window_set_contents_style (main_window,
1811 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1813 /* Set folder on header view. This function
1814 will call tny_folder_refresh_async so we
1815 pass a callback that will be called when
1816 finished. We use that callback to set the
1817 empty view if there are no messages */
1818 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1819 TNY_FOLDER (folder_store),
1820 folder_refreshed_cb,
1823 /* Restore configuration. We need to do this
1824 *after* the set_folder because the widget
1825 memory asks the header view about its
1827 modest_widget_memory_restore (modest_runtime_get_conf (),
1828 G_OBJECT(header_view),
1829 MODEST_CONF_HEADER_VIEW_KEY);
1831 /* Update the active account */
1832 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1833 /* Save only if we're seeing headers */
1834 if (modest_main_window_get_contents_style (main_window) ==
1835 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1836 modest_widget_memory_save (conf, G_OBJECT (header_view),
1837 MODEST_CONF_HEADER_VIEW_KEY);
1838 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1842 /* Update toolbar dimming state */
1843 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1847 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1854 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1856 online = tny_device_is_online (modest_runtime_get_device());
1859 /* already online -- the item is simply not there... */
1860 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1862 GTK_MESSAGE_WARNING,
1864 _("The %s you selected cannot be found"),
1866 gtk_dialog_run (GTK_DIALOG(dialog));
1868 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1872 GTK_RESPONSE_REJECT,
1874 GTK_RESPONSE_ACCEPT,
1876 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1877 "Do you want to get online?"), item);
1878 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1879 gtk_label_new (txt), FALSE, FALSE, 0);
1880 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1883 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1884 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1885 /* TODO: Comment about why is this commented out: */
1886 /* modest_platform_connect_and_wait (); */
1889 gtk_widget_destroy (dialog);
1893 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1896 /* g_message ("%s %s", __FUNCTION__, link); */
1901 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1904 modest_platform_activate_uri (link);
1908 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1911 modest_platform_show_uri_popup (link);
1915 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1918 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1922 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1923 const gchar *address,
1926 /* g_message ("%s %s", __FUNCTION__, address); */
1930 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1932 TnyTransportAccount *transport_account;
1933 ModestMailOperation *mail_operation;
1935 gchar *account_name, *from;
1936 ModestAccountMgr *account_mgr;
1937 gchar *info_text = NULL;
1939 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1941 data = modest_msg_edit_window_get_msg_data (edit_window);
1943 account_mgr = modest_runtime_get_account_mgr();
1944 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1946 account_name = modest_account_mgr_get_default_account (account_mgr);
1947 if (!account_name) {
1948 g_printerr ("modest: no account found\n");
1949 modest_msg_edit_window_free_msg_data (edit_window, data);
1953 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1954 account_name = g_strdup (data->account_name);
1958 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1959 (modest_runtime_get_account_store(),
1961 TNY_ACCOUNT_TYPE_TRANSPORT));
1962 if (!transport_account) {
1963 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1964 g_free (account_name);
1965 modest_msg_edit_window_free_msg_data (edit_window, data);
1968 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1970 /* Create the mail operation */
1971 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1972 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1974 modest_mail_operation_save_to_drafts (mail_operation,
1986 data->priority_flags);
1989 g_free (account_name);
1990 g_object_unref (G_OBJECT (transport_account));
1991 g_object_unref (G_OBJECT (mail_operation));
1993 modest_msg_edit_window_free_msg_data (edit_window, data);
1995 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1996 modest_platform_information_banner (NULL, NULL, info_text);
2000 /* For instance, when clicking the Send toolbar button when editing a message: */
2002 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2004 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2006 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2009 /* Offer the connection dialog, if necessary: */
2010 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2013 /* FIXME: Code added just for testing. The final version will
2014 use the send queue provided by tinymail and some
2016 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2017 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2019 account_name = modest_account_mgr_get_default_account (account_mgr);
2021 if (!account_name) {
2022 /* Run account setup wizard */
2023 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2027 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2029 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2030 account_name = g_strdup (data->account_name);
2033 /* Get the currently-active transport account for this modest account: */
2034 TnyTransportAccount *transport_account =
2035 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2036 (modest_runtime_get_account_store(),
2038 if (!transport_account) {
2039 /* Run account setup wizard */
2040 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2044 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2046 /* mail content checks and dialogs */
2047 if (data->subject == NULL || data->subject[0] == '\0') {
2048 GtkResponseType response;
2049 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2050 _("mcen_nc_subject_is_empty_send"));
2051 if (response == GTK_RESPONSE_CANCEL) {
2052 g_free (account_name);
2057 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2058 GtkResponseType response;
2059 gchar *note_message;
2060 gchar *note_subject = data->subject;
2061 if (note_subject == NULL || note_subject[0] == '\0')
2062 note_subject = _("mail_va_no_subject");
2063 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2064 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2066 g_free (note_message);
2067 if (response == GTK_RESPONSE_CANCEL) {
2068 g_free (account_name);
2073 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2075 /* Create the mail operation */
2076 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2077 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2079 modest_mail_operation_send_new_mail (mail_operation,
2090 data->priority_flags);
2094 g_free (account_name);
2095 g_object_unref (G_OBJECT (transport_account));
2096 g_object_unref (G_OBJECT (mail_operation));
2098 modest_msg_edit_window_free_msg_data (edit_window, data);
2099 modest_msg_edit_window_set_sent (edit_window, TRUE);
2101 /* Save settings and close the window: */
2102 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2106 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2107 ModestMsgEditWindow *window)
2109 ModestMsgEditFormatState *format_state = NULL;
2111 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2112 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2114 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2117 format_state = modest_msg_edit_window_get_format_state (window);
2118 g_return_if_fail (format_state != NULL);
2120 format_state->bold = gtk_toggle_action_get_active (action);
2121 modest_msg_edit_window_set_format_state (window, format_state);
2122 g_free (format_state);
2127 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2128 ModestMsgEditWindow *window)
2130 ModestMsgEditFormatState *format_state = NULL;
2132 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2133 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2135 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2138 format_state = modest_msg_edit_window_get_format_state (window);
2139 g_return_if_fail (format_state != NULL);
2141 format_state->italics = gtk_toggle_action_get_active (action);
2142 modest_msg_edit_window_set_format_state (window, format_state);
2143 g_free (format_state);
2148 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2149 ModestMsgEditWindow *window)
2151 ModestMsgEditFormatState *format_state = NULL;
2153 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2154 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2156 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2159 format_state = modest_msg_edit_window_get_format_state (window);
2160 g_return_if_fail (format_state != NULL);
2162 format_state->bullet = gtk_toggle_action_get_active (action);
2163 modest_msg_edit_window_set_format_state (window, format_state);
2164 g_free (format_state);
2169 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2170 GtkRadioAction *selected,
2171 ModestMsgEditWindow *window)
2173 ModestMsgEditFormatState *format_state = NULL;
2174 GtkJustification value;
2176 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2178 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2181 value = gtk_radio_action_get_current_value (selected);
2183 format_state = modest_msg_edit_window_get_format_state (window);
2184 g_return_if_fail (format_state != NULL);
2186 format_state->justification = value;
2187 modest_msg_edit_window_set_format_state (window, format_state);
2188 g_free (format_state);
2192 modest_ui_actions_on_select_editor_color (GtkAction *action,
2193 ModestMsgEditWindow *window)
2195 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2196 g_return_if_fail (GTK_IS_ACTION (action));
2198 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2201 modest_msg_edit_window_select_color (window);
2205 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2206 ModestMsgEditWindow *window)
2208 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2209 g_return_if_fail (GTK_IS_ACTION (action));
2211 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2214 modest_msg_edit_window_select_background_color (window);
2218 modest_ui_actions_on_insert_image (GtkAction *action,
2219 ModestMsgEditWindow *window)
2221 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2222 g_return_if_fail (GTK_IS_ACTION (action));
2224 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2227 modest_msg_edit_window_insert_image (window);
2231 modest_ui_actions_on_attach_file (GtkAction *action,
2232 ModestMsgEditWindow *window)
2234 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2235 g_return_if_fail (GTK_IS_ACTION (action));
2237 modest_msg_edit_window_offer_attach_file (window);
2241 modest_ui_actions_on_remove_attachments (GtkAction *action,
2242 ModestMsgEditWindow *window)
2244 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2245 g_return_if_fail (GTK_IS_ACTION (action));
2247 modest_msg_edit_window_remove_attachments (window, NULL);
2251 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2254 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2255 const GError *error = modest_mail_operation_get_error (mail_op);
2259 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2260 modest_mail_operation_get_error (mail_op)->message);
2265 modest_ui_actions_create_folder(GtkWidget *parent_window,
2266 GtkWidget *folder_view)
2268 TnyFolderStore *parent_folder;
2270 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2272 if (parent_folder) {
2273 gboolean finished = FALSE;
2275 gchar *folder_name = NULL, *suggested_name = NULL;
2276 const gchar *proto_str = NULL;
2277 TnyAccount *account;
2279 if (TNY_IS_ACCOUNT (parent_folder))
2280 account = g_object_ref (parent_folder);
2282 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2283 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2285 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2286 MODEST_PROTOCOL_STORE_POP) {
2288 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2290 g_object_unref (account);
2292 /* Run the new folder dialog */
2294 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2299 g_free (suggested_name);
2300 suggested_name = NULL;
2302 if (result == GTK_RESPONSE_REJECT) {
2305 ModestMailOperation *mail_op;
2306 TnyFolder *new_folder = NULL;
2308 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2309 G_OBJECT(parent_window),
2310 modest_ui_actions_new_folder_error_handler,
2313 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2315 new_folder = modest_mail_operation_create_folder (mail_op,
2317 (const gchar *) folder_name);
2319 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2322 g_object_unref (new_folder);
2325 g_object_unref (mail_op);
2328 suggested_name = folder_name;
2332 g_object_unref (parent_folder);
2337 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2339 GtkWidget *folder_view;
2341 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2343 folder_view = modest_main_window_get_child_widget (main_window,
2344 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2348 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2352 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2355 GObject *win = modest_mail_operation_get_source (mail_op);
2356 const GError *error = NULL;
2357 const gchar *message = NULL;
2359 /* Get error message */
2360 error = modest_mail_operation_get_error (mail_op);
2361 if (error != NULL && error->message != NULL) {
2362 message = error->message;
2364 message = _("!!! FIXME: Unable to rename");
2367 /* Show notification dialog */
2368 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2369 g_object_unref (win);
2373 modest_ui_actions_on_rename_folder (GtkAction *action,
2374 ModestMainWindow *main_window)
2376 TnyFolderStore *folder;
2377 GtkWidget *folder_view;
2378 GtkWidget *header_view;
2380 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2382 folder_view = modest_main_window_get_child_widget (main_window,
2383 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2387 header_view = modest_main_window_get_child_widget (main_window,
2388 MODEST_WIDGET_TYPE_HEADER_VIEW);
2393 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2397 /* Offer the connection dialog if necessary: */
2398 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2399 g_object_unref (G_OBJECT (folder));
2404 if (TNY_IS_FOLDER (folder)) {
2407 const gchar *current_name;
2409 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2410 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2411 current_name, &folder_name);
2413 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2414 ModestMailOperation *mail_op;
2417 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2418 G_OBJECT(main_window),
2419 modest_ui_actions_rename_folder_error_handler,
2423 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2426 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2428 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2429 TNY_FOLDER(folder), TRUE);
2432 modest_header_view_clear ((ModestHeaderView *) header_view);
2434 modest_mail_operation_rename_folder (mail_op,
2435 TNY_FOLDER (folder),
2436 (const gchar *) folder_name);
2438 g_object_unref (mail_op);
2439 g_free (folder_name);
2442 g_object_unref (folder);
2446 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2449 GObject *win = modest_mail_operation_get_source (mail_op);
2451 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2452 _("mail_in_ui_folder_delete_error"));
2453 g_object_unref (win);
2457 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2459 TnyFolderStore *folder;
2460 GtkWidget *folder_view;
2464 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2466 folder_view = modest_main_window_get_child_widget (main_window,
2467 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2471 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2473 /* Show an error if it's an account */
2474 if (!TNY_IS_FOLDER (folder)) {
2475 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2476 _("mail_in_ui_folder_delete_error"));
2477 g_object_unref (G_OBJECT (folder));
2481 /* Offer the connection dialog if necessary: */
2482 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2483 g_object_unref (G_OBJECT (folder));
2488 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2489 tny_folder_get_name (TNY_FOLDER (folder)));
2490 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2491 (const gchar *) message);
2494 if (response == GTK_RESPONSE_OK) {
2495 ModestMailOperation *mail_op =
2496 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2497 G_OBJECT(main_window),
2498 modest_ui_actions_delete_folder_error_handler,
2501 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2503 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2504 g_object_unref (G_OBJECT (mail_op));
2507 g_object_unref (G_OBJECT (folder));
2511 modest_ui_actions_on_delete_folder (GtkAction *action,
2512 ModestMainWindow *main_window)
2514 GtkWidget *folder_view;
2515 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2517 delete_folder (main_window, FALSE);
2518 folder_view = modest_main_window_get_child_widget (main_window,
2519 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2522 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2526 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2528 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2530 delete_folder (main_window, TRUE);
2535 show_error (GtkWidget *parent_widget, const gchar* text)
2537 hildon_banner_show_information(parent_widget, NULL, text);
2540 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2542 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2549 gtk_dialog_run (dialog);
2550 gtk_widget_destroy (GTK_WIDGET (dialog));
2555 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2556 const gchar* server_account_name,
2561 ModestMainWindow *main_window)
2563 g_return_if_fail(server_account_name);
2564 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2566 /* Initalize output parameters: */
2573 #ifdef MODEST_PLATFORM_MAEMO
2574 /* Maemo uses a different (awkward) button order,
2575 * It should probably just use gtk_alternative_dialog_button_order ().
2577 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2581 GTK_RESPONSE_ACCEPT,
2583 GTK_RESPONSE_REJECT,
2586 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2590 GTK_RESPONSE_REJECT,
2592 GTK_RESPONSE_ACCEPT,
2594 #endif /* MODEST_PLATFORM_MAEMO */
2596 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2598 gchar *server_name = modest_server_account_get_hostname (
2599 modest_runtime_get_account_mgr(), server_account_name);
2600 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2601 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2606 /* This causes a warning because the logical ID has no %s in it,
2607 * though the translation does, but there is not much we can do about that: */
2608 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2609 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2612 g_free (server_name);
2616 gchar *initial_username = modest_server_account_get_username (
2617 modest_runtime_get_account_mgr(), server_account_name);
2619 GtkWidget *entry_username = gtk_entry_new ();
2620 if (initial_username)
2621 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2622 /* Dim this if a connection has ever succeeded with this username,
2623 * as per the UI spec: */
2624 const gboolean username_known =
2625 modest_server_account_get_username_has_succeeded(
2626 modest_runtime_get_account_mgr(), server_account_name);
2627 gtk_widget_set_sensitive (entry_username, !username_known);
2629 #ifdef MODEST_PLATFORM_MAEMO
2630 /* Auto-capitalization is the default, so let's turn it off: */
2631 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2633 /* Create a size group to be used by all captions.
2634 * Note that HildonCaption does not create a default size group if we do not specify one.
2635 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2636 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2638 GtkWidget *caption = hildon_caption_new (sizegroup,
2639 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2640 gtk_widget_show (entry_username);
2641 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2642 FALSE, FALSE, MODEST_MARGIN_HALF);
2643 gtk_widget_show (caption);
2645 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2647 #endif /* MODEST_PLATFORM_MAEMO */
2650 GtkWidget *entry_password = gtk_entry_new ();
2651 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2652 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2654 #ifdef MODEST_PLATFORM_MAEMO
2655 /* Auto-capitalization is the default, so let's turn it off: */
2656 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2657 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2659 caption = hildon_caption_new (sizegroup,
2660 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2661 gtk_widget_show (entry_password);
2662 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2663 FALSE, FALSE, MODEST_MARGIN_HALF);
2664 gtk_widget_show (caption);
2665 g_object_unref (sizegroup);
2667 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2669 #endif /* MODEST_PLATFORM_MAEMO */
2671 /* This is not in the Maemo UI spec:
2672 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2673 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2677 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2679 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2681 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2683 modest_server_account_set_username (
2684 modest_runtime_get_account_mgr(), server_account_name,
2687 const gboolean username_was_changed =
2688 (strcmp (*username, initial_username) != 0);
2689 if (username_was_changed) {
2690 g_warning ("%s: tinymail does not yet support changing the "
2691 "username in the get_password() callback.\n", __FUNCTION__);
2696 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2698 /* We do not save the password in the configuration,
2699 * because this function is only called for passwords that should
2700 * not be remembered:
2701 modest_server_account_set_password (
2702 modest_runtime_get_account_mgr(), server_account_name,
2711 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2723 /* This is not in the Maemo UI spec:
2724 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2730 gtk_widget_destroy (dialog);
2732 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2736 modest_ui_actions_on_cut (GtkAction *action,
2737 ModestWindow *window)
2739 GtkWidget *focused_widget;
2740 GtkClipboard *clipboard;
2742 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2743 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2744 if (GTK_IS_EDITABLE (focused_widget)) {
2745 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2746 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2747 gtk_clipboard_store (clipboard);
2748 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2749 GtkTextBuffer *buffer;
2751 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2752 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2753 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2754 gtk_clipboard_store (clipboard);
2755 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2756 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2757 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2758 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2763 modest_ui_actions_on_copy (GtkAction *action,
2764 ModestWindow *window)
2766 GtkClipboard *clipboard;
2767 GtkWidget *focused_widget;
2769 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2770 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2772 if (GTK_IS_LABEL (focused_widget)) {
2773 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2774 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2775 gtk_clipboard_store (clipboard);
2776 } else if (GTK_IS_EDITABLE (focused_widget)) {
2777 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2778 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2779 gtk_clipboard_store (clipboard);
2780 } else if (GTK_IS_HTML (focused_widget)) {
2781 gtk_html_copy (GTK_HTML (focused_widget));
2782 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2783 gtk_clipboard_store (clipboard);
2784 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2785 GtkTextBuffer *buffer;
2786 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2787 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2788 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2789 gtk_clipboard_store (clipboard);
2790 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2791 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2792 TnyIterator *iter = tny_list_create_iterator (header_list);
2793 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2795 gboolean ask = FALSE;
2797 TnyFolder *folder = tny_header_get_folder (header);
2798 TnyAccount *account = tny_folder_get_account (folder);
2799 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2800 /* If it's POP then ask */
2801 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2802 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2803 g_object_unref (account);
2804 g_object_unref (folder);
2805 g_object_unref (header);
2808 g_object_unref (iter);
2810 /* Check that the messages have been previously downloaded */
2811 gboolean continue_download = TRUE;
2813 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2814 if (continue_download)
2815 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2816 g_object_unref (header_list);
2817 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2818 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2821 /* Show information banner */
2822 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2827 modest_ui_actions_on_undo (GtkAction *action,
2828 ModestWindow *window)
2830 ModestEmailClipboard *clipboard = NULL;
2832 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2833 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2834 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2835 /* Clear clipboard source */
2836 clipboard = modest_runtime_get_email_clipboard ();
2837 modest_email_clipboard_clear (clipboard);
2840 g_return_if_reached ();
2845 modest_ui_actions_on_redo (GtkAction *action,
2846 ModestWindow *window)
2848 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2849 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2852 g_return_if_reached ();
2858 paste_msgs_cb (const GObject *object, gpointer user_data)
2860 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2861 g_return_if_fail (GTK_IS_WIDGET (user_data));
2863 /* destroy information note */
2864 gtk_widget_destroy (GTK_WIDGET(user_data));
2868 paste_as_attachment_free (gpointer data)
2870 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2872 gtk_widget_destroy (helper->banner);
2873 g_object_unref (helper->banner);
2878 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2883 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2884 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2889 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2894 modest_ui_actions_on_paste (GtkAction *action,
2895 ModestWindow *window)
2897 GtkWidget *focused_widget = NULL;
2898 GtkWidget *inf_note = NULL;
2899 ModestMailOperation *mail_op = NULL;
2901 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2902 if (GTK_IS_EDITABLE (focused_widget)) {
2903 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2904 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2905 ModestEmailClipboard *e_clipboard = NULL;
2906 e_clipboard = modest_runtime_get_email_clipboard ();
2907 if (modest_email_clipboard_cleared (e_clipboard)) {
2908 GtkTextBuffer *buffer;
2909 GtkClipboard *clipboard;
2911 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2912 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2913 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2914 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2915 ModestMailOperation *mail_op;
2916 TnyFolder *src_folder;
2919 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2920 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2921 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2922 _CS("ckct_nw_pasting"));
2923 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2924 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2926 if (helper->banner != NULL) {
2927 g_object_ref (G_OBJECT (helper->banner));
2928 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2929 gtk_widget_show (GTK_WIDGET (helper->banner));
2933 modest_mail_operation_get_msgs_full (mail_op,
2935 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2937 paste_as_attachment_free);
2940 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2941 ModestEmailClipboard *clipboard = NULL;
2942 TnyFolder *src_folder = NULL;
2943 TnyFolderStore *folder_store = NULL;
2944 TnyList *data = NULL;
2945 gboolean delete = FALSE;
2947 /* Check clipboard source */
2948 clipboard = modest_runtime_get_email_clipboard ();
2949 if (modest_email_clipboard_cleared (clipboard))
2952 /* Get elements to paste */
2953 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2955 /* Create a new mail operation */
2956 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2958 /* Get destination folder */
2959 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2961 /* transfer messages */
2965 /* Ask for user confirmation */
2966 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2967 TNY_FOLDER (folder_store),
2971 if (response == GTK_RESPONSE_OK) {
2972 /* Launch notification */
2973 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2974 _CS("ckct_nw_pasting"));
2975 if (inf_note != NULL) {
2976 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2977 gtk_widget_show (GTK_WIDGET(inf_note));
2980 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2981 modest_mail_operation_xfer_msgs (mail_op,
2983 TNY_FOLDER (folder_store),
2988 g_object_unref (mail_op);
2991 } else if (src_folder != NULL) {
2992 /* Launch notification */
2993 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2994 _CS("ckct_nw_pasting"));
2995 if (inf_note != NULL) {
2996 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2997 gtk_widget_show (GTK_WIDGET(inf_note));
3000 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3001 modest_mail_operation_xfer_folder (mail_op,
3011 g_object_unref (data);
3012 if (src_folder != NULL)
3013 g_object_unref (src_folder);
3014 if (folder_store != NULL)
3015 g_object_unref (folder_store);
3021 modest_ui_actions_on_select_all (GtkAction *action,
3022 ModestWindow *window)
3024 GtkWidget *focused_widget;
3026 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3027 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3028 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3029 } else if (GTK_IS_LABEL (focused_widget)) {
3030 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3031 } else if (GTK_IS_EDITABLE (focused_widget)) {
3032 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3033 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3034 GtkTextBuffer *buffer;
3035 GtkTextIter start, end;
3037 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3038 gtk_text_buffer_get_start_iter (buffer, &start);
3039 gtk_text_buffer_get_end_iter (buffer, &end);
3040 gtk_text_buffer_select_range (buffer, &start, &end);
3041 } else if (GTK_IS_HTML (focused_widget)) {
3042 gtk_html_select_all (GTK_HTML (focused_widget));
3043 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3044 GtkWidget *header_view = focused_widget;
3045 GtkTreeSelection *selection = NULL;
3047 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3048 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3049 MODEST_WIDGET_TYPE_HEADER_VIEW);
3051 /* Select all messages */
3052 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3053 gtk_tree_selection_select_all (selection);
3055 /* Set focuse on header view */
3056 gtk_widget_grab_focus (header_view);
3062 modest_ui_actions_on_mark_as_read (GtkAction *action,
3063 ModestWindow *window)
3065 g_return_if_fail (MODEST_IS_WINDOW(window));
3067 /* Mark each header as read */
3068 do_headers_action (window, headers_action_mark_as_read, NULL);
3072 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3073 ModestWindow *window)
3075 g_return_if_fail (MODEST_IS_WINDOW(window));
3077 /* Mark each header as read */
3078 do_headers_action (window, headers_action_mark_as_unread, NULL);
3082 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3083 GtkRadioAction *selected,
3084 ModestWindow *window)
3088 value = gtk_radio_action_get_current_value (selected);
3089 if (MODEST_IS_WINDOW (window)) {
3090 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3094 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3095 GtkRadioAction *selected,
3096 ModestWindow *window)
3098 TnyHeaderFlags flags;
3099 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3101 flags = gtk_radio_action_get_current_value (selected);
3102 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3105 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3106 GtkRadioAction *selected,
3107 ModestWindow *window)
3111 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3113 file_format = gtk_radio_action_get_current_value (selected);
3114 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3119 modest_ui_actions_on_zoom_plus (GtkAction *action,
3120 ModestWindow *window)
3122 g_return_if_fail (MODEST_IS_WINDOW (window));
3124 modest_window_zoom_plus (MODEST_WINDOW (window));
3128 modest_ui_actions_on_zoom_minus (GtkAction *action,
3129 ModestWindow *window)
3131 g_return_if_fail (MODEST_IS_WINDOW (window));
3133 modest_window_zoom_minus (MODEST_WINDOW (window));
3137 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3138 ModestWindow *window)
3140 ModestWindowMgr *mgr;
3141 gboolean fullscreen, active;
3142 g_return_if_fail (MODEST_IS_WINDOW (window));
3144 mgr = modest_runtime_get_window_mgr ();
3146 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3147 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3149 if (active != fullscreen) {
3150 modest_window_mgr_set_fullscreen_mode (mgr, active);
3151 gtk_window_present (GTK_WINDOW (window));
3156 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3157 ModestWindow *window)
3159 ModestWindowMgr *mgr;
3160 gboolean fullscreen;
3162 g_return_if_fail (MODEST_IS_WINDOW (window));
3164 mgr = modest_runtime_get_window_mgr ();
3165 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3166 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3168 gtk_window_present (GTK_WINDOW (window));
3172 * Used by modest_ui_actions_on_details to call do_headers_action
3175 headers_action_show_details (TnyHeader *header,
3176 ModestWindow *window,
3183 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3186 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3187 gtk_widget_show_all (dialog);
3188 gtk_dialog_run (GTK_DIALOG (dialog));
3190 gtk_widget_destroy (dialog);
3194 * Show the folder details in a ModestDetailsDialog widget
3197 show_folder_details (TnyFolder *folder,
3203 dialog = modest_details_dialog_new_with_folder (window, folder);
3206 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3207 gtk_widget_show_all (dialog);
3208 gtk_dialog_run (GTK_DIALOG (dialog));
3210 gtk_widget_destroy (dialog);
3214 * Show the header details in a ModestDetailsDialog widget
3217 modest_ui_actions_on_details (GtkAction *action,
3220 TnyList * headers_list;
3224 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3227 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3230 g_object_unref (msg);
3232 headers_list = get_selected_headers (win);
3236 iter = tny_list_create_iterator (headers_list);
3238 header = TNY_HEADER (tny_iterator_get_current (iter));
3240 headers_action_show_details (header, win, NULL);
3241 g_object_unref (header);
3244 g_object_unref (iter);
3245 g_object_unref (headers_list);
3247 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3248 GtkWidget *folder_view, *header_view;
3250 /* Check which widget has the focus */
3251 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3252 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3253 if (gtk_widget_is_focus (folder_view)) {
3254 TnyFolderStore *folder_store
3255 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3256 if (!folder_store) {
3257 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3260 /* Show only when it's a folder */
3261 /* This function should not be called for account items,
3262 * because we dim the menu item for them. */
3263 if (TNY_IS_FOLDER (folder_store)) {
3264 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3267 g_object_unref (folder_store);
3270 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3271 MODEST_WIDGET_TYPE_HEADER_VIEW);
3272 /* Show details of each header */
3273 do_headers_action (win, headers_action_show_details, header_view);
3279 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3280 ModestMsgEditWindow *window)
3282 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3284 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3288 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3289 ModestMsgEditWindow *window)
3291 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3293 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3297 modest_ui_actions_toggle_folders_view (GtkAction *action,
3298 ModestMainWindow *main_window)
3300 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3302 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3303 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3305 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3309 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3310 ModestWindow *window)
3312 gboolean active, fullscreen = FALSE;
3313 ModestWindowMgr *mgr;
3315 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3317 /* Check if we want to toggle the toolbar vuew in fullscreen
3319 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3320 "ViewShowToolbarFullScreen")) {
3324 /* Toggle toolbar */
3325 mgr = modest_runtime_get_window_mgr ();
3326 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3330 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3331 ModestMsgEditWindow *window)
3333 modest_msg_edit_window_select_font (window);
3337 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3338 const gchar *display_name,
3341 /* Do not change the application name if the widget has not
3342 the focus. This callback could be called even if the folder
3343 view has not the focus, because the handled signal could be
3344 emitted when the folder view is redrawn */
3345 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3347 gtk_window_set_title (window, display_name);
3349 gtk_window_set_title (window, " ");
3354 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3356 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3357 modest_msg_edit_window_select_contacts (window);
3361 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3363 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3364 modest_msg_edit_window_check_names (window, FALSE);
3368 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3370 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3371 GTK_WIDGET (user_data));
3375 create_move_to_dialog (GtkWindow *win,
3376 GtkWidget *folder_view,
3377 GtkWidget **tree_view)
3379 GtkWidget *dialog, *scroll;
3380 GtkWidget *new_button;
3382 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3384 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3387 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3388 /* We do this manually so GTK+ does not associate a response ID for
3390 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3391 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3392 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3394 /* Create scrolled window */
3395 scroll = gtk_scrolled_window_new (NULL, NULL);
3396 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3397 GTK_POLICY_AUTOMATIC,
3398 GTK_POLICY_AUTOMATIC);
3400 /* Create folder view */
3401 *tree_view = modest_platform_create_folder_view (NULL);
3403 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3405 /* It could happen that we're trying to move a message from a
3406 window (msg window for example) after the main window was
3407 closed, so we can not just get the model of the folder
3409 if (MODEST_IS_FOLDER_VIEW (folder_view))
3410 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3411 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3413 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3414 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3416 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3418 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3420 /* Add scroll to dialog */
3421 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3422 scroll, TRUE, TRUE, 0);
3424 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3425 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3431 * Returns TRUE if at least one of the headers of the list belongs to
3432 * a message that has been fully retrieved.
3435 has_retrieved_msgs (TnyList *list)
3438 gboolean found = FALSE;
3440 iter = tny_list_create_iterator (list);
3441 while (!tny_iterator_is_done (iter) && !found) {
3443 TnyHeaderFlags flags = 0;
3445 header = TNY_HEADER (tny_iterator_get_current (iter));
3447 flags = tny_header_get_flags (header);
3448 if (flags & TNY_HEADER_FLAG_CACHED)
3449 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3452 g_object_unref (header);
3456 tny_iterator_next (iter);
3458 g_object_unref (iter);
3464 * Shows a confirmation dialog to the user when we're moving messages
3465 * from a remote server to the local storage. Returns the dialog
3466 * response. If it's other kind of movement the it always returns
3470 msgs_move_to_confirmation (GtkWindow *win,
3471 TnyFolder *dest_folder,
3475 gint response = GTK_RESPONSE_OK;
3477 /* If the destination is a local folder (or MMC folder )*/
3478 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3479 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3480 TnyFolder *src_folder = NULL;
3481 TnyIterator *iter = NULL;
3482 TnyHeader *header = NULL;
3484 /* Get source folder */
3485 iter = tny_list_create_iterator (headers);
3486 header = TNY_HEADER (tny_iterator_get_current (iter));
3488 src_folder = tny_header_get_folder (header);
3489 g_object_unref (header);
3492 g_object_unref (iter);
3494 /* if no src_folder, message may be an attahcment */
3495 if (src_folder == NULL)
3496 return GTK_RESPONSE_CANCEL;
3498 /* If the source is a remote folder */
3499 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3500 if (modest_tny_folder_is_remote_folder (src_folder)) {
3501 const gchar *message = NULL;
3502 gboolean cached = has_retrieved_msgs (headers);
3504 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3505 tny_list_get_length (headers));
3507 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3508 tny_list_get_length (headers));
3510 if (cached && !delete)
3511 response = GTK_RESPONSE_OK;
3513 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3514 (const gchar *) message);
3517 g_object_unref (src_folder);
3526 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3528 ModestMsgViewWindow *self = NULL;
3530 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3531 self = MODEST_MSG_VIEW_WINDOW (object);
3533 if (!modest_msg_view_window_select_next_message (self))
3534 if (!modest_msg_view_window_select_previous_message (self))
3535 /* No more messages to view, so close this window */
3536 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3540 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3543 GObject *win = modest_mail_operation_get_source (mail_op);
3544 const GError *error = NULL;
3545 const gchar *message = NULL;
3547 /* Get error message */
3548 error = modest_mail_operation_get_error (mail_op);
3549 if (error != NULL && error->message != NULL) {
3550 message = error->message;
3552 message = _("mail_in_ui_folder_move_target_error");
3555 /* Show notification dialog */
3556 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3557 g_object_unref (win);
3561 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3564 GObject *win = modest_mail_operation_get_source (mail_op);
3565 const GError *error = modest_mail_operation_get_error (mail_op);
3567 g_return_if_fail (error != NULL);
3568 if (error->message != NULL)
3569 g_printerr ("modest: %s\n", error->message);
3571 g_printerr ("modest: unkonw error on send&receive operation");
3573 /* Show error message */
3574 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3575 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3576 /* _CS("sfil_ib_unable_to_receive")); */
3578 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3579 /* _CS("sfil_ib_unable_to_send")); */
3580 g_object_unref (win);
3584 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3591 gint pending_purges = 0;
3592 gboolean some_purged = FALSE;
3593 ModestWindow *win = MODEST_WINDOW (user_data);
3594 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3596 /* If there was any error */
3597 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3598 modest_window_mgr_unregister_header (mgr, header);
3602 /* Once the message has been retrieved for purging, we check if
3603 * it's all ok for purging */
3605 parts = tny_simple_list_new ();
3606 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3607 iter = tny_list_create_iterator (parts);
3609 while (!tny_iterator_is_done (iter)) {
3611 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3612 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3613 if (tny_mime_part_is_purged (part))
3620 g_object_unref (part);
3622 tny_iterator_next (iter);
3625 if (pending_purges>0) {
3627 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3629 if (response == GTK_RESPONSE_OK) {
3630 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3631 tny_iterator_first (iter);
3632 while (!tny_iterator_is_done (iter)) {
3635 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3636 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3637 tny_mime_part_set_purged (part);
3640 g_object_unref (part);
3642 tny_iterator_next (iter);
3645 tny_msg_rewrite_cache (msg);
3648 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3651 /* remove attachments */
3652 tny_iterator_first (iter);
3653 while (!tny_iterator_is_done (iter)) {
3656 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3658 /* One for the reference given by tny_iterator_get_current(): */
3659 g_object_unref (part);
3661 /* TODO: Is this meant to remove the attachment by doing another unref()?
3662 * Otherwise, this seems useless. */
3665 tny_iterator_next (iter);
3667 modest_window_mgr_unregister_header (mgr, header);
3669 g_object_unref (iter);
3670 g_object_unref (parts);
3674 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3675 ModestMainWindow *win)
3677 GtkWidget *header_view;
3678 TnyList *header_list;
3681 TnyHeaderFlags flags;
3682 ModestWindow *msg_view_window = NULL;
3685 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3687 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3688 MODEST_WIDGET_TYPE_HEADER_VIEW);
3690 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3692 if (tny_list_get_length (header_list) == 1) {
3693 iter = tny_list_create_iterator (header_list);
3694 header = TNY_HEADER (tny_iterator_get_current (iter));
3695 g_object_unref (iter);
3700 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3701 header, &msg_view_window);
3702 flags = tny_header_get_flags (header);
3703 if (!(flags & TNY_HEADER_FLAG_CACHED))
3706 if (msg_view_window != NULL)
3707 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3709 /* do nothing; uid was registered before, so window is probably on it's way */
3710 g_warning ("debug: header %p has already been registered", header);
3713 ModestMailOperation *mail_op = NULL;
3714 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3715 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3717 modest_ui_actions_get_msgs_full_error_handler,
3719 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3720 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3722 g_object_unref (mail_op);
3725 g_object_unref (header);
3727 g_object_unref (header_list);
3731 * Utility function that transfer messages from both the main window
3732 * and the msg view window when using the "Move to" dialog
3735 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3738 TnyList *headers = NULL;
3740 TnyAccount *dst_account = NULL;
3741 const gchar *proto_str = NULL;
3742 gboolean dst_is_pop = FALSE;
3744 if (!TNY_IS_FOLDER (dst_folder)) {
3745 modest_platform_information_banner (GTK_WIDGET (win),
3747 _CS("ckdg_ib_unable_to_move_to_current_location"));
3751 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3752 proto_str = tny_account_get_proto (dst_account);
3753 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3754 MODEST_PROTOCOL_STORE_POP);
3755 g_object_unref (dst_account);
3757 /* Get selected headers */
3758 headers = get_selected_headers (MODEST_WINDOW (win));
3761 modest_platform_information_banner (GTK_WIDGET (win),
3763 ngettext("mail_in_ui_folder_move_target_error",
3764 "mail_in_ui_folder_move_targets_error",
3765 tny_list_get_length (headers)));
3766 g_object_unref (headers);
3770 /* Ask for user confirmation */
3771 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3772 TNY_FOLDER (dst_folder),
3776 /* Transfer messages */
3777 if (response == GTK_RESPONSE_OK) {
3778 ModestMailOperation *mail_op =
3779 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3781 modest_ui_actions_move_folder_error_handler,
3783 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3786 modest_mail_operation_xfer_msgs (mail_op,
3788 TNY_FOLDER (dst_folder),
3790 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3793 g_object_unref (G_OBJECT (mail_op));
3795 g_object_unref (headers);
3800 * UI handler for the "Move to" action when invoked from the
3804 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3805 GtkWidget *folder_view,
3806 TnyFolderStore *dst_folder,
3807 ModestMainWindow *win)
3809 GtkWidget *header_view = NULL;
3810 ModestMailOperation *mail_op = NULL;
3811 TnyFolderStore *src_folder;
3813 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3815 /* Get the source folder */
3816 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3818 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3819 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3823 /* Get header view */
3825 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3827 /* Get folder or messages to transfer */
3828 if (gtk_widget_is_focus (folder_view)) {
3830 /* Allow only to transfer folders to the local root folder */
3831 if (TNY_IS_ACCOUNT (dst_folder) &&
3832 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3835 /* Clean folder on header view before moving it */
3836 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3838 if (TNY_IS_FOLDER (src_folder)) {
3840 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3842 modest_ui_actions_move_folder_error_handler,
3844 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3847 modest_mail_operation_xfer_folder (mail_op,
3848 TNY_FOLDER (src_folder),
3851 /* Unref mail operation */
3852 g_object_unref (G_OBJECT (mail_op));
3854 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3856 } else if (gtk_widget_is_focus (header_view)) {
3857 /* Transfer messages */
3858 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3863 g_object_unref (src_folder);
3868 * UI handler for the "Move to" action when invoked from the
3869 * ModestMsgViewWindow
3872 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3873 TnyFolderStore *dst_folder,
3874 ModestMsgViewWindow *win)
3876 TnyHeader *header = NULL;
3877 TnyFolder *src_folder;
3879 /* Create header list */
3880 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3881 src_folder = tny_header_get_folder(header);
3882 g_object_unref (header);
3884 /* Transfer the message */
3885 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3886 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3888 g_object_unref (src_folder);
3892 modest_ui_actions_on_move_to (GtkAction *action,
3895 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3897 TnyFolderStore *dst_folder = NULL;
3898 ModestMainWindow *main_window;
3900 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3901 MODEST_IS_MSG_VIEW_WINDOW (win));
3903 /* Get the main window if exists */
3904 if (MODEST_IS_MAIN_WINDOW (win))
3905 main_window = MODEST_MAIN_WINDOW (win);
3908 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3910 /* Get the folder view widget if exists */
3912 folder_view = modest_main_window_get_child_widget (main_window,
3913 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3917 /* Create and run the dialog */
3918 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3919 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3920 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3921 result = gtk_dialog_run (GTK_DIALOG(dialog));
3922 g_object_ref (tree_view);
3923 gtk_widget_destroy (dialog);
3925 if (result != GTK_RESPONSE_ACCEPT)
3928 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3929 /* Offer the connection dialog if necessary: */
3930 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3933 /* Do window specific stuff */
3934 if (MODEST_IS_MAIN_WINDOW (win))
3935 modest_ui_actions_on_main_window_move_to (action,
3938 MODEST_MAIN_WINDOW (win));
3940 modest_ui_actions_on_msg_view_window_move_to (action,
3942 MODEST_MSG_VIEW_WINDOW (win));
3945 g_object_unref (dst_folder);
3949 * Calls #HeadersFunc for each header already selected in the main
3950 * window or the message currently being shown in the msg view window
3953 do_headers_action (ModestWindow *win,
3957 TnyList *headers_list = NULL;
3958 TnyIterator *iter = NULL;
3959 TnyHeader *header = NULL;
3960 TnyFolder *folder = NULL;
3963 headers_list = get_selected_headers (win);
3967 /* Get the folder */
3968 iter = tny_list_create_iterator (headers_list);
3969 header = TNY_HEADER (tny_iterator_get_current (iter));
3971 folder = tny_header_get_folder (header);
3972 g_object_unref (header);
3975 /* Call the function for each header */
3976 while (!tny_iterator_is_done (iter)) {
3977 header = TNY_HEADER (tny_iterator_get_current (iter));
3978 func (header, win, user_data);
3979 g_object_unref (header);
3980 tny_iterator_next (iter);
3983 /* Trick: do a poke status in order to speed up the signaling
3985 tny_folder_poke_status (folder);
3988 g_object_unref (folder);
3989 g_object_unref (iter);
3990 g_object_unref (headers_list);
3994 modest_ui_actions_view_attachment (GtkAction *action,
3995 ModestWindow *window)
3997 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3998 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4000 /* not supported window for this action */
4001 g_return_if_reached ();
4006 modest_ui_actions_save_attachments (GtkAction *action,
4007 ModestWindow *window)
4009 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4010 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4012 /* not supported window for this action */
4013 g_return_if_reached ();
4018 modest_ui_actions_remove_attachments (GtkAction *action,
4019 ModestWindow *window)
4021 if (MODEST_IS_MAIN_WINDOW (window)) {
4022 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4023 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4024 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4026 /* not supported window for this action */
4027 g_return_if_reached ();
4032 modest_ui_actions_on_settings (GtkAction *action,
4037 dialog = modest_platform_get_global_settings_dialog ();
4038 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4039 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4040 gtk_widget_show_all (dialog);
4042 gtk_dialog_run (GTK_DIALOG (dialog));
4044 gtk_widget_destroy (dialog);
4048 modest_ui_actions_on_help (GtkAction *action,
4051 const gchar *help_id = NULL;
4053 if (MODEST_IS_MAIN_WINDOW (win)) {
4054 const gchar *action_name;
4055 action_name = gtk_action_get_name (action);
4057 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4058 !strcmp (action_name, "HeaderViewCSMHelp")) {
4059 GtkWidget *folder_view;
4060 TnyFolderStore *folder_store;
4061 /* Get selected folder */
4062 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4063 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4064 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4066 /* Switch help_id */
4067 if (TNY_IS_FOLDER (folder_store)) {
4068 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4069 case TNY_FOLDER_TYPE_NORMAL:
4070 help_id = "applications_email_managefolders";
4072 case TNY_FOLDER_TYPE_INBOX:
4073 help_id = "applications_email_inbox";
4075 case TNY_FOLDER_TYPE_OUTBOX:
4076 help_id = "applications_email_outbox";
4078 case TNY_FOLDER_TYPE_SENT:
4079 help_id = "applications_email_sent";
4081 case TNY_FOLDER_TYPE_DRAFTS:
4082 help_id = "applications_email_drafts";
4084 case TNY_FOLDER_TYPE_ARCHIVE:
4085 help_id = "applications_email_managefolders";
4088 help_id = "applications_email_managefolders";
4091 help_id = "applications_email_mainview";
4093 g_object_unref (folder_store);
4095 help_id = "applications_email_mainview";
4097 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4098 help_id = "applications_email_viewer";
4099 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4100 help_id = "applications_email_editor";
4102 modest_platform_show_help (GTK_WINDOW (win), help_id);
4106 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4107 ModestWindow *window)
4109 ModestMailOperation *mail_op;
4113 headers = get_selected_headers (window);
4117 /* Create mail operation */
4118 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4120 modest_ui_actions_get_msgs_full_error_handler,
4122 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4123 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4126 g_object_unref (headers);
4127 g_object_unref (mail_op);
4131 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4132 ModestWindow *window)
4134 g_return_if_fail (MODEST_IS_WINDOW (window));
4137 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4141 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4142 ModestWindow *window)
4144 g_return_if_fail (MODEST_IS_WINDOW (window));
4147 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4151 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4152 ModestWindow *window)
4154 g_return_if_fail (MODEST_IS_WINDOW (window));
4157 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4161 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4162 ModestWindow *window)
4164 g_return_if_fail (MODEST_IS_WINDOW (window));
4167 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4171 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4172 ModestWindow *window)
4174 g_return_if_fail (MODEST_IS_WINDOW (window));
4177 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4181 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4182 ModestWindow *window)
4184 g_return_if_fail (MODEST_IS_WINDOW (window));
4187 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4191 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4192 ModestWindow *window)
4194 g_return_if_fail (MODEST_IS_WINDOW (window));
4197 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4201 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4202 ModestWindow *window)
4204 g_return_if_fail (MODEST_IS_WINDOW (window));
4207 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4211 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4213 g_return_if_fail (MODEST_IS_WINDOW (window));
4216 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4220 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4222 g_return_if_fail (MODEST_IS_WINDOW (window));
4224 modest_platform_show_search_messages (GTK_WINDOW (window));
4228 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4230 g_return_if_fail (MODEST_IS_WINDOW (win));
4231 modest_platform_show_addressbook (GTK_WINDOW (win));
4236 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4237 ModestWindow *window)
4239 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4241 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4245 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4246 ModestMailOperationState *state,
4249 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4251 /* Set send/receive operation finished */
4252 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4253 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));