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 (
1352 MODEST_MAIN_WINDOW(window),
1353 MODEST_WIDGET_TYPE_HEADER_VIEW);
1357 modest_header_view_select_next (
1358 MODEST_HEADER_VIEW(header_view));
1359 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1360 modest_msg_view_window_select_next_message (
1361 MODEST_MSG_VIEW_WINDOW (window));
1363 g_return_if_reached ();
1368 modest_ui_actions_on_prev (GtkAction *action,
1369 ModestWindow *window)
1371 g_return_if_fail (MODEST_IS_WINDOW(window));
1373 if (MODEST_IS_MAIN_WINDOW (window)) {
1374 GtkWidget *header_view;
1375 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1376 MODEST_WIDGET_TYPE_HEADER_VIEW);
1380 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1381 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1382 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1384 g_return_if_reached ();
1389 modest_ui_actions_on_sort (GtkAction *action,
1390 ModestWindow *window)
1392 g_return_if_fail (MODEST_IS_WINDOW(window));
1394 if (MODEST_IS_MAIN_WINDOW (window)) {
1395 GtkWidget *header_view;
1396 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1397 MODEST_WIDGET_TYPE_HEADER_VIEW);
1399 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1404 /* Show sorting dialog */
1405 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1410 new_messages_arrived (ModestMailOperation *self,
1414 ModestMainWindow *win = NULL;
1415 gboolean folder_empty = FALSE;
1417 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1418 win = MODEST_MAIN_WINDOW (user_data);
1420 if (new_messages == 0)
1423 /* Set contents style of headers view */
1424 folder_empty = modest_main_window_get_style (win);
1426 modest_main_window_set_contents_style (win,
1427 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1433 * This function performs the send & receive required actions. The
1434 * window is used to create the mail operation. Typically it should
1435 * always be the main window, but we pass it as argument in order to
1439 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1441 gchar *acc_name = NULL;
1442 ModestMailOperation *mail_op;
1444 /* If no account name was provided then get the current account, and if
1445 there is no current account then pick the default one: */
1446 if (!account_name) {
1447 acc_name = g_strdup (modest_window_get_active_account(win));
1449 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1451 g_printerr ("modest: cannot get default account\n");
1455 acc_name = g_strdup (account_name);
1458 /* Set send/receive operation in progress */
1459 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1461 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1463 modest_ui_actions_send_receive_error_handler,
1466 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1467 G_CALLBACK (_on_send_receive_progress_changed),
1470 /* Send & receive. */
1471 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1472 /* Receive and then send. The operation is tagged initially as
1473 a receive operation because the account update performs a
1474 receive and then a send. The operation changes its type
1475 internally, so the progress objects will receive the proper
1476 progress information */
1477 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1478 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1479 g_object_unref (G_OBJECT (mail_op));
1487 modest_ui_actions_do_cancel_send (const gchar *account_name,
1490 TnyTransportAccount *transport_account;
1491 TnySendQueue *send_queue = NULL;
1492 GError *error = NULL;
1494 /* Get transport account */
1496 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1497 (modest_runtime_get_account_store(),
1499 TNY_ACCOUNT_TYPE_TRANSPORT));
1500 if (!transport_account) {
1501 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1506 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1507 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1508 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1509 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1510 "modest: could not find send queue for account\n");
1512 /* Keeep messages in outbox folder */
1513 tny_send_queue_cancel (send_queue, FALSE, &error);
1517 if (transport_account != NULL)
1518 g_object_unref (G_OBJECT (transport_account));
1522 modest_ui_actions_cancel_send_all (ModestWindow *win)
1524 GSList *account_names, *iter;
1526 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1529 iter = account_names;
1531 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1532 iter = g_slist_next (iter);
1535 modest_account_mgr_free_account_names (account_names);
1536 account_names = NULL;
1540 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1543 /* Check if accounts exist */
1544 gboolean accounts_exist =
1545 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1547 /* If not, allow the user to create an account before trying to send/receive. */
1548 if (!accounts_exist)
1549 modest_ui_actions_on_accounts (NULL, win);
1551 /* Cancel all sending operaitons */
1552 modest_ui_actions_cancel_send_all (win);
1556 * Refreshes all accounts. This function will be used by automatic
1560 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1562 GSList *account_names, *iter;
1564 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1567 iter = account_names;
1569 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1570 iter = g_slist_next (iter);
1573 modest_account_mgr_free_account_names (account_names);
1574 account_names = NULL;
1578 modest_do_refresh_current_folder(ModestWindow *win)
1580 /* Refresh currently selected folder. Note that if we only
1581 want to retreive the headers, then the refresh only will
1582 invoke a poke_status over all folders, i.e., only the
1583 total/unread count will be updated */
1584 if (MODEST_IS_MAIN_WINDOW (win)) {
1585 GtkWidget *header_view, *folder_view;
1586 TnyFolderStore *folder_store;
1588 /* Get folder and header view */
1590 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1591 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1593 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1595 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1597 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1598 MODEST_WIDGET_TYPE_HEADER_VIEW);
1600 /* We do not need to set the contents style
1601 because it hasn't changed. We also do not
1602 need to save the widget status. Just force
1604 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1605 TNY_FOLDER (folder_store),
1606 folder_refreshed_cb,
1607 MODEST_MAIN_WINDOW (win));
1611 g_object_unref (folder_store);
1617 * Handler of the click on Send&Receive button in the main toolbar
1620 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1622 /* Check if accounts exist */
1623 gboolean accounts_exist =
1624 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1626 /* If not, allow the user to create an account before trying to send/receive. */
1627 if (!accounts_exist)
1628 modest_ui_actions_on_accounts (NULL, win);
1630 modest_do_refresh_current_folder (win);
1632 /* Refresh the active account */
1633 modest_ui_actions_do_send_receive (NULL, win);
1638 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1641 GtkWidget *header_view;
1643 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1645 header_view = modest_main_window_get_child_widget (main_window,
1646 MODEST_WIDGET_TYPE_HEADER_VIEW);
1650 conf = modest_runtime_get_conf ();
1652 /* what is saved/restored is depending on the style; thus; we save with
1653 * old style, then update the style, and restore for this new style
1655 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1657 if (modest_header_view_get_style
1658 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1659 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1660 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1662 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1663 MODEST_HEADER_VIEW_STYLE_DETAILS);
1665 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1666 MODEST_CONF_HEADER_VIEW_KEY);
1671 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1673 ModestMainWindow *main_window)
1675 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1676 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1678 /* in the case the folder is empty, show the empty folder message and focus
1680 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1681 if (modest_header_view_is_empty (header_view)) {
1682 TnyFolder *folder = modest_header_view_get_folder (header_view);
1683 GtkWidget *folder_view =
1684 modest_main_window_get_child_widget (main_window,
1685 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1687 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1688 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1692 /* If no header has been selected then exit */
1697 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1698 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1700 /* Update Main window title */
1701 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1702 const gchar *subject = tny_header_get_subject (header);
1703 if (subject && strlen(subject) > 0)
1704 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1706 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1709 /* Update toolbar dimming state */
1710 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1714 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1716 ModestMainWindow *main_window)
1720 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1725 headers = tny_simple_list_new ();
1726 tny_list_prepend (headers, G_OBJECT (header));
1728 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1730 g_object_unref (headers);
1734 set_active_account_from_tny_account (TnyAccount *account,
1735 ModestWindow *window)
1737 const gchar *server_acc_name = tny_account_get_id (account);
1739 /* We need the TnyAccount provided by the
1740 account store because that is the one that
1741 knows the name of the Modest account */
1742 TnyAccount *modest_server_account = modest_server_account =
1743 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1744 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1747 const gchar *modest_acc_name =
1748 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1749 modest_window_set_active_account (window, modest_acc_name);
1750 g_object_unref (modest_server_account);
1755 folder_refreshed_cb (ModestMailOperation *mail_op,
1759 ModestMainWindow *win = NULL;
1760 GtkWidget *header_view;
1761 TnyFolder *current_folder;
1763 g_return_if_fail (TNY_IS_FOLDER (folder));
1765 win = MODEST_MAIN_WINDOW (user_data);
1767 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1770 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1771 if (current_folder != NULL && folder != current_folder) {
1776 /* Check if folder is empty and set headers view contents style */
1777 if (tny_folder_get_all_count (folder) == 0) {
1778 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1779 modest_main_window_set_contents_style (win,
1780 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1782 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1787 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1788 TnyFolderStore *folder_store,
1790 ModestMainWindow *main_window)
1793 GtkWidget *header_view;
1795 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1797 header_view = modest_main_window_get_child_widget(main_window,
1798 MODEST_WIDGET_TYPE_HEADER_VIEW);
1802 conf = modest_runtime_get_conf ();
1804 if (TNY_IS_ACCOUNT (folder_store)) {
1806 /* Update active account */
1807 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1808 /* Show account details */
1809 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1812 if (TNY_IS_FOLDER (folder_store) && selected) {
1814 /* Update the active account */
1815 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1817 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1818 g_object_unref (account);
1822 /* Set the header style by default, it could
1823 be changed later by the refresh callback to
1825 modest_main_window_set_contents_style (main_window,
1826 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1828 /* Set folder on header view. This function
1829 will call tny_folder_refresh_async so we
1830 pass a callback that will be called when
1831 finished. We use that callback to set the
1832 empty view if there are no messages */
1833 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1834 TNY_FOLDER (folder_store),
1835 folder_refreshed_cb,
1838 /* Restore configuration. We need to do this
1839 *after* the set_folder because the widget
1840 memory asks the header view about its
1842 modest_widget_memory_restore (modest_runtime_get_conf (),
1843 G_OBJECT(header_view),
1844 MODEST_CONF_HEADER_VIEW_KEY);
1846 /* Update the active account */
1847 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1848 /* Save only if we're seeing headers */
1849 if (modest_main_window_get_contents_style (main_window) ==
1850 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1851 modest_widget_memory_save (conf, G_OBJECT (header_view),
1852 MODEST_CONF_HEADER_VIEW_KEY);
1853 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1857 /* Update toolbar dimming state */
1858 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1862 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1869 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1871 online = tny_device_is_online (modest_runtime_get_device());
1874 /* already online -- the item is simply not there... */
1875 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1877 GTK_MESSAGE_WARNING,
1879 _("The %s you selected cannot be found"),
1881 gtk_dialog_run (GTK_DIALOG(dialog));
1883 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1887 GTK_RESPONSE_REJECT,
1889 GTK_RESPONSE_ACCEPT,
1891 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1892 "Do you want to get online?"), item);
1893 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1894 gtk_label_new (txt), FALSE, FALSE, 0);
1895 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1898 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1899 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1900 /* TODO: Comment about why is this commented out: */
1901 /* modest_platform_connect_and_wait (); */
1904 gtk_widget_destroy (dialog);
1908 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1911 /* g_message ("%s %s", __FUNCTION__, link); */
1916 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1919 modest_platform_activate_uri (link);
1923 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1926 modest_platform_show_uri_popup (link);
1930 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1933 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1937 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1938 const gchar *address,
1941 /* g_message ("%s %s", __FUNCTION__, address); */
1945 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1947 TnyTransportAccount *transport_account;
1948 ModestMailOperation *mail_operation;
1950 gchar *account_name, *from;
1951 ModestAccountMgr *account_mgr;
1952 gchar *info_text = NULL;
1954 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1956 data = modest_msg_edit_window_get_msg_data (edit_window);
1958 account_mgr = modest_runtime_get_account_mgr();
1959 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1961 account_name = modest_account_mgr_get_default_account (account_mgr);
1962 if (!account_name) {
1963 g_printerr ("modest: no account found\n");
1964 modest_msg_edit_window_free_msg_data (edit_window, data);
1968 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1969 account_name = g_strdup (data->account_name);
1973 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1974 (modest_runtime_get_account_store(),
1976 TNY_ACCOUNT_TYPE_TRANSPORT));
1977 if (!transport_account) {
1978 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1979 g_free (account_name);
1980 modest_msg_edit_window_free_msg_data (edit_window, data);
1983 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1985 /* Create the mail operation */
1986 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1987 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1989 modest_mail_operation_save_to_drafts (mail_operation,
2001 data->priority_flags);
2004 g_free (account_name);
2005 g_object_unref (G_OBJECT (transport_account));
2006 g_object_unref (G_OBJECT (mail_operation));
2008 modest_msg_edit_window_free_msg_data (edit_window, data);
2010 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2011 modest_platform_information_banner (NULL, NULL, info_text);
2015 /* For instance, when clicking the Send toolbar button when editing a message: */
2017 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2019 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2021 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2024 /* Offer the connection dialog, if necessary: */
2025 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2028 /* FIXME: Code added just for testing. The final version will
2029 use the send queue provided by tinymail and some
2031 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2032 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2034 account_name = modest_account_mgr_get_default_account (account_mgr);
2036 if (!account_name) {
2037 /* Run account setup wizard */
2038 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2042 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2044 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2045 account_name = g_strdup (data->account_name);
2048 /* Get the currently-active transport account for this modest account: */
2049 TnyTransportAccount *transport_account =
2050 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2051 (modest_runtime_get_account_store(),
2053 if (!transport_account) {
2054 /* Run account setup wizard */
2055 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2059 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2061 /* mail content checks and dialogs */
2062 if (data->subject == NULL || data->subject[0] == '\0') {
2063 GtkResponseType response;
2064 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2065 _("mcen_nc_subject_is_empty_send"));
2066 if (response == GTK_RESPONSE_CANCEL) {
2067 g_free (account_name);
2072 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2073 GtkResponseType response;
2074 gchar *note_message;
2075 gchar *note_subject = data->subject;
2076 if (note_subject == NULL || note_subject[0] == '\0')
2077 note_subject = _("mail_va_no_subject");
2078 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2079 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2081 g_free (note_message);
2082 if (response == GTK_RESPONSE_CANCEL) {
2083 g_free (account_name);
2088 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2090 /* Create the mail operation */
2091 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2092 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2094 modest_mail_operation_send_new_mail (mail_operation,
2105 data->priority_flags);
2109 g_free (account_name);
2110 g_object_unref (G_OBJECT (transport_account));
2111 g_object_unref (G_OBJECT (mail_operation));
2113 modest_msg_edit_window_free_msg_data (edit_window, data);
2114 modest_msg_edit_window_set_sent (edit_window, TRUE);
2116 /* Save settings and close the window: */
2117 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2121 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2122 ModestMsgEditWindow *window)
2124 ModestMsgEditFormatState *format_state = NULL;
2126 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2127 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2129 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2132 format_state = modest_msg_edit_window_get_format_state (window);
2133 g_return_if_fail (format_state != NULL);
2135 format_state->bold = gtk_toggle_action_get_active (action);
2136 modest_msg_edit_window_set_format_state (window, format_state);
2137 g_free (format_state);
2142 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2143 ModestMsgEditWindow *window)
2145 ModestMsgEditFormatState *format_state = NULL;
2147 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2148 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2150 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2153 format_state = modest_msg_edit_window_get_format_state (window);
2154 g_return_if_fail (format_state != NULL);
2156 format_state->italics = gtk_toggle_action_get_active (action);
2157 modest_msg_edit_window_set_format_state (window, format_state);
2158 g_free (format_state);
2163 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2164 ModestMsgEditWindow *window)
2166 ModestMsgEditFormatState *format_state = NULL;
2168 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2169 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2171 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2174 format_state = modest_msg_edit_window_get_format_state (window);
2175 g_return_if_fail (format_state != NULL);
2177 format_state->bullet = gtk_toggle_action_get_active (action);
2178 modest_msg_edit_window_set_format_state (window, format_state);
2179 g_free (format_state);
2184 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2185 GtkRadioAction *selected,
2186 ModestMsgEditWindow *window)
2188 ModestMsgEditFormatState *format_state = NULL;
2189 GtkJustification value;
2191 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2193 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2196 value = gtk_radio_action_get_current_value (selected);
2198 format_state = modest_msg_edit_window_get_format_state (window);
2199 g_return_if_fail (format_state != NULL);
2201 format_state->justification = value;
2202 modest_msg_edit_window_set_format_state (window, format_state);
2203 g_free (format_state);
2207 modest_ui_actions_on_select_editor_color (GtkAction *action,
2208 ModestMsgEditWindow *window)
2210 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2211 g_return_if_fail (GTK_IS_ACTION (action));
2213 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2216 modest_msg_edit_window_select_color (window);
2220 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2221 ModestMsgEditWindow *window)
2223 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2224 g_return_if_fail (GTK_IS_ACTION (action));
2226 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2229 modest_msg_edit_window_select_background_color (window);
2233 modest_ui_actions_on_insert_image (GtkAction *action,
2234 ModestMsgEditWindow *window)
2236 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2237 g_return_if_fail (GTK_IS_ACTION (action));
2239 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2242 modest_msg_edit_window_insert_image (window);
2246 modest_ui_actions_on_attach_file (GtkAction *action,
2247 ModestMsgEditWindow *window)
2249 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2250 g_return_if_fail (GTK_IS_ACTION (action));
2252 modest_msg_edit_window_offer_attach_file (window);
2256 modest_ui_actions_on_remove_attachments (GtkAction *action,
2257 ModestMsgEditWindow *window)
2259 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2260 g_return_if_fail (GTK_IS_ACTION (action));
2262 modest_msg_edit_window_remove_attachments (window, NULL);
2266 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2269 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2270 const GError *error = modest_mail_operation_get_error (mail_op);
2274 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2275 modest_mail_operation_get_error (mail_op)->message);
2280 modest_ui_actions_create_folder(GtkWidget *parent_window,
2281 GtkWidget *folder_view)
2283 TnyFolderStore *parent_folder;
2285 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2287 if (parent_folder) {
2288 gboolean finished = FALSE;
2290 gchar *folder_name = NULL, *suggested_name = NULL;
2291 const gchar *proto_str = NULL;
2292 TnyAccount *account;
2294 if (TNY_IS_ACCOUNT (parent_folder))
2295 account = g_object_ref (parent_folder);
2297 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2298 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2300 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2301 MODEST_PROTOCOL_STORE_POP) {
2303 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2305 g_object_unref (account);
2307 /* Run the new folder dialog */
2309 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2314 g_free (suggested_name);
2315 suggested_name = NULL;
2317 if (result == GTK_RESPONSE_REJECT) {
2320 ModestMailOperation *mail_op;
2321 TnyFolder *new_folder = NULL;
2323 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2324 G_OBJECT(parent_window),
2325 modest_ui_actions_new_folder_error_handler,
2328 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2330 new_folder = modest_mail_operation_create_folder (mail_op,
2332 (const gchar *) folder_name);
2334 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2337 g_object_unref (new_folder);
2340 g_object_unref (mail_op);
2343 suggested_name = folder_name;
2347 g_object_unref (parent_folder);
2352 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2354 GtkWidget *folder_view;
2356 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2358 folder_view = modest_main_window_get_child_widget (main_window,
2359 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2363 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2367 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2370 GObject *win = modest_mail_operation_get_source (mail_op);
2371 const GError *error = NULL;
2372 const gchar *message = NULL;
2374 /* Get error message */
2375 error = modest_mail_operation_get_error (mail_op);
2376 if (error != NULL && error->message != NULL) {
2377 message = error->message;
2379 message = _("!!! FIXME: Unable to rename");
2382 /* Show notification dialog */
2383 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2384 g_object_unref (win);
2388 modest_ui_actions_on_rename_folder (GtkAction *action,
2389 ModestMainWindow *main_window)
2391 TnyFolderStore *folder;
2392 GtkWidget *folder_view;
2393 GtkWidget *header_view;
2395 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2397 folder_view = modest_main_window_get_child_widget (main_window,
2398 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2402 header_view = modest_main_window_get_child_widget (main_window,
2403 MODEST_WIDGET_TYPE_HEADER_VIEW);
2408 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2412 /* Offer the connection dialog if necessary: */
2413 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2414 g_object_unref (G_OBJECT (folder));
2419 if (TNY_IS_FOLDER (folder)) {
2422 const gchar *current_name;
2424 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2425 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2426 current_name, &folder_name);
2428 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2429 ModestMailOperation *mail_op;
2432 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2433 G_OBJECT(main_window),
2434 modest_ui_actions_rename_folder_error_handler,
2438 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2441 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2443 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2444 TNY_FOLDER(folder), TRUE);
2447 modest_header_view_clear ((ModestHeaderView *) header_view);
2449 modest_mail_operation_rename_folder (mail_op,
2450 TNY_FOLDER (folder),
2451 (const gchar *) folder_name);
2453 g_object_unref (mail_op);
2454 g_free (folder_name);
2457 g_object_unref (folder);
2461 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2464 GObject *win = modest_mail_operation_get_source (mail_op);
2466 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2467 _("mail_in_ui_folder_delete_error"));
2468 g_object_unref (win);
2472 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2474 TnyFolderStore *folder;
2475 GtkWidget *folder_view;
2479 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2481 folder_view = modest_main_window_get_child_widget (main_window,
2482 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2486 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2488 /* Show an error if it's an account */
2489 if (!TNY_IS_FOLDER (folder)) {
2490 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2491 _("mail_in_ui_folder_delete_error"));
2492 g_object_unref (G_OBJECT (folder));
2496 /* Offer the connection dialog if necessary: */
2497 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2498 g_object_unref (G_OBJECT (folder));
2503 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2504 tny_folder_get_name (TNY_FOLDER (folder)));
2505 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2506 (const gchar *) message);
2509 if (response == GTK_RESPONSE_OK) {
2510 ModestMailOperation *mail_op =
2511 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2512 G_OBJECT(main_window),
2513 modest_ui_actions_delete_folder_error_handler,
2516 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2518 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2519 g_object_unref (G_OBJECT (mail_op));
2522 g_object_unref (G_OBJECT (folder));
2526 modest_ui_actions_on_delete_folder (GtkAction *action,
2527 ModestMainWindow *main_window)
2529 GtkWidget *folder_view;
2530 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2532 delete_folder (main_window, FALSE);
2533 folder_view = modest_main_window_get_child_widget (main_window,
2534 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2537 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2541 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2543 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2545 delete_folder (main_window, TRUE);
2550 show_error (GtkWidget *parent_widget, const gchar* text)
2552 hildon_banner_show_information(parent_widget, NULL, text);
2555 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2557 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2564 gtk_dialog_run (dialog);
2565 gtk_widget_destroy (GTK_WIDGET (dialog));
2570 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2571 const gchar* server_account_name,
2576 ModestMainWindow *main_window)
2578 g_return_if_fail(server_account_name);
2579 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2581 /* Initalize output parameters: */
2588 #ifdef MODEST_PLATFORM_MAEMO
2589 /* Maemo uses a different (awkward) button order,
2590 * It should probably just use gtk_alternative_dialog_button_order ().
2592 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2596 GTK_RESPONSE_ACCEPT,
2598 GTK_RESPONSE_REJECT,
2601 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2605 GTK_RESPONSE_REJECT,
2607 GTK_RESPONSE_ACCEPT,
2609 #endif /* MODEST_PLATFORM_MAEMO */
2611 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2613 gchar *server_name = modest_server_account_get_hostname (
2614 modest_runtime_get_account_mgr(), server_account_name);
2615 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2616 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2621 /* This causes a warning because the logical ID has no %s in it,
2622 * though the translation does, but there is not much we can do about that: */
2623 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2624 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2627 g_free (server_name);
2631 gchar *initial_username = modest_server_account_get_username (
2632 modest_runtime_get_account_mgr(), server_account_name);
2634 GtkWidget *entry_username = gtk_entry_new ();
2635 if (initial_username)
2636 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2637 /* Dim this if a connection has ever succeeded with this username,
2638 * as per the UI spec: */
2639 const gboolean username_known =
2640 modest_server_account_get_username_has_succeeded(
2641 modest_runtime_get_account_mgr(), server_account_name);
2642 gtk_widget_set_sensitive (entry_username, !username_known);
2644 #ifdef MODEST_PLATFORM_MAEMO
2645 /* Auto-capitalization is the default, so let's turn it off: */
2646 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2648 /* Create a size group to be used by all captions.
2649 * Note that HildonCaption does not create a default size group if we do not specify one.
2650 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2651 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2653 GtkWidget *caption = hildon_caption_new (sizegroup,
2654 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2655 gtk_widget_show (entry_username);
2656 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2657 FALSE, FALSE, MODEST_MARGIN_HALF);
2658 gtk_widget_show (caption);
2660 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2662 #endif /* MODEST_PLATFORM_MAEMO */
2665 GtkWidget *entry_password = gtk_entry_new ();
2666 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2667 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2669 #ifdef MODEST_PLATFORM_MAEMO
2670 /* Auto-capitalization is the default, so let's turn it off: */
2671 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2672 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2674 caption = hildon_caption_new (sizegroup,
2675 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2676 gtk_widget_show (entry_password);
2677 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2678 FALSE, FALSE, MODEST_MARGIN_HALF);
2679 gtk_widget_show (caption);
2680 g_object_unref (sizegroup);
2682 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2684 #endif /* MODEST_PLATFORM_MAEMO */
2686 /* This is not in the Maemo UI spec:
2687 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2688 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2692 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2694 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2696 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2698 modest_server_account_set_username (
2699 modest_runtime_get_account_mgr(), server_account_name,
2702 const gboolean username_was_changed =
2703 (strcmp (*username, initial_username) != 0);
2704 if (username_was_changed) {
2705 g_warning ("%s: tinymail does not yet support changing the "
2706 "username in the get_password() callback.\n", __FUNCTION__);
2711 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2713 /* We do not save the password in the configuration,
2714 * because this function is only called for passwords that should
2715 * not be remembered:
2716 modest_server_account_set_password (
2717 modest_runtime_get_account_mgr(), server_account_name,
2726 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2738 /* This is not in the Maemo UI spec:
2739 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2745 gtk_widget_destroy (dialog);
2747 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2751 modest_ui_actions_on_cut (GtkAction *action,
2752 ModestWindow *window)
2754 GtkWidget *focused_widget;
2755 GtkClipboard *clipboard;
2757 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2758 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2759 if (GTK_IS_EDITABLE (focused_widget)) {
2760 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2761 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2762 gtk_clipboard_store (clipboard);
2763 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2764 GtkTextBuffer *buffer;
2766 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2767 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2768 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2769 gtk_clipboard_store (clipboard);
2770 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2771 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2772 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2773 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2778 modest_ui_actions_on_copy (GtkAction *action,
2779 ModestWindow *window)
2781 GtkClipboard *clipboard;
2782 GtkWidget *focused_widget;
2784 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2785 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2787 if (GTK_IS_LABEL (focused_widget)) {
2788 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2789 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2790 gtk_clipboard_store (clipboard);
2791 } else if (GTK_IS_EDITABLE (focused_widget)) {
2792 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2793 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2794 gtk_clipboard_store (clipboard);
2795 } else if (GTK_IS_HTML (focused_widget)) {
2796 gtk_html_copy (GTK_HTML (focused_widget));
2797 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2798 gtk_clipboard_store (clipboard);
2799 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2800 GtkTextBuffer *buffer;
2801 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2802 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2803 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2804 gtk_clipboard_store (clipboard);
2805 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2806 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2807 TnyIterator *iter = tny_list_create_iterator (header_list);
2808 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2810 gboolean ask = FALSE;
2812 TnyFolder *folder = tny_header_get_folder (header);
2813 TnyAccount *account = tny_folder_get_account (folder);
2814 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2815 /* If it's POP then ask */
2816 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2817 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2818 g_object_unref (account);
2819 g_object_unref (folder);
2820 g_object_unref (header);
2823 g_object_unref (iter);
2825 /* Check that the messages have been previously downloaded */
2826 gboolean continue_download = TRUE;
2828 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2829 if (continue_download)
2830 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2831 g_object_unref (header_list);
2832 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2833 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2836 /* Show information banner */
2837 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2842 modest_ui_actions_on_undo (GtkAction *action,
2843 ModestWindow *window)
2845 ModestEmailClipboard *clipboard = NULL;
2847 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2848 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2849 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2850 /* Clear clipboard source */
2851 clipboard = modest_runtime_get_email_clipboard ();
2852 modest_email_clipboard_clear (clipboard);
2855 g_return_if_reached ();
2860 modest_ui_actions_on_redo (GtkAction *action,
2861 ModestWindow *window)
2863 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2864 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2867 g_return_if_reached ();
2873 paste_msgs_cb (const GObject *object, gpointer user_data)
2875 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2876 g_return_if_fail (GTK_IS_WIDGET (user_data));
2878 /* destroy information note */
2879 gtk_widget_destroy (GTK_WIDGET(user_data));
2883 paste_as_attachment_free (gpointer data)
2885 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2887 gtk_widget_destroy (helper->banner);
2888 g_object_unref (helper->banner);
2893 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2898 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2899 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2904 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2909 modest_ui_actions_on_paste (GtkAction *action,
2910 ModestWindow *window)
2912 GtkWidget *focused_widget = NULL;
2913 GtkWidget *inf_note = NULL;
2914 ModestMailOperation *mail_op = NULL;
2916 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2917 if (GTK_IS_EDITABLE (focused_widget)) {
2918 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2919 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2920 ModestEmailClipboard *e_clipboard = NULL;
2921 e_clipboard = modest_runtime_get_email_clipboard ();
2922 if (modest_email_clipboard_cleared (e_clipboard)) {
2923 GtkTextBuffer *buffer;
2924 GtkClipboard *clipboard;
2926 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2927 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2928 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2929 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2930 ModestMailOperation *mail_op;
2931 TnyFolder *src_folder;
2934 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2935 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2936 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2937 _CS("ckct_nw_pasting"));
2938 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2939 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2941 if (helper->banner != NULL) {
2942 g_object_ref (G_OBJECT (helper->banner));
2943 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2944 gtk_widget_show (GTK_WIDGET (helper->banner));
2948 modest_mail_operation_get_msgs_full (mail_op,
2950 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2952 paste_as_attachment_free);
2955 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2956 ModestEmailClipboard *clipboard = NULL;
2957 TnyFolder *src_folder = NULL;
2958 TnyFolderStore *folder_store = NULL;
2959 TnyList *data = NULL;
2960 gboolean delete = FALSE;
2962 /* Check clipboard source */
2963 clipboard = modest_runtime_get_email_clipboard ();
2964 if (modest_email_clipboard_cleared (clipboard))
2967 /* Get elements to paste */
2968 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2970 /* Create a new mail operation */
2971 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2973 /* Get destination folder */
2974 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2976 /* transfer messages */
2980 /* Ask for user confirmation */
2981 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2982 TNY_FOLDER (folder_store),
2986 if (response == GTK_RESPONSE_OK) {
2987 /* Launch notification */
2988 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2989 _CS("ckct_nw_pasting"));
2990 if (inf_note != NULL) {
2991 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2992 gtk_widget_show (GTK_WIDGET(inf_note));
2995 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2996 modest_mail_operation_xfer_msgs (mail_op,
2998 TNY_FOLDER (folder_store),
3003 g_object_unref (mail_op);
3006 } else if (src_folder != NULL) {
3007 /* Launch notification */
3008 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3009 _CS("ckct_nw_pasting"));
3010 if (inf_note != NULL) {
3011 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3012 gtk_widget_show (GTK_WIDGET(inf_note));
3015 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3016 modest_mail_operation_xfer_folder (mail_op,
3026 g_object_unref (data);
3027 if (src_folder != NULL)
3028 g_object_unref (src_folder);
3029 if (folder_store != NULL)
3030 g_object_unref (folder_store);
3036 modest_ui_actions_on_select_all (GtkAction *action,
3037 ModestWindow *window)
3039 GtkWidget *focused_widget;
3041 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3042 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3043 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3044 } else if (GTK_IS_LABEL (focused_widget)) {
3045 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3046 } else if (GTK_IS_EDITABLE (focused_widget)) {
3047 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3048 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3049 GtkTextBuffer *buffer;
3050 GtkTextIter start, end;
3052 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3053 gtk_text_buffer_get_start_iter (buffer, &start);
3054 gtk_text_buffer_get_end_iter (buffer, &end);
3055 gtk_text_buffer_select_range (buffer, &start, &end);
3056 } else if (GTK_IS_HTML (focused_widget)) {
3057 gtk_html_select_all (GTK_HTML (focused_widget));
3058 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3059 GtkWidget *header_view = focused_widget;
3060 GtkTreeSelection *selection = NULL;
3062 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3063 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3064 MODEST_WIDGET_TYPE_HEADER_VIEW);
3066 /* Select all messages */
3067 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3068 gtk_tree_selection_select_all (selection);
3070 /* Set focuse on header view */
3071 gtk_widget_grab_focus (header_view);
3077 modest_ui_actions_on_mark_as_read (GtkAction *action,
3078 ModestWindow *window)
3080 g_return_if_fail (MODEST_IS_WINDOW(window));
3082 /* Mark each header as read */
3083 do_headers_action (window, headers_action_mark_as_read, NULL);
3087 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3088 ModestWindow *window)
3090 g_return_if_fail (MODEST_IS_WINDOW(window));
3092 /* Mark each header as read */
3093 do_headers_action (window, headers_action_mark_as_unread, NULL);
3097 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3098 GtkRadioAction *selected,
3099 ModestWindow *window)
3103 value = gtk_radio_action_get_current_value (selected);
3104 if (MODEST_IS_WINDOW (window)) {
3105 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3109 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3110 GtkRadioAction *selected,
3111 ModestWindow *window)
3113 TnyHeaderFlags flags;
3114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3116 flags = gtk_radio_action_get_current_value (selected);
3117 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3120 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3121 GtkRadioAction *selected,
3122 ModestWindow *window)
3126 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3128 file_format = gtk_radio_action_get_current_value (selected);
3129 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3134 modest_ui_actions_on_zoom_plus (GtkAction *action,
3135 ModestWindow *window)
3137 g_return_if_fail (MODEST_IS_WINDOW (window));
3139 modest_window_zoom_plus (MODEST_WINDOW (window));
3143 modest_ui_actions_on_zoom_minus (GtkAction *action,
3144 ModestWindow *window)
3146 g_return_if_fail (MODEST_IS_WINDOW (window));
3148 modest_window_zoom_minus (MODEST_WINDOW (window));
3152 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3153 ModestWindow *window)
3155 ModestWindowMgr *mgr;
3156 gboolean fullscreen, active;
3157 g_return_if_fail (MODEST_IS_WINDOW (window));
3159 mgr = modest_runtime_get_window_mgr ();
3161 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3162 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3164 if (active != fullscreen) {
3165 modest_window_mgr_set_fullscreen_mode (mgr, active);
3166 gtk_window_present (GTK_WINDOW (window));
3171 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3172 ModestWindow *window)
3174 ModestWindowMgr *mgr;
3175 gboolean fullscreen;
3177 g_return_if_fail (MODEST_IS_WINDOW (window));
3179 mgr = modest_runtime_get_window_mgr ();
3180 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3181 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3183 gtk_window_present (GTK_WINDOW (window));
3187 * Used by modest_ui_actions_on_details to call do_headers_action
3190 headers_action_show_details (TnyHeader *header,
3191 ModestWindow *window,
3198 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3201 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3202 gtk_widget_show_all (dialog);
3203 gtk_dialog_run (GTK_DIALOG (dialog));
3205 gtk_widget_destroy (dialog);
3209 * Show the folder details in a ModestDetailsDialog widget
3212 show_folder_details (TnyFolder *folder,
3218 dialog = modest_details_dialog_new_with_folder (window, folder);
3221 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3222 gtk_widget_show_all (dialog);
3223 gtk_dialog_run (GTK_DIALOG (dialog));
3225 gtk_widget_destroy (dialog);
3229 * Show the header details in a ModestDetailsDialog widget
3232 modest_ui_actions_on_details (GtkAction *action,
3235 TnyList * headers_list;
3239 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3242 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3245 g_object_unref (msg);
3247 headers_list = get_selected_headers (win);
3251 iter = tny_list_create_iterator (headers_list);
3253 header = TNY_HEADER (tny_iterator_get_current (iter));
3255 headers_action_show_details (header, win, NULL);
3256 g_object_unref (header);
3259 g_object_unref (iter);
3260 g_object_unref (headers_list);
3262 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3263 GtkWidget *folder_view, *header_view;
3265 /* Check which widget has the focus */
3266 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3267 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3268 if (gtk_widget_is_focus (folder_view)) {
3269 TnyFolderStore *folder_store
3270 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3271 if (!folder_store) {
3272 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3275 /* Show only when it's a folder */
3276 /* This function should not be called for account items,
3277 * because we dim the menu item for them. */
3278 if (TNY_IS_FOLDER (folder_store)) {
3279 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3282 g_object_unref (folder_store);
3285 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3286 MODEST_WIDGET_TYPE_HEADER_VIEW);
3287 /* Show details of each header */
3288 do_headers_action (win, headers_action_show_details, header_view);
3294 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3295 ModestMsgEditWindow *window)
3297 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3299 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3303 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3304 ModestMsgEditWindow *window)
3306 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3308 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3312 modest_ui_actions_toggle_folders_view (GtkAction *action,
3313 ModestMainWindow *main_window)
3315 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3317 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3318 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3320 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3324 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3325 ModestWindow *window)
3327 gboolean active, fullscreen = FALSE;
3328 ModestWindowMgr *mgr;
3330 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3332 /* Check if we want to toggle the toolbar vuew in fullscreen
3334 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3335 "ViewShowToolbarFullScreen")) {
3339 /* Toggle toolbar */
3340 mgr = modest_runtime_get_window_mgr ();
3341 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3345 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3346 ModestMsgEditWindow *window)
3348 modest_msg_edit_window_select_font (window);
3352 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3353 const gchar *display_name,
3356 /* Do not change the application name if the widget has not
3357 the focus. This callback could be called even if the folder
3358 view has not the focus, because the handled signal could be
3359 emitted when the folder view is redrawn */
3360 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3362 gtk_window_set_title (window, display_name);
3364 gtk_window_set_title (window, " ");
3369 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3371 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3372 modest_msg_edit_window_select_contacts (window);
3376 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3378 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3379 modest_msg_edit_window_check_names (window, FALSE);
3383 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3385 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3386 GTK_WIDGET (user_data));
3390 create_move_to_dialog (GtkWindow *win,
3391 GtkWidget *folder_view,
3392 GtkWidget **tree_view)
3394 GtkWidget *dialog, *scroll;
3395 GtkWidget *new_button;
3397 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3399 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3402 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3403 /* We do this manually so GTK+ does not associate a response ID for
3405 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3406 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3407 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3409 /* Create scrolled window */
3410 scroll = gtk_scrolled_window_new (NULL, NULL);
3411 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3412 GTK_POLICY_AUTOMATIC,
3413 GTK_POLICY_AUTOMATIC);
3415 /* Create folder view */
3416 *tree_view = modest_platform_create_folder_view (NULL);
3418 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3420 /* It could happen that we're trying to move a message from a
3421 window (msg window for example) after the main window was
3422 closed, so we can not just get the model of the folder
3424 if (MODEST_IS_FOLDER_VIEW (folder_view))
3425 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3426 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3428 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3429 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3431 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3433 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3435 /* Add scroll to dialog */
3436 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3437 scroll, TRUE, TRUE, 0);
3439 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3440 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3446 * Returns TRUE if at least one of the headers of the list belongs to
3447 * a message that has been fully retrieved.
3450 has_retrieved_msgs (TnyList *list)
3453 gboolean found = FALSE;
3455 iter = tny_list_create_iterator (list);
3456 while (!tny_iterator_is_done (iter) && !found) {
3458 TnyHeaderFlags flags = 0;
3460 header = TNY_HEADER (tny_iterator_get_current (iter));
3462 flags = tny_header_get_flags (header);
3463 if (flags & TNY_HEADER_FLAG_CACHED)
3464 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3467 g_object_unref (header);
3471 tny_iterator_next (iter);
3473 g_object_unref (iter);
3479 * Shows a confirmation dialog to the user when we're moving messages
3480 * from a remote server to the local storage. Returns the dialog
3481 * response. If it's other kind of movement the it always returns
3485 msgs_move_to_confirmation (GtkWindow *win,
3486 TnyFolder *dest_folder,
3490 gint response = GTK_RESPONSE_OK;
3492 /* If the destination is a local folder (or MMC folder )*/
3493 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3494 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3495 TnyFolder *src_folder = NULL;
3496 TnyIterator *iter = NULL;
3497 TnyHeader *header = NULL;
3499 /* Get source folder */
3500 iter = tny_list_create_iterator (headers);
3501 header = TNY_HEADER (tny_iterator_get_current (iter));
3503 src_folder = tny_header_get_folder (header);
3504 g_object_unref (header);
3507 g_object_unref (iter);
3509 /* if no src_folder, message may be an attahcment */
3510 if (src_folder == NULL)
3511 return GTK_RESPONSE_CANCEL;
3513 /* If the source is a remote folder */
3514 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3515 if (modest_tny_folder_is_remote_folder (src_folder)) {
3516 const gchar *message = NULL;
3517 gboolean cached = has_retrieved_msgs (headers);
3519 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3520 tny_list_get_length (headers));
3522 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3523 tny_list_get_length (headers));
3525 if (cached && !delete)
3526 response = GTK_RESPONSE_OK;
3528 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3529 (const gchar *) message);
3532 g_object_unref (src_folder);
3541 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3543 ModestMsgViewWindow *self = NULL;
3545 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3546 self = MODEST_MSG_VIEW_WINDOW (object);
3548 if (!modest_msg_view_window_select_next_message (self))
3549 if (!modest_msg_view_window_select_previous_message (self))
3550 /* No more messages to view, so close this window */
3551 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3555 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3558 GObject *win = modest_mail_operation_get_source (mail_op);
3559 const GError *error = NULL;
3560 const gchar *message = NULL;
3562 /* Get error message */
3563 error = modest_mail_operation_get_error (mail_op);
3564 if (error != NULL && error->message != NULL) {
3565 message = error->message;
3567 message = _("mail_in_ui_folder_move_target_error");
3570 /* Show notification dialog */
3571 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3572 g_object_unref (win);
3576 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3579 GObject *win = modest_mail_operation_get_source (mail_op);
3580 const GError *error = modest_mail_operation_get_error (mail_op);
3582 g_return_if_fail (error != NULL);
3583 if (error->message != NULL)
3584 g_printerr ("modest: %s\n", error->message);
3586 g_printerr ("modest: unkonw error on send&receive operation");
3588 /* Show error message */
3589 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3590 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3591 /* _CS("sfil_ib_unable_to_receive")); */
3593 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3594 /* _CS("sfil_ib_unable_to_send")); */
3595 g_object_unref (win);
3599 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3606 gint pending_purges = 0;
3607 gboolean some_purged = FALSE;
3608 ModestWindow *win = MODEST_WINDOW (user_data);
3609 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3611 /* If there was any error */
3612 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3613 modest_window_mgr_unregister_header (mgr, header);
3617 /* Once the message has been retrieved for purging, we check if
3618 * it's all ok for purging */
3620 parts = tny_simple_list_new ();
3621 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3622 iter = tny_list_create_iterator (parts);
3624 while (!tny_iterator_is_done (iter)) {
3626 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3627 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3628 if (tny_mime_part_is_purged (part))
3635 g_object_unref (part);
3637 tny_iterator_next (iter);
3640 if (pending_purges>0) {
3642 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3644 if (response == GTK_RESPONSE_OK) {
3645 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3646 tny_iterator_first (iter);
3647 while (!tny_iterator_is_done (iter)) {
3650 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3651 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3652 tny_mime_part_set_purged (part);
3655 g_object_unref (part);
3657 tny_iterator_next (iter);
3660 tny_msg_rewrite_cache (msg);
3663 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3666 /* remove attachments */
3667 tny_iterator_first (iter);
3668 while (!tny_iterator_is_done (iter)) {
3671 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3673 /* One for the reference given by tny_iterator_get_current(): */
3674 g_object_unref (part);
3676 /* TODO: Is this meant to remove the attachment by doing another unref()?
3677 * Otherwise, this seems useless. */
3680 tny_iterator_next (iter);
3682 modest_window_mgr_unregister_header (mgr, header);
3684 g_object_unref (iter);
3685 g_object_unref (parts);
3689 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3690 ModestMainWindow *win)
3692 GtkWidget *header_view;
3693 TnyList *header_list;
3696 TnyHeaderFlags flags;
3697 ModestWindow *msg_view_window = NULL;
3700 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3702 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3703 MODEST_WIDGET_TYPE_HEADER_VIEW);
3705 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3707 if (tny_list_get_length (header_list) == 1) {
3708 iter = tny_list_create_iterator (header_list);
3709 header = TNY_HEADER (tny_iterator_get_current (iter));
3710 g_object_unref (iter);
3715 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3716 header, &msg_view_window);
3717 flags = tny_header_get_flags (header);
3718 if (!(flags & TNY_HEADER_FLAG_CACHED))
3721 if (msg_view_window != NULL)
3722 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3724 /* do nothing; uid was registered before, so window is probably on it's way */
3725 g_warning ("debug: header %p has already been registered", header);
3728 ModestMailOperation *mail_op = NULL;
3729 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3730 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3732 modest_ui_actions_get_msgs_full_error_handler,
3734 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3735 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3737 g_object_unref (mail_op);
3740 g_object_unref (header);
3742 g_object_unref (header_list);
3746 * Utility function that transfer messages from both the main window
3747 * and the msg view window when using the "Move to" dialog
3750 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3753 TnyList *headers = NULL;
3755 TnyAccount *dst_account = NULL;
3756 const gchar *proto_str = NULL;
3757 gboolean dst_is_pop = FALSE;
3759 if (!TNY_IS_FOLDER (dst_folder)) {
3760 modest_platform_information_banner (GTK_WIDGET (win),
3762 _CS("ckdg_ib_unable_to_move_to_current_location"));
3766 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3767 proto_str = tny_account_get_proto (dst_account);
3768 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3769 MODEST_PROTOCOL_STORE_POP);
3770 g_object_unref (dst_account);
3772 /* Get selected headers */
3773 headers = get_selected_headers (MODEST_WINDOW (win));
3776 modest_platform_information_banner (GTK_WIDGET (win),
3778 ngettext("mail_in_ui_folder_move_target_error",
3779 "mail_in_ui_folder_move_targets_error",
3780 tny_list_get_length (headers)));
3781 g_object_unref (headers);
3785 /* Ask for user confirmation */
3786 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3787 TNY_FOLDER (dst_folder),
3791 /* Transfer messages */
3792 if (response == GTK_RESPONSE_OK) {
3793 ModestMailOperation *mail_op =
3794 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3796 modest_ui_actions_move_folder_error_handler,
3798 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3801 modest_mail_operation_xfer_msgs (mail_op,
3803 TNY_FOLDER (dst_folder),
3805 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3808 g_object_unref (G_OBJECT (mail_op));
3810 g_object_unref (headers);
3815 * UI handler for the "Move to" action when invoked from the
3819 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3820 GtkWidget *folder_view,
3821 TnyFolderStore *dst_folder,
3822 ModestMainWindow *win)
3824 GtkWidget *header_view = NULL;
3825 ModestMailOperation *mail_op = NULL;
3826 TnyFolderStore *src_folder;
3828 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3830 /* Get the source folder */
3831 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3833 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3834 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3838 /* Get header view */
3840 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3842 /* Get folder or messages to transfer */
3843 if (gtk_widget_is_focus (folder_view)) {
3845 /* Allow only to transfer folders to the local root folder */
3846 if (TNY_IS_ACCOUNT (dst_folder) &&
3847 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3850 /* Clean folder on header view before moving it */
3851 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3853 if (TNY_IS_FOLDER (src_folder)) {
3855 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3857 modest_ui_actions_move_folder_error_handler,
3859 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3862 modest_mail_operation_xfer_folder (mail_op,
3863 TNY_FOLDER (src_folder),
3866 /* Unref mail operation */
3867 g_object_unref (G_OBJECT (mail_op));
3869 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3871 } else if (gtk_widget_is_focus (header_view)) {
3872 /* Transfer messages */
3873 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3878 g_object_unref (src_folder);
3883 * UI handler for the "Move to" action when invoked from the
3884 * ModestMsgViewWindow
3887 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3888 TnyFolderStore *dst_folder,
3889 ModestMsgViewWindow *win)
3891 TnyHeader *header = NULL;
3892 TnyFolder *src_folder;
3894 /* Create header list */
3895 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3896 src_folder = tny_header_get_folder(header);
3897 g_object_unref (header);
3899 /* Transfer the message */
3900 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3901 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3903 g_object_unref (src_folder);
3907 modest_ui_actions_on_move_to (GtkAction *action,
3910 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3912 TnyFolderStore *dst_folder = NULL;
3913 ModestMainWindow *main_window;
3915 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3916 MODEST_IS_MSG_VIEW_WINDOW (win));
3918 /* Get the main window if exists */
3919 if (MODEST_IS_MAIN_WINDOW (win))
3920 main_window = MODEST_MAIN_WINDOW (win);
3923 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3925 /* Get the folder view widget if exists */
3927 folder_view = modest_main_window_get_child_widget (main_window,
3928 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3932 /* Create and run the dialog */
3933 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3934 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3935 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3936 result = gtk_dialog_run (GTK_DIALOG(dialog));
3937 g_object_ref (tree_view);
3938 gtk_widget_destroy (dialog);
3940 if (result != GTK_RESPONSE_ACCEPT)
3943 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3944 /* Offer the connection dialog if necessary: */
3945 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3948 /* Do window specific stuff */
3949 if (MODEST_IS_MAIN_WINDOW (win))
3950 modest_ui_actions_on_main_window_move_to (action,
3953 MODEST_MAIN_WINDOW (win));
3955 modest_ui_actions_on_msg_view_window_move_to (action,
3957 MODEST_MSG_VIEW_WINDOW (win));
3960 g_object_unref (dst_folder);
3964 * Calls #HeadersFunc for each header already selected in the main
3965 * window or the message currently being shown in the msg view window
3968 do_headers_action (ModestWindow *win,
3972 TnyList *headers_list = NULL;
3973 TnyIterator *iter = NULL;
3974 TnyHeader *header = NULL;
3975 TnyFolder *folder = NULL;
3978 headers_list = get_selected_headers (win);
3982 /* Get the folder */
3983 iter = tny_list_create_iterator (headers_list);
3984 header = TNY_HEADER (tny_iterator_get_current (iter));
3986 folder = tny_header_get_folder (header);
3987 g_object_unref (header);
3990 /* Call the function for each header */
3991 while (!tny_iterator_is_done (iter)) {
3992 header = TNY_HEADER (tny_iterator_get_current (iter));
3993 func (header, win, user_data);
3994 g_object_unref (header);
3995 tny_iterator_next (iter);
3998 /* Trick: do a poke status in order to speed up the signaling
4000 tny_folder_poke_status (folder);
4003 g_object_unref (folder);
4004 g_object_unref (iter);
4005 g_object_unref (headers_list);
4009 modest_ui_actions_view_attachment (GtkAction *action,
4010 ModestWindow *window)
4012 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4013 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4015 /* not supported window for this action */
4016 g_return_if_reached ();
4021 modest_ui_actions_save_attachments (GtkAction *action,
4022 ModestWindow *window)
4024 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4025 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4027 /* not supported window for this action */
4028 g_return_if_reached ();
4033 modest_ui_actions_remove_attachments (GtkAction *action,
4034 ModestWindow *window)
4036 if (MODEST_IS_MAIN_WINDOW (window)) {
4037 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4038 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4039 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4041 /* not supported window for this action */
4042 g_return_if_reached ();
4047 modest_ui_actions_on_settings (GtkAction *action,
4052 dialog = modest_platform_get_global_settings_dialog ();
4053 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4054 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4055 gtk_widget_show_all (dialog);
4057 gtk_dialog_run (GTK_DIALOG (dialog));
4059 gtk_widget_destroy (dialog);
4063 modest_ui_actions_on_help (GtkAction *action,
4066 const gchar *help_id = NULL;
4068 if (MODEST_IS_MAIN_WINDOW (win)) {
4069 const gchar *action_name;
4070 action_name = gtk_action_get_name (action);
4072 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4073 !strcmp (action_name, "HeaderViewCSMHelp")) {
4074 GtkWidget *folder_view;
4075 TnyFolderStore *folder_store;
4076 /* Get selected folder */
4077 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4078 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4079 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4081 /* Switch help_id */
4082 if (TNY_IS_FOLDER (folder_store)) {
4083 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4084 case TNY_FOLDER_TYPE_NORMAL:
4085 help_id = "applications_email_managefolders";
4087 case TNY_FOLDER_TYPE_INBOX:
4088 help_id = "applications_email_inbox";
4090 case TNY_FOLDER_TYPE_OUTBOX:
4091 help_id = "applications_email_outbox";
4093 case TNY_FOLDER_TYPE_SENT:
4094 help_id = "applications_email_sent";
4096 case TNY_FOLDER_TYPE_DRAFTS:
4097 help_id = "applications_email_drafts";
4099 case TNY_FOLDER_TYPE_ARCHIVE:
4100 help_id = "applications_email_managefolders";
4103 help_id = "applications_email_managefolders";
4106 help_id = "applications_email_mainview";
4108 g_object_unref (folder_store);
4110 help_id = "applications_email_mainview";
4112 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4113 help_id = "applications_email_viewer";
4114 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4115 help_id = "applications_email_editor";
4117 modest_platform_show_help (GTK_WINDOW (win), help_id);
4121 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4122 ModestWindow *window)
4124 ModestMailOperation *mail_op;
4128 headers = get_selected_headers (window);
4132 /* Create mail operation */
4133 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4135 modest_ui_actions_get_msgs_full_error_handler,
4137 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4138 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4141 g_object_unref (headers);
4142 g_object_unref (mail_op);
4146 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4147 ModestWindow *window)
4149 g_return_if_fail (MODEST_IS_WINDOW (window));
4152 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4156 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4157 ModestWindow *window)
4159 g_return_if_fail (MODEST_IS_WINDOW (window));
4162 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4166 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4167 ModestWindow *window)
4169 g_return_if_fail (MODEST_IS_WINDOW (window));
4172 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4176 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4177 ModestWindow *window)
4179 g_return_if_fail (MODEST_IS_WINDOW (window));
4182 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4186 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4187 ModestWindow *window)
4189 g_return_if_fail (MODEST_IS_WINDOW (window));
4192 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4196 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4197 ModestWindow *window)
4199 g_return_if_fail (MODEST_IS_WINDOW (window));
4202 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4206 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4207 ModestWindow *window)
4209 g_return_if_fail (MODEST_IS_WINDOW (window));
4212 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4216 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4217 ModestWindow *window)
4219 g_return_if_fail (MODEST_IS_WINDOW (window));
4222 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4226 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4228 g_return_if_fail (MODEST_IS_WINDOW (window));
4231 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4235 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4237 g_return_if_fail (MODEST_IS_WINDOW (window));
4239 modest_platform_show_search_messages (GTK_WINDOW (window));
4243 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4245 g_return_if_fail (MODEST_IS_WINDOW (win));
4246 modest_platform_show_addressbook (GTK_WINDOW (win));
4251 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4252 ModestWindow *window)
4254 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4256 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4260 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4261 ModestMailOperationState *state,
4264 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4266 /* Set send/receive operation finished */
4267 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4268 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));