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>
81 #include <gtkhtml/gtkhtml.h>
83 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
85 typedef struct _GetMsgAsyncHelper {
87 ModestMailOperation *mail_op;
94 typedef enum _ReplyForwardAction {
100 typedef struct _ReplyForwardHelper {
101 guint reply_forward_type;
102 ReplyForwardAction action;
105 GtkWidget *parent_window;
107 } ReplyForwardHelper;
109 typedef struct _MoveToHelper {
110 GtkTreeRowReference *reference;
114 typedef struct _PasteAsAttachmentHelper {
115 ModestMsgEditWindow *window;
117 } PasteAsAttachmentHelper;
125 * The do_headers_action uses this kind of functions to perform some
126 * action to each member of a list of headers
128 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
130 static void do_headers_action (ModestWindow *win,
134 static void open_msg_cb (ModestMailOperation *mail_op,
141 static void reply_forward_cb (ModestMailOperation *mail_op,
148 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
150 static gint header_list_count_uncached_msgs (TnyList *header_list);
152 static gboolean connect_to_get_msg (ModestWindow *win,
153 gint num_of_uncached_msgs,
154 TnyAccount *account);
156 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
158 static void do_create_folder (GtkWindow *window,
159 TnyFolderStore *parent_folder,
160 const gchar *suggested_name);
162 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
164 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
165 TnyFolderStore *dst_folder,
169 static void modest_ui_actions_on_window_move_to (GtkAction *action,
170 TnyList *list_to_move,
171 TnyFolderStore *dst_folder,
175 * This function checks whether a TnyFolderStore is a pop account
178 remote_folder_has_leave_on_server (TnyFolderStore *folder)
183 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
185 account = get_account_from_folder_store (folder);
186 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
187 modest_tny_account_get_protocol_type (account)));
188 g_object_unref (account);
193 /* FIXME: this should be merged with the similar code in modest-account-view-window */
194 /* Show the account creation wizard dialog.
195 * returns: TRUE if an account was created. FALSE if the user cancelled.
198 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
200 gboolean result = FALSE;
202 gint dialog_response;
204 /* there is no such wizard yet */
205 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
206 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
210 ModestWindowMgr *mgr;
212 mgr = modest_runtime_get_window_mgr ();
214 window_list = modest_window_mgr_get_window_list (mgr);
215 if (window_list == NULL) {
216 win = MODEST_WINDOW (modest_accounts_window_new ());
217 if (modest_window_mgr_register_window (mgr, win, NULL)) {
218 gtk_widget_show_all (GTK_WIDGET (win));
220 gtk_widget_destroy (GTK_WIDGET (win));
225 g_list_free (window_list);
230 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
232 /* make sure the mainwindow is visible. We need to present the
233 wizard again to give it the focus back. show_all are needed
234 in order to get the widgets properly drawn (MainWindow main
235 paned won't be in its right position and the dialog will be
238 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
239 gtk_widget_destroy (GTK_WIDGET (wizard));
240 if (gtk_events_pending ())
241 gtk_main_iteration ();
243 if (dialog_response == GTK_RESPONSE_CANCEL) {
246 /* Check whether an account was created: */
247 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
254 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
257 const gchar *authors[] = {
258 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
261 about = gtk_about_dialog_new ();
262 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
263 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
264 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
265 _("Copyright (c) 2006, Nokia Corporation\n"
266 "All rights reserved."));
267 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
268 _("a modest e-mail client\n\n"
269 "design and implementation: Dirk-Jan C. Binnema\n"
270 "contributions from the fine people at KC and Ig\n"
271 "uses the tinymail email framework written by Philip van Hoof"));
272 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
273 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
274 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
275 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
277 gtk_dialog_run (GTK_DIALOG (about));
278 gtk_widget_destroy(about);
282 * Gets the list of currently selected messages. If the win is the
283 * main window, then it returns a newly allocated list of the headers
284 * selected in the header view. If win is the msg view window, then
285 * the value returned is a list with just a single header.
287 * The caller of this funcion must free the list.
290 get_selected_headers (ModestWindow *win)
292 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
293 /* for MsgViewWindows, we simply return a list with one element */
295 TnyList *list = NULL;
297 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
298 if (header != NULL) {
299 list = tny_simple_list_new ();
300 tny_list_prepend (list, G_OBJECT(header));
301 g_object_unref (G_OBJECT(header));
305 } else if (MODEST_IS_HEADER_WINDOW (win)) {
306 GtkWidget *header_view;
308 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
309 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
316 headers_action_mark_as_read (TnyHeader *header,
320 TnyHeaderFlags flags;
322 g_return_if_fail (TNY_IS_HEADER(header));
324 flags = tny_header_get_flags (header);
325 if (flags & TNY_HEADER_FLAG_SEEN) return;
326 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
330 headers_action_mark_as_unread (TnyHeader *header,
334 TnyHeaderFlags flags;
336 g_return_if_fail (TNY_IS_HEADER(header));
338 flags = tny_header_get_flags (header);
339 if (flags & TNY_HEADER_FLAG_SEEN) {
340 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
344 /** After deleing a message that is currently visible in a window,
345 * show the next message from the list, or close the window if there are no more messages.
348 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
350 /* Close msg view window or select next */
351 if (!modest_msg_view_window_select_next_message (win) &&
352 !modest_msg_view_window_select_previous_message (win)) {
354 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
360 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
362 modest_ui_actions_on_edit_mode_delete_message (win);
366 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
368 TnyList *header_list = NULL;
369 TnyIterator *iter = NULL;
370 TnyHeader *header = NULL;
371 gchar *message = NULL;
374 ModestWindowMgr *mgr;
375 gboolean retval = TRUE;
377 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
379 /* Get the headers, either from the header view (if win is the main window),
380 * or from the message view window: */
381 header_list = get_selected_headers (win);
382 if (!header_list) return FALSE;
384 /* Check if any of the headers are already opened, or in the process of being opened */
387 if (tny_list_get_length(header_list) == 1) {
388 iter = tny_list_create_iterator (header_list);
389 header = TNY_HEADER (tny_iterator_get_current (iter));
392 subject = tny_header_dup_subject (header);
394 subject = g_strdup (_("mail_va_no_subject"));
395 desc = g_strdup_printf ("%s", subject);
397 g_object_unref (header);
400 g_object_unref (iter);
402 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
403 tny_list_get_length(header_list)), desc);
405 /* Confirmation dialog */
406 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
409 if (response == GTK_RESPONSE_OK) {
410 GtkTreeSelection *sel = NULL;
411 GList *sel_list = NULL;
412 ModestMailOperation *mail_op = NULL;
414 /* Find last selected row */
416 /* Disable window dimming management */
417 modest_window_disable_dimming (win);
419 /* Remove each header. If it's a view window header_view == NULL */
420 mail_op = modest_mail_operation_new ((GObject *) win);
421 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
423 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
424 g_object_unref (mail_op);
426 /* Enable window dimming management */
428 gtk_tree_selection_unselect_all (sel);
430 modest_window_enable_dimming (win);
432 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
433 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
435 /* Get main window */
436 mgr = modest_runtime_get_window_mgr ();
439 /* Update toolbar dimming state */
440 modest_ui_actions_check_menu_dimming_rules (win);
441 modest_ui_actions_check_toolbar_dimming_rules (win);
444 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
445 g_list_free (sel_list);
454 g_object_unref (header_list);
462 /* delete either message or folder, based on where we are */
464 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
466 g_return_if_fail (MODEST_IS_WINDOW(win));
468 /* Check first if the header view has the focus */
469 modest_ui_actions_on_delete_message (action, win);
473 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
475 ModestWindowMgr *mgr = NULL;
477 #ifdef MODEST_PLATFORM_MAEMO
478 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
479 #endif /* MODEST_PLATFORM_MAEMO */
481 g_debug ("closing down, clearing %d item(s) from operation queue",
482 modest_mail_operation_queue_num_elements
483 (modest_runtime_get_mail_operation_queue()));
485 /* cancel all outstanding operations */
486 modest_mail_operation_queue_cancel_all
487 (modest_runtime_get_mail_operation_queue());
489 g_debug ("queue has been cleared");
492 /* Check if there are opened editing windows */
493 mgr = modest_runtime_get_window_mgr ();
494 modest_window_mgr_close_all_windows (mgr);
496 /* note: when modest-tny-account-store is finalized,
497 it will automatically set all network connections
500 /* gtk_main_quit (); */
504 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
508 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
510 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
511 /* gtk_widget_destroy (GTK_WIDGET (win)); */
512 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
513 /* gboolean ret_value; */
514 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
515 /* } else if (MODEST_IS_WINDOW (win)) { */
516 /* gtk_widget_destroy (GTK_WIDGET (win)); */
518 /* g_return_if_reached (); */
523 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
525 if (MODEST_IS_MSG_VIEW_WINDOW (win))
526 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
527 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
528 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
532 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
534 GtkClipboard *clipboard = NULL;
535 gchar *selection = NULL;
537 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
538 selection = gtk_clipboard_wait_for_text (clipboard);
541 modest_address_book_add_address (selection, (GtkWindow *) win);
547 modest_ui_actions_on_new_account (GtkAction *action,
548 ModestWindow *window)
550 if (!modest_ui_actions_run_account_setup_wizard (window)) {
551 g_debug ("%s: wizard was already running", __FUNCTION__);
556 modest_ui_actions_on_accounts (GtkAction *action,
559 /* This is currently only implemented for Maemo */
560 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
561 if (!modest_ui_actions_run_account_setup_wizard (win))
562 g_debug ("%s: wizard was already running", __FUNCTION__);
566 /* Show the list of accounts */
567 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
569 /* The accounts dialog must be modal */
570 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
571 modest_utils_show_dialog_and_forget (modest_toolkit_utils_parent_window (GTK_WIDGET (win)), GTK_DIALOG (account_win));
576 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
578 /* This is currently only implemented for Maemo,
579 * because it requires an API (libconic) to detect different connection
582 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
584 /* Create the window if necessary: */
585 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
586 modest_connection_specific_smtp_window_fill_with_connections (
587 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
588 modest_runtime_get_account_mgr());
590 /* Show the window: */
591 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
592 GTK_WINDOW (specific_window), (GtkWindow *) win);
593 gtk_widget_show (specific_window);
594 #endif /* !MODEST_TOOLKIT_GTK */
598 count_part_size (const gchar *part)
600 GnomeVFSURI *vfs_uri;
601 gchar *escaped_filename;
603 GnomeVFSFileInfo *info;
606 /* Estimation of attachment size if we cannot get it from file info */
609 vfs_uri = gnome_vfs_uri_new (part);
611 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
612 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
613 g_free (escaped_filename);
614 gnome_vfs_uri_unref (vfs_uri);
616 info = gnome_vfs_file_info_new ();
618 if (gnome_vfs_get_file_info (part,
620 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
622 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
627 gnome_vfs_file_info_unref (info);
633 count_parts_size (GSList *parts)
638 for (node = parts; node != NULL; node = g_slist_next (node)) {
639 result += count_part_size ((const gchar *) node->data);
646 modest_ui_actions_compose_msg(ModestWindow *win,
649 const gchar *bcc_str,
650 const gchar *subject_str,
651 const gchar *body_str,
653 gboolean set_as_modified)
655 gchar *account_name = NULL;
656 const gchar *mailbox;
658 TnyAccount *account = NULL;
659 TnyFolder *folder = NULL;
660 gchar *from_str = NULL, *signature = NULL, *body = NULL;
661 gchar *recipient = NULL;
662 gboolean use_signature = FALSE;
663 ModestWindow *msg_win = NULL;
664 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
665 ModestTnyAccountStore *store = modest_runtime_get_account_store();
666 GnomeVFSFileSize total_size, allowed_size;
667 guint64 available_disk, expected_size, parts_size;
670 /* we check for low-mem */
671 if (modest_platform_check_memory_low (win, TRUE))
674 available_disk = modest_utils_get_available_space (NULL);
675 parts_count = g_slist_length (attachments);
676 parts_size = count_parts_size (attachments);
677 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
679 /* Double check: disk full condition or message too big */
680 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
681 expected_size > available_disk) {
682 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
683 modest_platform_system_banner (NULL, NULL, msg);
689 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
690 modest_platform_run_information_dialog (
692 _("mail_ib_error_attachment_size"),
699 account_name = g_strdup (modest_window_get_active_account(win));
701 account_name = modest_account_mgr_get_default_account(mgr);
704 g_printerr ("modest: no account found\n");
709 mailbox = modest_window_get_active_mailbox (win);
712 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
714 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
717 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
719 g_printerr ("modest: failed to find Drafts folder\n");
722 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
724 g_printerr ("modest: failed get from string for '%s'\n", account_name);
728 recipient = modest_text_utils_get_email_address (from_str);
729 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
731 if (body_str != NULL) {
732 body = use_signature ? g_strconcat(body_str, "\n",
733 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
734 "\n", signature, NULL) : g_strdup(body_str);
736 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
737 "\n", signature, NULL) : g_strdup("");
740 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
742 g_printerr ("modest: failed to create new msg\n");
746 /* Create and register edit window */
747 /* This is destroyed by TODO. */
749 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
750 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
752 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
753 gtk_widget_destroy (GTK_WIDGET (msg_win));
756 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
757 gtk_widget_show_all (GTK_WIDGET (msg_win));
759 while (attachments) {
760 GnomeVFSFileSize att_size;
762 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
763 attachments->data, allowed_size);
764 total_size += att_size;
766 if (att_size > allowed_size) {
767 g_debug ("%s: total size: %u",
768 __FUNCTION__, (unsigned int)total_size);
771 allowed_size -= att_size;
773 attachments = g_slist_next(attachments);
780 g_free (account_name);
782 g_object_unref (G_OBJECT(account));
784 g_object_unref (G_OBJECT(folder));
786 g_object_unref (G_OBJECT(msg));
790 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
792 /* if there are no accounts yet, just show the wizard */
793 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
794 if (!modest_ui_actions_run_account_setup_wizard (win))
797 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
802 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
806 ModestMailOperationStatus status;
808 /* If there is no message or the operation was not successful */
809 status = modest_mail_operation_get_status (mail_op);
810 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
813 /* If it's a memory low issue, then show a banner */
814 error = modest_mail_operation_get_error (mail_op);
815 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
816 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
817 GObject *source = modest_mail_operation_get_source (mail_op);
818 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
819 _KR("memr_ib_operation_disabled"),
821 g_object_unref (source);
824 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
825 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
826 gchar *subject, *msg, *format = NULL;
829 subject = (header) ? tny_header_dup_subject (header) : NULL;
831 subject = g_strdup (_("mail_va_no_subject"));
833 account = modest_mail_operation_get_account (mail_op);
835 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
836 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
839 if (tny_account_get_connection_status (account) ==
840 TNY_CONNECTION_STATUS_CONNECTED) {
842 format = modest_protocol_get_translation (protocol,
843 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
846 format = modest_protocol_get_translation (protocol,
847 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
850 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
851 tny_account_get_hostname (account));
854 g_object_unref (account);
859 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
861 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
865 msg = g_strdup_printf (format, subject);
866 modest_platform_run_information_dialog (NULL, msg, FALSE);
872 /* Remove the header from the preregistered uids */
873 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
891 ModestWindow *caller_window;
892 OpenMsgBannerInfo *banner_info;
893 GtkTreeRowReference *rowref;
897 open_msg_banner_idle (gpointer userdata)
899 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
901 gdk_threads_enter ();
902 banner_info->idle_handler = 0;
903 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
904 if (banner_info->banner)
905 g_object_ref (banner_info->banner);
907 gdk_threads_leave ();
913 get_header_view_from_window (ModestWindow *window)
915 GtkWidget *header_view;
917 if (MODEST_IS_HEADER_WINDOW (window)){
918 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
927 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
930 gchar *account = NULL;
931 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
936 folder = tny_header_get_folder (header);
937 /* Gets folder type (OUTBOX headers will be opened in edit window */
938 if (modest_tny_folder_is_local_folder (folder)) {
939 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
940 if (folder_type == TNY_FOLDER_TYPE_INVALID)
941 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
944 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
945 TnyTransportAccount *traccount = NULL;
946 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
947 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
949 ModestTnySendQueue *send_queue = NULL;
950 ModestTnySendQueueStatus status;
952 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
953 TNY_ACCOUNT(traccount)));
954 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
955 if (TNY_IS_SEND_QUEUE (send_queue)) {
956 msg_id = modest_tny_send_queue_get_msg_id (header);
957 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
959 /* Only open messages in outbox with the editor if they are in Failed state */
960 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
964 /* In Fremantle we can not
965 open any message from
966 outbox which is not in
971 g_object_unref(traccount);
973 g_warning("Cannot get transport account for message in outbox!!");
975 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
976 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
980 TnyAccount *acc = tny_folder_get_account (folder);
983 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
984 g_object_unref (acc);
988 g_object_unref (folder);
994 open_msg_cb (ModestMailOperation *mail_op,
1001 ModestWindowMgr *mgr = NULL;
1002 ModestWindow *parent_win = NULL;
1003 ModestWindow *win = NULL;
1004 gchar *account = NULL;
1005 gboolean open_in_editor = FALSE;
1007 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1009 /* Do nothing if there was any problem with the mail
1010 operation. The error will be shown by the error_handler of
1011 the mail operation */
1012 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1015 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1017 /* Mark header as read */
1018 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1020 account = get_info_from_header (header, &open_in_editor, &can_open);
1024 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1026 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1028 if (open_in_editor) {
1029 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1030 gchar *from_header = NULL, *acc_name;
1031 gchar *mailbox = NULL;
1033 from_header = tny_header_dup_from (header);
1035 /* we cannot edit without a valid account... */
1036 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1037 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1038 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1040 g_free (from_header);
1045 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1046 g_free (from_header);
1052 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1056 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1057 const gchar *mailbox = NULL;
1059 if (parent_win && MODEST_IS_WINDOW (parent_win))
1060 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1062 if (helper->rowref && helper->model) {
1063 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1064 helper->model, helper->rowref);
1066 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1071 /* Register and show new window */
1073 mgr = modest_runtime_get_window_mgr ();
1074 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1075 gtk_widget_destroy (GTK_WIDGET (win));
1078 gtk_widget_show_all (GTK_WIDGET(win));
1085 g_object_unref (parent_win);
1089 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1092 const GError *error;
1093 GObject *win = NULL;
1094 ModestMailOperationStatus status;
1096 win = modest_mail_operation_get_source (mail_op);
1097 error = modest_mail_operation_get_error (mail_op);
1098 status = modest_mail_operation_get_status (mail_op);
1100 /* If the mail op has been cancelled then it's not an error:
1101 don't show any message */
1102 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1103 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1104 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1105 (GError *) error, account)) {
1106 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1107 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1109 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1110 modest_platform_information_banner ((GtkWidget *) win,
1111 NULL, _("emev_ui_imap_inbox_select_error"));
1112 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1113 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1114 modest_platform_information_banner ((GtkWidget *) win,
1115 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1116 } else if (user_data) {
1117 modest_platform_information_banner ((GtkWidget *) win,
1121 g_object_unref (account);
1125 g_object_unref (win);
1129 * Returns the account a list of headers belongs to. It returns a
1130 * *new* reference so don't forget to unref it
1133 get_account_from_header_list (TnyList *headers)
1135 TnyAccount *account = NULL;
1137 if (tny_list_get_length (headers) > 0) {
1138 TnyIterator *iter = tny_list_create_iterator (headers);
1139 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1140 TnyFolder *folder = tny_header_get_folder (header);
1143 g_object_unref (header);
1145 while (!tny_iterator_is_done (iter)) {
1146 header = TNY_HEADER (tny_iterator_get_current (iter));
1147 folder = tny_header_get_folder (header);
1150 g_object_unref (header);
1152 tny_iterator_next (iter);
1157 account = tny_folder_get_account (folder);
1158 g_object_unref (folder);
1162 g_object_unref (header);
1164 g_object_unref (iter);
1170 get_account_from_header (TnyHeader *header)
1172 TnyAccount *account = NULL;
1175 folder = tny_header_get_folder (header);
1178 account = tny_folder_get_account (folder);
1179 g_object_unref (folder);
1185 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1187 if (helper->caller_window)
1188 helper->caller_window = NULL;
1192 open_msg_helper_destroyer (gpointer user_data)
1194 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1196 if (helper->caller_window) {
1197 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1198 helper->caller_window = NULL;
1201 if (helper->banner_info) {
1202 g_free (helper->banner_info->message);
1203 if (helper->banner_info->idle_handler > 0) {
1204 g_source_remove (helper->banner_info->idle_handler);
1205 helper->banner_info->idle_handler = 0;
1207 if (helper->banner_info->banner != NULL) {
1208 gtk_widget_destroy (helper->banner_info->banner);
1209 g_object_unref (helper->banner_info->banner);
1210 helper->banner_info->banner = NULL;
1212 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1213 helper->banner_info = NULL;
1215 g_object_unref (helper->model);
1216 g_object_unref (helper->header);
1217 gtk_tree_row_reference_free (helper->rowref);
1218 g_slice_free (OpenMsgHelper, helper);
1222 open_msg_performer(gboolean canceled,
1224 GtkWindow *parent_window,
1225 TnyAccount *account,
1228 ModestMailOperation *mail_op = NULL;
1229 gchar *error_msg = NULL;
1230 ModestProtocolType proto;
1231 TnyConnectionStatus status;
1232 OpenMsgHelper *helper = NULL;
1233 ModestProtocol *protocol;
1234 ModestProtocolRegistry *protocol_registry;
1237 helper = (OpenMsgHelper *) user_data;
1239 status = tny_account_get_connection_status (account);
1240 if (err || canceled || helper->caller_window == NULL) {
1241 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1242 /* Free the helper */
1243 open_msg_helper_destroyer (helper);
1245 /* In disk full conditions we could get this error here */
1246 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1247 (GtkWidget *) parent_window, err,
1253 /* Get the error message depending on the protocol */
1254 proto = modest_tny_account_get_protocol_type (account);
1255 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1256 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1259 protocol_registry = modest_runtime_get_protocol_registry ();
1260 subject = tny_header_dup_subject (helper->header);
1262 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1263 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1267 if (error_msg == NULL) {
1268 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1273 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1276 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1277 g_free (account_name);
1278 open_msg_helper_destroyer (helper);
1283 ModestWindow *window;
1284 GtkWidget *header_view;
1287 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1288 uid = modest_tny_folder_get_header_unique_id (helper->header);
1290 const gchar *mailbox = NULL;
1291 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1292 window = modest_msg_view_window_new_from_header_view
1293 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1294 if (window != NULL) {
1295 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1297 gtk_widget_destroy (GTK_WIDGET (window));
1299 gtk_widget_show_all (GTK_WIDGET(window));
1303 g_free (account_name);
1305 open_msg_helper_destroyer (helper);
1308 g_free (account_name);
1309 /* Create the mail operation */
1311 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1312 modest_ui_actions_disk_operations_error_handler,
1313 g_strdup (error_msg), g_free);
1314 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1320 headers = TNY_LIST (tny_simple_list_new ());
1321 tny_list_prepend (headers, G_OBJECT (helper->header));
1322 modest_mail_operation_get_msgs_full (mail_op,
1326 open_msg_helper_destroyer);
1327 g_object_unref (headers);
1334 g_object_unref (mail_op);
1335 g_object_unref (account);
1339 * This function is used by both modest_ui_actions_on_open and
1340 * modest_ui_actions_on_header_activated. This way we always do the
1341 * same when trying to open messages.
1344 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1346 ModestWindowMgr *mgr = NULL;
1347 TnyAccount *account;
1348 gboolean cached = FALSE;
1350 GtkWidget *header_view = NULL;
1351 OpenMsgHelper *helper;
1352 ModestWindow *window;
1354 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1356 mgr = modest_runtime_get_window_mgr ();
1359 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1360 if (header_view == NULL)
1363 /* Get the account */
1364 account = get_account_from_header (header);
1369 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1371 /* Do not open again the message and present the
1372 window to the user */
1375 #ifndef MODEST_TOOLKIT_HILDON2
1376 gtk_window_present (GTK_WINDOW (window));
1379 /* the header has been registered already, we don't do
1380 * anything but wait for the window to come up*/
1381 g_debug ("header %p already registered, waiting for window", header);
1386 /* Open each message */
1387 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1389 /* Allways download if we are online. */
1390 if (!tny_device_is_online (modest_runtime_get_device ())) {
1393 /* If ask for user permission to download the messages */
1394 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1395 _("mcen_nc_get_msg"));
1397 /* End if the user does not want to continue */
1398 if (response == GTK_RESPONSE_CANCEL) {
1404 /* We register the window for opening */
1405 modest_window_mgr_register_header (mgr, header, NULL);
1407 /* Create the helper. We need to get a reference to the model
1408 here because it could change while the message is readed
1409 (the user could switch between folders) */
1410 helper = g_slice_new (OpenMsgHelper);
1411 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1412 helper->caller_window = win;
1413 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1414 helper->header = g_object_ref (header);
1415 helper->rowref = gtk_tree_row_reference_copy (rowref);
1416 helper->banner_info = NULL;
1418 /* Connect to the account and perform */
1420 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1421 open_msg_performer, helper);
1423 /* Call directly the performer, do not need to connect */
1424 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1425 g_object_ref (account), helper);
1430 g_object_unref (account);
1434 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1441 /* we check for low-mem; in that case, show a warning, and don't allow
1444 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1448 headers = get_selected_headers (win);
1452 headers_count = tny_list_get_length (headers);
1453 if (headers_count != 1) {
1454 if (headers_count > 1) {
1455 /* Don't allow activation if there are more than one message selected */
1456 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1459 g_object_unref (headers);
1463 iter = tny_list_create_iterator (headers);
1464 header = TNY_HEADER (tny_iterator_get_current (iter));
1465 g_object_unref (iter);
1469 open_msg_from_header (header, NULL, win);
1470 g_object_unref (header);
1473 g_object_unref(headers);
1477 rf_helper_window_closed (gpointer data,
1480 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1482 helper->parent_window = NULL;
1485 static ReplyForwardHelper*
1486 create_reply_forward_helper (ReplyForwardAction action,
1488 guint reply_forward_type,
1491 ReplyForwardHelper *rf_helper = NULL;
1492 const gchar *active_acc = modest_window_get_active_account (win);
1493 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1495 rf_helper = g_slice_new0 (ReplyForwardHelper);
1496 rf_helper->reply_forward_type = reply_forward_type;
1497 rf_helper->action = action;
1498 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1499 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1500 rf_helper->account_name = (active_acc) ?
1501 g_strdup (active_acc) :
1502 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1503 rf_helper->mailbox = g_strdup (active_mailbox);
1505 /* Note that window could be destroyed just AFTER calling
1506 register_window so we must ensure that this pointer does
1507 not hold invalid references */
1508 if (rf_helper->parent_window)
1509 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1510 rf_helper_window_closed, rf_helper);
1516 free_reply_forward_helper (gpointer data)
1518 ReplyForwardHelper *helper;
1520 helper = (ReplyForwardHelper *) data;
1521 g_free (helper->account_name);
1522 g_free (helper->mailbox);
1524 g_object_unref (helper->header);
1525 if (helper->parent_window)
1526 g_object_weak_unref (G_OBJECT (helper->parent_window),
1527 rf_helper_window_closed, helper);
1528 g_slice_free (ReplyForwardHelper, helper);
1532 reply_forward_cb (ModestMailOperation *mail_op,
1539 TnyMsg *new_msg = NULL;
1540 ReplyForwardHelper *rf_helper;
1541 ModestWindow *msg_win = NULL;
1542 ModestEditType edit_type;
1544 TnyAccount *account = NULL;
1545 ModestWindowMgr *mgr = NULL;
1546 gchar *signature = NULL;
1547 gboolean use_signature;
1550 /* If there was any error. The mail operation could be NULL,
1551 this means that we already have the message downloaded and
1552 that we didn't do a mail operation to retrieve it */
1553 rf_helper = (ReplyForwardHelper *) user_data;
1554 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1557 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1558 rf_helper->account_name, rf_helper->mailbox);
1559 recipient = modest_text_utils_get_email_address (from);
1560 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1565 /* Create reply mail */
1566 switch (rf_helper->action) {
1567 /* Use the msg_header to ensure that we have all the
1568 information. The summary can lack some data */
1569 TnyHeader *msg_header;
1571 msg_header = tny_msg_get_header (msg);
1573 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1574 (use_signature) ? signature : NULL,
1575 rf_helper->reply_forward_type,
1576 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1577 g_object_unref (msg_header);
1579 case ACTION_REPLY_TO_ALL:
1580 msg_header = tny_msg_get_header (msg);
1582 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1583 (use_signature) ? signature : NULL,
1584 rf_helper->reply_forward_type,
1585 MODEST_TNY_MSG_REPLY_MODE_ALL);
1586 edit_type = MODEST_EDIT_TYPE_REPLY;
1587 g_object_unref (msg_header);
1589 case ACTION_FORWARD:
1591 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1592 rf_helper->reply_forward_type);
1593 edit_type = MODEST_EDIT_TYPE_FORWARD;
1596 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1598 g_return_if_reached ();
1606 g_warning ("%s: failed to create message\n", __FUNCTION__);
1610 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1611 rf_helper->account_name,
1612 TNY_ACCOUNT_TYPE_STORE);
1614 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1618 /* Create and register the windows */
1619 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1620 mgr = modest_runtime_get_window_mgr ();
1621 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1623 /* Note that register_window could have deleted the account */
1624 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1625 gdouble parent_zoom;
1627 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1628 modest_window_set_zoom (msg_win, parent_zoom);
1631 /* Show edit window */
1632 gtk_widget_show_all (GTK_WIDGET (msg_win));
1635 /* We always unregister the header because the message is
1636 forwarded or replied so the original one is no longer
1638 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1641 g_object_unref (G_OBJECT (new_msg));
1643 g_object_unref (G_OBJECT (account));
1644 free_reply_forward_helper (rf_helper);
1647 /* Checks a list of headers. If any of them are not currently
1648 * downloaded (CACHED) then returns TRUE else returns FALSE.
1651 header_list_count_uncached_msgs (TnyList *header_list)
1654 gint uncached_messages = 0;
1656 iter = tny_list_create_iterator (header_list);
1657 while (!tny_iterator_is_done (iter)) {
1660 header = TNY_HEADER (tny_iterator_get_current (iter));
1662 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1663 uncached_messages ++;
1664 g_object_unref (header);
1667 tny_iterator_next (iter);
1669 g_object_unref (iter);
1671 return uncached_messages;
1674 /* Returns FALSE if the user does not want to download the
1675 * messages. Returns TRUE if the user allowed the download.
1678 connect_to_get_msg (ModestWindow *win,
1679 gint num_of_uncached_msgs,
1680 TnyAccount *account)
1682 GtkResponseType response;
1684 /* Allways download if we are online. */
1685 if (tny_device_is_online (modest_runtime_get_device ()))
1688 /* If offline, then ask for user permission to download the messages */
1689 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1690 ngettext("mcen_nc_get_msg",
1692 num_of_uncached_msgs));
1694 if (response == GTK_RESPONSE_CANCEL)
1697 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1701 reply_forward_performer (gboolean canceled,
1703 GtkWindow *parent_window,
1704 TnyAccount *account,
1707 ReplyForwardHelper *rf_helper = NULL;
1708 ModestMailOperation *mail_op;
1710 rf_helper = (ReplyForwardHelper *) user_data;
1712 if (canceled || err) {
1713 free_reply_forward_helper (rf_helper);
1717 /* Retrieve the message */
1718 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1719 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1720 modest_ui_actions_disk_operations_error_handler,
1722 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1723 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1726 g_object_unref(mail_op);
1730 * Common code for the reply and forward actions
1733 reply_forward (ReplyForwardAction action, ModestWindow *win)
1735 ReplyForwardHelper *rf_helper = NULL;
1736 guint reply_forward_type;
1738 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1740 /* we check for low-mem; in that case, show a warning, and don't allow
1741 * reply/forward (because it could potentially require a lot of memory */
1742 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1746 /* we need an account when editing */
1747 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1748 if (!modest_ui_actions_run_account_setup_wizard (win))
1752 reply_forward_type =
1753 modest_conf_get_int (modest_runtime_get_conf (),
1754 (action == ACTION_FORWARD) ?
1755 MODEST_CONF_FORWARD_TYPE :
1756 MODEST_CONF_REPLY_TYPE,
1759 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1761 TnyHeader *header = NULL;
1762 /* Get header and message. Do not free them here, the
1763 reply_forward_cb must do it */
1764 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1765 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1767 if (msg && header) {
1769 rf_helper = create_reply_forward_helper (action, win,
1770 reply_forward_type, header);
1771 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1773 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1777 g_object_unref (msg);
1779 g_object_unref (header);
1781 TnyHeader *header = NULL;
1783 gboolean do_retrieve = TRUE;
1784 TnyList *header_list = NULL;
1786 header_list = get_selected_headers (win);
1789 /* Check that only one message is selected for replying */
1790 if (tny_list_get_length (header_list) != 1) {
1791 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1792 NULL, _("mcen_ib_select_one_message"));
1793 g_object_unref (header_list);
1797 /* Only reply/forward to one message */
1798 iter = tny_list_create_iterator (header_list);
1799 header = TNY_HEADER (tny_iterator_get_current (iter));
1800 g_object_unref (iter);
1802 /* Retrieve messages */
1803 do_retrieve = (action == ACTION_FORWARD) ||
1804 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1807 TnyAccount *account = NULL;
1808 TnyFolder *folder = NULL;
1809 gdouble download = TRUE;
1810 guint uncached_msgs = 0;
1812 folder = tny_header_get_folder (header);
1814 goto do_retrieve_frees;
1815 account = tny_folder_get_account (folder);
1817 goto do_retrieve_frees;
1819 uncached_msgs = header_list_count_uncached_msgs (header_list);
1821 if (uncached_msgs > 0) {
1822 /* Allways download if we are online. */
1823 if (!tny_device_is_online (modest_runtime_get_device ())) {
1826 /* If ask for user permission to download the messages */
1827 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1828 ngettext("mcen_nc_get_msg",
1832 /* End if the user does not want to continue */
1833 if (response == GTK_RESPONSE_CANCEL)
1840 rf_helper = create_reply_forward_helper (action, win,
1841 reply_forward_type, header);
1842 if (uncached_msgs > 0) {
1843 modest_platform_connect_and_perform (GTK_WINDOW (win),
1845 reply_forward_performer,
1848 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1849 account, rf_helper);
1854 g_object_unref (account);
1856 g_object_unref (folder);
1858 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
1861 g_object_unref (header_list);
1862 g_object_unref (header);
1867 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1869 g_return_if_fail (MODEST_IS_WINDOW(win));
1871 reply_forward (ACTION_REPLY, win);
1875 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1877 g_return_if_fail (MODEST_IS_WINDOW(win));
1879 reply_forward (ACTION_FORWARD, win);
1883 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1885 g_return_if_fail (MODEST_IS_WINDOW(win));
1887 reply_forward (ACTION_REPLY_TO_ALL, win);
1891 modest_ui_actions_on_next (GtkAction *action,
1892 ModestWindow *window)
1894 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1895 modest_msg_view_window_select_next_message (
1896 MODEST_MSG_VIEW_WINDOW (window));
1898 g_return_if_reached ();
1903 modest_ui_actions_on_prev (GtkAction *action,
1904 ModestWindow *window)
1906 g_return_if_fail (MODEST_IS_WINDOW(window));
1908 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1909 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1911 g_return_if_reached ();
1916 modest_ui_actions_on_sort (GtkAction *action,
1917 ModestWindow *window)
1919 GtkWidget *header_view = NULL;
1921 g_return_if_fail (MODEST_IS_WINDOW(window));
1923 if (MODEST_IS_HEADER_WINDOW (window)) {
1924 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1928 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1933 /* Show sorting dialog */
1934 modest_utils_run_sort_dialog (MODEST_WINDOW (window), MODEST_SORT_HEADERS);
1938 sync_folder_cb (ModestMailOperation *mail_op,
1942 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
1944 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
1945 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1947 /* We must clear first, because otherwise set_folder will ignore */
1948 /* the change as the folders are the same */
1949 modest_header_view_clear (header_view);
1950 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
1952 g_object_unref (parent);
1955 g_object_unref (header_view);
1959 idle_refresh_folder (gpointer source)
1961 ModestHeaderView *header_view = NULL;
1963 /* If the window still exists */
1964 if (!GTK_IS_WIDGET (source) ||
1965 !GTK_WIDGET_VISIBLE (source))
1968 /* Refresh the current view */
1969 if (MODEST_IS_HEADER_WINDOW (source))
1970 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
1972 TnyFolder *folder = modest_header_view_get_folder (header_view);
1974 /* Sync the folder status */
1975 ModestMailOperation *mail_op = modest_mail_operation_new (source);
1976 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1977 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
1978 g_object_unref (folder);
1979 g_object_unref (mail_op);
1987 update_account_cb (ModestMailOperation *self,
1988 TnyList *new_headers,
1992 gboolean show_visual_notifications;
1994 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
1995 show_visual_notifications = (top) ? FALSE : TRUE;
1997 /* Notify new messages have been downloaded. If the
1998 send&receive was invoked by the user then do not show any
1999 visual notification, only play a sound and activate the LED
2000 (for the Maemo version) */
2001 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2003 /* We only notify about really new messages (not seen) we get */
2004 TnyList *actually_new_list;
2005 TnyIterator *iterator;
2006 actually_new_list = TNY_LIST (tny_simple_list_new ());
2007 for (iterator = tny_list_create_iterator (new_headers);
2008 !tny_iterator_is_done (iterator);
2009 tny_iterator_next (iterator)) {
2011 TnyHeaderFlags flags;
2012 header = TNY_HEADER (tny_iterator_get_current (iterator));
2013 flags = tny_header_get_flags (header);
2015 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2016 /* Messages are ordered from most
2017 recent to oldest. But we want to
2018 show notifications starting from
2019 the oldest message. That's why we
2021 tny_list_prepend (actually_new_list, G_OBJECT (header));
2023 g_object_unref (header);
2025 g_object_unref (iterator);
2027 if (tny_list_get_length (actually_new_list) > 0) {
2028 GList *new_headers_list = NULL;
2030 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2032 /* Send notifications */
2033 if (new_headers_list) {
2034 modest_platform_on_new_headers_received (new_headers_list,
2035 show_visual_notifications);
2037 modest_utils_free_notification_list (new_headers_list);
2040 g_object_unref (actually_new_list);
2044 /* Refresh the current folder in an idle. We do this
2045 in order to avoid refresh cancelations if the
2046 currently viewed folder is the inbox */
2047 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2048 idle_refresh_folder,
2055 TnyAccount *account;
2057 gchar *account_name;
2058 gboolean poke_status;
2059 gboolean interactive;
2060 ModestMailOperation *mail_op;
2064 do_send_receive_performer (gboolean canceled,
2066 GtkWindow *parent_window,
2067 TnyAccount *account,
2070 SendReceiveInfo *info;
2072 info = (SendReceiveInfo *) user_data;
2074 if (err || canceled) {
2075 /* In disk full conditions we could get this error here */
2076 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2077 (GtkWidget *) parent_window, err,
2080 if (info->mail_op) {
2081 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2088 /* Send & receive. */
2089 modest_mail_operation_update_account (info->mail_op, info->account_name,
2090 info->poke_status, info->interactive,
2091 update_account_cb, info->win);
2096 g_object_unref (G_OBJECT (info->mail_op));
2097 if (info->account_name)
2098 g_free (info->account_name);
2100 g_object_unref (info->win);
2102 g_object_unref (info->account);
2103 g_slice_free (SendReceiveInfo, info);
2107 * This function performs the send & receive required actions. The
2108 * window is used to create the mail operation. Typically it should
2109 * always be the main window, but we pass it as argument in order to
2113 modest_ui_actions_do_send_receive (const gchar *account_name,
2114 gboolean force_connection,
2115 gboolean poke_status,
2116 gboolean interactive,
2119 gchar *acc_name = NULL;
2120 SendReceiveInfo *info;
2121 ModestTnyAccountStore *acc_store;
2122 TnyAccount *account;
2124 /* If no account name was provided then get the current account, and if
2125 there is no current account then pick the default one: */
2126 if (!account_name) {
2128 acc_name = g_strdup (modest_window_get_active_account (win));
2130 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2132 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2136 acc_name = g_strdup (account_name);
2139 acc_store = modest_runtime_get_account_store ();
2140 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2144 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2148 /* Do not automatically refresh accounts that are flagged as
2149 NO_AUTO_UPDATE. This could be useful for accounts that
2150 handle their own update times */
2152 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2153 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2154 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2155 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2157 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2158 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2159 g_object_unref (account);
2166 /* Create the info for the connect and perform */
2167 info = g_slice_new (SendReceiveInfo);
2168 info->account_name = acc_name;
2169 info->win = (win) ? g_object_ref (win) : NULL;
2170 info->poke_status = poke_status;
2171 info->interactive = interactive;
2172 info->account = account;
2173 /* We need to create the operation here, because otherwise it
2174 could happen that the queue emits the queue-empty signal
2175 while we're trying to connect the account */
2176 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2177 modest_ui_actions_disk_operations_error_handler,
2179 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2181 /* Invoke the connect and perform */
2182 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2183 force_connection, info->account,
2184 do_send_receive_performer, info);
2189 modest_ui_actions_do_cancel_send (const gchar *account_name,
2192 TnyTransportAccount *transport_account;
2193 TnySendQueue *send_queue = NULL;
2194 GError *error = NULL;
2196 /* Get transport account */
2198 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2199 (modest_runtime_get_account_store(),
2201 TNY_ACCOUNT_TYPE_TRANSPORT));
2202 if (!transport_account) {
2203 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2208 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2209 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2210 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2211 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2212 "modest: could not find send queue for account\n");
2214 /* Cancel the current send */
2215 tny_account_cancel (TNY_ACCOUNT (transport_account));
2217 /* Suspend all pending messages */
2218 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2222 if (transport_account != NULL)
2223 g_object_unref (G_OBJECT (transport_account));
2227 modest_ui_actions_cancel_send_all (ModestWindow *win)
2229 GSList *account_names, *iter;
2231 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2234 iter = account_names;
2236 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2237 iter = g_slist_next (iter);
2240 modest_account_mgr_free_account_names (account_names);
2241 account_names = NULL;
2245 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2248 /* Check if accounts exist */
2249 gboolean accounts_exist =
2250 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2252 /* If not, allow the user to create an account before trying to send/receive. */
2253 if (!accounts_exist)
2254 modest_ui_actions_on_accounts (NULL, win);
2256 /* Cancel all sending operaitons */
2257 modest_ui_actions_cancel_send_all (win);
2261 * Refreshes all accounts. This function will be used by automatic
2265 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2266 gboolean force_connection,
2267 gboolean poke_status,
2268 gboolean interactive)
2270 GSList *account_names, *iter;
2272 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2275 iter = account_names;
2277 modest_ui_actions_do_send_receive ((const char*) iter->data,
2279 poke_status, interactive, win);
2280 iter = g_slist_next (iter);
2283 modest_account_mgr_free_account_names (account_names);
2284 account_names = NULL;
2288 * Handler of the click on Send&Receive button in the main toolbar
2291 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2293 /* Check if accounts exist */
2294 gboolean accounts_exist;
2297 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2299 /* If not, allow the user to create an account before trying to send/receive. */
2300 if (!accounts_exist)
2301 modest_ui_actions_on_accounts (NULL, win);
2303 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2304 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2305 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2307 const gchar *active_account;
2308 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2310 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2317 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2320 ModestWindow *window)
2322 GtkTreeRowReference *rowref;
2324 g_return_if_fail (MODEST_IS_WINDOW(window));
2325 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2326 g_return_if_fail (TNY_IS_HEADER (header));
2328 if (modest_header_view_count_selected_headers (header_view) > 1) {
2329 /* Don't allow activation if there are more than one message selected */
2330 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2334 /* we check for low-mem; in that case, show a warning, and don't allow
2335 * activating headers
2337 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2341 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2342 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2343 gtk_tree_row_reference_free (rowref);
2347 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2354 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2356 online = tny_device_is_online (modest_runtime_get_device());
2359 /* already online -- the item is simply not there... */
2360 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2362 GTK_MESSAGE_WARNING,
2364 _("The %s you selected cannot be found"),
2366 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2367 gtk_dialog_run (GTK_DIALOG(dialog));
2369 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2372 _("mcen_bd_dialog_cancel"),
2373 GTK_RESPONSE_REJECT,
2374 _("mcen_bd_dialog_ok"),
2375 GTK_RESPONSE_ACCEPT,
2377 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2378 "Do you want to get online?"), item);
2379 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2380 gtk_label_new (txt), FALSE, FALSE, 0);
2381 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2384 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2385 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2386 /* TODO: Comment about why is this commented out: */
2387 /* modest_platform_connect_and_wait (); */
2390 gtk_widget_destroy (dialog);
2394 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2397 /* g_debug ("%s %s", __FUNCTION__, link); */
2402 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2405 modest_platform_activate_uri (link);
2409 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2412 modest_platform_show_uri_popup (link);
2416 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2419 /* we check for low-mem; in that case, show a warning, and don't allow
2420 * viewing attachments
2422 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2425 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2429 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2430 const gchar *address,
2433 /* g_debug ("%s %s", __FUNCTION__, address); */
2437 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2438 TnyMsg *saved_draft,
2441 ModestMsgEditWindow *edit_window;
2443 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2445 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2447 /* Set draft is there was no error */
2448 if (!modest_mail_operation_get_error (mail_op))
2449 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2451 g_object_unref(edit_window);
2455 enough_space_for_message (ModestMsgEditWindow *edit_window,
2458 guint64 available_disk, expected_size;
2463 available_disk = modest_utils_get_available_space (NULL);
2464 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2465 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2470 /* Double check: disk full condition or message too big */
2471 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2472 expected_size > available_disk) {
2473 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2474 modest_platform_information_banner (NULL, NULL, msg);
2481 * djcb: if we're in low-memory state, we only allow for
2482 * saving messages smaller than
2483 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2484 * should still allow for sending anything critical...
2486 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2487 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2491 * djcb: we also make sure that the attachments are smaller than the max size
2492 * this is for the case where we'd try to forward a message with attachments
2493 * bigger than our max allowed size, or sending an message from drafts which
2494 * somehow got past our checks when attaching.
2496 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2497 modest_platform_run_information_dialog (
2498 GTK_WINDOW(edit_window),
2499 _("mail_ib_error_attachment_size"),
2508 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2510 TnyTransportAccount *transport_account;
2511 ModestMailOperation *mail_operation;
2513 gchar *account_name;
2514 ModestAccountMgr *account_mgr;
2515 gboolean had_error = FALSE;
2517 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2519 data = modest_msg_edit_window_get_msg_data (edit_window);
2522 if (!enough_space_for_message (edit_window, data)) {
2523 modest_msg_edit_window_free_msg_data (edit_window, data);
2527 account_name = g_strdup (data->account_name);
2528 account_mgr = modest_runtime_get_account_mgr();
2530 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2532 account_name = modest_account_mgr_get_default_account (account_mgr);
2533 if (!account_name) {
2534 g_printerr ("modest: no account found\n");
2535 modest_msg_edit_window_free_msg_data (edit_window, data);
2539 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2540 account_name = g_strdup (data->account_name);
2544 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2545 (modest_runtime_get_account_store (),
2547 TNY_ACCOUNT_TYPE_TRANSPORT));
2548 if (!transport_account) {
2549 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2550 g_free (account_name);
2551 modest_msg_edit_window_free_msg_data (edit_window, data);
2555 /* Create the mail operation */
2556 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2558 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2560 modest_mail_operation_save_to_drafts (mail_operation,
2572 data->priority_flags,
2575 on_save_to_drafts_cb,
2576 g_object_ref(edit_window));
2578 /* In hildon2 we always show the information banner on saving to drafts.
2579 * It will be a system information banner in this case.
2581 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2582 modest_platform_information_banner (NULL, NULL, text);
2584 modest_msg_edit_window_set_modified (edit_window, FALSE);
2587 g_free (account_name);
2588 g_object_unref (G_OBJECT (transport_account));
2589 g_object_unref (G_OBJECT (mail_operation));
2591 modest_msg_edit_window_free_msg_data (edit_window, data);
2597 /* For instance, when clicking the Send toolbar button when editing a message: */
2599 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2601 TnyTransportAccount *transport_account = NULL;
2602 gboolean had_error = FALSE, add_to_contacts;
2604 ModestAccountMgr *account_mgr;
2605 gchar *account_name;
2606 ModestMailOperation *mail_operation;
2609 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2611 /* Check whether to automatically add new contacts to addressbook or not */
2612 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
2613 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
2614 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
2617 data = modest_msg_edit_window_get_msg_data (edit_window);
2619 recipients = g_strconcat (data->to?data->to:"",
2620 data->cc?data->cc:"",
2621 data->bcc?data->bcc:"",
2623 if (recipients == NULL || recipients[0] == '\0') {
2624 /* Empty subject -> no send */
2625 g_free (recipients);
2626 modest_msg_edit_window_free_msg_data (edit_window, data);
2629 g_free (recipients);
2632 if (!enough_space_for_message (edit_window, data)) {
2633 modest_msg_edit_window_free_msg_data (edit_window, data);
2637 account_mgr = modest_runtime_get_account_mgr();
2638 account_name = g_strdup (data->account_name);
2640 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2643 account_name = modest_account_mgr_get_default_account (account_mgr);
2645 if (!account_name) {
2646 modest_msg_edit_window_free_msg_data (edit_window, data);
2647 /* Run account setup wizard */
2648 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2653 /* Get the currently-active transport account for this modest account: */
2654 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2656 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2657 (modest_runtime_get_account_store (),
2658 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2661 if (!transport_account) {
2662 modest_msg_edit_window_free_msg_data (edit_window, data);
2663 /* Run account setup wizard */
2664 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2669 /* Create the mail operation */
2670 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2671 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2673 modest_mail_operation_send_new_mail (mail_operation,
2687 data->priority_flags);
2689 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2690 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2692 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2693 const GError *error = modest_mail_operation_get_error (mail_operation);
2694 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2695 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2696 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2697 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2703 g_free (account_name);
2704 g_object_unref (G_OBJECT (transport_account));
2705 g_object_unref (G_OBJECT (mail_operation));
2707 modest_msg_edit_window_free_msg_data (edit_window, data);
2710 modest_msg_edit_window_set_sent (edit_window, TRUE);
2712 /* Save settings and close the window: */
2713 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2720 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2721 ModestMsgEditWindow *window)
2723 ModestMsgEditFormatState *format_state = NULL;
2725 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2726 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2728 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2731 format_state = modest_msg_edit_window_get_format_state (window);
2732 g_return_if_fail (format_state != NULL);
2734 format_state->bold = gtk_toggle_action_get_active (action);
2735 modest_msg_edit_window_set_format_state (window, format_state);
2736 g_free (format_state);
2741 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2742 ModestMsgEditWindow *window)
2744 ModestMsgEditFormatState *format_state = NULL;
2746 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2747 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2749 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2752 format_state = modest_msg_edit_window_get_format_state (window);
2753 g_return_if_fail (format_state != NULL);
2755 format_state->italics = gtk_toggle_action_get_active (action);
2756 modest_msg_edit_window_set_format_state (window, format_state);
2757 g_free (format_state);
2762 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2763 ModestMsgEditWindow *window)
2765 ModestMsgEditFormatState *format_state = NULL;
2767 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2768 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2770 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2773 format_state = modest_msg_edit_window_get_format_state (window);
2774 g_return_if_fail (format_state != NULL);
2776 format_state->bullet = gtk_toggle_action_get_active (action);
2777 modest_msg_edit_window_set_format_state (window, format_state);
2778 g_free (format_state);
2783 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2784 GtkRadioAction *selected,
2785 ModestMsgEditWindow *window)
2787 ModestMsgEditFormatState *format_state = NULL;
2788 GtkJustification value;
2790 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2792 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2795 value = gtk_radio_action_get_current_value (selected);
2797 format_state = modest_msg_edit_window_get_format_state (window);
2798 g_return_if_fail (format_state != NULL);
2800 format_state->justification = value;
2801 modest_msg_edit_window_set_format_state (window, format_state);
2802 g_free (format_state);
2806 modest_ui_actions_on_select_editor_color (GtkAction *action,
2807 ModestMsgEditWindow *window)
2809 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2810 g_return_if_fail (GTK_IS_ACTION (action));
2812 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2815 modest_msg_edit_window_select_color (window);
2819 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2820 ModestMsgEditWindow *window)
2822 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2823 g_return_if_fail (GTK_IS_ACTION (action));
2825 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2831 modest_ui_actions_on_insert_image (GObject *object,
2832 ModestMsgEditWindow *window)
2834 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2837 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2840 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2843 modest_msg_edit_window_insert_image (window);
2847 modest_ui_actions_on_attach_file (GtkAction *action,
2848 ModestMsgEditWindow *window)
2850 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2851 g_return_if_fail (GTK_IS_ACTION (action));
2853 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2856 modest_msg_edit_window_offer_attach_file (window);
2860 modest_ui_actions_on_remove_attachments (GtkAction *action,
2861 ModestMsgEditWindow *window)
2863 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2865 modest_msg_edit_window_remove_attachments (window, NULL);
2869 do_create_folder_cb (ModestMailOperation *mail_op,
2870 TnyFolderStore *parent_folder,
2871 TnyFolder *new_folder,
2874 gchar *suggested_name = (gchar *) user_data;
2875 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
2876 const GError *error;
2878 error = modest_mail_operation_get_error (mail_op);
2880 gboolean disk_full = FALSE;
2881 TnyAccount *account;
2882 /* Show an error. If there was some problem writing to
2883 disk, show it, otherwise show the generic folder
2884 create error. We do it here and not in an error
2885 handler because the call to do_create_folder will
2886 stop the main loop in a gtk_dialog_run and then,
2887 the message won't be shown until that dialog is
2889 account = modest_mail_operation_get_account (mail_op);
2892 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2893 (GtkWidget *) source_win,
2896 _("mail_in_ui_folder_create_error_memory"));
2897 g_object_unref (account);
2900 /* Show an error and try again if there is no
2901 full memory condition */
2902 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
2903 _("mail_in_ui_folder_create_error"));
2904 do_create_folder (modest_toolkit_utils_parent_window (GTK_WIDGET (source_win)),
2905 parent_folder, (const gchar *) suggested_name);
2909 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
2910 * FIXME: any other? */
2911 GtkWidget *folder_view;
2913 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
2914 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
2916 /* Select the newly created folder. It could happen
2917 that the widget is no longer there (i.e. the window
2918 has been destroyed, so we need to check this */
2920 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
2922 g_object_unref (new_folder);
2924 /* Free. Note that the first time it'll be NULL so noop */
2925 g_free (suggested_name);
2926 g_object_unref (source_win);
2931 TnyFolderStore *parent;
2932 } CreateFolderConnect;
2935 do_create_folder_performer (gboolean canceled,
2937 GtkWindow *parent_window,
2938 TnyAccount *account,
2941 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
2942 ModestMailOperation *mail_op;
2944 if (canceled || err) {
2945 /* In disk full conditions we could get this error here */
2946 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2947 (GtkWidget *) parent_window, err,
2948 NULL, _("mail_in_ui_folder_create_error_memory"));
2950 /* This happens if we have selected the outbox folder
2952 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
2953 TNY_IS_MERGE_FOLDER (helper->parent)) {
2954 /* Show an error and retry */
2955 modest_platform_information_banner ((GtkWidget *) parent_window,
2957 _("mail_in_ui_folder_create_error"));
2959 do_create_folder (parent_window, helper->parent, helper->folder_name);
2965 mail_op = modest_mail_operation_new ((GObject *) parent_window);
2966 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2968 modest_mail_operation_create_folder (mail_op,
2970 (const gchar *) helper->folder_name,
2971 do_create_folder_cb,
2972 g_strdup (helper->folder_name));
2973 g_object_unref (mail_op);
2977 g_object_unref (helper->parent);
2978 if (helper->folder_name)
2979 g_free (helper->folder_name);
2980 g_slice_free (CreateFolderConnect, helper);
2985 do_create_folder (GtkWindow *parent_window,
2986 TnyFolderStore *suggested_parent,
2987 const gchar *suggested_name)
2990 gchar *folder_name = NULL;
2991 TnyFolderStore *parent_folder = NULL;
2993 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2995 (gchar *) suggested_name,
2999 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3000 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3001 helper->folder_name = g_strdup (folder_name);
3002 helper->parent = g_object_ref (parent_folder);
3004 modest_platform_connect_if_remote_and_perform (parent_window,
3007 do_create_folder_performer,
3012 g_free (folder_name);
3014 g_object_unref (parent_folder);
3018 modest_ui_actions_create_folder(GtkWindow *parent_window,
3019 GtkWidget *folder_view,
3020 TnyFolderStore *parent_folder)
3022 if (!parent_folder) {
3023 ModestTnyAccountStore *acc_store;
3025 acc_store = modest_runtime_get_account_store ();
3027 parent_folder = (TnyFolderStore *)
3028 modest_tny_account_store_get_local_folders_account (acc_store);
3031 if (parent_folder) {
3032 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3033 g_object_unref (parent_folder);
3038 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3041 g_return_if_fail (MODEST_IS_WINDOW(window));
3043 if (MODEST_IS_FOLDER_WINDOW (window)) {
3044 GtkWidget *folder_view;
3046 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3047 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3049 g_assert_not_reached ();
3054 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3057 const GError *error = NULL;
3058 gchar *message = NULL;
3060 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3062 /* Get error message */
3063 error = modest_mail_operation_get_error (mail_op);
3065 g_return_if_reached ();
3067 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3068 (GError *) error, account);
3070 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3071 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3072 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3073 message = _CS("ckdg_ib_folder_already_exists");
3074 } else if (error->domain == TNY_ERROR_DOMAIN &&
3075 error->code == TNY_SERVICE_ERROR_STATE) {
3076 /* This means that the folder is already in use (a
3077 message is opened for example */
3078 message = _("emev_ni_internal_error");
3080 message = _CS("ckdg_ib_unable_to_rename");
3083 /* We don't set a parent for the dialog because the dialog
3084 will be destroyed so the banner won't appear */
3085 modest_platform_information_banner (NULL, NULL, message);
3088 g_object_unref (account);
3094 TnyFolderStore *folder;
3099 on_rename_folder_cb (ModestMailOperation *mail_op,
3100 TnyFolder *new_folder,
3103 ModestFolderView *folder_view;
3105 /* If the window was closed when renaming a folder, or if
3106 * it's not a main window this will happen */
3107 if (!MODEST_IS_FOLDER_VIEW (user_data))
3110 folder_view = MODEST_FOLDER_VIEW (user_data);
3111 /* Note that if the rename fails new_folder will be NULL */
3113 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3115 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3119 on_rename_folder_performer (gboolean canceled,
3121 GtkWindow *parent_window,
3122 TnyAccount *account,
3125 ModestMailOperation *mail_op = NULL;
3126 GtkTreeSelection *sel = NULL;
3127 GtkWidget *folder_view = NULL;
3128 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3130 if (canceled || err) {
3131 /* In disk full conditions we could get this error here */
3132 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3133 (GtkWidget *) parent_window, err,
3138 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3139 modest_ui_actions_rename_folder_error_handler,
3140 parent_window, NULL);
3142 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3144 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3145 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3146 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3149 /* Clear the folders view */
3150 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3151 gtk_tree_selection_unselect_all (sel);
3153 /* Actually rename the folder */
3154 modest_mail_operation_rename_folder (mail_op,
3155 TNY_FOLDER (data->folder),
3156 (const gchar *) (data->new_name),
3157 on_rename_folder_cb,
3159 g_object_unref (mail_op);
3162 g_object_unref (data->folder);
3163 g_free (data->new_name);
3168 modest_ui_actions_on_rename_folder (GtkAction *action,
3169 ModestWindow *window)
3171 modest_ui_actions_on_edit_mode_rename_folder (window);
3175 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3177 TnyFolderStore *folder;
3178 GtkWidget *folder_view;
3179 gboolean do_rename = TRUE;
3181 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3183 if (MODEST_IS_FOLDER_WINDOW (window)) {
3184 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3189 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3194 if (TNY_IS_FOLDER (folder)) {
3195 gchar *folder_name = NULL;
3197 const gchar *current_name;
3198 TnyFolderStore *parent;
3200 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3201 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3202 response = modest_platform_run_rename_folder_dialog (MODEST_WINDOW (window),
3203 parent, current_name,
3205 g_object_unref (parent);
3207 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3210 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3211 rename_folder_data->folder = g_object_ref (folder);
3212 rename_folder_data->new_name = folder_name;
3213 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3214 folder, on_rename_folder_performer, rename_folder_data);
3217 g_object_unref (folder);
3222 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3225 GObject *win = modest_mail_operation_get_source (mail_op);
3227 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3228 _("mail_in_ui_folder_delete_error"),
3230 g_object_unref (win);
3234 TnyFolderStore *folder;
3235 gboolean move_to_trash;
3239 on_delete_folder_cb (gboolean canceled,
3241 GtkWindow *parent_window,
3242 TnyAccount *account,
3245 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3246 GtkWidget *folder_view;
3247 ModestMailOperation *mail_op;
3248 GtkTreeSelection *sel;
3250 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3251 /* Note that the connection process can fail due to
3252 memory low conditions as it can not successfully
3253 store the summary */
3254 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3255 (GtkWidget*) parent_window, err,
3257 g_debug ("Error connecting when trying to delete a folder");
3258 g_object_unref (G_OBJECT (info->folder));
3263 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3264 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3266 g_object_unref (G_OBJECT (info->folder));
3271 /* Unselect the folder before deleting it to free the headers */
3272 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3273 gtk_tree_selection_unselect_all (sel);
3275 /* Create the mail operation */
3277 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3278 modest_ui_actions_delete_folder_error_handler,
3281 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3283 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3285 g_object_unref (mail_op);
3286 g_object_unref (info->folder);
3291 delete_folder (ModestWindow *window, gboolean move_to_trash)
3293 TnyFolderStore *folder;
3294 GtkWidget *folder_view;
3298 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3300 if (MODEST_IS_FOLDER_WINDOW (window)) {
3301 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3308 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3313 /* Show an error if it's an account */
3314 if (!TNY_IS_FOLDER (folder)) {
3315 modest_platform_run_information_dialog (GTK_WINDOW (window),
3316 _("mail_in_ui_folder_delete_error"),
3318 g_object_unref (G_OBJECT (folder));
3323 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3324 tny_folder_get_name (TNY_FOLDER (folder)));
3325 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3326 (const gchar *) message);
3329 if (response == GTK_RESPONSE_OK) {
3330 TnyAccount *account = NULL;
3331 DeleteFolderInfo *info = NULL;
3332 info = g_new0(DeleteFolderInfo, 1);
3333 info->folder = g_object_ref (folder);
3334 info->move_to_trash = move_to_trash;
3336 account = tny_folder_get_account (TNY_FOLDER (folder));
3337 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3339 TNY_FOLDER_STORE (account),
3340 on_delete_folder_cb, info);
3341 g_object_unref (account);
3342 g_object_unref (folder);
3350 modest_ui_actions_on_delete_folder (GtkAction *action,
3351 ModestWindow *window)
3353 modest_ui_actions_on_edit_mode_delete_folder (window);
3357 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3359 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3361 return delete_folder (window, FALSE);
3365 typedef struct _PasswordDialogFields {
3366 GtkWidget *username;
3367 GtkWidget *password;
3369 } PasswordDialogFields;
3372 password_dialog_check_field (GtkEditable *editable,
3373 PasswordDialogFields *fields)
3376 gboolean any_value_empty = FALSE;
3378 value = modest_entry_get_text (fields->username);
3379 if ((value == NULL) || value[0] == '\0') {
3380 any_value_empty = TRUE;
3382 value = modest_entry_get_text (fields->password);
3383 if ((value == NULL) || value[0] == '\0') {
3384 any_value_empty = TRUE;
3386 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3390 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3391 const gchar* server_account_name,
3396 ModestMainWindow *main_window)
3398 g_return_if_fail(server_account_name);
3399 gboolean completed = FALSE;
3400 PasswordDialogFields *fields = NULL;
3402 /* Initalize output parameters: */
3409 #ifndef MODEST_TOOLKIT_GTK
3410 /* Maemo uses a different (awkward) button order,
3411 * It should probably just use gtk_alternative_dialog_button_order ().
3413 #ifdef MODEST_TOOLKIT_HILDON2
3415 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3418 _HL("wdgt_bd_done"),
3419 GTK_RESPONSE_ACCEPT,
3421 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3422 HILDON_MARGIN_DOUBLE);
3425 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3428 _("mcen_bd_dialog_ok"),
3429 GTK_RESPONSE_ACCEPT,
3430 _("mcen_bd_dialog_cancel"),
3431 GTK_RESPONSE_REJECT,
3433 #endif /* MODEST_TOOLKIT_HILDON2 */
3436 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3440 GTK_RESPONSE_REJECT,
3442 GTK_RESPONSE_ACCEPT,
3444 #endif /* MODEST_TOOLKIT_GTK */
3446 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3448 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3449 modest_runtime_get_account_mgr(), server_account_name);
3450 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3451 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3454 gtk_widget_destroy (dialog);
3458 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3459 GtkWidget *label = gtk_label_new (txt);
3460 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3462 g_free (server_name);
3463 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3468 gchar *initial_username = modest_account_mgr_get_server_account_username (
3469 modest_runtime_get_account_mgr(), server_account_name);
3471 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3472 if (initial_username)
3473 modest_entry_set_text (entry_username, initial_username);
3475 /* Dim this if a connection has ever succeeded with this username,
3476 * as per the UI spec: */
3477 /* const gboolean username_known = */
3478 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3479 /* modest_runtime_get_account_mgr(), server_account_name); */
3480 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3482 /* We drop the username sensitive code and disallow changing it here
3483 * as tinymail does not support really changing the username in the callback
3485 gtk_widget_set_sensitive (entry_username, FALSE);
3487 /* Auto-capitalization is the default, so let's turn it off: */
3488 #ifdef MAEMO_CHANGES
3489 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3492 /* Create a size group to be used by all captions.
3493 * Note that HildonCaption does not create a default size group if we do not specify one.
3494 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3495 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3497 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3498 _("mail_fi_username"), FALSE,
3500 gtk_widget_show (entry_username);
3501 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3502 FALSE, FALSE, MODEST_MARGIN_HALF);
3503 gtk_widget_show (caption);
3506 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3507 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3508 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3510 /* Auto-capitalization is the default, so let's turn it off: */
3511 #ifdef MAEMO_CHANGES
3512 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3513 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3516 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3517 _("mail_fi_password"), FALSE,
3519 gtk_widget_show (entry_password);
3520 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3521 FALSE, FALSE, MODEST_MARGIN_HALF);
3522 gtk_widget_show (caption);
3523 g_object_unref (sizegroup);
3525 if (initial_username != NULL)
3526 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3528 /* This is not in the Maemo UI spec:
3529 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3530 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3534 fields = g_slice_new0 (PasswordDialogFields);
3535 fields->username = entry_username;
3536 fields->password = entry_password;
3537 fields->dialog = dialog;
3539 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3540 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3541 password_dialog_check_field (NULL, fields);
3543 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3545 while (!completed) {
3547 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3549 *username = g_strdup (modest_entry_get_text (entry_username));
3551 /* Note that an empty field becomes the "" string */
3552 if (*username && strlen (*username) > 0) {
3553 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3554 server_account_name,
3558 const gboolean username_was_changed =
3559 (strcmp (*username, initial_username) != 0);
3560 if (username_was_changed) {
3561 g_warning ("%s: tinymail does not yet support changing the "
3562 "username in the get_password() callback.\n", __FUNCTION__);
3568 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3569 _("mcen_ib_username_pw_incorrect"));
3575 *password = g_strdup (modest_entry_get_text (entry_password));
3577 /* We do not save the password in the configuration,
3578 * because this function is only called for passwords that should
3579 * not be remembered:
3580 modest_server_account_set_password (
3581 modest_runtime_get_account_mgr(), server_account_name,
3598 /* This is not in the Maemo UI spec:
3599 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3605 g_free (initial_username);
3606 gtk_widget_destroy (dialog);
3607 g_slice_free (PasswordDialogFields, fields);
3609 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3613 modest_ui_actions_on_cut (GtkAction *action,
3614 ModestWindow *window)
3616 GtkWidget *focused_widget;
3617 GtkClipboard *clipboard;
3619 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3620 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3621 if (GTK_IS_EDITABLE (focused_widget)) {
3622 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3623 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3624 gtk_clipboard_store (clipboard);
3625 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3626 GtkTextBuffer *buffer;
3628 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3629 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3630 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3631 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3632 gtk_clipboard_store (clipboard);
3634 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3635 TnyList *header_list = modest_header_view_get_selected_headers (
3636 MODEST_HEADER_VIEW (focused_widget));
3637 gboolean continue_download = FALSE;
3638 gint num_of_unc_msgs;
3640 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3642 if (num_of_unc_msgs) {
3643 TnyAccount *account = get_account_from_header_list (header_list);
3645 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3646 g_object_unref (account);
3650 if (num_of_unc_msgs == 0 || continue_download) {
3651 /* modest_platform_information_banner (
3652 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3653 modest_header_view_cut_selection (
3654 MODEST_HEADER_VIEW (focused_widget));
3657 g_object_unref (header_list);
3658 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3659 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3664 modest_ui_actions_on_copy (GtkAction *action,
3665 ModestWindow *window)
3667 GtkClipboard *clipboard;
3668 GtkWidget *focused_widget;
3669 gboolean copied = TRUE;
3671 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3672 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3674 if (GTK_IS_LABEL (focused_widget)) {
3676 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3677 gtk_clipboard_set_text (clipboard, selection, -1);
3679 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3680 gtk_clipboard_store (clipboard);
3681 } else if (GTK_IS_EDITABLE (focused_widget)) {
3682 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3683 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3684 gtk_clipboard_store (clipboard);
3685 } else if (GTK_IS_HTML (focused_widget)) {
3688 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3689 if ((sel == NULL) || (sel[0] == '\0')) {
3692 gtk_html_copy (GTK_HTML (focused_widget));
3693 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3694 gtk_clipboard_store (clipboard);
3696 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3697 GtkTextBuffer *buffer;
3698 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3699 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3700 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3701 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3702 gtk_clipboard_store (clipboard);
3704 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3705 TnyList *header_list = modest_header_view_get_selected_headers (
3706 MODEST_HEADER_VIEW (focused_widget));
3707 gboolean continue_download = FALSE;
3708 gint num_of_unc_msgs;
3710 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3712 if (num_of_unc_msgs) {
3713 TnyAccount *account = get_account_from_header_list (header_list);
3715 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3716 g_object_unref (account);
3720 if (num_of_unc_msgs == 0 || continue_download) {
3721 modest_platform_information_banner (
3722 NULL, NULL, _CS("mcen_ib_getting_items"));
3723 modest_header_view_copy_selection (
3724 MODEST_HEADER_VIEW (focused_widget));
3728 g_object_unref (header_list);
3730 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3731 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3734 /* Show information banner if there was a copy to clipboard */
3736 modest_platform_information_banner (
3737 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3741 modest_ui_actions_on_undo (GtkAction *action,
3742 ModestWindow *window)
3744 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3745 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3747 g_return_if_reached ();
3752 modest_ui_actions_on_redo (GtkAction *action,
3753 ModestWindow *window)
3755 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3756 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3759 g_return_if_reached ();
3765 destroy_information_note (ModestMailOperation *mail_op,
3768 /* destroy information note */
3769 gtk_widget_destroy (GTK_WIDGET(user_data));
3773 destroy_folder_information_note (ModestMailOperation *mail_op,
3774 TnyFolder *new_folder,
3777 /* destroy information note */
3778 gtk_widget_destroy (GTK_WIDGET(user_data));
3783 paste_as_attachment_free (gpointer data)
3785 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3787 if (helper->banner) {
3788 gtk_widget_destroy (helper->banner);
3789 g_object_unref (helper->banner);
3795 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3800 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3801 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3806 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3811 modest_ui_actions_on_paste (GtkAction *action,
3812 ModestWindow *window)
3814 GtkWidget *focused_widget = NULL;
3815 GtkWidget *inf_note = NULL;
3816 ModestMailOperation *mail_op = NULL;
3818 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3819 if (GTK_IS_EDITABLE (focused_widget)) {
3820 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3821 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3822 ModestEmailClipboard *e_clipboard = NULL;
3823 e_clipboard = modest_runtime_get_email_clipboard ();
3824 if (modest_email_clipboard_cleared (e_clipboard)) {
3825 GtkTextBuffer *buffer;
3826 GtkClipboard *clipboard;
3828 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3829 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3830 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3831 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3832 ModestMailOperation *mail_op;
3833 TnyFolder *src_folder = NULL;
3834 TnyList *data = NULL;
3836 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3837 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3838 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3839 _CS("ckct_nw_pasting"));
3840 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3841 mail_op = modest_mail_operation_new (G_OBJECT (window));
3842 if (helper->banner != NULL) {
3843 g_object_ref (G_OBJECT (helper->banner));
3844 gtk_widget_show (GTK_WIDGET (helper->banner));
3848 modest_mail_operation_get_msgs_full (mail_op,
3850 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3852 paste_as_attachment_free);
3856 g_object_unref (data);
3858 g_object_unref (src_folder);
3861 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3862 ModestEmailClipboard *clipboard = NULL;
3863 TnyFolder *src_folder = NULL;
3864 TnyFolderStore *folder_store = NULL;
3865 TnyList *data = NULL;
3866 gboolean delete = FALSE;
3868 /* Check clipboard source */
3869 clipboard = modest_runtime_get_email_clipboard ();
3870 if (modest_email_clipboard_cleared (clipboard))
3873 /* Get elements to paste */
3874 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3876 /* Create a new mail operation */
3877 mail_op = modest_mail_operation_new (G_OBJECT(window));
3879 /* Get destination folder */
3880 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3882 /* transfer messages */
3886 /* Ask for user confirmation */
3888 modest_ui_actions_msgs_move_to_confirmation (window,
3889 TNY_FOLDER (folder_store),
3893 if (response == GTK_RESPONSE_OK) {
3894 /* Launch notification */
3895 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3896 _CS("ckct_nw_pasting"));
3897 if (inf_note != NULL) {
3898 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3899 gtk_widget_show (GTK_WIDGET(inf_note));
3902 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3903 modest_mail_operation_xfer_msgs (mail_op,
3905 TNY_FOLDER (folder_store),
3907 destroy_information_note,
3910 g_object_unref (mail_op);
3913 } else if (src_folder != NULL) {
3914 /* Launch notification */
3915 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3916 _CS("ckct_nw_pasting"));
3917 if (inf_note != NULL) {
3918 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3919 gtk_widget_show (GTK_WIDGET(inf_note));
3922 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3923 modest_mail_operation_xfer_folder (mail_op,
3927 destroy_folder_information_note,
3933 g_object_unref (data);
3934 if (src_folder != NULL)
3935 g_object_unref (src_folder);
3936 if (folder_store != NULL)
3937 g_object_unref (folder_store);
3943 modest_ui_actions_on_select_all (GtkAction *action,
3944 ModestWindow *window)
3946 GtkWidget *focused_widget;
3948 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3949 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3950 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3951 } else if (GTK_IS_LABEL (focused_widget)) {
3952 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3953 } else if (GTK_IS_EDITABLE (focused_widget)) {
3954 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3955 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3956 GtkTextBuffer *buffer;
3957 GtkTextIter start, end;
3959 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3960 gtk_text_buffer_get_start_iter (buffer, &start);
3961 gtk_text_buffer_get_end_iter (buffer, &end);
3962 gtk_text_buffer_select_range (buffer, &start, &end);
3963 } else if (GTK_IS_HTML (focused_widget)) {
3964 gtk_html_select_all (GTK_HTML (focused_widget));
3970 modest_ui_actions_on_mark_as_read (GtkAction *action,
3971 ModestWindow *window)
3973 g_return_if_fail (MODEST_IS_WINDOW(window));
3975 /* Mark each header as read */
3976 do_headers_action (window, headers_action_mark_as_read, NULL);
3980 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3981 ModestWindow *window)
3983 g_return_if_fail (MODEST_IS_WINDOW(window));
3985 /* Mark each header as read */
3986 do_headers_action (window, headers_action_mark_as_unread, NULL);
3990 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3991 GtkRadioAction *selected,
3992 ModestWindow *window)
3996 value = gtk_radio_action_get_current_value (selected);
3997 if (MODEST_IS_WINDOW (window)) {
3998 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4003 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4004 GtkRadioAction *selected,
4005 ModestWindow *window)
4007 TnyHeaderFlags flags;
4008 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4010 flags = gtk_radio_action_get_current_value (selected);
4011 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4015 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4016 GtkRadioAction *selected,
4017 ModestWindow *window)
4021 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4023 file_format = gtk_radio_action_get_current_value (selected);
4024 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4029 modest_ui_actions_on_zoom_plus (GtkAction *action,
4030 ModestWindow *window)
4032 g_return_if_fail (MODEST_IS_WINDOW (window));
4034 modest_window_zoom_plus (MODEST_WINDOW (window));
4038 modest_ui_actions_on_zoom_minus (GtkAction *action,
4039 ModestWindow *window)
4041 g_return_if_fail (MODEST_IS_WINDOW (window));
4043 modest_window_zoom_minus (MODEST_WINDOW (window));
4047 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4048 ModestWindow *window)
4050 ModestWindowMgr *mgr;
4051 gboolean fullscreen, active;
4052 g_return_if_fail (MODEST_IS_WINDOW (window));
4054 mgr = modest_runtime_get_window_mgr ();
4056 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4057 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4059 if (active != fullscreen) {
4060 modest_window_mgr_set_fullscreen_mode (mgr, active);
4061 #ifndef MODEST_TOOLKIT_HILDON2
4062 gtk_window_present (GTK_WINDOW (window));
4068 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4069 ModestWindow *window)
4071 ModestWindowMgr *mgr;
4072 gboolean fullscreen;
4074 g_return_if_fail (MODEST_IS_WINDOW (window));
4076 mgr = modest_runtime_get_window_mgr ();
4077 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4078 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4080 #ifndef MODEST_TOOLKIT_HILDON2
4081 gtk_window_present (GTK_WINDOW (window));
4086 * Used by modest_ui_actions_on_details to call do_headers_action
4089 headers_action_show_details (TnyHeader *header,
4090 ModestWindow *window,
4094 gboolean async_retrieval;
4097 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4098 async_retrieval = TRUE;
4099 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4101 async_retrieval = FALSE;
4103 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4105 g_object_unref (msg);
4109 * Show the header details in a ModestDetailsDialog widget
4112 modest_ui_actions_on_details (GtkAction *action,
4115 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4119 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4123 header = tny_msg_get_header (msg);
4125 headers_action_show_details (header, win, NULL);
4126 g_object_unref (header);
4128 g_object_unref (msg);
4129 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4131 GtkWidget *header_view;
4133 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4134 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4136 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4138 g_object_unref (folder);
4144 modest_ui_actions_on_limit_error (GtkAction *action,
4147 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4149 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4154 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4155 ModestMsgEditWindow *window)
4157 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4159 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4163 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4164 ModestMsgEditWindow *window)
4166 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4168 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4173 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4174 ModestWindow *window)
4176 gboolean active, fullscreen = FALSE;
4177 ModestWindowMgr *mgr;
4179 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4181 /* Check if we want to toggle the toolbar view in fullscreen
4183 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4184 "ViewShowToolbarFullScreen")) {
4188 /* Toggle toolbar */
4189 mgr = modest_runtime_get_window_mgr ();
4190 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4194 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4195 ModestMsgEditWindow *window)
4197 modest_msg_edit_window_select_font (window);
4202 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4203 const gchar *display_name,
4206 /* don't update the display name if it was already set;
4207 * updating the display name apparently is expensive */
4208 const gchar* old_name = gtk_window_get_title (window);
4210 if (display_name == NULL)
4213 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4214 return; /* don't do anything */
4216 /* This is usually used to change the title of the main window, which
4217 * is the one that holds the folder view. Note that this change can
4218 * happen even when the widget doesn't have the focus. */
4219 gtk_window_set_title (window, display_name);
4224 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4226 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4227 modest_msg_edit_window_select_contacts (window);
4231 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4233 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4234 modest_msg_edit_window_check_names (window, FALSE);
4239 on_move_to_dialog_response (GtkDialog *dialog,
4243 GtkWidget *parent_win;
4244 MoveToInfo *helper = NULL;
4245 ModestFolderView *folder_view;
4246 gboolean unset_edit_mode = FALSE;
4248 helper = (MoveToInfo *) user_data;
4250 parent_win = (GtkWidget *) helper->win;
4251 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4252 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4254 TnyFolderStore *dst_folder;
4255 TnyFolderStore *selected;
4257 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4258 selected = modest_folder_view_get_selected (folder_view);
4259 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
4260 g_object_unref (selected);
4262 case GTK_RESPONSE_NONE:
4263 case GTK_RESPONSE_CANCEL:
4264 case GTK_RESPONSE_DELETE_EVENT:
4266 case GTK_RESPONSE_OK:
4267 dst_folder = modest_folder_view_get_selected (folder_view);
4269 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4270 /* Clean list to move used for filtering */
4271 modest_folder_view_set_list_to_move (folder_view, NULL);
4273 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4276 GTK_WINDOW (parent_win));
4278 /* if the user selected a root folder
4279 (account) then do not perform any action */
4280 if (TNY_IS_ACCOUNT (dst_folder)) {
4281 g_signal_stop_emission_by_name (dialog, "response");
4285 /* Clean list to move used for filtering */
4286 modest_folder_view_set_list_to_move (folder_view, NULL);
4288 /* Moving from headers window in edit mode */
4289 modest_ui_actions_on_window_move_to (NULL, helper->list,
4291 MODEST_WINDOW (parent_win));
4295 g_object_unref (dst_folder);
4297 unset_edit_mode = TRUE;
4300 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4303 /* Free the helper and exit */
4305 g_object_unref (helper->list);
4306 if (unset_edit_mode) {
4307 #ifdef MODEST_TOOLKIT_HILDON2
4308 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4311 g_slice_free (MoveToInfo, helper);
4312 gtk_widget_destroy (GTK_WIDGET (dialog));
4316 create_move_to_dialog (GtkWindow *win,
4317 GtkWidget *folder_view,
4318 TnyList *list_to_move)
4320 GtkWidget *dialog, *tree_view = NULL;
4322 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4325 /* It could happen that we're trying to move a message from a
4326 window (msg window for example) after the main window was
4327 closed, so we can not just get the model of the folder
4329 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4330 const gchar *visible_id = NULL;
4332 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4333 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4334 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4335 MODEST_FOLDER_VIEW(tree_view));
4338 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4340 /* Show the same account than the one that is shown in the main window */
4341 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4344 const gchar *active_account_name = NULL;
4345 ModestAccountMgr *mgr = NULL;
4346 ModestAccountSettings *settings = NULL;
4347 ModestServerAccountSettings *store_settings = NULL;
4349 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4350 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4351 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4352 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4354 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4355 mgr = modest_runtime_get_account_mgr ();
4356 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4359 const gchar *store_account_name;
4360 store_settings = modest_account_settings_get_store_settings (settings);
4361 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4363 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4364 store_account_name);
4365 g_object_unref (store_settings);
4366 g_object_unref (settings);
4370 /* we keep a pointer to the embedded folder view, so we can
4371 * retrieve it with get_folder_view_from_move_to_dialog (see
4372 * above) later (needed for focus handling)
4374 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4376 /* Hide special folders */
4378 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4380 gtk_widget_show (GTK_WIDGET (tree_view));
4386 * Shows a confirmation dialog to the user when we're moving messages
4387 * from a remote server to the local storage. Returns the dialog
4388 * response. If it's other kind of movement then it always returns
4391 * This one is used by the next functions:
4392 * modest_ui_actions_on_paste - commented out
4393 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4396 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4397 TnyFolder *dest_folder,
4401 gint response = GTK_RESPONSE_OK;
4402 TnyAccount *account = NULL;
4403 TnyFolder *src_folder = NULL;
4404 TnyIterator *iter = NULL;
4405 TnyHeader *header = NULL;
4407 /* return with OK if the destination is a remote folder */
4408 if (modest_tny_folder_is_remote_folder (dest_folder))
4409 return GTK_RESPONSE_OK;
4411 /* Get source folder */
4412 iter = tny_list_create_iterator (headers);
4413 header = TNY_HEADER (tny_iterator_get_current (iter));
4415 src_folder = tny_header_get_folder (header);
4416 g_object_unref (header);
4418 g_object_unref (iter);
4420 /* if no src_folder, message may be an attahcment */
4421 if (src_folder == NULL)
4422 return GTK_RESPONSE_CANCEL;
4424 /* If the source is a local or MMC folder */
4425 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4426 g_object_unref (src_folder);
4427 return GTK_RESPONSE_OK;
4430 /* Get the account */
4431 account = tny_folder_get_account (src_folder);
4433 /* now if offline we ask the user */
4434 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4435 response = GTK_RESPONSE_OK;
4437 response = GTK_RESPONSE_CANCEL;
4440 g_object_unref (src_folder);
4441 g_object_unref (account);
4447 move_to_helper_destroyer (gpointer user_data)
4449 MoveToHelper *helper = (MoveToHelper *) user_data;
4451 /* Close the "Pasting" information banner */
4452 if (helper->banner) {
4453 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4454 g_object_unref (helper->banner);
4456 if (gtk_tree_row_reference_valid (helper->reference)) {
4457 gtk_tree_row_reference_free (helper->reference);
4458 helper->reference = NULL;
4464 move_to_cb (ModestMailOperation *mail_op,
4467 MoveToHelper *helper = (MoveToHelper *) user_data;
4468 GObject *object = modest_mail_operation_get_source (mail_op);
4470 /* Note that the operation could have failed, in that case do
4472 if (modest_mail_operation_get_status (mail_op) !=
4473 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4476 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4477 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4479 if (!modest_msg_view_window_select_next_message (self) &&
4480 !modest_msg_view_window_select_previous_message (self)) {
4481 /* No more messages to view, so close this window */
4482 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4485 g_object_unref (object);
4488 /* Destroy the helper */
4489 move_to_helper_destroyer (helper);
4493 folder_move_to_cb (ModestMailOperation *mail_op,
4494 TnyFolder *new_folder,
4499 object = modest_mail_operation_get_source (mail_op);
4501 move_to_cb (mail_op, user_data);
4506 msgs_move_to_cb (ModestMailOperation *mail_op,
4509 move_to_cb (mail_op, user_data);
4513 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4516 GObject *win = NULL;
4517 const GError *error;
4518 TnyAccount *account = NULL;
4520 win = modest_mail_operation_get_source (mail_op);
4521 error = modest_mail_operation_get_error (mail_op);
4523 if (TNY_IS_FOLDER (user_data))
4524 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4525 else if (TNY_IS_ACCOUNT (user_data))
4526 account = g_object_ref (user_data);
4528 /* If it's not a disk full error then show a generic error */
4529 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4530 (GtkWidget *) win, (GError *) error,
4532 modest_platform_run_information_dialog ((GtkWindow *) win,
4533 _("mail_in_ui_folder_move_target_error"),
4536 g_object_unref (account);
4538 g_object_unref (win);
4543 * Checks if we need a connection to do the transfer and if the user
4544 * wants to connect to complete it
4547 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
4548 TnyFolderStore *src_folder,
4550 TnyFolder *dst_folder,
4551 gboolean delete_originals,
4552 gboolean *need_connection,
4555 TnyAccount *src_account;
4556 gint uncached_msgs = 0;
4558 /* We don't need any further check if
4560 * 1- the source folder is local OR
4561 * 2- the device is already online
4563 if (!modest_tny_folder_store_is_remote (src_folder) ||
4564 tny_device_is_online (modest_runtime_get_device())) {
4565 *need_connection = FALSE;
4570 /* We must ask for a connection when
4572 * - the message(s) is not already cached OR
4573 * - the message(s) is cached but the leave_on_server setting
4574 * is FALSE (because we need to sync the source folder to
4575 * delete the message from the server (for IMAP we could do it
4576 * offline, it'll take place the next time we get a
4579 uncached_msgs = header_list_count_uncached_msgs (headers);
4580 src_account = get_account_from_folder_store (src_folder);
4581 if (uncached_msgs > 0) {
4585 *need_connection = TRUE;
4586 num_headers = tny_list_get_length (headers);
4587 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4589 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
4590 GTK_RESPONSE_CANCEL) {
4596 /* The transfer is possible and the user wants to */
4599 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4600 const gchar *account_name;
4601 gboolean leave_on_server;
4603 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4604 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4607 if (leave_on_server == TRUE) {
4608 *need_connection = FALSE;
4610 *need_connection = TRUE;
4613 *need_connection = FALSE;
4618 g_object_unref (src_account);
4622 xfer_messages_error_handler (ModestMailOperation *mail_op,
4626 const GError *error;
4627 TnyAccount *account;
4629 win = modest_mail_operation_get_source (mail_op);
4630 error = modest_mail_operation_get_error (mail_op);
4632 /* We cannot get the account from the mail op as that is the
4633 source account and for checking memory full conditions we
4634 need the destination one */
4635 account = TNY_ACCOUNT (user_data);
4638 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4639 (GtkWidget *) win, (GError*) error,
4640 account, _KR("cerm_memory_card_full"))) {
4641 modest_platform_run_information_dialog ((GtkWindow *) win,
4642 _("mail_in_ui_folder_move_target_error"),
4646 g_object_unref (win);
4650 TnyFolderStore *dst_folder;
4655 * Utility function that transfer messages from both the main window
4656 * and the msg view window when using the "Move to" dialog
4659 xfer_messages_performer (gboolean canceled,
4661 GtkWindow *parent_window,
4662 TnyAccount *account,
4665 ModestWindow *win = MODEST_WINDOW (parent_window);
4666 TnyAccount *dst_account = NULL;
4667 gboolean dst_forbids_message_add = FALSE;
4668 XferMsgsHelper *helper;
4669 MoveToHelper *movehelper;
4670 ModestMailOperation *mail_op;
4672 helper = (XferMsgsHelper *) user_data;
4674 if (canceled || err) {
4675 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4676 (GtkWidget *) parent_window, err,
4678 /* Show the proper error message */
4679 modest_ui_actions_on_account_connection_error (parent_window, account);
4684 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4686 /* tinymail will return NULL for local folders it seems */
4687 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4688 modest_tny_account_get_protocol_type (dst_account),
4689 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4691 if (dst_forbids_message_add) {
4692 modest_platform_information_banner (GTK_WIDGET (win),
4694 ngettext("mail_in_ui_folder_move_target_error",
4695 "mail_in_ui_folder_move_targets_error",
4696 tny_list_get_length (helper->headers)));
4700 movehelper = g_new0 (MoveToHelper, 1);
4703 /* Perform the mail operation */
4704 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4705 xfer_messages_error_handler,
4706 g_object_ref (dst_account),
4708 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4711 modest_mail_operation_xfer_msgs (mail_op,
4713 TNY_FOLDER (helper->dst_folder),
4718 g_object_unref (G_OBJECT (mail_op));
4721 g_object_unref (dst_account);
4722 g_object_unref (helper->dst_folder);
4723 g_object_unref (helper->headers);
4724 g_slice_free (XferMsgsHelper, helper);
4728 TnyFolder *src_folder;
4729 TnyFolderStore *dst_folder;
4730 gboolean delete_original;
4731 GtkWidget *folder_view;
4735 on_move_folder_cb (gboolean canceled,
4737 GtkWindow *parent_window,
4738 TnyAccount *account,
4741 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4742 GtkTreeSelection *sel;
4743 ModestMailOperation *mail_op = NULL;
4745 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4746 /* Note that the connection process can fail due to
4747 memory low conditions as it can not successfully
4748 store the summary */
4749 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4750 (GtkWidget*) parent_window, err,
4752 g_debug ("Error connecting when trying to move a folder");
4754 g_object_unref (G_OBJECT (info->src_folder));
4755 g_object_unref (G_OBJECT (info->dst_folder));
4760 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4761 #ifndef MODEST_TOOLKIT_HILDON2
4762 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4763 _CS("ckct_nw_pasting"));
4764 if (helper->banner != NULL) {
4765 g_object_ref (helper->banner);
4766 gtk_widget_show (GTK_WIDGET(helper->banner));
4769 /* Clean folder on header view before moving it */
4770 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4771 gtk_tree_selection_unselect_all (sel);
4773 /* Let gtk events run. We need that the folder
4774 view frees its reference to the source
4775 folder *before* issuing the mail operation
4776 so we need the signal handler of selection
4777 changed to happen before the mail
4779 while (gtk_events_pending ())
4780 gtk_main_iteration (); */
4783 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4784 modest_ui_actions_move_folder_error_handler,
4785 g_object_ref (info->dst_folder), g_object_unref);
4786 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4789 modest_mail_operation_xfer_folder (mail_op,
4790 TNY_FOLDER (info->src_folder),
4792 info->delete_original,
4795 g_object_unref (G_OBJECT (info->src_folder));
4797 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4800 /* Unref mail operation */
4801 g_object_unref (G_OBJECT (mail_op));
4802 g_object_unref (G_OBJECT (info->dst_folder));
4807 get_account_from_folder_store (TnyFolderStore *folder_store)
4809 if (TNY_IS_ACCOUNT (folder_store))
4810 return g_object_ref (folder_store);
4812 return tny_folder_get_account (TNY_FOLDER (folder_store));
4816 * UI handler for the "Move to" action when invoked from the
4817 * ModestFolderWindow
4820 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4821 TnyFolderStore *dst_folder,
4825 TnyFolderStore *src_folder = NULL;
4826 TnyIterator *iterator;
4828 if (tny_list_get_length (selection) != 1)
4831 iterator = tny_list_create_iterator (selection);
4832 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
4833 g_object_unref (iterator);
4836 gboolean do_xfer = TRUE;
4838 /* Allow only to transfer folders to the local root folder */
4839 if (TNY_IS_ACCOUNT (dst_folder) &&
4840 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
4841 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
4844 modest_platform_run_information_dialog (win,
4845 _("mail_in_ui_folder_move_target_error"),
4847 } else if (!TNY_IS_FOLDER (src_folder)) {
4848 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4853 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4854 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4856 info->src_folder = g_object_ref (src_folder);
4857 info->dst_folder = g_object_ref (dst_folder);
4858 info->delete_original = TRUE;
4859 info->folder_view = folder_view;
4861 connect_info->callback = on_move_folder_cb;
4862 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
4863 connect_info->data = info;
4865 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4866 TNY_FOLDER_STORE (src_folder),
4871 g_object_unref (src_folder);
4876 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
4877 TnyFolder *src_folder,
4879 TnyFolder *dst_folder)
4881 gboolean need_connection = TRUE;
4882 gboolean do_xfer = TRUE;
4883 XferMsgsHelper *helper;
4885 g_return_if_fail (TNY_IS_FOLDER (src_folder));
4886 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4887 g_return_if_fail (TNY_IS_LIST (headers));
4889 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
4890 headers, TNY_FOLDER (dst_folder),
4891 TRUE, &need_connection,
4894 /* If we don't want to transfer just return */
4898 /* Create the helper */
4899 helper = g_slice_new (XferMsgsHelper);
4900 helper->dst_folder = g_object_ref (dst_folder);
4901 helper->headers = g_object_ref (headers);
4903 if (need_connection) {
4904 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4905 connect_info->callback = xfer_messages_performer;
4906 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4907 connect_info->data = helper;
4909 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4910 TNY_FOLDER_STORE (src_folder),
4913 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
4914 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
4915 src_account, helper);
4916 g_object_unref (src_account);
4921 * UI handler for the "Move to" action when invoked from the
4922 * ModestMsgViewWindow
4925 modest_ui_actions_on_window_move_to (GtkAction *action,
4927 TnyFolderStore *dst_folder,
4930 TnyFolder *src_folder = NULL;
4932 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4935 TnyHeader *header = NULL;
4938 iter = tny_list_create_iterator (headers);
4939 header = (TnyHeader *) tny_iterator_get_current (iter);
4940 src_folder = tny_header_get_folder (header);
4942 /* Transfer the messages */
4943 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
4945 TNY_FOLDER (dst_folder));
4948 g_object_unref (header);
4949 g_object_unref (iter);
4950 g_object_unref (src_folder);
4955 modest_ui_actions_on_move_to (GtkAction *action,
4958 modest_ui_actions_on_edit_mode_move_to (win);
4962 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
4964 GtkWidget *dialog = NULL;
4965 MoveToInfo *helper = NULL;
4966 TnyList *list_to_move;
4968 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
4971 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
4976 if (tny_list_get_length (list_to_move) < 1) {
4977 g_object_unref (list_to_move);
4981 /* Create and run the dialog */
4982 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
4983 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
4984 GTK_WINDOW (dialog),
4988 helper = g_slice_new0 (MoveToInfo);
4989 helper->list = list_to_move;
4992 /* Listen to response signal */
4993 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
4995 /* Show the dialog */
4996 gtk_widget_show (dialog);
5002 * Calls #HeadersFunc for each header already selected in the main
5003 * window or the message currently being shown in the msg view window
5006 do_headers_action (ModestWindow *win,
5010 TnyList *headers_list = NULL;
5011 TnyIterator *iter = NULL;
5012 TnyHeader *header = NULL;
5013 TnyFolder *folder = NULL;
5016 headers_list = get_selected_headers (win);
5020 /* Get the folder */
5021 iter = tny_list_create_iterator (headers_list);
5022 header = TNY_HEADER (tny_iterator_get_current (iter));
5024 folder = tny_header_get_folder (header);
5025 g_object_unref (header);
5028 /* Call the function for each header */
5029 while (!tny_iterator_is_done (iter)) {
5030 header = TNY_HEADER (tny_iterator_get_current (iter));
5031 func (header, win, user_data);
5032 g_object_unref (header);
5033 tny_iterator_next (iter);
5036 /* Trick: do a poke status in order to speed up the signaling
5039 tny_folder_poke_status (folder);
5040 g_object_unref (folder);
5044 g_object_unref (iter);
5045 g_object_unref (headers_list);
5049 modest_ui_actions_view_attachment (GtkAction *action,
5050 ModestWindow *window)
5052 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5053 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5055 /* not supported window for this action */
5056 g_return_if_reached ();
5061 modest_ui_actions_save_attachments (GtkAction *action,
5062 ModestWindow *window)
5064 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5066 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5069 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5071 /* not supported window for this action */
5072 g_return_if_reached ();
5077 modest_ui_actions_remove_attachments (GtkAction *action,
5078 ModestWindow *window)
5080 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5081 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5083 /* not supported window for this action */
5084 g_return_if_reached ();
5089 modest_ui_actions_on_settings (GtkAction *action,
5094 dialog = modest_platform_get_global_settings_dialog ();
5095 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5096 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5097 gtk_widget_show_all (dialog);
5099 gtk_dialog_run (GTK_DIALOG (dialog));
5101 gtk_widget_destroy (dialog);
5105 modest_ui_actions_on_help (GtkAction *action,
5108 /* Help app is not available at all in fremantle */
5109 #ifndef MODEST_TOOLKIT_HILDON2
5110 const gchar *help_id;
5112 g_return_if_fail (win && GTK_IS_WINDOW(win));
5114 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5117 modest_platform_show_help (GTK_WINDOW (win), help_id);
5122 modest_ui_actions_on_csm_help (GtkAction *action,
5125 /* Help app is not available at all in fremantle */
5129 retrieve_contents_cb (ModestMailOperation *mail_op,
5136 /* We only need this callback to show an error in case of
5137 memory low condition */
5138 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5139 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5144 retrieve_msg_contents_performer (gboolean canceled,
5146 GtkWindow *parent_window,
5147 TnyAccount *account,
5150 ModestMailOperation *mail_op;
5151 TnyList *headers = TNY_LIST (user_data);
5153 if (err || canceled) {
5154 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5155 (GtkWidget *) parent_window, err,
5160 /* Create mail operation */
5161 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5162 modest_ui_actions_disk_operations_error_handler,
5164 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5165 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5168 g_object_unref (mail_op);
5170 g_object_unref (headers);
5171 g_object_unref (account);
5175 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5176 ModestWindow *window)
5178 TnyList *headers = NULL;
5179 TnyAccount *account = NULL;
5180 TnyIterator *iter = NULL;
5181 TnyHeader *header = NULL;
5182 TnyFolder *folder = NULL;
5185 headers = get_selected_headers (window);
5189 /* Pick the account */
5190 iter = tny_list_create_iterator (headers);
5191 header = TNY_HEADER (tny_iterator_get_current (iter));
5192 folder = tny_header_get_folder (header);
5193 account = tny_folder_get_account (folder);
5194 g_object_unref (folder);
5195 g_object_unref (header);
5196 g_object_unref (iter);
5198 /* Connect and perform the message retrieval */
5199 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5200 g_object_ref (account),
5201 retrieve_msg_contents_performer,
5202 g_object_ref (headers));
5205 g_object_unref (account);
5206 g_object_unref (headers);
5210 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5212 g_return_if_fail (MODEST_IS_WINDOW (window));
5215 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5219 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5221 g_return_if_fail (MODEST_IS_WINDOW (window));
5224 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5228 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5229 ModestWindow *window)
5231 g_return_if_fail (MODEST_IS_WINDOW (window));
5234 modest_ui_actions_check_menu_dimming_rules (window);
5238 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5239 ModestWindow *window)
5241 g_return_if_fail (MODEST_IS_WINDOW (window));
5244 modest_ui_actions_check_menu_dimming_rules (window);
5248 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5249 ModestWindow *window)
5251 g_return_if_fail (MODEST_IS_WINDOW (window));
5254 modest_ui_actions_check_menu_dimming_rules (window);
5258 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5259 ModestWindow *window)
5261 g_return_if_fail (MODEST_IS_WINDOW (window));
5264 modest_ui_actions_check_menu_dimming_rules (window);
5268 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5269 ModestWindow *window)
5271 g_return_if_fail (MODEST_IS_WINDOW (window));
5274 modest_ui_actions_check_menu_dimming_rules (window);
5278 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5279 ModestWindow *window)
5281 g_return_if_fail (MODEST_IS_WINDOW (window));
5284 modest_ui_actions_check_menu_dimming_rules (window);
5288 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5289 ModestWindow *window)
5291 g_return_if_fail (MODEST_IS_WINDOW (window));
5294 modest_ui_actions_check_menu_dimming_rules (window);
5298 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5299 ModestWindow *window)
5301 g_return_if_fail (MODEST_IS_WINDOW (window));
5304 modest_ui_actions_check_menu_dimming_rules (window);
5308 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5309 ModestWindow *window)
5311 g_return_if_fail (MODEST_IS_WINDOW (window));
5314 modest_ui_actions_check_menu_dimming_rules (window);
5318 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5320 g_return_if_fail (MODEST_IS_WINDOW (window));
5322 /* we check for low-mem; in that case, show a warning, and don't allow
5325 if (modest_platform_check_memory_low (window, TRUE))
5328 modest_platform_show_search_messages (GTK_WINDOW (window));
5332 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5334 g_return_if_fail (MODEST_IS_WINDOW (win));
5337 /* we check for low-mem; in that case, show a warning, and don't allow
5338 * for the addressbook
5340 if (modest_platform_check_memory_low (win, TRUE))
5344 modest_platform_show_addressbook (GTK_WINDOW (win));
5349 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5350 ModestWindow *window)
5353 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5355 if (GTK_IS_TOGGLE_ACTION (action))
5356 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5360 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5366 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5372 const gchar* server_name = NULL;
5373 TnyTransportAccount *transport;
5374 gchar *message = NULL;
5375 ModestProtocol *protocol;
5377 /* Don't show anything if the user cancelled something or the
5378 * send receive request is not interactive. Authentication
5379 * errors are managed by the account store so no need to show
5380 * a dialog here again */
5381 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5382 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5383 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5387 /* Get the server name. Note that we could be using a
5388 connection specific transport account */
5389 transport = (TnyTransportAccount *)
5390 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5392 ModestTnyAccountStore *acc_store;
5393 const gchar *acc_name;
5394 TnyTransportAccount *conn_specific;
5396 acc_store = modest_runtime_get_account_store();
5397 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5398 conn_specific = (TnyTransportAccount *)
5399 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5400 if (conn_specific) {
5401 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5402 g_object_unref (conn_specific);
5404 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5406 g_object_unref (transport);
5410 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5411 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5412 tny_account_get_proto (TNY_ACCOUNT (transport)));
5414 g_warning ("%s: Account with no proto", __FUNCTION__);
5418 /* Show the appropriate message text for the GError: */
5419 switch (err->code) {
5420 case TNY_SERVICE_ERROR_CONNECT:
5421 message = modest_protocol_get_translation (protocol,
5422 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5425 case TNY_SERVICE_ERROR_SEND:
5426 message = g_strdup (_CS("sfil_ib_unable_to_send"));
5428 case TNY_SERVICE_ERROR_UNAVAILABLE:
5429 message = modest_protocol_get_translation (protocol,
5430 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5434 g_warning ("%s: unexpected ERROR %d",
5435 __FUNCTION__, err->code);
5436 message = g_strdup (_CS("sfil_ib_unable_to_send"));
5440 modest_platform_run_information_dialog (NULL, message, FALSE);
5445 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5450 ModestWindow *top_window = NULL;
5451 ModestWindowMgr *mgr = NULL;
5452 GtkWidget *header_view = NULL;
5453 TnyFolder *selected_folder = NULL;
5454 TnyFolderType folder_type;
5456 mgr = modest_runtime_get_window_mgr ();
5457 top_window = modest_window_mgr_get_current_top (mgr);
5462 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5463 header_view = (GtkWidget *)
5464 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5467 /* Get selected folder */
5469 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5470 if (!selected_folder)
5473 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5474 #if GTK_CHECK_VERSION(2, 8, 0)
5475 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5476 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5477 GtkTreeViewColumn *tree_column;
5479 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5480 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5482 gtk_tree_view_column_queue_resize (tree_column);
5484 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5485 gtk_widget_queue_draw (header_view);
5488 #ifndef MODEST_TOOLKIT_HILDON2
5489 /* Rerun dimming rules, because the message could become deletable for example */
5490 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5491 MODEST_DIMMING_RULES_TOOLBAR);
5492 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5493 MODEST_DIMMING_RULES_MENU);
5497 g_object_unref (selected_folder);
5501 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5502 TnyAccount *account)
5504 ModestProtocolType protocol_type;
5505 ModestProtocol *protocol;
5506 gchar *error_note = NULL;
5508 protocol_type = modest_tny_account_get_protocol_type (account);
5509 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5512 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5513 if (error_note == NULL) {
5514 g_warning ("%s: This should not be reached", __FUNCTION__);
5516 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
5517 g_free (error_note);
5522 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5526 TnyFolderStore *folder = NULL;
5527 TnyAccount *account = NULL;
5528 ModestProtocolType proto;
5529 ModestProtocol *protocol;
5530 TnyHeader *header = NULL;
5532 if (MODEST_IS_HEADER_WINDOW (win)) {
5533 GtkWidget *header_view;
5534 TnyList* headers = NULL;
5536 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5537 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5538 if (!headers || tny_list_get_length (headers) == 0) {
5540 g_object_unref (headers);
5543 iter = tny_list_create_iterator (headers);
5544 header = TNY_HEADER (tny_iterator_get_current (iter));
5546 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5548 g_warning ("List should contain headers");
5550 g_object_unref (iter);
5551 g_object_unref (headers);
5552 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5553 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5555 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5558 if (!header || !folder)
5561 /* Get the account type */
5562 account = tny_folder_get_account (TNY_FOLDER (folder));
5563 proto = modest_tny_account_get_protocol_type (account);
5564 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5567 subject = tny_header_dup_subject (header);
5568 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5572 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5578 g_object_unref (account);
5580 g_object_unref (folder);
5582 g_object_unref (header);
5588 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5589 const gchar *account_name,
5590 const gchar *account_title)
5592 ModestAccountMgr *account_mgr;
5595 ModestProtocol *protocol;
5596 gboolean removed = FALSE;
5598 g_return_val_if_fail (account_name, FALSE);
5599 g_return_val_if_fail (account_title, FALSE);
5601 account_mgr = modest_runtime_get_account_mgr();
5603 /* The warning text depends on the account type: */
5604 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5605 modest_account_mgr_get_store_protocol (account_mgr,
5607 txt = modest_protocol_get_translation (protocol,
5608 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5611 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5613 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5617 if (response == GTK_RESPONSE_OK) {
5618 /* Remove account. If it succeeds then it also removes
5619 the account from the ModestAccountView: */
5620 gboolean is_default = FALSE;
5621 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5622 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5624 g_free (default_account_name);
5626 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5628 /* Close all email notifications, we cannot
5629 distinguish if the notification belongs to
5630 this account or not, so for safety reasons
5631 we remove them all */
5632 modest_platform_remove_new_mail_notifications (FALSE);
5634 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5641 on_fetch_images_performer (gboolean canceled,
5643 GtkWindow *parent_window,
5644 TnyAccount *account,
5647 if (err || canceled) {
5648 /* Show an unable to retrieve images ??? */
5652 /* Note that the user could have closed the window while connecting */
5653 if (GTK_WIDGET_VISIBLE (parent_window))
5654 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5655 g_object_unref ((GObject *) user_data);
5659 modest_ui_actions_on_fetch_images (GtkAction *action,
5660 ModestWindow *window)
5662 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5664 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5666 on_fetch_images_performer,
5667 g_object_ref (window));
5671 modest_ui_actions_on_reload_message (const gchar *msg_id)
5673 ModestWindow *window = NULL;
5675 g_return_if_fail (msg_id && msg_id[0] != '\0');
5676 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5682 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5685 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5688 /** Check whether any connections are active, and cancel them if
5690 * Returns TRUE is there was no problem,
5691 * or if an operation was cancelled so we can continue.
5692 * Returns FALSE if the user chose to cancel his request instead.
5696 modest_ui_actions_check_for_active_account (ModestWindow *self,
5697 const gchar* account_name)
5699 ModestTnySendQueue *send_queue;
5700 ModestTnyAccountStore *acc_store;
5701 ModestMailOperationQueue* queue;
5702 TnyConnectionStatus store_conn_status;
5703 TnyAccount *store_account = NULL, *transport_account = NULL;
5704 gboolean retval = TRUE, sending = FALSE;
5706 acc_store = modest_runtime_get_account_store ();
5707 queue = modest_runtime_get_mail_operation_queue ();
5710 modest_tny_account_store_get_server_account (acc_store,
5712 TNY_ACCOUNT_TYPE_STORE);
5714 /* This could happen if the account was deleted before the
5715 call to this function */
5720 modest_tny_account_store_get_server_account (acc_store,
5722 TNY_ACCOUNT_TYPE_TRANSPORT);
5724 /* This could happen if the account was deleted before the
5725 call to this function */
5726 if (!transport_account) {
5727 g_object_unref (store_account);
5731 /* If the transport account was not used yet, then the send
5732 queue could not exist (it's created on demand) */
5733 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5734 if (TNY_IS_SEND_QUEUE (send_queue))
5735 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5737 store_conn_status = tny_account_get_connection_status (store_account);
5738 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5741 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
5742 _("emev_nc_disconnect_account"));
5743 if (response == GTK_RESPONSE_OK) {
5752 /* FIXME: We should only cancel those of this account */
5753 modest_mail_operation_queue_cancel_all (queue);
5755 /* Also disconnect the account */
5756 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5757 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5758 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5762 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5768 g_object_unref (store_account);
5769 g_object_unref (transport_account);