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-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #include <widgets/modest-header-window.h>
54 #include <widgets/modest-folder-window.h>
55 #include <widgets/modest-accounts-window.h>
56 #ifdef MODEST_TOOLKIT_HILDON2
57 #include <hildon/hildon-gtk.h>
58 #include <modest-maemo-utils.h>
60 #include "modest-utils.h"
61 #include "widgets/modest-connection-specific-smtp-window.h"
62 #include "widgets/modest-ui-constants.h"
63 #include <widgets/modest-main-window.h>
64 #include <widgets/modest-msg-view-window.h>
65 #include <widgets/modest-account-view-window.h>
66 #include <widgets/modest-details-dialog.h>
67 #include <widgets/modest-attachments-view.h>
68 #include "widgets/modest-folder-view.h"
69 #include "widgets/modest-global-settings-dialog.h"
70 #include "modest-account-mgr-helpers.h"
71 #include "modest-mail-operation.h"
72 #include "modest-text-utils.h"
73 #include <modest-widget-memory.h>
74 #include <tny-error.h>
75 #include <tny-simple-list.h>
76 #include <tny-msg-view.h>
77 #include <tny-device.h>
78 #include <tny-merge-folder.h>
79 #include <widgets/modest-toolkit-utils.h>
80 #include <tny-camel-bs-msg.h>
81 #include <tny-camel-bs-mime-part.h>
83 #include <gtkhtml/gtkhtml.h>
85 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
87 typedef struct _GetMsgAsyncHelper {
89 ModestMailOperation *mail_op;
96 typedef enum _ReplyForwardAction {
100 } ReplyForwardAction;
102 typedef struct _ReplyForwardHelper {
103 guint reply_forward_type;
104 ReplyForwardAction action;
107 GtkWidget *parent_window;
110 } ReplyForwardHelper;
112 typedef struct _MoveToHelper {
113 GtkTreeRowReference *reference;
117 typedef struct _PasteAsAttachmentHelper {
118 ModestMsgEditWindow *window;
120 } PasteAsAttachmentHelper;
128 * The do_headers_action uses this kind of functions to perform some
129 * action to each member of a list of headers
131 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
133 static void do_headers_action (ModestWindow *win,
137 static void open_msg_cb (ModestMailOperation *mail_op,
144 static void reply_forward_cb (ModestMailOperation *mail_op,
151 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
153 static gint header_list_count_uncached_msgs (TnyList *header_list);
155 static gboolean connect_to_get_msg (ModestWindow *win,
156 gint num_of_uncached_msgs,
157 TnyAccount *account);
159 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
161 static void do_create_folder (GtkWindow *window,
162 TnyFolderStore *parent_folder,
163 const gchar *suggested_name);
165 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
167 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
168 TnyFolderStore *dst_folder,
172 static void modest_ui_actions_on_window_move_to (GtkAction *action,
173 TnyList *list_to_move,
174 TnyFolderStore *dst_folder,
178 * This function checks whether a TnyFolderStore is a pop account
181 remote_folder_has_leave_on_server (TnyFolderStore *folder)
186 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
188 account = get_account_from_folder_store (folder);
189 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
190 modest_tny_account_get_protocol_type (account)));
191 g_object_unref (account);
196 /* FIXME: this should be merged with the similar code in modest-account-view-window */
197 /* Show the account creation wizard dialog.
198 * returns: TRUE if an account was created. FALSE if the user cancelled.
201 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
203 gboolean result = FALSE;
205 gint dialog_response;
207 /* there is no such wizard yet */
208 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
209 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
213 ModestWindowMgr *mgr;
215 mgr = modest_runtime_get_window_mgr ();
217 window_list = modest_window_mgr_get_window_list (mgr);
218 if (window_list == NULL) {
219 win = MODEST_WINDOW (modest_accounts_window_new ());
220 if (modest_window_mgr_register_window (mgr, win, NULL)) {
221 gtk_widget_show_all (GTK_WIDGET (win));
223 gtk_widget_destroy (GTK_WIDGET (win));
228 g_list_free (window_list);
233 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
235 /* make sure the mainwindow is visible. We need to present the
236 wizard again to give it the focus back. show_all are needed
237 in order to get the widgets properly drawn (MainWindow main
238 paned won't be in its right position and the dialog will be
241 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
242 gtk_widget_destroy (GTK_WIDGET (wizard));
243 if (gtk_events_pending ())
244 gtk_main_iteration ();
246 if (dialog_response == GTK_RESPONSE_CANCEL) {
249 /* Check whether an account was created: */
250 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
257 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
260 const gchar *authors[] = {
261 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
264 about = gtk_about_dialog_new ();
265 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
266 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
267 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
268 _("Copyright (c) 2006, Nokia Corporation\n"
269 "All rights reserved."));
270 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
271 _("a modest e-mail client\n\n"
272 "design and implementation: Dirk-Jan C. Binnema\n"
273 "contributions from the fine people at KC and Ig\n"
274 "uses the tinymail email framework written by Philip van Hoof"));
275 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
276 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
277 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
278 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
280 gtk_dialog_run (GTK_DIALOG (about));
281 gtk_widget_destroy(about);
285 * Gets the list of currently selected messages. If the win is the
286 * main window, then it returns a newly allocated list of the headers
287 * selected in the header view. If win is the msg view window, then
288 * the value returned is a list with just a single header.
290 * The caller of this funcion must free the list.
293 get_selected_headers (ModestWindow *win)
295 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
296 /* for MsgViewWindows, we simply return a list with one element */
298 TnyList *list = NULL;
300 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
301 if (header != NULL) {
302 list = tny_simple_list_new ();
303 tny_list_prepend (list, G_OBJECT(header));
304 g_object_unref (G_OBJECT(header));
308 } else if (MODEST_IS_HEADER_WINDOW (win)) {
309 GtkWidget *header_view;
311 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
312 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
319 headers_action_mark_as_read (TnyHeader *header,
323 TnyHeaderFlags flags;
325 g_return_if_fail (TNY_IS_HEADER(header));
327 flags = tny_header_get_flags (header);
328 if (flags & TNY_HEADER_FLAG_SEEN) return;
329 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
333 headers_action_mark_as_unread (TnyHeader *header,
337 TnyHeaderFlags flags;
339 g_return_if_fail (TNY_IS_HEADER(header));
341 flags = tny_header_get_flags (header);
342 if (flags & TNY_HEADER_FLAG_SEEN) {
343 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
347 /** After deleing a message that is currently visible in a window,
348 * show the next message from the list, or close the window if there are no more messages.
351 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
353 /* Close msg view window or select next */
354 if (!modest_msg_view_window_select_next_message (win) &&
355 !modest_msg_view_window_select_previous_message (win)) {
357 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
363 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
365 modest_ui_actions_on_edit_mode_delete_message (win);
369 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
371 TnyList *header_list = NULL;
372 TnyIterator *iter = NULL;
373 TnyHeader *header = NULL;
374 gchar *message = NULL;
377 ModestWindowMgr *mgr;
378 gboolean retval = TRUE;
380 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
382 /* Get the headers, either from the header view (if win is the main window),
383 * or from the message view window: */
384 header_list = get_selected_headers (win);
385 if (!header_list) return FALSE;
387 /* Check if any of the headers are already opened, or in the process of being opened */
390 if (tny_list_get_length(header_list) == 1) {
391 iter = tny_list_create_iterator (header_list);
392 header = TNY_HEADER (tny_iterator_get_current (iter));
395 subject = tny_header_dup_subject (header);
397 subject = g_strdup (_("mail_va_no_subject"));
398 desc = g_strdup_printf ("%s", subject);
400 g_object_unref (header);
403 g_object_unref (iter);
405 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
406 tny_list_get_length(header_list)), desc);
408 /* Confirmation dialog */
409 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
412 if (response == GTK_RESPONSE_OK) {
413 GtkTreeSelection *sel = NULL;
414 GList *sel_list = NULL;
415 ModestMailOperation *mail_op = NULL;
417 /* Find last selected row */
419 /* Disable window dimming management */
420 modest_window_disable_dimming (win);
422 /* Remove each header. If it's a view window header_view == NULL */
423 mail_op = modest_mail_operation_new ((GObject *) win);
424 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
426 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
427 g_object_unref (mail_op);
429 /* Enable window dimming management */
431 gtk_tree_selection_unselect_all (sel);
433 modest_window_enable_dimming (win);
435 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
436 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
438 /* Get main window */
439 mgr = modest_runtime_get_window_mgr ();
442 /* Update toolbar dimming state */
443 modest_ui_actions_check_menu_dimming_rules (win);
444 modest_ui_actions_check_toolbar_dimming_rules (win);
447 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
448 g_list_free (sel_list);
457 g_object_unref (header_list);
465 /* delete either message or folder, based on where we are */
467 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
469 g_return_if_fail (MODEST_IS_WINDOW(win));
471 /* Check first if the header view has the focus */
472 modest_ui_actions_on_delete_message (action, win);
476 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
478 ModestWindowMgr *mgr = NULL;
480 #ifdef MODEST_PLATFORM_MAEMO
481 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
482 #endif /* MODEST_PLATFORM_MAEMO */
484 g_debug ("closing down, clearing %d item(s) from operation queue",
485 modest_mail_operation_queue_num_elements
486 (modest_runtime_get_mail_operation_queue()));
488 /* cancel all outstanding operations */
489 modest_mail_operation_queue_cancel_all
490 (modest_runtime_get_mail_operation_queue());
492 g_debug ("queue has been cleared");
495 /* Check if there are opened editing windows */
496 mgr = modest_runtime_get_window_mgr ();
497 modest_window_mgr_close_all_windows (mgr);
499 /* note: when modest-tny-account-store is finalized,
500 it will automatically set all network connections
503 /* gtk_main_quit (); */
507 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
511 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
513 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
514 /* gtk_widget_destroy (GTK_WIDGET (win)); */
515 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
516 /* gboolean ret_value; */
517 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
518 /* } else if (MODEST_IS_WINDOW (win)) { */
519 /* gtk_widget_destroy (GTK_WIDGET (win)); */
521 /* g_return_if_reached (); */
526 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
528 if (MODEST_IS_MSG_VIEW_WINDOW (win))
529 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
530 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
531 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
535 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
537 GtkClipboard *clipboard = NULL;
538 gchar *selection = NULL;
540 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
541 selection = gtk_clipboard_wait_for_text (clipboard);
544 modest_address_book_add_address (selection, (GtkWindow *) win);
550 modest_ui_actions_on_new_account (GtkAction *action,
551 ModestWindow *window)
553 if (!modest_ui_actions_run_account_setup_wizard (window)) {
554 g_debug ("%s: wizard was already running", __FUNCTION__);
559 modest_ui_actions_on_accounts (GtkAction *action,
562 /* This is currently only implemented for Maemo */
563 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
564 if (!modest_ui_actions_run_account_setup_wizard (win))
565 g_debug ("%s: wizard was already running", __FUNCTION__);
569 /* Show the list of accounts */
570 GtkWindow *toplevel, *account_win;
572 account_win = GTK_WINDOW (modest_account_view_window_new ());
573 toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (win)));
575 /* The accounts dialog must be modal */
576 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
577 modest_utils_show_dialog_and_forget (toplevel, GTK_DIALOG (account_win));
582 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
584 /* This is currently only implemented for Maemo,
585 * because it requires an API (libconic) to detect different connection
588 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
590 /* Create the window if necessary: */
591 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
592 modest_connection_specific_smtp_window_fill_with_connections (
593 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
594 modest_runtime_get_account_mgr());
596 /* Show the window: */
597 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
598 GTK_WINDOW (specific_window), (GtkWindow *) win);
599 gtk_widget_show (specific_window);
600 #endif /* !MODEST_TOOLKIT_GTK */
604 count_part_size (const gchar *part)
606 GnomeVFSURI *vfs_uri;
607 gchar *escaped_filename;
609 GnomeVFSFileInfo *info;
612 /* Estimation of attachment size if we cannot get it from file info */
615 vfs_uri = gnome_vfs_uri_new (part);
617 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
618 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
619 g_free (escaped_filename);
620 gnome_vfs_uri_unref (vfs_uri);
622 info = gnome_vfs_file_info_new ();
624 if (gnome_vfs_get_file_info (part,
626 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
628 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
633 gnome_vfs_file_info_unref (info);
639 count_parts_size (GSList *parts)
644 for (node = parts; node != NULL; node = g_slist_next (node)) {
645 result += count_part_size ((const gchar *) node->data);
652 modest_ui_actions_compose_msg(ModestWindow *win,
655 const gchar *bcc_str,
656 const gchar *subject_str,
657 const gchar *body_str,
659 gboolean set_as_modified)
661 gchar *account_name = NULL;
662 const gchar *mailbox;
664 TnyAccount *account = NULL;
665 TnyFolder *folder = NULL;
666 gchar *from_str = NULL, *signature = NULL, *body = NULL;
667 gchar *recipient = NULL;
668 gboolean use_signature = FALSE;
669 ModestWindow *msg_win = NULL;
670 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
671 ModestTnyAccountStore *store = modest_runtime_get_account_store();
672 GnomeVFSFileSize total_size, allowed_size;
673 guint64 available_disk, expected_size, parts_size;
676 /* we check for low-mem */
677 if (modest_platform_check_memory_low (win, TRUE))
680 available_disk = modest_utils_get_available_space (NULL);
681 parts_count = g_slist_length (attachments);
682 parts_size = count_parts_size (attachments);
683 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
685 /* Double check: disk full condition or message too big */
686 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
687 expected_size > available_disk) {
688 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
689 modest_platform_system_banner (NULL, NULL, msg);
695 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
696 modest_platform_run_information_dialog (
698 _("mail_ib_error_attachment_size"),
705 account_name = g_strdup (modest_window_get_active_account(win));
707 account_name = modest_account_mgr_get_default_account(mgr);
710 g_printerr ("modest: no account found\n");
715 mailbox = modest_window_get_active_mailbox (win);
718 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
720 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
723 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
725 g_printerr ("modest: failed to find Drafts folder\n");
728 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
730 g_printerr ("modest: failed get from string for '%s'\n", account_name);
734 recipient = modest_text_utils_get_email_address (from_str);
735 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
737 if (body_str != NULL) {
738 body = use_signature ? g_strconcat(body_str, "\n",
739 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
740 "\n", signature, NULL) : g_strdup(body_str);
742 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
743 "\n", signature, NULL) : g_strdup("");
746 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
748 g_printerr ("modest: failed to create new msg\n");
752 /* Create and register edit window */
753 /* This is destroyed by TODO. */
755 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
756 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
758 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
759 gtk_widget_destroy (GTK_WIDGET (msg_win));
762 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
763 gtk_widget_show_all (GTK_WIDGET (msg_win));
765 while (attachments) {
766 GnomeVFSFileSize att_size;
768 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
769 attachments->data, allowed_size);
770 total_size += att_size;
772 if (att_size > allowed_size) {
773 g_debug ("%s: total size: %u",
774 __FUNCTION__, (unsigned int)total_size);
777 allowed_size -= att_size;
779 attachments = g_slist_next(attachments);
786 g_free (account_name);
788 g_object_unref (G_OBJECT(account));
790 g_object_unref (G_OBJECT(folder));
792 g_object_unref (G_OBJECT(msg));
796 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
798 /* if there are no accounts yet, just show the wizard */
799 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
800 if (!modest_ui_actions_run_account_setup_wizard (win))
803 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
808 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
812 ModestMailOperationStatus status;
814 /* If there is no message or the operation was not successful */
815 status = modest_mail_operation_get_status (mail_op);
816 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
819 /* If it's a memory low issue, then show a banner */
820 error = modest_mail_operation_get_error (mail_op);
821 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
822 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
823 GObject *source = modest_mail_operation_get_source (mail_op);
824 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
825 _KR("memr_ib_operation_disabled"),
827 g_object_unref (source);
830 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
831 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
832 gchar *subject, *msg, *format = NULL;
835 subject = (header) ? tny_header_dup_subject (header) : NULL;
837 subject = g_strdup (_("mail_va_no_subject"));
839 account = modest_mail_operation_get_account (mail_op);
841 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
842 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
845 if (tny_account_get_connection_status (account) ==
846 TNY_CONNECTION_STATUS_CONNECTED) {
848 format = modest_protocol_get_translation (protocol,
849 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
852 format = modest_protocol_get_translation (protocol,
853 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
856 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
857 tny_account_get_hostname (account));
860 g_object_unref (account);
865 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
867 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
871 msg = g_strdup_printf (format, subject);
872 modest_platform_run_information_dialog (NULL, msg, FALSE);
878 /* Remove the header from the preregistered uids */
879 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
897 ModestWindow *caller_window;
898 OpenMsgBannerInfo *banner_info;
899 GtkTreeRowReference *rowref;
903 open_msg_banner_idle (gpointer userdata)
905 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
907 gdk_threads_enter ();
908 banner_info->idle_handler = 0;
909 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
910 if (banner_info->banner)
911 g_object_ref (banner_info->banner);
913 gdk_threads_leave ();
919 get_header_view_from_window (ModestWindow *window)
921 GtkWidget *header_view;
923 if (MODEST_IS_HEADER_WINDOW (window)){
924 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
933 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
936 gchar *account = NULL;
937 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
942 folder = tny_header_get_folder (header);
943 /* Gets folder type (OUTBOX headers will be opened in edit window */
944 if (modest_tny_folder_is_local_folder (folder)) {
945 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
946 if (folder_type == TNY_FOLDER_TYPE_INVALID)
947 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
950 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
951 TnyTransportAccount *traccount = NULL;
952 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
953 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
955 ModestTnySendQueue *send_queue = NULL;
956 ModestTnySendQueueStatus status;
958 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
959 TNY_ACCOUNT(traccount)));
960 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
961 if (TNY_IS_SEND_QUEUE (send_queue)) {
962 msg_id = modest_tny_send_queue_get_msg_id (header);
963 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
965 /* Only open messages in outbox with the editor if they are in Failed state */
966 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
970 /* In Fremantle we can not
971 open any message from
972 outbox which is not in
977 g_object_unref(traccount);
979 g_warning("Cannot get transport account for message in outbox!!");
981 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
982 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
986 TnyAccount *acc = tny_folder_get_account (folder);
989 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
990 g_object_unref (acc);
994 g_object_unref (folder);
1000 open_msg_cb (ModestMailOperation *mail_op,
1007 ModestWindowMgr *mgr = NULL;
1008 ModestWindow *parent_win = NULL;
1009 ModestWindow *win = NULL;
1010 gchar *account = NULL;
1011 gboolean open_in_editor = FALSE;
1013 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1015 /* Do nothing if there was any problem with the mail
1016 operation. The error will be shown by the error_handler of
1017 the mail operation */
1018 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1021 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1023 /* Mark header as read */
1024 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1026 account = get_info_from_header (header, &open_in_editor, &can_open);
1030 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1032 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1034 if (open_in_editor) {
1035 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1036 gchar *from_header = NULL, *acc_name;
1037 gchar *mailbox = NULL;
1039 from_header = tny_header_dup_from (header);
1041 /* we cannot edit without a valid account... */
1042 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1043 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1044 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1046 g_free (from_header);
1051 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1052 g_free (from_header);
1058 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1062 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1063 const gchar *mailbox = NULL;
1065 if (parent_win && MODEST_IS_WINDOW (parent_win))
1066 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1068 if (helper->rowref && helper->model) {
1069 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1070 helper->model, helper->rowref);
1072 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1077 /* Register and show new window */
1079 mgr = modest_runtime_get_window_mgr ();
1080 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1081 gtk_widget_destroy (GTK_WIDGET (win));
1084 gtk_widget_show_all (GTK_WIDGET(win));
1091 g_object_unref (parent_win);
1095 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1098 const GError *error;
1099 GObject *win = NULL;
1100 ModestMailOperationStatus status;
1102 win = modest_mail_operation_get_source (mail_op);
1103 error = modest_mail_operation_get_error (mail_op);
1104 status = modest_mail_operation_get_status (mail_op);
1106 /* If the mail op has been cancelled then it's not an error:
1107 don't show any message */
1108 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1109 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1110 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1111 (GError *) error, account)) {
1112 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1113 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1115 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1116 modest_platform_information_banner ((GtkWidget *) win,
1117 NULL, _("emev_ui_imap_inbox_select_error"));
1118 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1119 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1120 modest_platform_information_banner ((GtkWidget *) win,
1121 NULL, _CS_UNABLE_TO_OPEN_FILE_NOT_FOUND);
1122 } else if (user_data) {
1123 modest_platform_information_banner ((GtkWidget *) win,
1127 g_object_unref (account);
1131 g_object_unref (win);
1135 * Returns the account a list of headers belongs to. It returns a
1136 * *new* reference so don't forget to unref it
1139 get_account_from_header_list (TnyList *headers)
1141 TnyAccount *account = NULL;
1143 if (tny_list_get_length (headers) > 0) {
1144 TnyIterator *iter = tny_list_create_iterator (headers);
1145 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1146 TnyFolder *folder = tny_header_get_folder (header);
1149 g_object_unref (header);
1151 while (!tny_iterator_is_done (iter)) {
1152 header = TNY_HEADER (tny_iterator_get_current (iter));
1153 folder = tny_header_get_folder (header);
1156 g_object_unref (header);
1158 tny_iterator_next (iter);
1163 account = tny_folder_get_account (folder);
1164 g_object_unref (folder);
1168 g_object_unref (header);
1170 g_object_unref (iter);
1176 get_account_from_header (TnyHeader *header)
1178 TnyAccount *account = NULL;
1181 folder = tny_header_get_folder (header);
1184 account = tny_folder_get_account (folder);
1185 g_object_unref (folder);
1191 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1193 if (helper->caller_window)
1194 helper->caller_window = NULL;
1198 open_msg_helper_destroyer (gpointer user_data)
1200 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1202 if (helper->caller_window) {
1203 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1204 helper->caller_window = NULL;
1207 if (helper->banner_info) {
1208 g_free (helper->banner_info->message);
1209 if (helper->banner_info->idle_handler > 0) {
1210 g_source_remove (helper->banner_info->idle_handler);
1211 helper->banner_info->idle_handler = 0;
1213 if (helper->banner_info->banner != NULL) {
1214 gtk_widget_destroy (helper->banner_info->banner);
1215 g_object_unref (helper->banner_info->banner);
1216 helper->banner_info->banner = NULL;
1218 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1219 helper->banner_info = NULL;
1221 g_object_unref (helper->model);
1222 g_object_unref (helper->header);
1223 gtk_tree_row_reference_free (helper->rowref);
1224 g_slice_free (OpenMsgHelper, helper);
1228 open_msg_performer(gboolean canceled,
1230 GtkWindow *parent_window,
1231 TnyAccount *account,
1234 ModestMailOperation *mail_op = NULL;
1235 gchar *error_msg = NULL;
1236 ModestProtocolType proto;
1237 TnyConnectionStatus status;
1238 OpenMsgHelper *helper = NULL;
1239 ModestProtocol *protocol;
1240 ModestProtocolRegistry *protocol_registry;
1243 helper = (OpenMsgHelper *) user_data;
1245 status = tny_account_get_connection_status (account);
1246 if (err || canceled || helper->caller_window == NULL) {
1247 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1248 /* Free the helper */
1249 open_msg_helper_destroyer (helper);
1251 /* In disk full conditions we could get this error here */
1252 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1253 (GtkWidget *) parent_window, err,
1259 /* Get the error message depending on the protocol */
1260 proto = modest_tny_account_get_protocol_type (account);
1261 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1262 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1265 protocol_registry = modest_runtime_get_protocol_registry ();
1266 subject = tny_header_dup_subject (helper->header);
1268 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1269 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1273 if (error_msg == NULL) {
1274 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1279 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1282 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1283 g_free (account_name);
1284 open_msg_helper_destroyer (helper);
1289 ModestWindow *window;
1290 GtkWidget *header_view;
1293 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1294 uid = modest_tny_folder_get_header_unique_id (helper->header);
1296 const gchar *mailbox = NULL;
1297 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1298 window = modest_msg_view_window_new_from_header_view
1299 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1300 if (window != NULL) {
1301 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1303 gtk_widget_destroy (GTK_WIDGET (window));
1305 gtk_widget_show_all (GTK_WIDGET(window));
1309 g_free (account_name);
1311 open_msg_helper_destroyer (helper);
1314 g_free (account_name);
1315 /* Create the mail operation */
1317 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1318 modest_ui_actions_disk_operations_error_handler,
1319 g_strdup (error_msg), g_free);
1320 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1326 headers = TNY_LIST (tny_simple_list_new ());
1327 tny_list_prepend (headers, G_OBJECT (helper->header));
1328 modest_mail_operation_get_msgs_full (mail_op,
1332 open_msg_helper_destroyer);
1333 g_object_unref (headers);
1340 g_object_unref (mail_op);
1341 g_object_unref (account);
1345 * This function is used by both modest_ui_actions_on_open and
1346 * modest_ui_actions_on_header_activated. This way we always do the
1347 * same when trying to open messages.
1350 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1352 ModestWindowMgr *mgr = NULL;
1353 TnyAccount *account;
1354 gboolean cached = FALSE;
1356 GtkWidget *header_view = NULL;
1357 OpenMsgHelper *helper;
1358 ModestWindow *window;
1360 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1362 mgr = modest_runtime_get_window_mgr ();
1365 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1366 if (header_view == NULL)
1369 /* Get the account */
1370 account = get_account_from_header (header);
1375 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1377 /* Do not open again the message and present the
1378 window to the user */
1381 #ifndef MODEST_TOOLKIT_HILDON2
1382 gtk_window_present (GTK_WINDOW (window));
1385 /* the header has been registered already, we don't do
1386 * anything but wait for the window to come up*/
1387 g_debug ("header %p already registered, waiting for window", header);
1392 /* Open each message */
1393 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1395 /* Allways download if we are online. */
1396 if (!tny_device_is_online (modest_runtime_get_device ())) {
1399 /* If ask for user permission to download the messages */
1400 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1401 _("mcen_nc_get_msg"));
1403 /* End if the user does not want to continue */
1404 if (response == GTK_RESPONSE_CANCEL) {
1410 /* We register the window for opening */
1411 modest_window_mgr_register_header (mgr, header, NULL);
1413 /* Create the helper. We need to get a reference to the model
1414 here because it could change while the message is readed
1415 (the user could switch between folders) */
1416 helper = g_slice_new (OpenMsgHelper);
1417 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1418 helper->caller_window = win;
1419 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1420 helper->header = g_object_ref (header);
1421 helper->rowref = gtk_tree_row_reference_copy (rowref);
1422 helper->banner_info = NULL;
1424 /* Connect to the account and perform */
1426 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1427 open_msg_performer, helper);
1429 /* Call directly the performer, do not need to connect */
1430 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1431 g_object_ref (account), helper);
1436 g_object_unref (account);
1440 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1447 /* we check for low-mem; in that case, show a warning, and don't allow
1450 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1454 headers = get_selected_headers (win);
1458 headers_count = tny_list_get_length (headers);
1459 if (headers_count != 1) {
1460 if (headers_count > 1) {
1461 /* Don't allow activation if there are more than one message selected */
1462 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1465 g_object_unref (headers);
1469 iter = tny_list_create_iterator (headers);
1470 header = TNY_HEADER (tny_iterator_get_current (iter));
1471 g_object_unref (iter);
1475 open_msg_from_header (header, NULL, win);
1476 g_object_unref (header);
1479 g_object_unref(headers);
1483 rf_helper_window_closed (gpointer data,
1486 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1488 helper->parent_window = NULL;
1491 static ReplyForwardHelper*
1492 create_reply_forward_helper (ReplyForwardAction action,
1494 guint reply_forward_type,
1498 ReplyForwardHelper *rf_helper = NULL;
1499 const gchar *active_acc = modest_window_get_active_account (win);
1500 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1502 rf_helper = g_slice_new0 (ReplyForwardHelper);
1503 rf_helper->reply_forward_type = reply_forward_type;
1504 rf_helper->action = action;
1505 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1506 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1507 rf_helper->account_name = (active_acc) ?
1508 g_strdup (active_acc) :
1509 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1510 rf_helper->mailbox = g_strdup (active_mailbox);
1512 rf_helper->parts = g_object_ref (parts);
1514 rf_helper->parts = NULL;
1516 /* Note that window could be destroyed just AFTER calling
1517 register_window so we must ensure that this pointer does
1518 not hold invalid references */
1519 if (rf_helper->parent_window)
1520 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1521 rf_helper_window_closed, rf_helper);
1527 free_reply_forward_helper (gpointer data)
1529 ReplyForwardHelper *helper;
1531 helper = (ReplyForwardHelper *) data;
1532 g_free (helper->account_name);
1533 g_free (helper->mailbox);
1535 g_object_unref (helper->header);
1537 g_object_unref (helper->parts);
1538 if (helper->parent_window)
1539 g_object_weak_unref (G_OBJECT (helper->parent_window),
1540 rf_helper_window_closed, helper);
1541 g_slice_free (ReplyForwardHelper, helper);
1545 reply_forward_cb (ModestMailOperation *mail_op,
1552 TnyMsg *new_msg = NULL;
1553 ReplyForwardHelper *rf_helper;
1554 ModestWindow *msg_win = NULL;
1555 ModestEditType edit_type;
1557 TnyAccount *account = NULL;
1558 ModestWindowMgr *mgr = NULL;
1559 gchar *signature = NULL;
1560 gboolean use_signature;
1563 /* If there was any error. The mail operation could be NULL,
1564 this means that we already have the message downloaded and
1565 that we didn't do a mail operation to retrieve it */
1566 rf_helper = (ReplyForwardHelper *) user_data;
1567 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1570 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1571 rf_helper->account_name, rf_helper->mailbox);
1572 recipient = modest_text_utils_get_email_address (from);
1573 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1578 /* Create reply mail */
1579 switch (rf_helper->action) {
1580 /* Use the msg_header to ensure that we have all the
1581 information. The summary can lack some data */
1582 TnyHeader *msg_header;
1584 msg_header = tny_msg_get_header (msg);
1586 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1587 (use_signature) ? signature : NULL,
1588 rf_helper->reply_forward_type,
1589 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1590 g_object_unref (msg_header);
1592 case ACTION_REPLY_TO_ALL:
1593 msg_header = tny_msg_get_header (msg);
1595 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1596 (use_signature) ? signature : NULL,
1597 rf_helper->reply_forward_type,
1598 MODEST_TNY_MSG_REPLY_MODE_ALL);
1599 edit_type = MODEST_EDIT_TYPE_REPLY;
1600 g_object_unref (msg_header);
1602 case ACTION_FORWARD:
1604 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1605 rf_helper->reply_forward_type);
1606 edit_type = MODEST_EDIT_TYPE_FORWARD;
1609 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1611 g_return_if_reached ();
1619 g_warning ("%s: failed to create message\n", __FUNCTION__);
1623 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1624 rf_helper->account_name,
1625 TNY_ACCOUNT_TYPE_STORE);
1627 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1631 /* Create and register the windows */
1632 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1633 mgr = modest_runtime_get_window_mgr ();
1634 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1636 /* Note that register_window could have deleted the account */
1637 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1638 gdouble parent_zoom;
1640 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1641 modest_window_set_zoom (msg_win, parent_zoom);
1644 /* Show edit window */
1645 gtk_widget_show_all (GTK_WIDGET (msg_win));
1648 /* We always unregister the header because the message is
1649 forwarded or replied so the original one is no longer
1651 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1654 g_object_unref (G_OBJECT (new_msg));
1656 g_object_unref (G_OBJECT (account));
1657 free_reply_forward_helper (rf_helper);
1660 /* Checks a list of headers. If any of them are not currently
1661 * downloaded (CACHED) then returns TRUE else returns FALSE.
1664 header_list_count_uncached_msgs (TnyList *header_list)
1667 gint uncached_messages = 0;
1669 iter = tny_list_create_iterator (header_list);
1670 while (!tny_iterator_is_done (iter)) {
1673 header = TNY_HEADER (tny_iterator_get_current (iter));
1675 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1676 uncached_messages ++;
1677 g_object_unref (header);
1680 tny_iterator_next (iter);
1682 g_object_unref (iter);
1684 return uncached_messages;
1687 /* Returns FALSE if the user does not want to download the
1688 * messages. Returns TRUE if the user allowed the download.
1691 connect_to_get_msg (ModestWindow *win,
1692 gint num_of_uncached_msgs,
1693 TnyAccount *account)
1695 GtkResponseType response;
1697 /* Allways download if we are online. */
1698 if (tny_device_is_online (modest_runtime_get_device ()))
1701 /* If offline, then ask for user permission to download the messages */
1702 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1703 ngettext("mcen_nc_get_msg",
1705 num_of_uncached_msgs));
1707 if (response == GTK_RESPONSE_CANCEL)
1710 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1714 reply_forward_performer (gboolean canceled,
1716 GtkWindow *parent_window,
1717 TnyAccount *account,
1720 ReplyForwardHelper *rf_helper = NULL;
1721 ModestMailOperation *mail_op;
1723 rf_helper = (ReplyForwardHelper *) user_data;
1725 if (canceled || err) {
1726 free_reply_forward_helper (rf_helper);
1730 /* Retrieve the message */
1731 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1732 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1733 modest_ui_actions_disk_operations_error_handler,
1735 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1736 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1739 g_object_unref(mail_op);
1743 all_parts_retrieved (TnyMimePart *part)
1745 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1748 TnyList *pending_parts;
1749 TnyIterator *iterator;
1750 gboolean all_retrieved = TRUE;
1752 pending_parts = TNY_LIST (tny_simple_list_new ());
1753 tny_mime_part_get_parts (part, pending_parts);
1754 iterator = tny_list_create_iterator (pending_parts);
1755 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1758 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1760 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1761 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1763 all_retrieved = FALSE;
1766 g_object_unref (child);
1767 tny_iterator_next (iterator);
1769 g_object_unref (iterator);
1770 g_object_unref (pending_parts);
1771 return all_retrieved;
1776 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1779 TnyIterator *iterator;
1781 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
1782 tny_list_append (list, G_OBJECT (part));
1784 parts = TNY_LIST (tny_simple_list_new ());
1785 tny_mime_part_get_parts (part, parts);
1786 for (iterator = tny_list_create_iterator (parts);
1787 !tny_iterator_is_done (iterator);
1788 tny_iterator_next (iterator)) {
1791 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1792 forward_pending_parts_helper (child, list);
1793 g_object_unref (child);
1795 g_object_unref (iterator);
1796 g_object_unref (parts);
1800 forward_pending_parts (TnyMsg *msg)
1802 TnyList *result = TNY_LIST (tny_simple_list_new ());
1803 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
1804 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
1811 * Common code for the reply and forward actions
1814 reply_forward (ReplyForwardAction action, ModestWindow *win)
1816 ReplyForwardHelper *rf_helper = NULL;
1817 guint reply_forward_type;
1819 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1821 /* we check for low-mem; in that case, show a warning, and don't allow
1822 * reply/forward (because it could potentially require a lot of memory */
1823 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1827 /* we need an account when editing */
1828 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1829 if (!modest_ui_actions_run_account_setup_wizard (win))
1833 reply_forward_type =
1834 modest_conf_get_int (modest_runtime_get_conf (),
1835 (action == ACTION_FORWARD) ?
1836 MODEST_CONF_FORWARD_TYPE :
1837 MODEST_CONF_REPLY_TYPE,
1840 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1842 TnyHeader *header = NULL;
1843 /* Get header and message. Do not free them here, the
1844 reply_forward_cb must do it */
1845 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1846 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1848 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
1850 rf_helper = create_reply_forward_helper (action, win,
1851 reply_forward_type, header, NULL);
1852 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1854 gboolean do_download = TRUE;
1856 if (msg && header && action == ACTION_FORWARD) {
1857 /* Not all parts retrieved. Then we have to retrieve them all before
1858 * creating the forward message */
1859 if (!tny_device_is_online (modest_runtime_get_device ())) {
1862 /* If ask for user permission to download the messages */
1863 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1864 ngettext("mcen_nc_get_msg",
1868 /* End if the user does not want to continue */
1869 if (response == GTK_RESPONSE_CANCEL)
1870 do_download = FALSE;
1874 TnyList *pending_parts;
1876 TnyAccount *account;
1879 pending_parts = forward_pending_parts (msg);
1880 rf_helper = create_reply_forward_helper (action, win,
1881 reply_forward_type, header, pending_parts);
1882 g_object_unref (pending_parts);
1884 folder = tny_header_get_folder (header);
1885 account = tny_folder_get_account (folder);
1886 modest_platform_connect_and_perform (GTK_WINDOW (win),
1888 reply_forward_performer,
1890 g_object_unref (folder);
1891 g_object_unref (account);
1895 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1900 g_object_unref (msg);
1902 g_object_unref (header);
1904 TnyHeader *header = NULL;
1906 gboolean do_retrieve = TRUE;
1907 TnyList *header_list = NULL;
1909 header_list = get_selected_headers (win);
1912 /* Check that only one message is selected for replying */
1913 if (tny_list_get_length (header_list) != 1) {
1914 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1915 NULL, _("mcen_ib_select_one_message"));
1916 g_object_unref (header_list);
1920 /* Only reply/forward to one message */
1921 iter = tny_list_create_iterator (header_list);
1922 header = TNY_HEADER (tny_iterator_get_current (iter));
1923 g_object_unref (iter);
1925 /* Retrieve messages */
1926 do_retrieve = (action == ACTION_FORWARD) ||
1927 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1930 TnyAccount *account = NULL;
1931 TnyFolder *folder = NULL;
1932 gdouble download = TRUE;
1933 guint uncached_msgs = 0;
1935 folder = tny_header_get_folder (header);
1937 goto do_retrieve_frees;
1938 account = tny_folder_get_account (folder);
1940 goto do_retrieve_frees;
1942 uncached_msgs = header_list_count_uncached_msgs (header_list);
1944 if (uncached_msgs > 0) {
1945 /* Allways download if we are online. */
1946 if (!tny_device_is_online (modest_runtime_get_device ())) {
1949 /* If ask for user permission to download the messages */
1950 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1951 ngettext("mcen_nc_get_msg",
1955 /* End if the user does not want to continue */
1956 if (response == GTK_RESPONSE_CANCEL)
1963 rf_helper = create_reply_forward_helper (action, win,
1964 reply_forward_type, header, NULL);
1965 if (uncached_msgs > 0) {
1966 modest_platform_connect_and_perform (GTK_WINDOW (win),
1968 reply_forward_performer,
1971 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1972 account, rf_helper);
1977 g_object_unref (account);
1979 g_object_unref (folder);
1981 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
1984 g_object_unref (header_list);
1985 g_object_unref (header);
1990 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1992 g_return_if_fail (MODEST_IS_WINDOW(win));
1994 reply_forward (ACTION_REPLY, win);
1998 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2000 g_return_if_fail (MODEST_IS_WINDOW(win));
2002 reply_forward (ACTION_FORWARD, win);
2006 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2008 g_return_if_fail (MODEST_IS_WINDOW(win));
2010 reply_forward (ACTION_REPLY_TO_ALL, win);
2014 modest_ui_actions_on_next (GtkAction *action,
2015 ModestWindow *window)
2017 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2018 modest_msg_view_window_select_next_message (
2019 MODEST_MSG_VIEW_WINDOW (window));
2021 g_return_if_reached ();
2026 modest_ui_actions_on_prev (GtkAction *action,
2027 ModestWindow *window)
2029 g_return_if_fail (MODEST_IS_WINDOW(window));
2031 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2032 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2034 g_return_if_reached ();
2039 modest_ui_actions_on_sort (GtkAction *action,
2040 ModestWindow *window)
2042 GtkWidget *header_view = NULL;
2044 g_return_if_fail (MODEST_IS_WINDOW(window));
2046 if (MODEST_IS_HEADER_WINDOW (window)) {
2047 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2051 modest_platform_information_banner (NULL, NULL, _CS_NOTHING_TO_SORT);
2056 /* Show sorting dialog */
2057 modest_utils_run_sort_dialog (MODEST_WINDOW (window), MODEST_SORT_HEADERS);
2061 sync_folder_cb (ModestMailOperation *mail_op,
2065 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2067 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2068 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2070 /* We must clear first, because otherwise set_folder will ignore */
2071 /* the change as the folders are the same */
2072 modest_header_view_clear (header_view);
2073 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2075 g_object_unref (parent);
2078 g_object_unref (header_view);
2082 idle_refresh_folder (gpointer source)
2084 ModestHeaderView *header_view = NULL;
2086 /* If the window still exists */
2087 if (!GTK_IS_WIDGET (source) ||
2088 !GTK_WIDGET_VISIBLE (source))
2091 /* Refresh the current view */
2092 if (MODEST_IS_HEADER_WINDOW (source))
2093 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2095 TnyFolder *folder = modest_header_view_get_folder (header_view);
2097 /* Sync the folder status */
2098 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2099 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2100 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2101 g_object_unref (folder);
2102 g_object_unref (mail_op);
2110 update_account_cb (ModestMailOperation *self,
2111 TnyList *new_headers,
2115 gboolean show_visual_notifications;
2117 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2118 show_visual_notifications = (top) ? FALSE : TRUE;
2120 /* Notify new messages have been downloaded. If the
2121 send&receive was invoked by the user then do not show any
2122 visual notification, only play a sound and activate the LED
2123 (for the Maemo version) */
2124 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2126 /* We only notify about really new messages (not seen) we get */
2127 TnyList *actually_new_list;
2128 TnyIterator *iterator;
2129 actually_new_list = TNY_LIST (tny_simple_list_new ());
2130 for (iterator = tny_list_create_iterator (new_headers);
2131 !tny_iterator_is_done (iterator);
2132 tny_iterator_next (iterator)) {
2134 TnyHeaderFlags flags;
2135 header = TNY_HEADER (tny_iterator_get_current (iterator));
2136 flags = tny_header_get_flags (header);
2138 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2139 /* Messages are ordered from most
2140 recent to oldest. But we want to
2141 show notifications starting from
2142 the oldest message. That's why we
2144 tny_list_prepend (actually_new_list, G_OBJECT (header));
2146 g_object_unref (header);
2148 g_object_unref (iterator);
2150 if (tny_list_get_length (actually_new_list) > 0) {
2151 GList *new_headers_list = NULL;
2153 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2155 /* Send notifications */
2156 if (new_headers_list) {
2157 modest_platform_on_new_headers_received (new_headers_list,
2158 show_visual_notifications);
2160 modest_utils_free_notification_list (new_headers_list);
2163 g_object_unref (actually_new_list);
2167 /* Refresh the current folder in an idle. We do this
2168 in order to avoid refresh cancelations if the
2169 currently viewed folder is the inbox */
2170 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2171 idle_refresh_folder,
2178 TnyAccount *account;
2180 gchar *account_name;
2181 gboolean poke_status;
2182 gboolean interactive;
2183 ModestMailOperation *mail_op;
2187 do_send_receive_performer (gboolean canceled,
2189 GtkWindow *parent_window,
2190 TnyAccount *account,
2193 SendReceiveInfo *info;
2195 info = (SendReceiveInfo *) user_data;
2197 if (err || canceled) {
2198 /* In disk full conditions we could get this error here */
2199 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2200 (GtkWidget *) parent_window, err,
2203 if (info->mail_op) {
2204 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2211 /* Send & receive. */
2212 modest_mail_operation_update_account (info->mail_op, info->account_name,
2213 info->poke_status, info->interactive,
2214 update_account_cb, info->win);
2219 g_object_unref (G_OBJECT (info->mail_op));
2220 if (info->account_name)
2221 g_free (info->account_name);
2223 g_object_unref (info->win);
2225 g_object_unref (info->account);
2226 g_slice_free (SendReceiveInfo, info);
2230 * This function performs the send & receive required actions. The
2231 * window is used to create the mail operation. Typically it should
2232 * always be the main window, but we pass it as argument in order to
2236 modest_ui_actions_do_send_receive (const gchar *account_name,
2237 gboolean force_connection,
2238 gboolean poke_status,
2239 gboolean interactive,
2242 gchar *acc_name = NULL;
2243 SendReceiveInfo *info;
2244 ModestTnyAccountStore *acc_store;
2245 TnyAccount *account;
2247 /* If no account name was provided then get the current account, and if
2248 there is no current account then pick the default one: */
2249 if (!account_name) {
2251 acc_name = g_strdup (modest_window_get_active_account (win));
2253 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2255 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2259 acc_name = g_strdup (account_name);
2262 acc_store = modest_runtime_get_account_store ();
2263 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2267 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2271 /* Do not automatically refresh accounts that are flagged as
2272 NO_AUTO_UPDATE. This could be useful for accounts that
2273 handle their own update times */
2275 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2276 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2277 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2278 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2280 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2281 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2282 g_object_unref (account);
2289 /* Create the info for the connect and perform */
2290 info = g_slice_new (SendReceiveInfo);
2291 info->account_name = acc_name;
2292 info->win = (win) ? g_object_ref (win) : NULL;
2293 info->poke_status = poke_status;
2294 info->interactive = interactive;
2295 info->account = account;
2296 /* We need to create the operation here, because otherwise it
2297 could happen that the queue emits the queue-empty signal
2298 while we're trying to connect the account */
2299 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2300 modest_ui_actions_disk_operations_error_handler,
2302 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2304 /* Invoke the connect and perform */
2305 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2306 force_connection, info->account,
2307 do_send_receive_performer, info);
2312 modest_ui_actions_do_cancel_send (const gchar *account_name,
2315 TnyTransportAccount *transport_account;
2316 TnySendQueue *send_queue = NULL;
2317 GError *error = NULL;
2319 /* Get transport account */
2321 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2322 (modest_runtime_get_account_store(),
2324 TNY_ACCOUNT_TYPE_TRANSPORT));
2325 if (!transport_account) {
2326 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2331 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2332 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2333 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2334 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2335 "modest: could not find send queue for account\n");
2337 /* Cancel the current send */
2338 tny_account_cancel (TNY_ACCOUNT (transport_account));
2340 /* Suspend all pending messages */
2341 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2345 if (transport_account != NULL)
2346 g_object_unref (G_OBJECT (transport_account));
2350 modest_ui_actions_cancel_send_all (ModestWindow *win)
2352 GSList *account_names, *iter;
2354 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2357 iter = account_names;
2359 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2360 iter = g_slist_next (iter);
2363 modest_account_mgr_free_account_names (account_names);
2364 account_names = NULL;
2368 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2371 /* Check if accounts exist */
2372 gboolean accounts_exist =
2373 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2375 /* If not, allow the user to create an account before trying to send/receive. */
2376 if (!accounts_exist)
2377 modest_ui_actions_on_accounts (NULL, win);
2379 /* Cancel all sending operaitons */
2380 modest_ui_actions_cancel_send_all (win);
2384 * Refreshes all accounts. This function will be used by automatic
2388 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2389 gboolean force_connection,
2390 gboolean poke_status,
2391 gboolean interactive)
2393 GSList *account_names, *iter;
2395 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2398 iter = account_names;
2400 modest_ui_actions_do_send_receive ((const char*) iter->data,
2402 poke_status, interactive, win);
2403 iter = g_slist_next (iter);
2406 modest_account_mgr_free_account_names (account_names);
2407 account_names = NULL;
2411 * Handler of the click on Send&Receive button in the main toolbar
2414 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2416 /* Check if accounts exist */
2417 gboolean accounts_exist;
2420 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2422 /* If not, allow the user to create an account before trying to send/receive. */
2423 if (!accounts_exist)
2424 modest_ui_actions_on_accounts (NULL, win);
2426 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2427 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2428 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2430 const gchar *active_account;
2431 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2433 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2440 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2443 ModestWindow *window)
2445 GtkTreeRowReference *rowref;
2447 g_return_if_fail (MODEST_IS_WINDOW(window));
2448 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2449 g_return_if_fail (TNY_IS_HEADER (header));
2451 if (modest_header_view_count_selected_headers (header_view) > 1) {
2452 /* Don't allow activation if there are more than one message selected */
2453 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2457 /* we check for low-mem; in that case, show a warning, and don't allow
2458 * activating headers
2460 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2464 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2465 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2466 gtk_tree_row_reference_free (rowref);
2470 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2477 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2479 online = tny_device_is_online (modest_runtime_get_device());
2482 /* already online -- the item is simply not there... */
2483 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2485 GTK_MESSAGE_WARNING,
2487 _("The %s you selected cannot be found"),
2489 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2490 gtk_dialog_run (GTK_DIALOG(dialog));
2492 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2495 _("mcen_bd_dialog_cancel"),
2496 GTK_RESPONSE_REJECT,
2497 _("mcen_bd_dialog_ok"),
2498 GTK_RESPONSE_ACCEPT,
2500 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2501 "Do you want to get online?"), item);
2502 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2503 gtk_label_new (txt), FALSE, FALSE, 0);
2504 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2507 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2508 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2509 /* TODO: Comment about why is this commented out: */
2510 /* modest_platform_connect_and_wait (); */
2513 gtk_widget_destroy (dialog);
2517 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2520 /* g_debug ("%s %s", __FUNCTION__, link); */
2525 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2528 modest_platform_activate_uri (link);
2532 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2535 modest_platform_show_uri_popup (link);
2539 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2542 /* we check for low-mem; in that case, show a warning, and don't allow
2543 * viewing attachments
2545 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2548 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2552 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2553 const gchar *address,
2556 /* g_debug ("%s %s", __FUNCTION__, address); */
2560 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2561 TnyMsg *saved_draft,
2564 ModestMsgEditWindow *edit_window;
2566 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2568 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2570 /* Set draft is there was no error */
2571 if (!modest_mail_operation_get_error (mail_op))
2572 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2574 g_object_unref(edit_window);
2578 enough_space_for_message (ModestMsgEditWindow *edit_window,
2581 guint64 available_disk, expected_size;
2586 available_disk = modest_utils_get_available_space (NULL);
2587 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2588 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2593 /* Double check: disk full condition or message too big */
2594 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2595 expected_size > available_disk) {
2596 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2597 modest_platform_information_banner (NULL, NULL, msg);
2604 * djcb: if we're in low-memory state, we only allow for
2605 * saving messages smaller than
2606 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2607 * should still allow for sending anything critical...
2609 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2610 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2614 * djcb: we also make sure that the attachments are smaller than the max size
2615 * this is for the case where we'd try to forward a message with attachments
2616 * bigger than our max allowed size, or sending an message from drafts which
2617 * somehow got past our checks when attaching.
2619 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2620 modest_platform_run_information_dialog (
2621 GTK_WINDOW(edit_window),
2622 _("mail_ib_error_attachment_size"),
2631 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2633 TnyTransportAccount *transport_account;
2634 ModestMailOperation *mail_operation;
2636 gchar *account_name;
2637 ModestAccountMgr *account_mgr;
2638 gboolean had_error = FALSE;
2640 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2642 data = modest_msg_edit_window_get_msg_data (edit_window);
2645 if (!enough_space_for_message (edit_window, data)) {
2646 modest_msg_edit_window_free_msg_data (edit_window, data);
2650 account_name = g_strdup (data->account_name);
2651 account_mgr = modest_runtime_get_account_mgr();
2653 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2655 account_name = modest_account_mgr_get_default_account (account_mgr);
2656 if (!account_name) {
2657 g_printerr ("modest: no account found\n");
2658 modest_msg_edit_window_free_msg_data (edit_window, data);
2662 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2663 account_name = g_strdup (data->account_name);
2667 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2668 (modest_runtime_get_account_store (),
2670 TNY_ACCOUNT_TYPE_TRANSPORT));
2671 if (!transport_account) {
2672 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2673 g_free (account_name);
2674 modest_msg_edit_window_free_msg_data (edit_window, data);
2678 /* Create the mail operation */
2679 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2681 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2683 modest_mail_operation_save_to_drafts (mail_operation,
2695 data->priority_flags,
2698 on_save_to_drafts_cb,
2699 g_object_ref(edit_window));
2701 /* In hildon2 we always show the information banner on saving to drafts.
2702 * It will be a system information banner in this case.
2704 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2705 modest_platform_information_banner (NULL, NULL, text);
2707 modest_msg_edit_window_set_modified (edit_window, FALSE);
2710 g_free (account_name);
2711 g_object_unref (G_OBJECT (transport_account));
2712 g_object_unref (G_OBJECT (mail_operation));
2714 modest_msg_edit_window_free_msg_data (edit_window, data);
2720 /* For instance, when clicking the Send toolbar button when editing a message: */
2722 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2724 TnyTransportAccount *transport_account = NULL;
2725 gboolean had_error = FALSE, add_to_contacts;
2727 ModestAccountMgr *account_mgr;
2728 gchar *account_name;
2729 ModestMailOperation *mail_operation;
2732 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2734 /* Check whether to automatically add new contacts to addressbook or not */
2735 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
2736 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
2737 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
2740 data = modest_msg_edit_window_get_msg_data (edit_window);
2742 recipients = g_strconcat (data->to?data->to:"",
2743 data->cc?data->cc:"",
2744 data->bcc?data->bcc:"",
2746 if (recipients == NULL || recipients[0] == '\0') {
2747 /* Empty subject -> no send */
2748 g_free (recipients);
2749 modest_msg_edit_window_free_msg_data (edit_window, data);
2752 g_free (recipients);
2755 if (!enough_space_for_message (edit_window, data)) {
2756 modest_msg_edit_window_free_msg_data (edit_window, data);
2760 account_mgr = modest_runtime_get_account_mgr();
2761 account_name = g_strdup (data->account_name);
2763 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2766 account_name = modest_account_mgr_get_default_account (account_mgr);
2768 if (!account_name) {
2769 modest_msg_edit_window_free_msg_data (edit_window, data);
2770 /* Run account setup wizard */
2771 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2776 /* Get the currently-active transport account for this modest account: */
2777 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2779 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2780 (modest_runtime_get_account_store (),
2781 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2784 if (!transport_account) {
2785 modest_msg_edit_window_free_msg_data (edit_window, data);
2786 /* Run account setup wizard */
2787 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2792 /* Create the mail operation */
2793 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2794 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2796 modest_mail_operation_send_new_mail (mail_operation,
2810 data->priority_flags);
2812 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2813 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2815 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2816 const GError *error = modest_mail_operation_get_error (mail_operation);
2817 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2818 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2819 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2820 modest_platform_information_banner (NULL, NULL, _CS_NOT_ENOUGH_MEMORY);
2826 g_free (account_name);
2827 g_object_unref (G_OBJECT (transport_account));
2828 g_object_unref (G_OBJECT (mail_operation));
2830 modest_msg_edit_window_free_msg_data (edit_window, data);
2833 modest_msg_edit_window_set_sent (edit_window, TRUE);
2835 /* Save settings and close the window: */
2836 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2843 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2844 ModestMsgEditWindow *window)
2846 ModestMsgEditFormatState *format_state = NULL;
2848 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2849 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2851 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2854 format_state = modest_msg_edit_window_get_format_state (window);
2855 g_return_if_fail (format_state != NULL);
2857 format_state->bold = gtk_toggle_action_get_active (action);
2858 modest_msg_edit_window_set_format_state (window, format_state);
2859 g_free (format_state);
2864 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2865 ModestMsgEditWindow *window)
2867 ModestMsgEditFormatState *format_state = NULL;
2869 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2870 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2872 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2875 format_state = modest_msg_edit_window_get_format_state (window);
2876 g_return_if_fail (format_state != NULL);
2878 format_state->italics = gtk_toggle_action_get_active (action);
2879 modest_msg_edit_window_set_format_state (window, format_state);
2880 g_free (format_state);
2885 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2886 ModestMsgEditWindow *window)
2888 ModestMsgEditFormatState *format_state = NULL;
2890 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2891 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2893 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2896 format_state = modest_msg_edit_window_get_format_state (window);
2897 g_return_if_fail (format_state != NULL);
2899 format_state->bullet = gtk_toggle_action_get_active (action);
2900 modest_msg_edit_window_set_format_state (window, format_state);
2901 g_free (format_state);
2906 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2907 GtkRadioAction *selected,
2908 ModestMsgEditWindow *window)
2910 ModestMsgEditFormatState *format_state = NULL;
2911 GtkJustification value;
2913 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2915 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2918 value = gtk_radio_action_get_current_value (selected);
2920 format_state = modest_msg_edit_window_get_format_state (window);
2921 g_return_if_fail (format_state != NULL);
2923 format_state->justification = value;
2924 modest_msg_edit_window_set_format_state (window, format_state);
2925 g_free (format_state);
2929 modest_ui_actions_on_select_editor_color (GtkAction *action,
2930 ModestMsgEditWindow *window)
2932 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2933 g_return_if_fail (GTK_IS_ACTION (action));
2935 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2938 modest_msg_edit_window_select_color (window);
2942 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2943 ModestMsgEditWindow *window)
2945 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2946 g_return_if_fail (GTK_IS_ACTION (action));
2948 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2954 modest_ui_actions_on_insert_image (GObject *object,
2955 ModestMsgEditWindow *window)
2957 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2960 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2963 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2966 modest_msg_edit_window_insert_image (window);
2970 modest_ui_actions_on_attach_file (GtkAction *action,
2971 ModestMsgEditWindow *window)
2973 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2974 g_return_if_fail (GTK_IS_ACTION (action));
2976 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2979 modest_msg_edit_window_offer_attach_file (window);
2983 modest_ui_actions_on_remove_attachments (GtkAction *action,
2984 ModestMsgEditWindow *window)
2986 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2988 modest_msg_edit_window_remove_attachments (window, NULL);
2992 do_create_folder_cb (ModestMailOperation *mail_op,
2993 TnyFolderStore *parent_folder,
2994 TnyFolder *new_folder,
2997 gchar *suggested_name = (gchar *) user_data;
2998 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
2999 const GError *error;
3001 error = modest_mail_operation_get_error (mail_op);
3003 gboolean disk_full = FALSE;
3004 TnyAccount *account;
3005 /* Show an error. If there was some problem writing to
3006 disk, show it, otherwise show the generic folder
3007 create error. We do it here and not in an error
3008 handler because the call to do_create_folder will
3009 stop the main loop in a gtk_dialog_run and then,
3010 the message won't be shown until that dialog is
3012 account = modest_mail_operation_get_account (mail_op);
3015 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3016 (GtkWidget *) source_win,
3019 _("mail_in_ui_folder_create_error_memory"));
3020 g_object_unref (account);
3023 /* Show an error and try again if there is no
3024 full memory condition */
3025 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3026 _("mail_in_ui_folder_create_error"));
3027 do_create_folder ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (source_win)),
3028 parent_folder, (const gchar *) suggested_name);
3032 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3033 * FIXME: any other? */
3034 GtkWidget *folder_view;
3036 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3037 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3039 /* Select the newly created folder. It could happen
3040 that the widget is no longer there (i.e. the window
3041 has been destroyed, so we need to check this */
3043 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3045 g_object_unref (new_folder);
3047 /* Free. Note that the first time it'll be NULL so noop */
3048 g_free (suggested_name);
3049 g_object_unref (source_win);
3054 TnyFolderStore *parent;
3055 } CreateFolderConnect;
3058 do_create_folder_performer (gboolean canceled,
3060 GtkWindow *parent_window,
3061 TnyAccount *account,
3064 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3065 ModestMailOperation *mail_op;
3067 if (canceled || err) {
3068 /* In disk full conditions we could get this error here */
3069 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3070 (GtkWidget *) parent_window, err,
3071 NULL, _("mail_in_ui_folder_create_error_memory"));
3073 /* This happens if we have selected the outbox folder
3075 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3076 TNY_IS_MERGE_FOLDER (helper->parent)) {
3077 /* Show an error and retry */
3078 modest_platform_information_banner ((GtkWidget *) parent_window,
3080 _("mail_in_ui_folder_create_error"));
3082 do_create_folder (parent_window, helper->parent, helper->folder_name);
3088 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3089 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3091 modest_mail_operation_create_folder (mail_op,
3093 (const gchar *) helper->folder_name,
3094 do_create_folder_cb,
3095 g_strdup (helper->folder_name));
3096 g_object_unref (mail_op);
3100 g_object_unref (helper->parent);
3101 if (helper->folder_name)
3102 g_free (helper->folder_name);
3103 g_slice_free (CreateFolderConnect, helper);
3108 do_create_folder (GtkWindow *parent_window,
3109 TnyFolderStore *suggested_parent,
3110 const gchar *suggested_name)
3113 gchar *folder_name = NULL;
3114 TnyFolderStore *parent_folder = NULL;
3116 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3118 (gchar *) suggested_name,
3122 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3123 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3124 helper->folder_name = g_strdup (folder_name);
3125 helper->parent = g_object_ref (parent_folder);
3127 modest_platform_connect_if_remote_and_perform (parent_window,
3130 do_create_folder_performer,
3135 g_free (folder_name);
3137 g_object_unref (parent_folder);
3141 modest_ui_actions_create_folder(GtkWindow *parent_window,
3142 GtkWidget *folder_view,
3143 TnyFolderStore *parent_folder)
3145 if (!parent_folder) {
3146 ModestTnyAccountStore *acc_store;
3148 acc_store = modest_runtime_get_account_store ();
3150 parent_folder = (TnyFolderStore *)
3151 modest_tny_account_store_get_local_folders_account (acc_store);
3154 if (parent_folder) {
3155 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3156 g_object_unref (parent_folder);
3161 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3164 g_return_if_fail (MODEST_IS_WINDOW(window));
3166 if (MODEST_IS_FOLDER_WINDOW (window)) {
3167 GtkWidget *folder_view;
3168 GtkWindow *toplevel;
3170 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3171 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
3172 modest_ui_actions_create_folder (toplevel, folder_view, NULL);
3174 g_assert_not_reached ();
3179 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3182 const GError *error = NULL;
3183 gchar *message = NULL;
3185 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3187 /* Get error message */
3188 error = modest_mail_operation_get_error (mail_op);
3190 g_return_if_reached ();
3192 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3193 (GError *) error, account);
3195 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3196 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3197 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3198 message = _CS_FOLDER_ALREADY_EXISTS;
3199 } else if (error->domain == TNY_ERROR_DOMAIN &&
3200 error->code == TNY_SERVICE_ERROR_STATE) {
3201 /* This means that the folder is already in use (a
3202 message is opened for example */
3203 message = _("emev_ni_internal_error");
3205 message = _CS_UNABLE_TO_RENAME;
3208 /* We don't set a parent for the dialog because the dialog
3209 will be destroyed so the banner won't appear */
3210 modest_platform_information_banner (NULL, NULL, message);
3213 g_object_unref (account);
3219 TnyFolderStore *folder;
3224 on_rename_folder_cb (ModestMailOperation *mail_op,
3225 TnyFolder *new_folder,
3228 ModestFolderView *folder_view;
3230 /* If the window was closed when renaming a folder, or if
3231 * it's not a main window this will happen */
3232 if (!MODEST_IS_FOLDER_VIEW (user_data))
3235 folder_view = MODEST_FOLDER_VIEW (user_data);
3236 /* Note that if the rename fails new_folder will be NULL */
3238 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3240 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3244 on_rename_folder_performer (gboolean canceled,
3246 GtkWindow *parent_window,
3247 TnyAccount *account,
3250 ModestMailOperation *mail_op = NULL;
3251 GtkTreeSelection *sel = NULL;
3252 GtkWidget *folder_view = NULL;
3253 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3255 if (canceled || err) {
3256 /* In disk full conditions we could get this error here */
3257 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3258 (GtkWidget *) parent_window, err,
3263 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3264 modest_ui_actions_rename_folder_error_handler,
3265 parent_window, NULL);
3267 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3269 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3270 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3271 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3274 /* Clear the folders view */
3275 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3276 gtk_tree_selection_unselect_all (sel);
3278 /* Actually rename the folder */
3279 modest_mail_operation_rename_folder (mail_op,
3280 TNY_FOLDER (data->folder),
3281 (const gchar *) (data->new_name),
3282 on_rename_folder_cb,
3284 g_object_unref (mail_op);
3287 g_object_unref (data->folder);
3288 g_free (data->new_name);
3293 modest_ui_actions_on_rename_folder (GtkAction *action,
3294 ModestWindow *window)
3296 modest_ui_actions_on_edit_mode_rename_folder (window);
3300 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3302 TnyFolderStore *folder;
3303 GtkWidget *folder_view;
3304 gboolean do_rename = TRUE;
3306 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3308 if (MODEST_IS_FOLDER_WINDOW (window)) {
3309 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3314 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3319 if (TNY_IS_FOLDER (folder)) {
3320 gchar *folder_name = NULL;
3322 const gchar *current_name;
3323 TnyFolderStore *parent;
3325 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3326 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3327 response = modest_platform_run_rename_folder_dialog (MODEST_WINDOW (window),
3328 parent, current_name,
3330 g_object_unref (parent);
3332 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3335 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3336 rename_folder_data->folder = g_object_ref (folder);
3337 rename_folder_data->new_name = folder_name;
3338 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3339 folder, on_rename_folder_performer, rename_folder_data);
3342 g_object_unref (folder);
3347 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3350 GObject *win = modest_mail_operation_get_source (mail_op);
3352 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3353 _("mail_in_ui_folder_delete_error"),
3355 g_object_unref (win);
3359 TnyFolderStore *folder;
3360 gboolean move_to_trash;
3364 on_delete_folder_cb (gboolean canceled,
3366 GtkWindow *parent_window,
3367 TnyAccount *account,
3370 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3371 GtkWidget *folder_view;
3372 ModestMailOperation *mail_op;
3373 GtkTreeSelection *sel;
3375 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3376 /* Note that the connection process can fail due to
3377 memory low conditions as it can not successfully
3378 store the summary */
3379 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3380 (GtkWidget*) parent_window, err,
3382 g_debug ("Error connecting when trying to delete a folder");
3383 g_object_unref (G_OBJECT (info->folder));
3388 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3389 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3391 g_object_unref (G_OBJECT (info->folder));
3396 /* Unselect the folder before deleting it to free the headers */
3397 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3398 gtk_tree_selection_unselect_all (sel);
3400 /* Create the mail operation */
3402 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3403 modest_ui_actions_delete_folder_error_handler,
3406 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3408 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3410 g_object_unref (mail_op);
3411 g_object_unref (info->folder);
3416 delete_folder (ModestWindow *window, gboolean move_to_trash)
3418 TnyFolderStore *folder;
3419 GtkWidget *folder_view;
3423 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3425 if (MODEST_IS_FOLDER_WINDOW (window)) {
3426 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3433 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3438 /* Show an error if it's an account */
3439 if (!TNY_IS_FOLDER (folder)) {
3440 modest_platform_run_information_dialog (GTK_WINDOW (window),
3441 _("mail_in_ui_folder_delete_error"),
3443 g_object_unref (G_OBJECT (folder));
3448 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3449 tny_folder_get_name (TNY_FOLDER (folder)));
3450 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3451 (const gchar *) message);
3454 if (response == GTK_RESPONSE_OK) {
3455 TnyAccount *account = NULL;
3456 DeleteFolderInfo *info = NULL;
3457 info = g_new0(DeleteFolderInfo, 1);
3458 info->folder = g_object_ref (folder);
3459 info->move_to_trash = move_to_trash;
3461 account = tny_folder_get_account (TNY_FOLDER (folder));
3462 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3464 TNY_FOLDER_STORE (account),
3465 on_delete_folder_cb, info);
3466 g_object_unref (account);
3467 g_object_unref (folder);
3475 modest_ui_actions_on_delete_folder (GtkAction *action,
3476 ModestWindow *window)
3478 modest_ui_actions_on_edit_mode_delete_folder (window);
3482 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3484 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3486 return delete_folder (window, FALSE);
3490 typedef struct _PasswordDialogFields {
3491 GtkWidget *username;
3492 GtkWidget *password;
3494 } PasswordDialogFields;
3497 password_dialog_check_field (GtkEditable *editable,
3498 PasswordDialogFields *fields)
3501 gboolean any_value_empty = FALSE;
3503 value = modest_entry_get_text (fields->username);
3504 if ((value == NULL) || value[0] == '\0') {
3505 any_value_empty = TRUE;
3507 value = modest_entry_get_text (fields->password);
3508 if ((value == NULL) || value[0] == '\0') {
3509 any_value_empty = TRUE;
3511 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3515 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3516 const gchar* server_account_name,
3521 ModestMainWindow *main_window)
3523 g_return_if_fail(server_account_name);
3524 gboolean completed = FALSE;
3525 PasswordDialogFields *fields = NULL;
3527 /* Initalize output parameters: */
3534 #ifndef MODEST_TOOLKIT_GTK
3535 /* Maemo uses a different (awkward) button order,
3536 * It should probably just use gtk_alternative_dialog_button_order ().
3538 #ifdef MODEST_TOOLKIT_HILDON2
3540 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3544 GTK_RESPONSE_ACCEPT,
3546 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3547 HILDON_MARGIN_DOUBLE);
3550 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3553 _("mcen_bd_dialog_ok"),
3554 GTK_RESPONSE_ACCEPT,
3555 _("mcen_bd_dialog_cancel"),
3556 GTK_RESPONSE_REJECT,
3558 #endif /* MODEST_TOOLKIT_HILDON2 */
3561 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3565 GTK_RESPONSE_REJECT,
3567 GTK_RESPONSE_ACCEPT,
3569 #endif /* MODEST_TOOLKIT_GTK */
3571 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3573 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3574 modest_runtime_get_account_mgr(), server_account_name);
3575 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3576 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3579 gtk_widget_destroy (dialog);
3583 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3584 GtkWidget *label = gtk_label_new (txt);
3585 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3587 g_free (server_name);
3588 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3593 gchar *initial_username = modest_account_mgr_get_server_account_username (
3594 modest_runtime_get_account_mgr(), server_account_name);
3596 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3597 if (initial_username)
3598 modest_entry_set_text (entry_username, initial_username);
3600 /* Dim this if a connection has ever succeeded with this username,
3601 * as per the UI spec: */
3602 /* const gboolean username_known = */
3603 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3604 /* modest_runtime_get_account_mgr(), server_account_name); */
3605 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3607 /* We drop the username sensitive code and disallow changing it here
3608 * as tinymail does not support really changing the username in the callback
3610 gtk_widget_set_sensitive (entry_username, FALSE);
3612 /* Auto-capitalization is the default, so let's turn it off: */
3613 #ifdef MAEMO_CHANGES
3614 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3617 /* Create a size group to be used by all captions.
3618 * Note that HildonCaption does not create a default size group if we do not specify one.
3619 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3620 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3622 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3623 _("mail_fi_username"), FALSE,
3625 gtk_widget_show (entry_username);
3626 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3627 FALSE, FALSE, MODEST_MARGIN_HALF);
3628 gtk_widget_show (caption);
3631 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3632 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3633 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3635 /* Auto-capitalization is the default, so let's turn it off: */
3636 #ifdef MAEMO_CHANGES
3637 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3638 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3641 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3642 _("mail_fi_password"), FALSE,
3644 gtk_widget_show (entry_password);
3645 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3646 FALSE, FALSE, MODEST_MARGIN_HALF);
3647 gtk_widget_show (caption);
3648 g_object_unref (sizegroup);
3650 if (initial_username != NULL)
3651 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3653 /* This is not in the Maemo UI spec:
3654 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3655 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3659 fields = g_slice_new0 (PasswordDialogFields);
3660 fields->username = entry_username;
3661 fields->password = entry_password;
3662 fields->dialog = dialog;
3664 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3665 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3666 password_dialog_check_field (NULL, fields);
3668 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3670 while (!completed) {
3672 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3674 *username = g_strdup (modest_entry_get_text (entry_username));
3676 /* Note that an empty field becomes the "" string */
3677 if (*username && strlen (*username) > 0) {
3678 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3679 server_account_name,
3683 const gboolean username_was_changed =
3684 (strcmp (*username, initial_username) != 0);
3685 if (username_was_changed) {
3686 g_warning ("%s: tinymail does not yet support changing the "
3687 "username in the get_password() callback.\n", __FUNCTION__);
3693 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3694 _("mcen_ib_username_pw_incorrect"));
3700 *password = g_strdup (modest_entry_get_text (entry_password));
3702 /* We do not save the password in the configuration,
3703 * because this function is only called for passwords that should
3704 * not be remembered:
3705 modest_server_account_set_password (
3706 modest_runtime_get_account_mgr(), server_account_name,
3723 /* This is not in the Maemo UI spec:
3724 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3730 g_free (initial_username);
3731 gtk_widget_destroy (dialog);
3732 g_slice_free (PasswordDialogFields, fields);
3734 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3738 modest_ui_actions_on_cut (GtkAction *action,
3739 ModestWindow *window)
3741 GtkWidget *focused_widget;
3742 GtkClipboard *clipboard;
3744 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3745 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3746 if (GTK_IS_EDITABLE (focused_widget)) {
3747 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3748 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3749 gtk_clipboard_store (clipboard);
3750 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3751 GtkTextBuffer *buffer;
3753 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3754 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3755 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3756 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3757 gtk_clipboard_store (clipboard);
3759 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3760 TnyList *header_list = modest_header_view_get_selected_headers (
3761 MODEST_HEADER_VIEW (focused_widget));
3762 gboolean continue_download = FALSE;
3763 gint num_of_unc_msgs;
3765 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3767 if (num_of_unc_msgs) {
3768 TnyAccount *account = get_account_from_header_list (header_list);
3770 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3771 g_object_unref (account);
3775 if (num_of_unc_msgs == 0 || continue_download) {
3776 /* modest_platform_information_banner (
3777 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3778 modest_header_view_cut_selection (
3779 MODEST_HEADER_VIEW (focused_widget));
3782 g_object_unref (header_list);
3783 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3784 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3789 modest_ui_actions_on_copy (GtkAction *action,
3790 ModestWindow *window)
3792 GtkClipboard *clipboard;
3793 GtkWidget *focused_widget;
3794 gboolean copied = TRUE;
3796 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3797 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3799 if (GTK_IS_LABEL (focused_widget)) {
3801 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3802 gtk_clipboard_set_text (clipboard, selection, -1);
3804 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3805 gtk_clipboard_store (clipboard);
3806 } else if (GTK_IS_EDITABLE (focused_widget)) {
3807 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3808 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3809 gtk_clipboard_store (clipboard);
3810 } else if (GTK_IS_HTML (focused_widget)) {
3813 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3814 if ((sel == NULL) || (sel[0] == '\0')) {
3817 gtk_html_copy (GTK_HTML (focused_widget));
3818 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3819 gtk_clipboard_store (clipboard);
3821 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3822 GtkTextBuffer *buffer;
3823 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3824 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3825 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3826 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3827 gtk_clipboard_store (clipboard);
3829 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3830 TnyList *header_list = modest_header_view_get_selected_headers (
3831 MODEST_HEADER_VIEW (focused_widget));
3832 gboolean continue_download = FALSE;
3833 gint num_of_unc_msgs;
3835 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3837 if (num_of_unc_msgs) {
3838 TnyAccount *account = get_account_from_header_list (header_list);
3840 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3841 g_object_unref (account);
3845 if (num_of_unc_msgs == 0 || continue_download) {
3846 modest_platform_information_banner (
3847 NULL, NULL, _CS_GETTING_ITEMS);
3848 modest_header_view_copy_selection (
3849 MODEST_HEADER_VIEW (focused_widget));
3853 g_object_unref (header_list);
3855 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3856 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3859 /* Show information banner if there was a copy to clipboard */
3861 modest_platform_information_banner (
3862 NULL, NULL, _CS_COPIED);
3866 modest_ui_actions_on_undo (GtkAction *action,
3867 ModestWindow *window)
3869 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3870 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3872 g_return_if_reached ();
3877 modest_ui_actions_on_redo (GtkAction *action,
3878 ModestWindow *window)
3880 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3881 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3884 g_return_if_reached ();
3890 destroy_information_note (ModestMailOperation *mail_op,
3893 /* destroy information note */
3894 gtk_widget_destroy (GTK_WIDGET(user_data));
3898 destroy_folder_information_note (ModestMailOperation *mail_op,
3899 TnyFolder *new_folder,
3902 /* destroy information note */
3903 gtk_widget_destroy (GTK_WIDGET(user_data));
3908 paste_as_attachment_free (gpointer data)
3910 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3912 if (helper->banner) {
3913 gtk_widget_destroy (helper->banner);
3914 g_object_unref (helper->banner);
3920 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3925 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3926 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3931 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3936 modest_ui_actions_on_paste (GtkAction *action,
3937 ModestWindow *window)
3939 GtkWidget *focused_widget = NULL;
3940 GtkWidget *inf_note = NULL;
3941 ModestMailOperation *mail_op = NULL;
3943 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3944 if (GTK_IS_EDITABLE (focused_widget)) {
3945 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3946 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3947 ModestEmailClipboard *e_clipboard = NULL;
3948 e_clipboard = modest_runtime_get_email_clipboard ();
3949 if (modest_email_clipboard_cleared (e_clipboard)) {
3950 GtkTextBuffer *buffer;
3951 GtkClipboard *clipboard;
3953 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3954 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3955 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3956 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3957 ModestMailOperation *mail_op;
3958 TnyFolder *src_folder = NULL;
3959 TnyList *data = NULL;
3961 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3962 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3963 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3965 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3966 mail_op = modest_mail_operation_new (G_OBJECT (window));
3967 if (helper->banner != NULL) {
3968 g_object_ref (G_OBJECT (helper->banner));
3969 gtk_widget_show (GTK_WIDGET (helper->banner));
3973 modest_mail_operation_get_msgs_full (mail_op,
3975 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3977 paste_as_attachment_free);
3981 g_object_unref (data);
3983 g_object_unref (src_folder);
3986 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3987 ModestEmailClipboard *clipboard = NULL;
3988 TnyFolder *src_folder = NULL;
3989 TnyFolderStore *folder_store = NULL;
3990 TnyList *data = NULL;
3991 gboolean delete = FALSE;
3993 /* Check clipboard source */
3994 clipboard = modest_runtime_get_email_clipboard ();
3995 if (modest_email_clipboard_cleared (clipboard))
3998 /* Get elements to paste */
3999 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4001 /* Create a new mail operation */
4002 mail_op = modest_mail_operation_new (G_OBJECT(window));
4004 /* Get destination folder */
4005 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4007 /* transfer messages */
4011 /* Ask for user confirmation */
4013 modest_ui_actions_msgs_move_to_confirmation (window,
4014 TNY_FOLDER (folder_store),
4018 if (response == GTK_RESPONSE_OK) {
4019 /* Launch notification */
4020 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4022 if (inf_note != NULL) {
4023 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4024 gtk_widget_show (GTK_WIDGET(inf_note));
4027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4028 modest_mail_operation_xfer_msgs (mail_op,
4030 TNY_FOLDER (folder_store),
4032 destroy_information_note,
4035 g_object_unref (mail_op);
4038 } else if (src_folder != NULL) {
4039 /* Launch notification */
4040 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4042 if (inf_note != NULL) {
4043 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4044 gtk_widget_show (GTK_WIDGET(inf_note));
4047 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4048 modest_mail_operation_xfer_folder (mail_op,
4052 destroy_folder_information_note,
4058 g_object_unref (data);
4059 if (src_folder != NULL)
4060 g_object_unref (src_folder);
4061 if (folder_store != NULL)
4062 g_object_unref (folder_store);
4068 modest_ui_actions_on_select_all (GtkAction *action,
4069 ModestWindow *window)
4071 GtkWidget *focused_widget;
4073 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4074 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4075 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4076 } else if (GTK_IS_LABEL (focused_widget)) {
4077 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4078 } else if (GTK_IS_EDITABLE (focused_widget)) {
4079 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4080 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4081 GtkTextBuffer *buffer;
4082 GtkTextIter start, end;
4084 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4085 gtk_text_buffer_get_start_iter (buffer, &start);
4086 gtk_text_buffer_get_end_iter (buffer, &end);
4087 gtk_text_buffer_select_range (buffer, &start, &end);
4088 } else if (GTK_IS_HTML (focused_widget)) {
4089 gtk_html_select_all (GTK_HTML (focused_widget));
4095 modest_ui_actions_on_mark_as_read (GtkAction *action,
4096 ModestWindow *window)
4098 g_return_if_fail (MODEST_IS_WINDOW(window));
4100 /* Mark each header as read */
4101 do_headers_action (window, headers_action_mark_as_read, NULL);
4105 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4106 ModestWindow *window)
4108 g_return_if_fail (MODEST_IS_WINDOW(window));
4110 /* Mark each header as read */
4111 do_headers_action (window, headers_action_mark_as_unread, NULL);
4115 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4116 GtkRadioAction *selected,
4117 ModestWindow *window)
4121 value = gtk_radio_action_get_current_value (selected);
4122 if (MODEST_IS_WINDOW (window)) {
4123 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4128 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4129 GtkRadioAction *selected,
4130 ModestWindow *window)
4132 TnyHeaderFlags flags;
4133 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4135 flags = gtk_radio_action_get_current_value (selected);
4136 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4140 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4141 GtkRadioAction *selected,
4142 ModestWindow *window)
4146 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4148 file_format = gtk_radio_action_get_current_value (selected);
4149 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4154 modest_ui_actions_on_zoom_plus (GtkAction *action,
4155 ModestWindow *window)
4157 g_return_if_fail (MODEST_IS_WINDOW (window));
4159 modest_window_zoom_plus (MODEST_WINDOW (window));
4163 modest_ui_actions_on_zoom_minus (GtkAction *action,
4164 ModestWindow *window)
4166 g_return_if_fail (MODEST_IS_WINDOW (window));
4168 modest_window_zoom_minus (MODEST_WINDOW (window));
4172 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4173 ModestWindow *window)
4175 ModestWindowMgr *mgr;
4176 gboolean fullscreen, active;
4177 g_return_if_fail (MODEST_IS_WINDOW (window));
4179 mgr = modest_runtime_get_window_mgr ();
4181 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4182 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4184 if (active != fullscreen) {
4185 modest_window_mgr_set_fullscreen_mode (mgr, active);
4186 #ifndef MODEST_TOOLKIT_HILDON2
4187 gtk_window_present (GTK_WINDOW (window));
4193 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4194 ModestWindow *window)
4196 ModestWindowMgr *mgr;
4197 gboolean fullscreen;
4199 g_return_if_fail (MODEST_IS_WINDOW (window));
4201 mgr = modest_runtime_get_window_mgr ();
4202 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4203 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4208 * Used by modest_ui_actions_on_details to call do_headers_action
4211 headers_action_show_details (TnyHeader *header,
4212 ModestWindow *window,
4216 gboolean async_retrieval;
4217 GtkWindow *toplevel;
4220 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4221 async_retrieval = TRUE;
4222 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4224 async_retrieval = FALSE;
4226 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4227 modest_platform_run_header_details_dialog (toplevel, header, async_retrieval, msg);
4229 g_object_unref (msg);
4233 * Show the header details in a ModestDetailsDialog widget
4236 modest_ui_actions_on_details (GtkAction *action,
4239 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4243 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4247 header = tny_msg_get_header (msg);
4249 headers_action_show_details (header, win, NULL);
4250 g_object_unref (header);
4252 g_object_unref (msg);
4253 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4255 GtkWidget *header_view;
4257 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4258 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4260 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4262 modest_platform_run_folder_details_dialog (toplevel, folder);
4263 g_object_unref (folder);
4269 modest_ui_actions_on_limit_error (GtkAction *action,
4272 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4274 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS_MAXIMUM_CHARACTERS_REACHED);
4279 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4280 ModestMsgEditWindow *window)
4282 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4284 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4288 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4289 ModestMsgEditWindow *window)
4291 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4293 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4298 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4299 ModestWindow *window)
4301 gboolean active, fullscreen = FALSE;
4302 ModestWindowMgr *mgr;
4304 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4306 /* Check if we want to toggle the toolbar view in fullscreen
4308 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4309 "ViewShowToolbarFullScreen")) {
4313 /* Toggle toolbar */
4314 mgr = modest_runtime_get_window_mgr ();
4315 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4319 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4320 ModestMsgEditWindow *window)
4322 modest_msg_edit_window_select_font (window);
4327 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4328 const gchar *display_name,
4331 /* don't update the display name if it was already set;
4332 * updating the display name apparently is expensive */
4333 const gchar* old_name = gtk_window_get_title (window);
4335 if (display_name == NULL)
4338 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4339 return; /* don't do anything */
4341 /* This is usually used to change the title of the main window, which
4342 * is the one that holds the folder view. Note that this change can
4343 * happen even when the widget doesn't have the focus. */
4344 gtk_window_set_title (window, display_name);
4349 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4351 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4352 modest_msg_edit_window_select_contacts (window);
4356 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4358 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4359 modest_msg_edit_window_check_names (window, FALSE);
4364 on_move_to_dialog_response (GtkDialog *dialog,
4368 GtkWidget *parent_win;
4369 MoveToInfo *helper = NULL;
4370 ModestFolderView *folder_view;
4371 gboolean unset_edit_mode = FALSE;
4373 helper = (MoveToInfo *) user_data;
4375 parent_win = (GtkWidget *) helper->win;
4376 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4377 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4379 TnyFolderStore *dst_folder;
4380 TnyFolderStore *selected;
4382 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4383 selected = modest_folder_view_get_selected (folder_view);
4384 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4385 g_object_unref (selected);
4387 case GTK_RESPONSE_NONE:
4388 case GTK_RESPONSE_CANCEL:
4389 case GTK_RESPONSE_DELETE_EVENT:
4391 case GTK_RESPONSE_OK:
4392 dst_folder = modest_folder_view_get_selected (folder_view);
4394 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4395 /* Clean list to move used for filtering */
4396 modest_folder_view_set_list_to_move (folder_view, NULL);
4398 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4401 GTK_WINDOW (parent_win));
4403 /* if the user selected a root folder
4404 (account) then do not perform any action */
4405 if (TNY_IS_ACCOUNT (dst_folder)) {
4406 g_signal_stop_emission_by_name (dialog, "response");
4410 /* Clean list to move used for filtering */
4411 modest_folder_view_set_list_to_move (folder_view, NULL);
4413 /* Moving from headers window in edit mode */
4414 modest_ui_actions_on_window_move_to (NULL, helper->list,
4416 MODEST_WINDOW (parent_win));
4420 g_object_unref (dst_folder);
4422 unset_edit_mode = TRUE;
4425 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4428 /* Free the helper and exit */
4430 g_object_unref (helper->list);
4431 if (unset_edit_mode) {
4432 #ifdef MODEST_TOOLKIT_HILDON2
4433 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4436 g_slice_free (MoveToInfo, helper);
4437 gtk_widget_destroy (GTK_WIDGET (dialog));
4441 create_move_to_dialog (GtkWindow *win,
4442 GtkWidget *folder_view,
4443 TnyList *list_to_move)
4445 GtkWidget *dialog, *tree_view = NULL;
4447 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4450 /* It could happen that we're trying to move a message from a
4451 window (msg window for example) after the main window was
4452 closed, so we can not just get the model of the folder
4454 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4455 const gchar *visible_id = NULL;
4457 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4458 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4459 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4460 MODEST_FOLDER_VIEW(tree_view));
4463 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4465 /* Show the same account than the one that is shown in the main window */
4466 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4469 const gchar *active_account_name = NULL;
4470 ModestAccountMgr *mgr = NULL;
4471 ModestAccountSettings *settings = NULL;
4472 ModestServerAccountSettings *store_settings = NULL;
4474 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4475 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4476 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4477 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4479 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4480 mgr = modest_runtime_get_account_mgr ();
4481 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4484 const gchar *store_account_name;
4485 store_settings = modest_account_settings_get_store_settings (settings);
4486 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4488 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4489 store_account_name);
4490 g_object_unref (store_settings);
4491 g_object_unref (settings);
4495 /* we keep a pointer to the embedded folder view, so we can
4496 * retrieve it with get_folder_view_from_move_to_dialog (see
4497 * above) later (needed for focus handling)
4499 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4501 /* Hide special folders */
4503 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4505 gtk_widget_show (GTK_WIDGET (tree_view));
4511 * Shows a confirmation dialog to the user when we're moving messages
4512 * from a remote server to the local storage. Returns the dialog
4513 * response. If it's other kind of movement then it always returns
4516 * This one is used by the next functions:
4517 * modest_ui_actions_on_paste - commented out
4518 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4521 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4522 TnyFolder *dest_folder,
4526 gint response = GTK_RESPONSE_OK;
4527 TnyAccount *account = NULL;
4528 TnyFolder *src_folder = NULL;
4529 TnyIterator *iter = NULL;
4530 TnyHeader *header = NULL;
4532 /* return with OK if the destination is a remote folder */
4533 if (modest_tny_folder_is_remote_folder (dest_folder))
4534 return GTK_RESPONSE_OK;
4536 /* Get source folder */
4537 iter = tny_list_create_iterator (headers);
4538 header = TNY_HEADER (tny_iterator_get_current (iter));
4540 src_folder = tny_header_get_folder (header);
4541 g_object_unref (header);
4543 g_object_unref (iter);
4545 /* if no src_folder, message may be an attahcment */
4546 if (src_folder == NULL)
4547 return GTK_RESPONSE_CANCEL;
4549 /* If the source is a local or MMC folder */
4550 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4551 g_object_unref (src_folder);
4552 return GTK_RESPONSE_OK;
4555 /* Get the account */
4556 account = tny_folder_get_account (src_folder);
4558 /* now if offline we ask the user */
4559 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4560 response = GTK_RESPONSE_OK;
4562 response = GTK_RESPONSE_CANCEL;
4565 g_object_unref (src_folder);
4566 g_object_unref (account);
4572 move_to_helper_destroyer (gpointer user_data)
4574 MoveToHelper *helper = (MoveToHelper *) user_data;
4576 /* Close the "Pasting" information banner */
4577 if (helper->banner) {
4578 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4579 g_object_unref (helper->banner);
4581 if (gtk_tree_row_reference_valid (helper->reference)) {
4582 gtk_tree_row_reference_free (helper->reference);
4583 helper->reference = NULL;
4589 move_to_cb (ModestMailOperation *mail_op,
4592 MoveToHelper *helper = (MoveToHelper *) user_data;
4593 GObject *object = modest_mail_operation_get_source (mail_op);
4595 /* Note that the operation could have failed, in that case do
4597 if (modest_mail_operation_get_status (mail_op) !=
4598 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4601 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4602 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4604 if (!modest_msg_view_window_select_next_message (self) &&
4605 !modest_msg_view_window_select_previous_message (self)) {
4606 /* No more messages to view, so close this window */
4607 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4610 g_object_unref (object);
4613 /* Destroy the helper */
4614 move_to_helper_destroyer (helper);
4618 folder_move_to_cb (ModestMailOperation *mail_op,
4619 TnyFolder *new_folder,
4624 object = modest_mail_operation_get_source (mail_op);
4626 move_to_cb (mail_op, user_data);
4631 msgs_move_to_cb (ModestMailOperation *mail_op,
4634 move_to_cb (mail_op, user_data);
4638 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4641 GObject *win = NULL;
4642 const GError *error;
4643 TnyAccount *account = NULL;
4645 win = modest_mail_operation_get_source (mail_op);
4646 error = modest_mail_operation_get_error (mail_op);
4648 if (TNY_IS_FOLDER (user_data))
4649 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4650 else if (TNY_IS_ACCOUNT (user_data))
4651 account = g_object_ref (user_data);
4653 /* If it's not a disk full error then show a generic error */
4654 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4655 (GtkWidget *) win, (GError *) error,
4657 modest_platform_run_information_dialog ((GtkWindow *) win,
4658 _("mail_in_ui_folder_move_target_error"),
4661 g_object_unref (account);
4663 g_object_unref (win);
4668 * Checks if we need a connection to do the transfer and if the user
4669 * wants to connect to complete it
4672 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
4673 TnyFolderStore *src_folder,
4675 TnyFolder *dst_folder,
4676 gboolean delete_originals,
4677 gboolean *need_connection,
4680 TnyAccount *src_account;
4681 gint uncached_msgs = 0;
4683 /* We don't need any further check if
4685 * 1- the source folder is local OR
4686 * 2- the device is already online
4688 if (!modest_tny_folder_store_is_remote (src_folder) ||
4689 tny_device_is_online (modest_runtime_get_device())) {
4690 *need_connection = FALSE;
4695 /* We must ask for a connection when
4697 * - the message(s) is not already cached OR
4698 * - the message(s) is cached but the leave_on_server setting
4699 * is FALSE (because we need to sync the source folder to
4700 * delete the message from the server (for IMAP we could do it
4701 * offline, it'll take place the next time we get a
4704 uncached_msgs = header_list_count_uncached_msgs (headers);
4705 src_account = get_account_from_folder_store (src_folder);
4706 if (uncached_msgs > 0) {
4710 *need_connection = TRUE;
4711 num_headers = tny_list_get_length (headers);
4712 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4714 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
4715 GTK_RESPONSE_CANCEL) {
4721 /* The transfer is possible and the user wants to */
4724 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4725 const gchar *account_name;
4726 gboolean leave_on_server;
4728 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4729 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4732 if (leave_on_server == TRUE) {
4733 *need_connection = FALSE;
4735 *need_connection = TRUE;
4738 *need_connection = FALSE;
4743 g_object_unref (src_account);
4747 xfer_messages_error_handler (ModestMailOperation *mail_op,
4751 const GError *error;
4752 TnyAccount *account;
4754 win = modest_mail_operation_get_source (mail_op);
4755 error = modest_mail_operation_get_error (mail_op);
4757 /* We cannot get the account from the mail op as that is the
4758 source account and for checking memory full conditions we
4759 need the destination one */
4760 account = TNY_ACCOUNT (user_data);
4763 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4764 (GtkWidget *) win, (GError*) error,
4765 account, _KR("cerm_memory_card_full"))) {
4766 modest_platform_run_information_dialog ((GtkWindow *) win,
4767 _("mail_in_ui_folder_move_target_error"),
4771 g_object_unref (win);
4775 TnyFolderStore *dst_folder;
4780 * Utility function that transfer messages from both the main window
4781 * and the msg view window when using the "Move to" dialog
4784 xfer_messages_performer (gboolean canceled,
4786 GtkWindow *parent_window,
4787 TnyAccount *account,
4790 ModestWindow *win = MODEST_WINDOW (parent_window);
4791 TnyAccount *dst_account = NULL;
4792 gboolean dst_forbids_message_add = FALSE;
4793 XferMsgsHelper *helper;
4794 MoveToHelper *movehelper;
4795 ModestMailOperation *mail_op;
4797 helper = (XferMsgsHelper *) user_data;
4799 if (canceled || err) {
4800 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4801 (GtkWidget *) parent_window, err,
4803 /* Show the proper error message */
4804 modest_ui_actions_on_account_connection_error (parent_window, account);
4809 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4811 /* tinymail will return NULL for local folders it seems */
4812 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4813 modest_tny_account_get_protocol_type (dst_account),
4814 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4816 if (dst_forbids_message_add) {
4817 modest_platform_information_banner (GTK_WIDGET (win),
4819 ngettext("mail_in_ui_folder_move_target_error",
4820 "mail_in_ui_folder_move_targets_error",
4821 tny_list_get_length (helper->headers)));
4825 movehelper = g_new0 (MoveToHelper, 1);
4828 /* Perform the mail operation */
4829 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4830 xfer_messages_error_handler,
4831 g_object_ref (dst_account),
4833 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4836 modest_mail_operation_xfer_msgs (mail_op,
4838 TNY_FOLDER (helper->dst_folder),
4843 g_object_unref (G_OBJECT (mail_op));
4846 g_object_unref (dst_account);
4847 g_object_unref (helper->dst_folder);
4848 g_object_unref (helper->headers);
4849 g_slice_free (XferMsgsHelper, helper);
4853 TnyFolder *src_folder;
4854 TnyFolderStore *dst_folder;
4855 gboolean delete_original;
4856 GtkWidget *folder_view;
4860 on_move_folder_cb (gboolean canceled,
4862 GtkWindow *parent_window,
4863 TnyAccount *account,
4866 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4867 GtkTreeSelection *sel;
4868 ModestMailOperation *mail_op = NULL;
4870 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4871 /* Note that the connection process can fail due to
4872 memory low conditions as it can not successfully
4873 store the summary */
4874 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4875 (GtkWidget*) parent_window, err,
4877 g_debug ("Error connecting when trying to move a folder");
4879 g_object_unref (G_OBJECT (info->src_folder));
4880 g_object_unref (G_OBJECT (info->dst_folder));
4885 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4886 #ifndef MODEST_TOOLKIT_HILDON2
4887 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4889 if (helper->banner != NULL) {
4890 g_object_ref (helper->banner);
4891 gtk_widget_show (GTK_WIDGET(helper->banner));
4894 /* Clean folder on header view before moving it */
4895 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4896 gtk_tree_selection_unselect_all (sel);
4898 /* Let gtk events run. We need that the folder
4899 view frees its reference to the source
4900 folder *before* issuing the mail operation
4901 so we need the signal handler of selection
4902 changed to happen before the mail
4904 while (gtk_events_pending ())
4905 gtk_main_iteration (); */
4908 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4909 modest_ui_actions_move_folder_error_handler,
4910 g_object_ref (info->dst_folder), g_object_unref);
4911 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4914 modest_mail_operation_xfer_folder (mail_op,
4915 TNY_FOLDER (info->src_folder),
4917 info->delete_original,
4920 g_object_unref (G_OBJECT (info->src_folder));
4922 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4925 /* Unref mail operation */
4926 g_object_unref (G_OBJECT (mail_op));
4927 g_object_unref (G_OBJECT (info->dst_folder));
4932 get_account_from_folder_store (TnyFolderStore *folder_store)
4934 if (TNY_IS_ACCOUNT (folder_store))
4935 return g_object_ref (folder_store);
4937 return tny_folder_get_account (TNY_FOLDER (folder_store));
4941 * UI handler for the "Move to" action when invoked from the
4942 * ModestFolderWindow
4945 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4946 TnyFolderStore *dst_folder,
4950 TnyFolderStore *src_folder = NULL;
4951 TnyIterator *iterator;
4953 if (tny_list_get_length (selection) != 1)
4956 iterator = tny_list_create_iterator (selection);
4957 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
4958 g_object_unref (iterator);
4961 gboolean do_xfer = TRUE;
4963 /* Allow only to transfer folders to the local root folder */
4964 if (TNY_IS_ACCOUNT (dst_folder) &&
4965 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
4966 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
4969 modest_platform_run_information_dialog (win,
4970 _("mail_in_ui_folder_move_target_error"),
4972 } else if (!TNY_IS_FOLDER (src_folder)) {
4973 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4978 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4979 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4981 info->src_folder = g_object_ref (src_folder);
4982 info->dst_folder = g_object_ref (dst_folder);
4983 info->delete_original = TRUE;
4984 info->folder_view = folder_view;
4986 connect_info->callback = on_move_folder_cb;
4987 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
4988 connect_info->data = info;
4990 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4991 TNY_FOLDER_STORE (src_folder),
4996 g_object_unref (src_folder);
5001 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5002 TnyFolder *src_folder,
5004 TnyFolder *dst_folder)
5006 gboolean need_connection = TRUE;
5007 gboolean do_xfer = TRUE;
5008 XferMsgsHelper *helper;
5010 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5011 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5012 g_return_if_fail (TNY_IS_LIST (headers));
5014 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5015 headers, TNY_FOLDER (dst_folder),
5016 TRUE, &need_connection,
5019 /* If we don't want to transfer just return */
5023 /* Create the helper */
5024 helper = g_slice_new (XferMsgsHelper);
5025 helper->dst_folder = g_object_ref (dst_folder);
5026 helper->headers = g_object_ref (headers);
5028 if (need_connection) {
5029 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5030 connect_info->callback = xfer_messages_performer;
5031 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5032 connect_info->data = helper;
5034 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5035 TNY_FOLDER_STORE (src_folder),
5038 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5039 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5040 src_account, helper);
5041 g_object_unref (src_account);
5046 * UI handler for the "Move to" action when invoked from the
5047 * ModestMsgViewWindow
5050 modest_ui_actions_on_window_move_to (GtkAction *action,
5052 TnyFolderStore *dst_folder,
5055 TnyFolder *src_folder = NULL;
5057 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5060 TnyHeader *header = NULL;
5063 iter = tny_list_create_iterator (headers);
5064 header = (TnyHeader *) tny_iterator_get_current (iter);
5065 src_folder = tny_header_get_folder (header);
5067 /* Transfer the messages */
5068 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5070 TNY_FOLDER (dst_folder));
5073 g_object_unref (header);
5074 g_object_unref (iter);
5075 g_object_unref (src_folder);
5080 modest_ui_actions_on_move_to (GtkAction *action,
5083 modest_ui_actions_on_edit_mode_move_to (win);
5087 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5089 GtkWidget *dialog = NULL;
5090 MoveToInfo *helper = NULL;
5091 TnyList *list_to_move;
5093 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5096 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5101 if (tny_list_get_length (list_to_move) < 1) {
5102 g_object_unref (list_to_move);
5106 /* Create and run the dialog */
5107 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5108 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5109 GTK_WINDOW (dialog),
5113 helper = g_slice_new0 (MoveToInfo);
5114 helper->list = list_to_move;
5117 /* Listen to response signal */
5118 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5120 /* Show the dialog */
5121 gtk_widget_show (dialog);
5127 * Calls #HeadersFunc for each header already selected in the main
5128 * window or the message currently being shown in the msg view window
5131 do_headers_action (ModestWindow *win,
5135 TnyList *headers_list = NULL;
5136 TnyIterator *iter = NULL;
5137 TnyHeader *header = NULL;
5138 TnyFolder *folder = NULL;
5141 headers_list = get_selected_headers (win);
5145 /* Get the folder */
5146 iter = tny_list_create_iterator (headers_list);
5147 header = TNY_HEADER (tny_iterator_get_current (iter));
5149 folder = tny_header_get_folder (header);
5150 g_object_unref (header);
5153 /* Call the function for each header */
5154 while (!tny_iterator_is_done (iter)) {
5155 header = TNY_HEADER (tny_iterator_get_current (iter));
5156 func (header, win, user_data);
5157 g_object_unref (header);
5158 tny_iterator_next (iter);
5161 /* Trick: do a poke status in order to speed up the signaling
5164 tny_folder_poke_status (folder);
5165 g_object_unref (folder);
5169 g_object_unref (iter);
5170 g_object_unref (headers_list);
5174 modest_ui_actions_view_attachment (GtkAction *action,
5175 ModestWindow *window)
5177 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5178 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5180 /* not supported window for this action */
5181 g_return_if_reached ();
5186 modest_ui_actions_save_attachments (GtkAction *action,
5187 ModestWindow *window)
5189 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5191 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5194 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5196 /* not supported window for this action */
5197 g_return_if_reached ();
5202 modest_ui_actions_remove_attachments (GtkAction *action,
5203 ModestWindow *window)
5205 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5206 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5208 /* not supported window for this action */
5209 g_return_if_reached ();
5214 modest_ui_actions_on_settings (GtkAction *action,
5218 GtkWindow *toplevel;
5220 dialog = modest_platform_get_global_settings_dialog ();
5221 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5222 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5223 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5224 gtk_widget_show_all (dialog);
5226 gtk_dialog_run (GTK_DIALOG (dialog));
5228 gtk_widget_destroy (dialog);
5232 modest_ui_actions_on_help (GtkAction *action,
5235 /* Help app is not available at all in fremantle */
5236 #ifndef MODEST_TOOLKIT_HILDON2
5237 const gchar *help_id;
5239 g_return_if_fail (win && GTK_IS_WINDOW(win));
5241 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5244 modest_platform_show_help (GTK_WINDOW (win), help_id);
5249 modest_ui_actions_on_csm_help (GtkAction *action,
5252 /* Help app is not available at all in fremantle */
5256 retrieve_contents_cb (ModestMailOperation *mail_op,
5263 /* We only need this callback to show an error in case of
5264 memory low condition */
5265 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5266 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5271 retrieve_msg_contents_performer (gboolean canceled,
5273 GtkWindow *parent_window,
5274 TnyAccount *account,
5277 ModestMailOperation *mail_op;
5278 TnyList *headers = TNY_LIST (user_data);
5280 if (err || canceled) {
5281 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5282 (GtkWidget *) parent_window, err,
5287 /* Create mail operation */
5288 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5289 modest_ui_actions_disk_operations_error_handler,
5291 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5292 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5295 g_object_unref (mail_op);
5297 g_object_unref (headers);
5298 g_object_unref (account);
5302 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5303 ModestWindow *window)
5305 TnyList *headers = NULL;
5306 TnyAccount *account = NULL;
5307 TnyIterator *iter = NULL;
5308 TnyHeader *header = NULL;
5309 TnyFolder *folder = NULL;
5312 headers = get_selected_headers (window);
5316 /* Pick the account */
5317 iter = tny_list_create_iterator (headers);
5318 header = TNY_HEADER (tny_iterator_get_current (iter));
5319 folder = tny_header_get_folder (header);
5320 account = tny_folder_get_account (folder);
5321 g_object_unref (folder);
5322 g_object_unref (header);
5323 g_object_unref (iter);
5325 /* Connect and perform the message retrieval */
5326 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5327 g_object_ref (account),
5328 retrieve_msg_contents_performer,
5329 g_object_ref (headers));
5332 g_object_unref (account);
5333 g_object_unref (headers);
5337 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5339 g_return_if_fail (MODEST_IS_WINDOW (window));
5342 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5346 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5348 g_return_if_fail (MODEST_IS_WINDOW (window));
5351 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5355 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5356 ModestWindow *window)
5358 g_return_if_fail (MODEST_IS_WINDOW (window));
5361 modest_ui_actions_check_menu_dimming_rules (window);
5365 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5366 ModestWindow *window)
5368 g_return_if_fail (MODEST_IS_WINDOW (window));
5371 modest_ui_actions_check_menu_dimming_rules (window);
5375 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5376 ModestWindow *window)
5378 g_return_if_fail (MODEST_IS_WINDOW (window));
5381 modest_ui_actions_check_menu_dimming_rules (window);
5385 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5386 ModestWindow *window)
5388 g_return_if_fail (MODEST_IS_WINDOW (window));
5391 modest_ui_actions_check_menu_dimming_rules (window);
5395 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5396 ModestWindow *window)
5398 g_return_if_fail (MODEST_IS_WINDOW (window));
5401 modest_ui_actions_check_menu_dimming_rules (window);
5405 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5406 ModestWindow *window)
5408 g_return_if_fail (MODEST_IS_WINDOW (window));
5411 modest_ui_actions_check_menu_dimming_rules (window);
5415 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5416 ModestWindow *window)
5418 g_return_if_fail (MODEST_IS_WINDOW (window));
5421 modest_ui_actions_check_menu_dimming_rules (window);
5425 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5426 ModestWindow *window)
5428 g_return_if_fail (MODEST_IS_WINDOW (window));
5431 modest_ui_actions_check_menu_dimming_rules (window);
5435 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5436 ModestWindow *window)
5438 g_return_if_fail (MODEST_IS_WINDOW (window));
5441 modest_ui_actions_check_menu_dimming_rules (window);
5445 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5447 g_return_if_fail (MODEST_IS_WINDOW (window));
5449 /* we check for low-mem; in that case, show a warning, and don't allow
5452 if (modest_platform_check_memory_low (window, TRUE))
5455 modest_platform_show_search_messages (GTK_WINDOW (window));
5459 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5461 g_return_if_fail (MODEST_IS_WINDOW (win));
5464 /* we check for low-mem; in that case, show a warning, and don't allow
5465 * for the addressbook
5467 if (modest_platform_check_memory_low (win, TRUE))
5471 modest_platform_show_addressbook (GTK_WINDOW (win));
5476 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5477 ModestWindow *window)
5480 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5482 if (GTK_IS_TOGGLE_ACTION (action))
5483 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5487 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5493 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5499 const gchar* server_name = NULL;
5500 TnyTransportAccount *transport;
5501 gchar *message = NULL;
5502 ModestProtocol *protocol;
5504 /* Don't show anything if the user cancelled something or the
5505 * send receive request is not interactive. Authentication
5506 * errors are managed by the account store so no need to show
5507 * a dialog here again */
5508 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5509 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5510 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5514 /* Get the server name. Note that we could be using a
5515 connection specific transport account */
5516 transport = (TnyTransportAccount *)
5517 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5519 ModestTnyAccountStore *acc_store;
5520 const gchar *acc_name;
5521 TnyTransportAccount *conn_specific;
5523 acc_store = modest_runtime_get_account_store();
5524 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5525 conn_specific = (TnyTransportAccount *)
5526 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5527 if (conn_specific) {
5528 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5529 g_object_unref (conn_specific);
5531 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5533 g_object_unref (transport);
5537 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5538 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5539 tny_account_get_proto (TNY_ACCOUNT (transport)));
5541 g_warning ("%s: Account with no proto", __FUNCTION__);
5545 /* Show the appropriate message text for the GError: */
5546 switch (err->code) {
5547 case TNY_SERVICE_ERROR_CONNECT:
5548 message = modest_protocol_get_translation (protocol,
5549 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5552 case TNY_SERVICE_ERROR_SEND:
5553 message = g_strdup (_CS_UNABLE_TO_SEND);
5555 case TNY_SERVICE_ERROR_UNAVAILABLE:
5556 message = modest_protocol_get_translation (protocol,
5557 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5561 g_warning ("%s: unexpected ERROR %d",
5562 __FUNCTION__, err->code);
5563 message = g_strdup (_CS_UNABLE_TO_SEND);
5567 modest_platform_run_information_dialog (NULL, message, FALSE);
5572 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5577 ModestWindow *top_window = NULL;
5578 ModestWindowMgr *mgr = NULL;
5579 GtkWidget *header_view = NULL;
5580 TnyFolder *selected_folder = NULL;
5581 TnyFolderType folder_type;
5583 mgr = modest_runtime_get_window_mgr ();
5584 top_window = modest_window_mgr_get_current_top (mgr);
5589 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5590 header_view = (GtkWidget *)
5591 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5594 /* Get selected folder */
5596 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5597 if (!selected_folder)
5600 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5601 #if GTK_CHECK_VERSION(2, 8, 0)
5602 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5603 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5604 GtkTreeViewColumn *tree_column;
5606 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5607 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5609 gtk_tree_view_column_queue_resize (tree_column);
5611 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5612 gtk_widget_queue_draw (header_view);
5615 #ifndef MODEST_TOOLKIT_HILDON2
5616 /* Rerun dimming rules, because the message could become deletable for example */
5617 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5618 MODEST_DIMMING_RULES_TOOLBAR);
5619 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5620 MODEST_DIMMING_RULES_MENU);
5624 g_object_unref (selected_folder);
5628 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5629 TnyAccount *account)
5631 ModestProtocolType protocol_type;
5632 ModestProtocol *protocol;
5633 gchar *error_note = NULL;
5635 protocol_type = modest_tny_account_get_protocol_type (account);
5636 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5639 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5640 if (error_note == NULL) {
5641 g_warning ("%s: This should not be reached", __FUNCTION__);
5643 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
5644 g_free (error_note);
5649 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5653 TnyFolderStore *folder = NULL;
5654 TnyAccount *account = NULL;
5655 ModestProtocolType proto;
5656 ModestProtocol *protocol;
5657 TnyHeader *header = NULL;
5659 if (MODEST_IS_HEADER_WINDOW (win)) {
5660 GtkWidget *header_view;
5661 TnyList* headers = NULL;
5663 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5664 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5665 if (!headers || tny_list_get_length (headers) == 0) {
5667 g_object_unref (headers);
5670 iter = tny_list_create_iterator (headers);
5671 header = TNY_HEADER (tny_iterator_get_current (iter));
5673 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5675 g_warning ("List should contain headers");
5677 g_object_unref (iter);
5678 g_object_unref (headers);
5679 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5680 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5682 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5685 if (!header || !folder)
5688 /* Get the account type */
5689 account = tny_folder_get_account (TNY_FOLDER (folder));
5690 proto = modest_tny_account_get_protocol_type (account);
5691 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5694 subject = tny_header_dup_subject (header);
5695 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5699 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5705 g_object_unref (account);
5707 g_object_unref (folder);
5709 g_object_unref (header);
5715 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5716 const gchar *account_name,
5717 const gchar *account_title)
5719 ModestAccountMgr *account_mgr;
5722 ModestProtocol *protocol;
5723 gboolean removed = FALSE;
5725 g_return_val_if_fail (account_name, FALSE);
5726 g_return_val_if_fail (account_title, FALSE);
5728 account_mgr = modest_runtime_get_account_mgr();
5730 /* The warning text depends on the account type: */
5731 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5732 modest_account_mgr_get_store_protocol (account_mgr,
5734 txt = modest_protocol_get_translation (protocol,
5735 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5738 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5740 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5744 if (response == GTK_RESPONSE_OK) {
5745 /* Remove account. If it succeeds then it also removes
5746 the account from the ModestAccountView: */
5747 gboolean is_default = FALSE;
5748 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5749 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5751 g_free (default_account_name);
5753 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5755 /* Close all email notifications, we cannot
5756 distinguish if the notification belongs to
5757 this account or not, so for safety reasons
5758 we remove them all */
5759 modest_platform_remove_new_mail_notifications (FALSE);
5761 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5768 on_fetch_images_performer (gboolean canceled,
5770 GtkWindow *parent_window,
5771 TnyAccount *account,
5774 if (err || canceled) {
5775 /* Show an unable to retrieve images ??? */
5779 /* Note that the user could have closed the window while connecting */
5780 if (GTK_WIDGET_VISIBLE (parent_window))
5781 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5782 g_object_unref ((GObject *) user_data);
5786 modest_ui_actions_on_fetch_images (GtkAction *action,
5787 ModestWindow *window)
5789 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5791 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5793 on_fetch_images_performer,
5794 g_object_ref (window));
5798 modest_ui_actions_on_reload_message (const gchar *msg_id)
5800 ModestWindow *window = NULL;
5802 g_return_if_fail (msg_id && msg_id[0] != '\0');
5803 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5809 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5812 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5815 /** Check whether any connections are active, and cancel them if
5817 * Returns TRUE is there was no problem,
5818 * or if an operation was cancelled so we can continue.
5819 * Returns FALSE if the user chose to cancel his request instead.
5823 modest_ui_actions_check_for_active_account (ModestWindow *self,
5824 const gchar* account_name)
5826 ModestTnySendQueue *send_queue;
5827 ModestTnyAccountStore *acc_store;
5828 ModestMailOperationQueue* queue;
5829 TnyConnectionStatus store_conn_status;
5830 TnyAccount *store_account = NULL, *transport_account = NULL;
5831 gboolean retval = TRUE, sending = FALSE;
5833 acc_store = modest_runtime_get_account_store ();
5834 queue = modest_runtime_get_mail_operation_queue ();
5837 modest_tny_account_store_get_server_account (acc_store,
5839 TNY_ACCOUNT_TYPE_STORE);
5841 /* This could happen if the account was deleted before the
5842 call to this function */
5847 modest_tny_account_store_get_server_account (acc_store,
5849 TNY_ACCOUNT_TYPE_TRANSPORT);
5851 /* This could happen if the account was deleted before the
5852 call to this function */
5853 if (!transport_account) {
5854 g_object_unref (store_account);
5858 /* If the transport account was not used yet, then the send
5859 queue could not exist (it's created on demand) */
5860 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5861 if (TNY_IS_SEND_QUEUE (send_queue))
5862 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5864 store_conn_status = tny_account_get_connection_status (store_account);
5865 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5868 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
5869 _("emev_nc_disconnect_account"));
5870 if (response == GTK_RESPONSE_OK) {
5879 /* FIXME: We should only cancel those of this account */
5880 modest_mail_operation_queue_cancel_all (queue);
5882 /* Also disconnect the account */
5883 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5884 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5885 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5889 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5895 g_object_unref (store_account);
5896 g_object_unref (transport_account);