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 GtkWidget *folder_view = NULL;
1416 TnyFolderStore *folder = NULL;
1417 gboolean folder_empty = FALSE;
1419 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1420 win = MODEST_MAIN_WINDOW (user_data);
1422 /* Set contents style of headers view */
1423 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1424 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1425 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1426 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1429 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1432 modest_main_window_set_contents_style (win,
1433 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1436 /* Notify new messages have been downloaded */
1437 if (new_messages > 0)
1438 modest_platform_on_new_msg ();
1442 * This function performs the send & receive required actions. The
1443 * window is used to create the mail operation. Typically it should
1444 * always be the main window, but we pass it as argument in order to
1448 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1450 gchar *acc_name = NULL;
1451 ModestMailOperation *mail_op;
1453 /* If no account name was provided then get the current account, and if
1454 there is no current account then pick the default one: */
1455 if (!account_name) {
1456 acc_name = g_strdup (modest_window_get_active_account(win));
1458 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1460 g_printerr ("modest: cannot get default account\n");
1464 acc_name = g_strdup (account_name);
1467 /* Set send/receive operation in progress */
1468 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1470 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1472 modest_ui_actions_send_receive_error_handler,
1475 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1476 G_CALLBACK (_on_send_receive_progress_changed),
1479 /* Send & receive. */
1480 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1481 /* Receive and then send. The operation is tagged initially as
1482 a receive operation because the account update performs a
1483 receive and then a send. The operation changes its type
1484 internally, so the progress objects will receive the proper
1485 progress information */
1486 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1487 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1488 g_object_unref (G_OBJECT (mail_op));
1496 modest_ui_actions_do_cancel_send (const gchar *account_name,
1499 TnyTransportAccount *transport_account;
1500 TnySendQueue *send_queue = NULL;
1501 GError *error = NULL;
1503 /* Get transport account */
1505 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1506 (modest_runtime_get_account_store(),
1508 TNY_ACCOUNT_TYPE_TRANSPORT));
1509 if (!transport_account) {
1510 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1515 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1516 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1517 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1518 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1519 "modest: could not find send queue for account\n");
1521 /* Keeep messages in outbox folder */
1522 tny_send_queue_cancel (send_queue, FALSE, &error);
1526 if (transport_account != NULL)
1527 g_object_unref (G_OBJECT (transport_account));
1531 modest_ui_actions_cancel_send_all (ModestWindow *win)
1533 GSList *account_names, *iter;
1535 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1538 iter = account_names;
1540 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1541 iter = g_slist_next (iter);
1544 modest_account_mgr_free_account_names (account_names);
1545 account_names = NULL;
1549 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1552 /* Check if accounts exist */
1553 gboolean accounts_exist =
1554 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1556 /* If not, allow the user to create an account before trying to send/receive. */
1557 if (!accounts_exist)
1558 modest_ui_actions_on_accounts (NULL, win);
1560 /* Cancel all sending operaitons */
1561 modest_ui_actions_cancel_send_all (win);
1565 * Refreshes all accounts. This function will be used by automatic
1569 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1571 GSList *account_names, *iter;
1573 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1576 iter = account_names;
1578 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1579 iter = g_slist_next (iter);
1582 modest_account_mgr_free_account_names (account_names);
1583 account_names = NULL;
1587 modest_do_refresh_current_folder(ModestWindow *win)
1589 /* Refresh currently selected folder. Note that if we only
1590 want to retreive the headers, then the refresh only will
1591 invoke a poke_status over all folders, i.e., only the
1592 total/unread count will be updated */
1593 if (MODEST_IS_MAIN_WINDOW (win)) {
1594 GtkWidget *header_view, *folder_view;
1595 TnyFolderStore *folder_store;
1597 /* Get folder and header view */
1599 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1600 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1602 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1604 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1606 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1607 MODEST_WIDGET_TYPE_HEADER_VIEW);
1609 /* We do not need to set the contents style
1610 because it hasn't changed. We also do not
1611 need to save the widget status. Just force
1613 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1614 TNY_FOLDER (folder_store),
1615 folder_refreshed_cb,
1616 MODEST_MAIN_WINDOW (win));
1620 g_object_unref (folder_store);
1626 * Handler of the click on Send&Receive button in the main toolbar
1629 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1631 /* Check if accounts exist */
1632 gboolean accounts_exist =
1633 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1635 /* If not, allow the user to create an account before trying to send/receive. */
1636 if (!accounts_exist)
1637 modest_ui_actions_on_accounts (NULL, win);
1639 modest_do_refresh_current_folder (win);
1641 /* Refresh the active account */
1642 modest_ui_actions_do_send_receive (NULL, win);
1647 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1650 GtkWidget *header_view;
1652 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1654 header_view = modest_main_window_get_child_widget (main_window,
1655 MODEST_WIDGET_TYPE_HEADER_VIEW);
1659 conf = modest_runtime_get_conf ();
1661 /* what is saved/restored is depending on the style; thus; we save with
1662 * old style, then update the style, and restore for this new style
1664 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1666 if (modest_header_view_get_style
1667 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1668 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1669 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1671 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1672 MODEST_HEADER_VIEW_STYLE_DETAILS);
1674 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1675 MODEST_CONF_HEADER_VIEW_KEY);
1680 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1682 ModestMainWindow *main_window)
1684 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1685 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1687 /* in the case the folder is empty, show the empty folder message and focus
1689 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1690 if (modest_header_view_is_empty (header_view)) {
1691 TnyFolder *folder = modest_header_view_get_folder (header_view);
1692 GtkWidget *folder_view =
1693 modest_main_window_get_child_widget (main_window,
1694 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1696 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1697 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1701 /* If no header has been selected then exit */
1706 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1707 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1709 /* Update Main window title */
1710 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1711 const gchar *subject = tny_header_get_subject (header);
1712 if (subject && strlen(subject) > 0)
1713 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1715 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1718 /* Update toolbar dimming state */
1719 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1723 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1725 ModestMainWindow *main_window)
1729 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1734 headers = tny_simple_list_new ();
1735 tny_list_prepend (headers, G_OBJECT (header));
1737 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1739 g_object_unref (headers);
1743 set_active_account_from_tny_account (TnyAccount *account,
1744 ModestWindow *window)
1746 const gchar *server_acc_name = tny_account_get_id (account);
1748 /* We need the TnyAccount provided by the
1749 account store because that is the one that
1750 knows the name of the Modest account */
1751 TnyAccount *modest_server_account = modest_server_account =
1752 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1753 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1756 const gchar *modest_acc_name =
1757 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1758 modest_window_set_active_account (window, modest_acc_name);
1759 g_object_unref (modest_server_account);
1764 folder_refreshed_cb (ModestMailOperation *mail_op,
1768 ModestMainWindow *win = NULL;
1769 GtkWidget *header_view;
1770 TnyFolder *current_folder;
1772 g_return_if_fail (TNY_IS_FOLDER (folder));
1774 win = MODEST_MAIN_WINDOW (user_data);
1776 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1779 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1780 if (current_folder != NULL && folder != current_folder) {
1785 /* Check if folder is empty and set headers view contents style */
1786 if (tny_folder_get_all_count (folder) == 0) {
1787 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1788 modest_main_window_set_contents_style (win,
1789 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1791 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1796 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1797 TnyFolderStore *folder_store,
1799 ModestMainWindow *main_window)
1802 GtkWidget *header_view;
1804 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1806 header_view = modest_main_window_get_child_widget(main_window,
1807 MODEST_WIDGET_TYPE_HEADER_VIEW);
1811 conf = modest_runtime_get_conf ();
1813 if (TNY_IS_ACCOUNT (folder_store)) {
1815 /* Update active account */
1816 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1817 /* Show account details */
1818 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1821 if (TNY_IS_FOLDER (folder_store) && selected) {
1823 /* Update the active account */
1824 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1826 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1827 g_object_unref (account);
1831 /* Set the header style by default, it could
1832 be changed later by the refresh callback to
1834 modest_main_window_set_contents_style (main_window,
1835 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1837 /* Set folder on header view. This function
1838 will call tny_folder_refresh_async so we
1839 pass a callback that will be called when
1840 finished. We use that callback to set the
1841 empty view if there are no messages */
1842 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1843 TNY_FOLDER (folder_store),
1844 folder_refreshed_cb,
1847 /* Restore configuration. We need to do this
1848 *after* the set_folder because the widget
1849 memory asks the header view about its
1851 modest_widget_memory_restore (modest_runtime_get_conf (),
1852 G_OBJECT(header_view),
1853 MODEST_CONF_HEADER_VIEW_KEY);
1855 /* Update the active account */
1856 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1857 /* Save only if we're seeing headers */
1858 if (modest_main_window_get_contents_style (main_window) ==
1859 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1860 modest_widget_memory_save (conf, G_OBJECT (header_view),
1861 MODEST_CONF_HEADER_VIEW_KEY);
1862 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1866 /* Update toolbar dimming state */
1867 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1871 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1878 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1880 online = tny_device_is_online (modest_runtime_get_device());
1883 /* already online -- the item is simply not there... */
1884 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1886 GTK_MESSAGE_WARNING,
1888 _("The %s you selected cannot be found"),
1890 gtk_dialog_run (GTK_DIALOG(dialog));
1892 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1896 GTK_RESPONSE_REJECT,
1898 GTK_RESPONSE_ACCEPT,
1900 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1901 "Do you want to get online?"), item);
1902 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1903 gtk_label_new (txt), FALSE, FALSE, 0);
1904 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1907 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1908 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1909 /* TODO: Comment about why is this commented out: */
1910 /* modest_platform_connect_and_wait (); */
1913 gtk_widget_destroy (dialog);
1917 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1920 /* g_message ("%s %s", __FUNCTION__, link); */
1925 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1928 modest_platform_activate_uri (link);
1932 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1935 modest_platform_show_uri_popup (link);
1939 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1942 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1946 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1947 const gchar *address,
1950 /* g_message ("%s %s", __FUNCTION__, address); */
1954 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1956 TnyTransportAccount *transport_account;
1957 ModestMailOperation *mail_operation;
1959 gchar *account_name, *from;
1960 ModestAccountMgr *account_mgr;
1961 gchar *info_text = NULL;
1963 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1965 data = modest_msg_edit_window_get_msg_data (edit_window);
1967 account_mgr = modest_runtime_get_account_mgr();
1968 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1970 account_name = modest_account_mgr_get_default_account (account_mgr);
1971 if (!account_name) {
1972 g_printerr ("modest: no account found\n");
1973 modest_msg_edit_window_free_msg_data (edit_window, data);
1977 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1978 account_name = g_strdup (data->account_name);
1982 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1983 (modest_runtime_get_account_store(),
1985 TNY_ACCOUNT_TYPE_TRANSPORT));
1986 if (!transport_account) {
1987 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1988 g_free (account_name);
1989 modest_msg_edit_window_free_msg_data (edit_window, data);
1992 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1994 /* Create the mail operation */
1995 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1996 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1998 modest_mail_operation_save_to_drafts (mail_operation,
2010 data->priority_flags);
2013 g_free (account_name);
2014 g_object_unref (G_OBJECT (transport_account));
2015 g_object_unref (G_OBJECT (mail_operation));
2017 modest_msg_edit_window_free_msg_data (edit_window, data);
2019 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2020 modest_platform_information_banner (NULL, NULL, info_text);
2024 /* For instance, when clicking the Send toolbar button when editing a message: */
2026 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2028 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2030 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2033 /* Offer the connection dialog, if necessary: */
2034 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2037 /* FIXME: Code added just for testing. The final version will
2038 use the send queue provided by tinymail and some
2040 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2041 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2043 account_name = modest_account_mgr_get_default_account (account_mgr);
2045 if (!account_name) {
2046 /* Run account setup wizard */
2047 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2051 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2053 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2054 account_name = g_strdup (data->account_name);
2057 /* Get the currently-active transport account for this modest account: */
2058 TnyTransportAccount *transport_account =
2059 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2060 (modest_runtime_get_account_store(),
2062 if (!transport_account) {
2063 /* Run account setup wizard */
2064 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2068 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2070 /* mail content checks and dialogs */
2071 if (data->subject == NULL || data->subject[0] == '\0') {
2072 GtkResponseType response;
2073 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2074 _("mcen_nc_subject_is_empty_send"));
2075 if (response == GTK_RESPONSE_CANCEL) {
2076 g_free (account_name);
2081 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2082 GtkResponseType response;
2083 gchar *note_message;
2084 gchar *note_subject = data->subject;
2085 if (note_subject == NULL || note_subject[0] == '\0')
2086 note_subject = _("mail_va_no_subject");
2087 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2088 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2090 g_free (note_message);
2091 if (response == GTK_RESPONSE_CANCEL) {
2092 g_free (account_name);
2097 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2099 /* Create the mail operation */
2100 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2101 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2103 modest_mail_operation_send_new_mail (mail_operation,
2114 data->priority_flags);
2118 g_free (account_name);
2119 g_object_unref (G_OBJECT (transport_account));
2120 g_object_unref (G_OBJECT (mail_operation));
2122 modest_msg_edit_window_free_msg_data (edit_window, data);
2123 modest_msg_edit_window_set_sent (edit_window, TRUE);
2125 /* Save settings and close the window: */
2126 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2130 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2131 ModestMsgEditWindow *window)
2133 ModestMsgEditFormatState *format_state = NULL;
2135 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2136 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2138 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2141 format_state = modest_msg_edit_window_get_format_state (window);
2142 g_return_if_fail (format_state != NULL);
2144 format_state->bold = gtk_toggle_action_get_active (action);
2145 modest_msg_edit_window_set_format_state (window, format_state);
2146 g_free (format_state);
2151 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2152 ModestMsgEditWindow *window)
2154 ModestMsgEditFormatState *format_state = NULL;
2156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2157 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2159 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2162 format_state = modest_msg_edit_window_get_format_state (window);
2163 g_return_if_fail (format_state != NULL);
2165 format_state->italics = gtk_toggle_action_get_active (action);
2166 modest_msg_edit_window_set_format_state (window, format_state);
2167 g_free (format_state);
2172 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2173 ModestMsgEditWindow *window)
2175 ModestMsgEditFormatState *format_state = NULL;
2177 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2178 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2180 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2183 format_state = modest_msg_edit_window_get_format_state (window);
2184 g_return_if_fail (format_state != NULL);
2186 format_state->bullet = gtk_toggle_action_get_active (action);
2187 modest_msg_edit_window_set_format_state (window, format_state);
2188 g_free (format_state);
2193 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2194 GtkRadioAction *selected,
2195 ModestMsgEditWindow *window)
2197 ModestMsgEditFormatState *format_state = NULL;
2198 GtkJustification value;
2200 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2202 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2205 value = gtk_radio_action_get_current_value (selected);
2207 format_state = modest_msg_edit_window_get_format_state (window);
2208 g_return_if_fail (format_state != NULL);
2210 format_state->justification = value;
2211 modest_msg_edit_window_set_format_state (window, format_state);
2212 g_free (format_state);
2216 modest_ui_actions_on_select_editor_color (GtkAction *action,
2217 ModestMsgEditWindow *window)
2219 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2220 g_return_if_fail (GTK_IS_ACTION (action));
2222 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2225 modest_msg_edit_window_select_color (window);
2229 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2230 ModestMsgEditWindow *window)
2232 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2233 g_return_if_fail (GTK_IS_ACTION (action));
2235 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2238 modest_msg_edit_window_select_background_color (window);
2242 modest_ui_actions_on_insert_image (GtkAction *action,
2243 ModestMsgEditWindow *window)
2245 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2246 g_return_if_fail (GTK_IS_ACTION (action));
2248 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2251 modest_msg_edit_window_insert_image (window);
2255 modest_ui_actions_on_attach_file (GtkAction *action,
2256 ModestMsgEditWindow *window)
2258 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2259 g_return_if_fail (GTK_IS_ACTION (action));
2261 modest_msg_edit_window_offer_attach_file (window);
2265 modest_ui_actions_on_remove_attachments (GtkAction *action,
2266 ModestMsgEditWindow *window)
2268 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2269 g_return_if_fail (GTK_IS_ACTION (action));
2271 modest_msg_edit_window_remove_attachments (window, NULL);
2275 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2278 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2279 const GError *error = modest_mail_operation_get_error (mail_op);
2283 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2284 modest_mail_operation_get_error (mail_op)->message);
2289 modest_ui_actions_create_folder(GtkWidget *parent_window,
2290 GtkWidget *folder_view)
2292 TnyFolderStore *parent_folder;
2294 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2296 if (parent_folder) {
2297 gboolean finished = FALSE;
2299 gchar *folder_name = NULL, *suggested_name = NULL;
2300 const gchar *proto_str = NULL;
2301 TnyAccount *account;
2303 if (TNY_IS_ACCOUNT (parent_folder))
2304 account = g_object_ref (parent_folder);
2306 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2307 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2309 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2310 MODEST_PROTOCOL_STORE_POP) {
2312 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2314 g_object_unref (account);
2316 /* Run the new folder dialog */
2318 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2323 g_free (suggested_name);
2324 suggested_name = NULL;
2326 if (result == GTK_RESPONSE_REJECT) {
2329 ModestMailOperation *mail_op;
2330 TnyFolder *new_folder = NULL;
2332 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2333 G_OBJECT(parent_window),
2334 modest_ui_actions_new_folder_error_handler,
2337 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2339 new_folder = modest_mail_operation_create_folder (mail_op,
2341 (const gchar *) folder_name);
2343 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2346 g_object_unref (new_folder);
2349 g_object_unref (mail_op);
2352 suggested_name = folder_name;
2356 g_object_unref (parent_folder);
2361 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2363 GtkWidget *folder_view;
2365 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2367 folder_view = modest_main_window_get_child_widget (main_window,
2368 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2372 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2376 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2379 GObject *win = modest_mail_operation_get_source (mail_op);
2380 const GError *error = NULL;
2381 const gchar *message = NULL;
2383 /* Get error message */
2384 error = modest_mail_operation_get_error (mail_op);
2385 if (error != NULL && error->message != NULL) {
2386 message = error->message;
2388 message = _("!!! FIXME: Unable to rename");
2391 /* Show notification dialog */
2392 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2393 g_object_unref (win);
2397 modest_ui_actions_on_rename_folder (GtkAction *action,
2398 ModestMainWindow *main_window)
2400 TnyFolderStore *folder;
2401 GtkWidget *folder_view;
2402 GtkWidget *header_view;
2404 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2406 folder_view = modest_main_window_get_child_widget (main_window,
2407 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2411 header_view = modest_main_window_get_child_widget (main_window,
2412 MODEST_WIDGET_TYPE_HEADER_VIEW);
2417 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2421 /* Offer the connection dialog if necessary: */
2422 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2423 g_object_unref (G_OBJECT (folder));
2428 if (TNY_IS_FOLDER (folder)) {
2431 const gchar *current_name;
2433 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2434 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2435 current_name, &folder_name);
2437 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2438 ModestMailOperation *mail_op;
2441 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2442 G_OBJECT(main_window),
2443 modest_ui_actions_rename_folder_error_handler,
2447 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2450 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2452 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2453 TNY_FOLDER(folder), TRUE);
2456 modest_header_view_clear ((ModestHeaderView *) header_view);
2458 modest_mail_operation_rename_folder (mail_op,
2459 TNY_FOLDER (folder),
2460 (const gchar *) folder_name);
2462 g_object_unref (mail_op);
2463 g_free (folder_name);
2466 g_object_unref (folder);
2470 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2473 GObject *win = modest_mail_operation_get_source (mail_op);
2475 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2476 _("mail_in_ui_folder_delete_error"));
2477 g_object_unref (win);
2481 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2483 TnyFolderStore *folder;
2484 GtkWidget *folder_view;
2488 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2490 folder_view = modest_main_window_get_child_widget (main_window,
2491 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2495 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2497 /* Show an error if it's an account */
2498 if (!TNY_IS_FOLDER (folder)) {
2499 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2500 _("mail_in_ui_folder_delete_error"));
2501 g_object_unref (G_OBJECT (folder));
2505 /* Offer the connection dialog if necessary: */
2506 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2507 g_object_unref (G_OBJECT (folder));
2512 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2513 tny_folder_get_name (TNY_FOLDER (folder)));
2514 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2515 (const gchar *) message);
2518 if (response == GTK_RESPONSE_OK) {
2519 ModestMailOperation *mail_op =
2520 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2521 G_OBJECT(main_window),
2522 modest_ui_actions_delete_folder_error_handler,
2525 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2527 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2528 g_object_unref (G_OBJECT (mail_op));
2531 g_object_unref (G_OBJECT (folder));
2535 modest_ui_actions_on_delete_folder (GtkAction *action,
2536 ModestMainWindow *main_window)
2538 GtkWidget *folder_view;
2539 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2541 delete_folder (main_window, FALSE);
2542 folder_view = modest_main_window_get_child_widget (main_window,
2543 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2546 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2550 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2552 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2554 delete_folder (main_window, TRUE);
2559 show_error (GtkWidget *parent_widget, const gchar* text)
2561 hildon_banner_show_information(parent_widget, NULL, text);
2564 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2566 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2573 gtk_dialog_run (dialog);
2574 gtk_widget_destroy (GTK_WIDGET (dialog));
2579 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2580 const gchar* server_account_name,
2585 ModestMainWindow *main_window)
2587 g_return_if_fail(server_account_name);
2588 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2590 /* Initalize output parameters: */
2597 #ifdef MODEST_PLATFORM_MAEMO
2598 /* Maemo uses a different (awkward) button order,
2599 * It should probably just use gtk_alternative_dialog_button_order ().
2601 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2605 GTK_RESPONSE_ACCEPT,
2607 GTK_RESPONSE_REJECT,
2610 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2614 GTK_RESPONSE_REJECT,
2616 GTK_RESPONSE_ACCEPT,
2618 #endif /* MODEST_PLATFORM_MAEMO */
2620 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2622 gchar *server_name = modest_server_account_get_hostname (
2623 modest_runtime_get_account_mgr(), server_account_name);
2624 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2625 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2630 /* This causes a warning because the logical ID has no %s in it,
2631 * though the translation does, but there is not much we can do about that: */
2632 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2633 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2636 g_free (server_name);
2640 gchar *initial_username = modest_server_account_get_username (
2641 modest_runtime_get_account_mgr(), server_account_name);
2643 GtkWidget *entry_username = gtk_entry_new ();
2644 if (initial_username)
2645 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2646 /* Dim this if a connection has ever succeeded with this username,
2647 * as per the UI spec: */
2648 const gboolean username_known =
2649 modest_server_account_get_username_has_succeeded(
2650 modest_runtime_get_account_mgr(), server_account_name);
2651 gtk_widget_set_sensitive (entry_username, !username_known);
2653 #ifdef MODEST_PLATFORM_MAEMO
2654 /* Auto-capitalization is the default, so let's turn it off: */
2655 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2657 /* Create a size group to be used by all captions.
2658 * Note that HildonCaption does not create a default size group if we do not specify one.
2659 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2660 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2662 GtkWidget *caption = hildon_caption_new (sizegroup,
2663 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2664 gtk_widget_show (entry_username);
2665 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2666 FALSE, FALSE, MODEST_MARGIN_HALF);
2667 gtk_widget_show (caption);
2669 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2671 #endif /* MODEST_PLATFORM_MAEMO */
2674 GtkWidget *entry_password = gtk_entry_new ();
2675 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2676 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2678 #ifdef MODEST_PLATFORM_MAEMO
2679 /* Auto-capitalization is the default, so let's turn it off: */
2680 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2681 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2683 caption = hildon_caption_new (sizegroup,
2684 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2685 gtk_widget_show (entry_password);
2686 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2687 FALSE, FALSE, MODEST_MARGIN_HALF);
2688 gtk_widget_show (caption);
2689 g_object_unref (sizegroup);
2691 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2693 #endif /* MODEST_PLATFORM_MAEMO */
2695 /* This is not in the Maemo UI spec:
2696 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2697 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2701 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2703 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2705 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2707 modest_server_account_set_username (
2708 modest_runtime_get_account_mgr(), server_account_name,
2711 const gboolean username_was_changed =
2712 (strcmp (*username, initial_username) != 0);
2713 if (username_was_changed) {
2714 g_warning ("%s: tinymail does not yet support changing the "
2715 "username in the get_password() callback.\n", __FUNCTION__);
2720 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2722 /* We do not save the password in the configuration,
2723 * because this function is only called for passwords that should
2724 * not be remembered:
2725 modest_server_account_set_password (
2726 modest_runtime_get_account_mgr(), server_account_name,
2735 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2747 /* This is not in the Maemo UI spec:
2748 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2754 gtk_widget_destroy (dialog);
2756 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2760 modest_ui_actions_on_cut (GtkAction *action,
2761 ModestWindow *window)
2763 GtkWidget *focused_widget;
2764 GtkClipboard *clipboard;
2766 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2767 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2768 if (GTK_IS_EDITABLE (focused_widget)) {
2769 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2770 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2771 gtk_clipboard_store (clipboard);
2772 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2773 GtkTextBuffer *buffer;
2775 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2776 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2777 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2778 gtk_clipboard_store (clipboard);
2779 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2780 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2781 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2782 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2787 modest_ui_actions_on_copy (GtkAction *action,
2788 ModestWindow *window)
2790 GtkClipboard *clipboard;
2791 GtkWidget *focused_widget;
2793 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2794 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2796 if (GTK_IS_LABEL (focused_widget)) {
2797 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2798 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2799 gtk_clipboard_store (clipboard);
2800 } else if (GTK_IS_EDITABLE (focused_widget)) {
2801 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2802 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2803 gtk_clipboard_store (clipboard);
2804 } else if (GTK_IS_HTML (focused_widget)) {
2805 gtk_html_copy (GTK_HTML (focused_widget));
2806 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2807 gtk_clipboard_store (clipboard);
2808 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2809 GtkTextBuffer *buffer;
2810 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2811 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2812 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2813 gtk_clipboard_store (clipboard);
2814 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2815 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2816 TnyIterator *iter = tny_list_create_iterator (header_list);
2817 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2819 gboolean ask = FALSE;
2821 TnyFolder *folder = tny_header_get_folder (header);
2822 TnyAccount *account = tny_folder_get_account (folder);
2823 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2824 /* If it's POP then ask */
2825 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2826 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2827 g_object_unref (account);
2828 g_object_unref (folder);
2829 g_object_unref (header);
2832 g_object_unref (iter);
2834 /* Check that the messages have been previously downloaded */
2835 gboolean continue_download = TRUE;
2837 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2838 if (continue_download)
2839 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2840 g_object_unref (header_list);
2841 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2842 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2845 /* Show information banner */
2846 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2851 modest_ui_actions_on_undo (GtkAction *action,
2852 ModestWindow *window)
2854 ModestEmailClipboard *clipboard = NULL;
2856 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2857 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2858 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2859 /* Clear clipboard source */
2860 clipboard = modest_runtime_get_email_clipboard ();
2861 modest_email_clipboard_clear (clipboard);
2864 g_return_if_reached ();
2869 modest_ui_actions_on_redo (GtkAction *action,
2870 ModestWindow *window)
2872 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2873 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2876 g_return_if_reached ();
2882 paste_msgs_cb (const GObject *object, gpointer user_data)
2884 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2885 g_return_if_fail (GTK_IS_WIDGET (user_data));
2887 /* destroy information note */
2888 gtk_widget_destroy (GTK_WIDGET(user_data));
2892 paste_as_attachment_free (gpointer data)
2894 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2896 gtk_widget_destroy (helper->banner);
2897 g_object_unref (helper->banner);
2902 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2907 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2908 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2913 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2918 modest_ui_actions_on_paste (GtkAction *action,
2919 ModestWindow *window)
2921 GtkWidget *focused_widget = NULL;
2922 GtkWidget *inf_note = NULL;
2923 ModestMailOperation *mail_op = NULL;
2925 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2926 if (GTK_IS_EDITABLE (focused_widget)) {
2927 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2928 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2929 ModestEmailClipboard *e_clipboard = NULL;
2930 e_clipboard = modest_runtime_get_email_clipboard ();
2931 if (modest_email_clipboard_cleared (e_clipboard)) {
2932 GtkTextBuffer *buffer;
2933 GtkClipboard *clipboard;
2935 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2936 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2937 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2938 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2939 ModestMailOperation *mail_op;
2940 TnyFolder *src_folder;
2943 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2944 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2945 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2946 _CS("ckct_nw_pasting"));
2947 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2948 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2950 if (helper->banner != NULL) {
2951 g_object_ref (G_OBJECT (helper->banner));
2952 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2953 gtk_widget_show (GTK_WIDGET (helper->banner));
2957 modest_mail_operation_get_msgs_full (mail_op,
2959 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2961 paste_as_attachment_free);
2964 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2965 ModestEmailClipboard *clipboard = NULL;
2966 TnyFolder *src_folder = NULL;
2967 TnyFolderStore *folder_store = NULL;
2968 TnyList *data = NULL;
2969 gboolean delete = FALSE;
2971 /* Check clipboard source */
2972 clipboard = modest_runtime_get_email_clipboard ();
2973 if (modest_email_clipboard_cleared (clipboard))
2976 /* Get elements to paste */
2977 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2979 /* Create a new mail operation */
2980 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2982 /* Get destination folder */
2983 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2985 /* transfer messages */
2989 /* Ask for user confirmation */
2990 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2991 TNY_FOLDER (folder_store),
2995 if (response == GTK_RESPONSE_OK) {
2996 /* Launch notification */
2997 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2998 _CS("ckct_nw_pasting"));
2999 if (inf_note != NULL) {
3000 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3001 gtk_widget_show (GTK_WIDGET(inf_note));
3004 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3005 modest_mail_operation_xfer_msgs (mail_op,
3007 TNY_FOLDER (folder_store),
3012 g_object_unref (mail_op);
3015 } else if (src_folder != NULL) {
3016 /* Launch notification */
3017 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3018 _CS("ckct_nw_pasting"));
3019 if (inf_note != NULL) {
3020 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3021 gtk_widget_show (GTK_WIDGET(inf_note));
3024 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3025 modest_mail_operation_xfer_folder (mail_op,
3035 g_object_unref (data);
3036 if (src_folder != NULL)
3037 g_object_unref (src_folder);
3038 if (folder_store != NULL)
3039 g_object_unref (folder_store);
3045 modest_ui_actions_on_select_all (GtkAction *action,
3046 ModestWindow *window)
3048 GtkWidget *focused_widget;
3050 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3051 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3052 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3053 } else if (GTK_IS_LABEL (focused_widget)) {
3054 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3055 } else if (GTK_IS_EDITABLE (focused_widget)) {
3056 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3057 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3058 GtkTextBuffer *buffer;
3059 GtkTextIter start, end;
3061 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3062 gtk_text_buffer_get_start_iter (buffer, &start);
3063 gtk_text_buffer_get_end_iter (buffer, &end);
3064 gtk_text_buffer_select_range (buffer, &start, &end);
3065 } else if (GTK_IS_HTML (focused_widget)) {
3066 gtk_html_select_all (GTK_HTML (focused_widget));
3067 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3068 GtkWidget *header_view = focused_widget;
3069 GtkTreeSelection *selection = NULL;
3071 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3072 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3073 MODEST_WIDGET_TYPE_HEADER_VIEW);
3075 /* Select all messages */
3076 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3077 gtk_tree_selection_select_all (selection);
3079 /* Set focuse on header view */
3080 gtk_widget_grab_focus (header_view);
3086 modest_ui_actions_on_mark_as_read (GtkAction *action,
3087 ModestWindow *window)
3089 g_return_if_fail (MODEST_IS_WINDOW(window));
3091 /* Mark each header as read */
3092 do_headers_action (window, headers_action_mark_as_read, NULL);
3096 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3097 ModestWindow *window)
3099 g_return_if_fail (MODEST_IS_WINDOW(window));
3101 /* Mark each header as read */
3102 do_headers_action (window, headers_action_mark_as_unread, NULL);
3106 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3107 GtkRadioAction *selected,
3108 ModestWindow *window)
3112 value = gtk_radio_action_get_current_value (selected);
3113 if (MODEST_IS_WINDOW (window)) {
3114 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3118 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3119 GtkRadioAction *selected,
3120 ModestWindow *window)
3122 TnyHeaderFlags flags;
3123 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3125 flags = gtk_radio_action_get_current_value (selected);
3126 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3129 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3130 GtkRadioAction *selected,
3131 ModestWindow *window)
3135 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3137 file_format = gtk_radio_action_get_current_value (selected);
3138 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3143 modest_ui_actions_on_zoom_plus (GtkAction *action,
3144 ModestWindow *window)
3146 g_return_if_fail (MODEST_IS_WINDOW (window));
3148 modest_window_zoom_plus (MODEST_WINDOW (window));
3152 modest_ui_actions_on_zoom_minus (GtkAction *action,
3153 ModestWindow *window)
3155 g_return_if_fail (MODEST_IS_WINDOW (window));
3157 modest_window_zoom_minus (MODEST_WINDOW (window));
3161 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3162 ModestWindow *window)
3164 ModestWindowMgr *mgr;
3165 gboolean fullscreen, active;
3166 g_return_if_fail (MODEST_IS_WINDOW (window));
3168 mgr = modest_runtime_get_window_mgr ();
3170 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3171 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3173 if (active != fullscreen) {
3174 modest_window_mgr_set_fullscreen_mode (mgr, active);
3175 gtk_window_present (GTK_WINDOW (window));
3180 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3181 ModestWindow *window)
3183 ModestWindowMgr *mgr;
3184 gboolean fullscreen;
3186 g_return_if_fail (MODEST_IS_WINDOW (window));
3188 mgr = modest_runtime_get_window_mgr ();
3189 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3190 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3192 gtk_window_present (GTK_WINDOW (window));
3196 * Used by modest_ui_actions_on_details to call do_headers_action
3199 headers_action_show_details (TnyHeader *header,
3200 ModestWindow *window,
3207 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3210 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3211 gtk_widget_show_all (dialog);
3212 gtk_dialog_run (GTK_DIALOG (dialog));
3214 gtk_widget_destroy (dialog);
3218 * Show the folder details in a ModestDetailsDialog widget
3221 show_folder_details (TnyFolder *folder,
3227 dialog = modest_details_dialog_new_with_folder (window, folder);
3230 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3231 gtk_widget_show_all (dialog);
3232 gtk_dialog_run (GTK_DIALOG (dialog));
3234 gtk_widget_destroy (dialog);
3238 * Show the header details in a ModestDetailsDialog widget
3241 modest_ui_actions_on_details (GtkAction *action,
3244 TnyList * headers_list;
3248 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3251 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3254 g_object_unref (msg);
3256 headers_list = get_selected_headers (win);
3260 iter = tny_list_create_iterator (headers_list);
3262 header = TNY_HEADER (tny_iterator_get_current (iter));
3264 headers_action_show_details (header, win, NULL);
3265 g_object_unref (header);
3268 g_object_unref (iter);
3269 g_object_unref (headers_list);
3271 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3272 GtkWidget *folder_view, *header_view;
3274 /* Check which widget has the focus */
3275 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3276 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3277 if (gtk_widget_is_focus (folder_view)) {
3278 TnyFolderStore *folder_store
3279 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3280 if (!folder_store) {
3281 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3284 /* Show only when it's a folder */
3285 /* This function should not be called for account items,
3286 * because we dim the menu item for them. */
3287 if (TNY_IS_FOLDER (folder_store)) {
3288 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3291 g_object_unref (folder_store);
3294 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3295 MODEST_WIDGET_TYPE_HEADER_VIEW);
3296 /* Show details of each header */
3297 do_headers_action (win, headers_action_show_details, header_view);
3303 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3304 ModestMsgEditWindow *window)
3306 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3308 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3312 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3313 ModestMsgEditWindow *window)
3315 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3317 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3321 modest_ui_actions_toggle_folders_view (GtkAction *action,
3322 ModestMainWindow *main_window)
3324 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3326 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3327 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3329 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3333 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3334 ModestWindow *window)
3336 gboolean active, fullscreen = FALSE;
3337 ModestWindowMgr *mgr;
3339 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3341 /* Check if we want to toggle the toolbar vuew in fullscreen
3343 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3344 "ViewShowToolbarFullScreen")) {
3348 /* Toggle toolbar */
3349 mgr = modest_runtime_get_window_mgr ();
3350 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3354 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3355 ModestMsgEditWindow *window)
3357 modest_msg_edit_window_select_font (window);
3361 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3362 const gchar *display_name,
3365 /* Do not change the application name if the widget has not
3366 the focus. This callback could be called even if the folder
3367 view has not the focus, because the handled signal could be
3368 emitted when the folder view is redrawn */
3369 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3371 gtk_window_set_title (window, display_name);
3373 gtk_window_set_title (window, " ");
3378 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3380 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3381 modest_msg_edit_window_select_contacts (window);
3385 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3388 modest_msg_edit_window_check_names (window, FALSE);
3392 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3394 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3395 GTK_WIDGET (user_data));
3399 create_move_to_dialog (GtkWindow *win,
3400 GtkWidget *folder_view,
3401 GtkWidget **tree_view)
3403 GtkWidget *dialog, *scroll;
3404 GtkWidget *new_button;
3406 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3408 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3411 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3412 /* We do this manually so GTK+ does not associate a response ID for
3414 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3415 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3416 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3418 /* Create scrolled window */
3419 scroll = gtk_scrolled_window_new (NULL, NULL);
3420 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3421 GTK_POLICY_AUTOMATIC,
3422 GTK_POLICY_AUTOMATIC);
3424 /* Create folder view */
3425 *tree_view = modest_platform_create_folder_view (NULL);
3427 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3429 /* It could happen that we're trying to move a message from a
3430 window (msg window for example) after the main window was
3431 closed, so we can not just get the model of the folder
3433 if (MODEST_IS_FOLDER_VIEW (folder_view))
3434 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3435 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3437 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3438 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3440 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3442 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3444 /* Add scroll to dialog */
3445 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3446 scroll, TRUE, TRUE, 0);
3448 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3449 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3455 * Returns TRUE if at least one of the headers of the list belongs to
3456 * a message that has been fully retrieved.
3459 has_retrieved_msgs (TnyList *list)
3462 gboolean found = FALSE;
3464 iter = tny_list_create_iterator (list);
3465 while (!tny_iterator_is_done (iter) && !found) {
3467 TnyHeaderFlags flags = 0;
3469 header = TNY_HEADER (tny_iterator_get_current (iter));
3471 flags = tny_header_get_flags (header);
3472 if (flags & TNY_HEADER_FLAG_CACHED)
3473 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3476 g_object_unref (header);
3480 tny_iterator_next (iter);
3482 g_object_unref (iter);
3488 * Shows a confirmation dialog to the user when we're moving messages
3489 * from a remote server to the local storage. Returns the dialog
3490 * response. If it's other kind of movement the it always returns
3494 msgs_move_to_confirmation (GtkWindow *win,
3495 TnyFolder *dest_folder,
3499 gint response = GTK_RESPONSE_OK;
3501 /* If the destination is a local folder (or MMC folder )*/
3502 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3503 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3504 TnyFolder *src_folder = NULL;
3505 TnyIterator *iter = NULL;
3506 TnyHeader *header = NULL;
3508 /* Get source folder */
3509 iter = tny_list_create_iterator (headers);
3510 header = TNY_HEADER (tny_iterator_get_current (iter));
3512 src_folder = tny_header_get_folder (header);
3513 g_object_unref (header);
3516 g_object_unref (iter);
3518 /* if no src_folder, message may be an attahcment */
3519 if (src_folder == NULL)
3520 return GTK_RESPONSE_CANCEL;
3522 /* If the source is a remote folder */
3523 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3524 if (modest_tny_folder_is_remote_folder (src_folder)) {
3525 const gchar *message = NULL;
3526 gboolean cached = has_retrieved_msgs (headers);
3528 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3529 tny_list_get_length (headers));
3531 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3532 tny_list_get_length (headers));
3534 if (cached && !delete)
3535 response = GTK_RESPONSE_OK;
3537 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3538 (const gchar *) message);
3541 g_object_unref (src_folder);
3550 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3552 ModestMsgViewWindow *self = NULL;
3554 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3555 self = MODEST_MSG_VIEW_WINDOW (object);
3557 if (!modest_msg_view_window_select_next_message (self))
3558 if (!modest_msg_view_window_select_previous_message (self))
3559 /* No more messages to view, so close this window */
3560 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3564 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3567 GObject *win = modest_mail_operation_get_source (mail_op);
3568 const GError *error = NULL;
3569 const gchar *message = NULL;
3571 /* Get error message */
3572 error = modest_mail_operation_get_error (mail_op);
3573 if (error != NULL && error->message != NULL) {
3574 message = error->message;
3576 message = _("mail_in_ui_folder_move_target_error");
3579 /* Show notification dialog */
3580 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3581 g_object_unref (win);
3585 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3588 GObject *win = modest_mail_operation_get_source (mail_op);
3589 const GError *error = modest_mail_operation_get_error (mail_op);
3591 g_return_if_fail (error != NULL);
3592 if (error->message != NULL)
3593 g_printerr ("modest: %s\n", error->message);
3595 g_printerr ("modest: unkonw error on send&receive operation");
3597 /* Show error message */
3598 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3599 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3600 /* _CS("sfil_ib_unable_to_receive")); */
3602 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3603 /* _CS("sfil_ib_unable_to_send")); */
3604 g_object_unref (win);
3608 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3615 gint pending_purges = 0;
3616 gboolean some_purged = FALSE;
3617 ModestWindow *win = MODEST_WINDOW (user_data);
3618 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3620 /* If there was any error */
3621 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3622 modest_window_mgr_unregister_header (mgr, header);
3626 /* Once the message has been retrieved for purging, we check if
3627 * it's all ok for purging */
3629 parts = tny_simple_list_new ();
3630 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3631 iter = tny_list_create_iterator (parts);
3633 while (!tny_iterator_is_done (iter)) {
3635 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3636 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3637 if (tny_mime_part_is_purged (part))
3644 g_object_unref (part);
3646 tny_iterator_next (iter);
3649 if (pending_purges>0) {
3651 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3653 if (response == GTK_RESPONSE_OK) {
3654 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3655 tny_iterator_first (iter);
3656 while (!tny_iterator_is_done (iter)) {
3659 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3660 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3661 tny_mime_part_set_purged (part);
3664 g_object_unref (part);
3666 tny_iterator_next (iter);
3669 tny_msg_rewrite_cache (msg);
3672 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3675 /* remove attachments */
3676 tny_iterator_first (iter);
3677 while (!tny_iterator_is_done (iter)) {
3680 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3682 /* One for the reference given by tny_iterator_get_current(): */
3683 g_object_unref (part);
3685 /* TODO: Is this meant to remove the attachment by doing another unref()?
3686 * Otherwise, this seems useless. */
3689 tny_iterator_next (iter);
3691 modest_window_mgr_unregister_header (mgr, header);
3693 g_object_unref (iter);
3694 g_object_unref (parts);
3698 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3699 ModestMainWindow *win)
3701 GtkWidget *header_view;
3702 TnyList *header_list;
3705 TnyHeaderFlags flags;
3706 ModestWindow *msg_view_window = NULL;
3709 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3711 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3712 MODEST_WIDGET_TYPE_HEADER_VIEW);
3714 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3716 if (tny_list_get_length (header_list) == 1) {
3717 iter = tny_list_create_iterator (header_list);
3718 header = TNY_HEADER (tny_iterator_get_current (iter));
3719 g_object_unref (iter);
3724 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3725 header, &msg_view_window);
3726 flags = tny_header_get_flags (header);
3727 if (!(flags & TNY_HEADER_FLAG_CACHED))
3730 if (msg_view_window != NULL)
3731 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3733 /* do nothing; uid was registered before, so window is probably on it's way */
3734 g_warning ("debug: header %p has already been registered", header);
3737 ModestMailOperation *mail_op = NULL;
3738 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3739 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3741 modest_ui_actions_get_msgs_full_error_handler,
3743 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3744 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3746 g_object_unref (mail_op);
3749 g_object_unref (header);
3751 g_object_unref (header_list);
3755 * Utility function that transfer messages from both the main window
3756 * and the msg view window when using the "Move to" dialog
3759 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3762 TnyList *headers = NULL;
3764 TnyAccount *dst_account = NULL;
3765 const gchar *proto_str = NULL;
3766 gboolean dst_is_pop = FALSE;
3768 if (!TNY_IS_FOLDER (dst_folder)) {
3769 modest_platform_information_banner (GTK_WIDGET (win),
3771 _CS("ckdg_ib_unable_to_move_to_current_location"));
3775 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3776 proto_str = tny_account_get_proto (dst_account);
3777 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3778 MODEST_PROTOCOL_STORE_POP);
3779 g_object_unref (dst_account);
3781 /* Get selected headers */
3782 headers = get_selected_headers (MODEST_WINDOW (win));
3785 modest_platform_information_banner (GTK_WIDGET (win),
3787 ngettext("mail_in_ui_folder_move_target_error",
3788 "mail_in_ui_folder_move_targets_error",
3789 tny_list_get_length (headers)));
3790 g_object_unref (headers);
3794 /* Ask for user confirmation */
3795 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3796 TNY_FOLDER (dst_folder),
3800 /* Transfer messages */
3801 if (response == GTK_RESPONSE_OK) {
3802 ModestMailOperation *mail_op =
3803 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3805 modest_ui_actions_move_folder_error_handler,
3807 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3810 modest_mail_operation_xfer_msgs (mail_op,
3812 TNY_FOLDER (dst_folder),
3814 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3817 g_object_unref (G_OBJECT (mail_op));
3819 g_object_unref (headers);
3824 * UI handler for the "Move to" action when invoked from the
3828 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3829 GtkWidget *folder_view,
3830 TnyFolderStore *dst_folder,
3831 ModestMainWindow *win)
3833 GtkWidget *header_view = NULL;
3834 ModestMailOperation *mail_op = NULL;
3835 TnyFolderStore *src_folder;
3837 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3839 /* Get the source folder */
3840 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3842 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3843 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3847 /* Get header view */
3849 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3851 /* Get folder or messages to transfer */
3852 if (gtk_widget_is_focus (folder_view)) {
3854 /* Allow only to transfer folders to the local root folder */
3855 if (TNY_IS_ACCOUNT (dst_folder) &&
3856 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3859 /* Clean folder on header view before moving it */
3860 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3862 if (TNY_IS_FOLDER (src_folder)) {
3864 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3866 modest_ui_actions_move_folder_error_handler,
3868 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3871 modest_mail_operation_xfer_folder (mail_op,
3872 TNY_FOLDER (src_folder),
3875 /* Unref mail operation */
3876 g_object_unref (G_OBJECT (mail_op));
3878 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3880 } else if (gtk_widget_is_focus (header_view)) {
3881 /* Transfer messages */
3882 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3887 g_object_unref (src_folder);
3892 * UI handler for the "Move to" action when invoked from the
3893 * ModestMsgViewWindow
3896 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3897 TnyFolderStore *dst_folder,
3898 ModestMsgViewWindow *win)
3900 TnyHeader *header = NULL;
3901 TnyFolder *src_folder;
3903 /* Create header list */
3904 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3905 src_folder = tny_header_get_folder(header);
3906 g_object_unref (header);
3908 /* Transfer the message */
3909 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3910 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3912 g_object_unref (src_folder);
3916 modest_ui_actions_on_move_to (GtkAction *action,
3919 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3921 TnyFolderStore *dst_folder = NULL;
3922 ModestMainWindow *main_window;
3924 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3925 MODEST_IS_MSG_VIEW_WINDOW (win));
3927 /* Get the main window if exists */
3928 if (MODEST_IS_MAIN_WINDOW (win))
3929 main_window = MODEST_MAIN_WINDOW (win);
3932 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3934 /* Get the folder view widget if exists */
3936 folder_view = modest_main_window_get_child_widget (main_window,
3937 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3941 /* Create and run the dialog */
3942 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3943 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3944 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3945 result = gtk_dialog_run (GTK_DIALOG(dialog));
3946 g_object_ref (tree_view);
3947 gtk_widget_destroy (dialog);
3949 if (result != GTK_RESPONSE_ACCEPT)
3952 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3953 /* Offer the connection dialog if necessary: */
3954 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3957 /* Do window specific stuff */
3958 if (MODEST_IS_MAIN_WINDOW (win))
3959 modest_ui_actions_on_main_window_move_to (action,
3962 MODEST_MAIN_WINDOW (win));
3964 modest_ui_actions_on_msg_view_window_move_to (action,
3966 MODEST_MSG_VIEW_WINDOW (win));
3969 g_object_unref (dst_folder);
3973 * Calls #HeadersFunc for each header already selected in the main
3974 * window or the message currently being shown in the msg view window
3977 do_headers_action (ModestWindow *win,
3981 TnyList *headers_list = NULL;
3982 TnyIterator *iter = NULL;
3983 TnyHeader *header = NULL;
3984 TnyFolder *folder = NULL;
3987 headers_list = get_selected_headers (win);
3991 /* Get the folder */
3992 iter = tny_list_create_iterator (headers_list);
3993 header = TNY_HEADER (tny_iterator_get_current (iter));
3995 folder = tny_header_get_folder (header);
3996 g_object_unref (header);
3999 /* Call the function for each header */
4000 while (!tny_iterator_is_done (iter)) {
4001 header = TNY_HEADER (tny_iterator_get_current (iter));
4002 func (header, win, user_data);
4003 g_object_unref (header);
4004 tny_iterator_next (iter);
4007 /* Trick: do a poke status in order to speed up the signaling
4009 tny_folder_poke_status (folder);
4012 g_object_unref (folder);
4013 g_object_unref (iter);
4014 g_object_unref (headers_list);
4018 modest_ui_actions_view_attachment (GtkAction *action,
4019 ModestWindow *window)
4021 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4022 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4024 /* not supported window for this action */
4025 g_return_if_reached ();
4030 modest_ui_actions_save_attachments (GtkAction *action,
4031 ModestWindow *window)
4033 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4034 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4036 /* not supported window for this action */
4037 g_return_if_reached ();
4042 modest_ui_actions_remove_attachments (GtkAction *action,
4043 ModestWindow *window)
4045 if (MODEST_IS_MAIN_WINDOW (window)) {
4046 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4047 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4048 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4050 /* not supported window for this action */
4051 g_return_if_reached ();
4056 modest_ui_actions_on_settings (GtkAction *action,
4061 dialog = modest_platform_get_global_settings_dialog ();
4062 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4063 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4064 gtk_widget_show_all (dialog);
4066 gtk_dialog_run (GTK_DIALOG (dialog));
4068 gtk_widget_destroy (dialog);
4072 modest_ui_actions_on_help (GtkAction *action,
4075 const gchar *help_id = NULL;
4077 if (MODEST_IS_MAIN_WINDOW (win)) {
4078 const gchar *action_name;
4079 action_name = gtk_action_get_name (action);
4081 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4082 !strcmp (action_name, "HeaderViewCSMHelp")) {
4083 GtkWidget *folder_view;
4084 TnyFolderStore *folder_store;
4085 /* Get selected folder */
4086 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4087 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4088 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4090 /* Switch help_id */
4091 if (TNY_IS_FOLDER (folder_store)) {
4092 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4093 case TNY_FOLDER_TYPE_NORMAL:
4094 help_id = "applications_email_managefolders";
4096 case TNY_FOLDER_TYPE_INBOX:
4097 help_id = "applications_email_inbox";
4099 case TNY_FOLDER_TYPE_OUTBOX:
4100 help_id = "applications_email_outbox";
4102 case TNY_FOLDER_TYPE_SENT:
4103 help_id = "applications_email_sent";
4105 case TNY_FOLDER_TYPE_DRAFTS:
4106 help_id = "applications_email_drafts";
4108 case TNY_FOLDER_TYPE_ARCHIVE:
4109 help_id = "applications_email_managefolders";
4112 help_id = "applications_email_managefolders";
4115 help_id = "applications_email_mainview";
4117 g_object_unref (folder_store);
4119 help_id = "applications_email_mainview";
4121 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4122 help_id = "applications_email_viewer";
4123 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4124 help_id = "applications_email_editor";
4126 modest_platform_show_help (GTK_WINDOW (win), help_id);
4130 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4131 ModestWindow *window)
4133 ModestMailOperation *mail_op;
4137 headers = get_selected_headers (window);
4141 /* Create mail operation */
4142 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4144 modest_ui_actions_get_msgs_full_error_handler,
4146 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4147 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4150 g_object_unref (headers);
4151 g_object_unref (mail_op);
4155 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4156 ModestWindow *window)
4158 g_return_if_fail (MODEST_IS_WINDOW (window));
4161 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4165 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4166 ModestWindow *window)
4168 g_return_if_fail (MODEST_IS_WINDOW (window));
4171 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4175 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4176 ModestWindow *window)
4178 g_return_if_fail (MODEST_IS_WINDOW (window));
4181 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4185 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4186 ModestWindow *window)
4188 g_return_if_fail (MODEST_IS_WINDOW (window));
4191 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4195 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4196 ModestWindow *window)
4198 g_return_if_fail (MODEST_IS_WINDOW (window));
4201 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4205 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4206 ModestWindow *window)
4208 g_return_if_fail (MODEST_IS_WINDOW (window));
4211 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4215 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4216 ModestWindow *window)
4218 g_return_if_fail (MODEST_IS_WINDOW (window));
4221 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4225 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4226 ModestWindow *window)
4228 g_return_if_fail (MODEST_IS_WINDOW (window));
4231 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4235 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4237 g_return_if_fail (MODEST_IS_WINDOW (window));
4240 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4244 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4246 g_return_if_fail (MODEST_IS_WINDOW (window));
4248 modest_platform_show_search_messages (GTK_WINDOW (window));
4252 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4254 g_return_if_fail (MODEST_IS_WINDOW (win));
4255 modest_platform_show_addressbook (GTK_WINDOW (win));
4260 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4261 ModestWindow *window)
4263 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4265 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4269 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4270 ModestMailOperationState *state,
4273 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4275 /* Set send/receive operation finished */
4276 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4277 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));