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 (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 (GTK_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 (source_win, parent_folder, (const gchar *) suggested_name);
2908 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
2909 * FIXME: any other? */
2910 GtkWidget *folder_view;
2912 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
2913 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
2915 /* Select the newly created folder. It could happen
2916 that the widget is no longer there (i.e. the window
2917 has been destroyed, so we need to check this */
2919 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
2921 g_object_unref (new_folder);
2923 /* Free. Note that the first time it'll be NULL so noop */
2924 g_free (suggested_name);
2925 g_object_unref (source_win);
2930 TnyFolderStore *parent;
2931 } CreateFolderConnect;
2934 do_create_folder_performer (gboolean canceled,
2936 GtkWindow *parent_window,
2937 TnyAccount *account,
2940 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
2941 ModestMailOperation *mail_op;
2943 if (canceled || err) {
2944 /* In disk full conditions we could get this error here */
2945 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2946 (GtkWidget *) parent_window, err,
2947 NULL, _("mail_in_ui_folder_create_error_memory"));
2949 /* This happens if we have selected the outbox folder
2951 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
2952 TNY_IS_MERGE_FOLDER (helper->parent)) {
2953 /* Show an error and retry */
2954 modest_platform_information_banner ((GtkWidget *) parent_window,
2956 _("mail_in_ui_folder_create_error"));
2958 do_create_folder (parent_window, helper->parent, helper->folder_name);
2964 mail_op = modest_mail_operation_new ((GObject *) parent_window);
2965 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2967 modest_mail_operation_create_folder (mail_op,
2969 (const gchar *) helper->folder_name,
2970 do_create_folder_cb,
2971 g_strdup (helper->folder_name));
2972 g_object_unref (mail_op);
2976 g_object_unref (helper->parent);
2977 if (helper->folder_name)
2978 g_free (helper->folder_name);
2979 g_slice_free (CreateFolderConnect, helper);
2984 do_create_folder (GtkWindow *parent_window,
2985 TnyFolderStore *suggested_parent,
2986 const gchar *suggested_name)
2989 gchar *folder_name = NULL;
2990 TnyFolderStore *parent_folder = NULL;
2992 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2994 (gchar *) suggested_name,
2998 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
2999 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3000 helper->folder_name = g_strdup (folder_name);
3001 helper->parent = g_object_ref (parent_folder);
3003 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3006 do_create_folder_performer,
3011 g_free (folder_name);
3013 g_object_unref (parent_folder);
3017 modest_ui_actions_create_folder(GtkWidget *parent_window,
3018 GtkWidget *folder_view,
3019 TnyFolderStore *parent_folder)
3021 if (!parent_folder) {
3022 ModestTnyAccountStore *acc_store;
3024 acc_store = modest_runtime_get_account_store ();
3026 parent_folder = (TnyFolderStore *)
3027 modest_tny_account_store_get_local_folders_account (acc_store);
3030 if (parent_folder) {
3031 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3032 g_object_unref (parent_folder);
3037 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3040 g_return_if_fail (MODEST_IS_WINDOW(window));
3042 if (MODEST_IS_FOLDER_WINDOW (window)) {
3043 GtkWidget *folder_view;
3045 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3046 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3048 g_assert_not_reached ();
3053 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3056 const GError *error = NULL;
3057 gchar *message = NULL;
3059 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3061 /* Get error message */
3062 error = modest_mail_operation_get_error (mail_op);
3064 g_return_if_reached ();
3066 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3067 (GError *) error, account);
3069 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3070 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3071 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3072 message = _CS("ckdg_ib_folder_already_exists");
3073 } else if (error->domain == TNY_ERROR_DOMAIN &&
3074 error->code == TNY_SERVICE_ERROR_STATE) {
3075 /* This means that the folder is already in use (a
3076 message is opened for example */
3077 message = _("emev_ni_internal_error");
3079 message = _CS("ckdg_ib_unable_to_rename");
3082 /* We don't set a parent for the dialog because the dialog
3083 will be destroyed so the banner won't appear */
3084 modest_platform_information_banner (NULL, NULL, message);
3087 g_object_unref (account);
3093 TnyFolderStore *folder;
3098 on_rename_folder_cb (ModestMailOperation *mail_op,
3099 TnyFolder *new_folder,
3102 ModestFolderView *folder_view;
3104 /* If the window was closed when renaming a folder, or if
3105 * it's not a main window this will happen */
3106 if (!MODEST_IS_FOLDER_VIEW (user_data))
3109 folder_view = MODEST_FOLDER_VIEW (user_data);
3110 /* Note that if the rename fails new_folder will be NULL */
3112 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3114 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3118 on_rename_folder_performer (gboolean canceled,
3120 GtkWindow *parent_window,
3121 TnyAccount *account,
3124 ModestMailOperation *mail_op = NULL;
3125 GtkTreeSelection *sel = NULL;
3126 GtkWidget *folder_view = NULL;
3127 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3129 if (canceled || err) {
3130 /* In disk full conditions we could get this error here */
3131 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3132 (GtkWidget *) parent_window, err,
3137 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3138 modest_ui_actions_rename_folder_error_handler,
3139 parent_window, NULL);
3141 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3143 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3144 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3145 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3148 /* Clear the folders view */
3149 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3150 gtk_tree_selection_unselect_all (sel);
3152 /* Actually rename the folder */
3153 modest_mail_operation_rename_folder (mail_op,
3154 TNY_FOLDER (data->folder),
3155 (const gchar *) (data->new_name),
3156 on_rename_folder_cb,
3158 g_object_unref (mail_op);
3161 g_object_unref (data->folder);
3162 g_free (data->new_name);
3167 modest_ui_actions_on_rename_folder (GtkAction *action,
3168 ModestWindow *window)
3170 modest_ui_actions_on_edit_mode_rename_folder (window);
3174 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3176 TnyFolderStore *folder;
3177 GtkWidget *folder_view;
3178 gboolean do_rename = TRUE;
3180 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3182 if (MODEST_IS_FOLDER_WINDOW (window)) {
3183 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3188 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3193 if (TNY_IS_FOLDER (folder)) {
3194 gchar *folder_name = NULL;
3196 const gchar *current_name;
3197 TnyFolderStore *parent;
3199 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3200 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3201 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3202 parent, current_name,
3204 g_object_unref (parent);
3206 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3209 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3210 rename_folder_data->folder = g_object_ref (folder);
3211 rename_folder_data->new_name = folder_name;
3212 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3213 folder, on_rename_folder_performer, rename_folder_data);
3216 g_object_unref (folder);
3221 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3224 GObject *win = modest_mail_operation_get_source (mail_op);
3226 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3227 _("mail_in_ui_folder_delete_error"),
3229 g_object_unref (win);
3233 TnyFolderStore *folder;
3234 gboolean move_to_trash;
3238 on_delete_folder_cb (gboolean canceled,
3240 GtkWindow *parent_window,
3241 TnyAccount *account,
3244 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3245 GtkWidget *folder_view;
3246 ModestMailOperation *mail_op;
3247 GtkTreeSelection *sel;
3249 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3250 /* Note that the connection process can fail due to
3251 memory low conditions as it can not successfully
3252 store the summary */
3253 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3254 (GtkWidget*) parent_window, err,
3256 g_debug ("Error connecting when trying to delete a folder");
3257 g_object_unref (G_OBJECT (info->folder));
3262 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3263 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3265 g_object_unref (G_OBJECT (info->folder));
3270 /* Unselect the folder before deleting it to free the headers */
3271 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3272 gtk_tree_selection_unselect_all (sel);
3274 /* Create the mail operation */
3276 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3277 modest_ui_actions_delete_folder_error_handler,
3280 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3282 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3284 g_object_unref (mail_op);
3285 g_object_unref (info->folder);
3290 delete_folder (ModestWindow *window, gboolean move_to_trash)
3292 TnyFolderStore *folder;
3293 GtkWidget *folder_view;
3297 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3299 if (MODEST_IS_FOLDER_WINDOW (window)) {
3300 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3307 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3312 /* Show an error if it's an account */
3313 if (!TNY_IS_FOLDER (folder)) {
3314 modest_platform_run_information_dialog (GTK_WINDOW (window),
3315 _("mail_in_ui_folder_delete_error"),
3317 g_object_unref (G_OBJECT (folder));
3322 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3323 tny_folder_get_name (TNY_FOLDER (folder)));
3324 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3325 (const gchar *) message);
3328 if (response == GTK_RESPONSE_OK) {
3329 TnyAccount *account = NULL;
3330 DeleteFolderInfo *info = NULL;
3331 info = g_new0(DeleteFolderInfo, 1);
3332 info->folder = g_object_ref (folder);
3333 info->move_to_trash = move_to_trash;
3335 account = tny_folder_get_account (TNY_FOLDER (folder));
3336 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3338 TNY_FOLDER_STORE (account),
3339 on_delete_folder_cb, info);
3340 g_object_unref (account);
3341 g_object_unref (folder);
3349 modest_ui_actions_on_delete_folder (GtkAction *action,
3350 ModestWindow *window)
3352 modest_ui_actions_on_edit_mode_delete_folder (window);
3356 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3358 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3360 return delete_folder (window, FALSE);
3364 typedef struct _PasswordDialogFields {
3365 GtkWidget *username;
3366 GtkWidget *password;
3368 } PasswordDialogFields;
3371 password_dialog_check_field (GtkEditable *editable,
3372 PasswordDialogFields *fields)
3375 gboolean any_value_empty = FALSE;
3377 value = modest_entry_get_text (fields->username);
3378 if ((value == NULL) || value[0] == '\0') {
3379 any_value_empty = TRUE;
3381 value = modest_entry_get_text (fields->password);
3382 if ((value == NULL) || value[0] == '\0') {
3383 any_value_empty = TRUE;
3385 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3389 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3390 const gchar* server_account_name,
3395 ModestMainWindow *main_window)
3397 g_return_if_fail(server_account_name);
3398 gboolean completed = FALSE;
3399 PasswordDialogFields *fields = NULL;
3401 /* Initalize output parameters: */
3408 #ifndef MODEST_TOOLKIT_GTK
3409 /* Maemo uses a different (awkward) button order,
3410 * It should probably just use gtk_alternative_dialog_button_order ().
3412 #ifdef MODEST_TOOLKIT_HILDON2
3414 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3417 _HL("wdgt_bd_done"),
3418 GTK_RESPONSE_ACCEPT,
3420 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3421 HILDON_MARGIN_DOUBLE);
3424 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3427 _("mcen_bd_dialog_ok"),
3428 GTK_RESPONSE_ACCEPT,
3429 _("mcen_bd_dialog_cancel"),
3430 GTK_RESPONSE_REJECT,
3432 #endif /* MODEST_TOOLKIT_HILDON2 */
3435 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3439 GTK_RESPONSE_REJECT,
3441 GTK_RESPONSE_ACCEPT,
3443 #endif /* MODEST_TOOLKIT_GTK */
3445 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3447 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3448 modest_runtime_get_account_mgr(), server_account_name);
3449 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3450 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3453 gtk_widget_destroy (dialog);
3457 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3458 GtkWidget *label = gtk_label_new (txt);
3459 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3461 g_free (server_name);
3462 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3467 gchar *initial_username = modest_account_mgr_get_server_account_username (
3468 modest_runtime_get_account_mgr(), server_account_name);
3470 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3471 if (initial_username)
3472 modest_entry_set_text (entry_username, initial_username);
3474 /* Dim this if a connection has ever succeeded with this username,
3475 * as per the UI spec: */
3476 /* const gboolean username_known = */
3477 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3478 /* modest_runtime_get_account_mgr(), server_account_name); */
3479 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3481 /* We drop the username sensitive code and disallow changing it here
3482 * as tinymail does not support really changing the username in the callback
3484 gtk_widget_set_sensitive (entry_username, FALSE);
3486 /* Auto-capitalization is the default, so let's turn it off: */
3487 #ifdef MAEMO_CHANGES
3488 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3491 /* Create a size group to be used by all captions.
3492 * Note that HildonCaption does not create a default size group if we do not specify one.
3493 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3494 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3496 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3497 _("mail_fi_username"), FALSE,
3499 gtk_widget_show (entry_username);
3500 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3501 FALSE, FALSE, MODEST_MARGIN_HALF);
3502 gtk_widget_show (caption);
3505 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3506 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3507 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3509 /* Auto-capitalization is the default, so let's turn it off: */
3510 #ifdef MAEMO_CHANGES
3511 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3512 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3515 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3516 _("mail_fi_password"), FALSE,
3518 gtk_widget_show (entry_password);
3519 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3520 FALSE, FALSE, MODEST_MARGIN_HALF);
3521 gtk_widget_show (caption);
3522 g_object_unref (sizegroup);
3524 if (initial_username != NULL)
3525 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3527 /* This is not in the Maemo UI spec:
3528 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3529 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3533 fields = g_slice_new0 (PasswordDialogFields);
3534 fields->username = entry_username;
3535 fields->password = entry_password;
3536 fields->dialog = dialog;
3538 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3539 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3540 password_dialog_check_field (NULL, fields);
3542 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3544 while (!completed) {
3546 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3548 *username = g_strdup (modest_entry_get_text (entry_username));
3550 /* Note that an empty field becomes the "" string */
3551 if (*username && strlen (*username) > 0) {
3552 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3553 server_account_name,
3557 const gboolean username_was_changed =
3558 (strcmp (*username, initial_username) != 0);
3559 if (username_was_changed) {
3560 g_warning ("%s: tinymail does not yet support changing the "
3561 "username in the get_password() callback.\n", __FUNCTION__);
3567 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3568 _("mcen_ib_username_pw_incorrect"));
3574 *password = g_strdup (modest_entry_get_text (entry_password));
3576 /* We do not save the password in the configuration,
3577 * because this function is only called for passwords that should
3578 * not be remembered:
3579 modest_server_account_set_password (
3580 modest_runtime_get_account_mgr(), server_account_name,
3597 /* This is not in the Maemo UI spec:
3598 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3604 g_free (initial_username);
3605 gtk_widget_destroy (dialog);
3606 g_slice_free (PasswordDialogFields, fields);
3608 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3612 modest_ui_actions_on_cut (GtkAction *action,
3613 ModestWindow *window)
3615 GtkWidget *focused_widget;
3616 GtkClipboard *clipboard;
3618 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3619 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3620 if (GTK_IS_EDITABLE (focused_widget)) {
3621 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3622 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3623 gtk_clipboard_store (clipboard);
3624 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3625 GtkTextBuffer *buffer;
3627 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3628 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3629 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3630 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3631 gtk_clipboard_store (clipboard);
3633 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3634 TnyList *header_list = modest_header_view_get_selected_headers (
3635 MODEST_HEADER_VIEW (focused_widget));
3636 gboolean continue_download = FALSE;
3637 gint num_of_unc_msgs;
3639 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3641 if (num_of_unc_msgs) {
3642 TnyAccount *account = get_account_from_header_list (header_list);
3644 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3645 g_object_unref (account);
3649 if (num_of_unc_msgs == 0 || continue_download) {
3650 /* modest_platform_information_banner (
3651 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3652 modest_header_view_cut_selection (
3653 MODEST_HEADER_VIEW (focused_widget));
3656 g_object_unref (header_list);
3657 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3658 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3663 modest_ui_actions_on_copy (GtkAction *action,
3664 ModestWindow *window)
3666 GtkClipboard *clipboard;
3667 GtkWidget *focused_widget;
3668 gboolean copied = TRUE;
3670 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3671 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3673 if (GTK_IS_LABEL (focused_widget)) {
3675 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3676 gtk_clipboard_set_text (clipboard, selection, -1);
3678 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3679 gtk_clipboard_store (clipboard);
3680 } else if (GTK_IS_EDITABLE (focused_widget)) {
3681 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3682 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3683 gtk_clipboard_store (clipboard);
3684 } else if (GTK_IS_HTML (focused_widget)) {
3687 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3688 if ((sel == NULL) || (sel[0] == '\0')) {
3691 gtk_html_copy (GTK_HTML (focused_widget));
3692 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3693 gtk_clipboard_store (clipboard);
3695 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3696 GtkTextBuffer *buffer;
3697 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3698 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3699 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3700 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3701 gtk_clipboard_store (clipboard);
3703 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3704 TnyList *header_list = modest_header_view_get_selected_headers (
3705 MODEST_HEADER_VIEW (focused_widget));
3706 gboolean continue_download = FALSE;
3707 gint num_of_unc_msgs;
3709 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3711 if (num_of_unc_msgs) {
3712 TnyAccount *account = get_account_from_header_list (header_list);
3714 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3715 g_object_unref (account);
3719 if (num_of_unc_msgs == 0 || continue_download) {
3720 modest_platform_information_banner (
3721 NULL, NULL, _CS("mcen_ib_getting_items"));
3722 modest_header_view_copy_selection (
3723 MODEST_HEADER_VIEW (focused_widget));
3727 g_object_unref (header_list);
3729 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3730 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3733 /* Show information banner if there was a copy to clipboard */
3735 modest_platform_information_banner (
3736 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3740 modest_ui_actions_on_undo (GtkAction *action,
3741 ModestWindow *window)
3743 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3744 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3746 g_return_if_reached ();
3751 modest_ui_actions_on_redo (GtkAction *action,
3752 ModestWindow *window)
3754 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3755 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3758 g_return_if_reached ();
3764 destroy_information_note (ModestMailOperation *mail_op,
3767 /* destroy information note */
3768 gtk_widget_destroy (GTK_WIDGET(user_data));
3772 destroy_folder_information_note (ModestMailOperation *mail_op,
3773 TnyFolder *new_folder,
3776 /* destroy information note */
3777 gtk_widget_destroy (GTK_WIDGET(user_data));
3782 paste_as_attachment_free (gpointer data)
3784 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3786 if (helper->banner) {
3787 gtk_widget_destroy (helper->banner);
3788 g_object_unref (helper->banner);
3794 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3799 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3800 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3805 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3810 modest_ui_actions_on_paste (GtkAction *action,
3811 ModestWindow *window)
3813 GtkWidget *focused_widget = NULL;
3814 GtkWidget *inf_note = NULL;
3815 ModestMailOperation *mail_op = NULL;
3817 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3818 if (GTK_IS_EDITABLE (focused_widget)) {
3819 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3820 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3821 ModestEmailClipboard *e_clipboard = NULL;
3822 e_clipboard = modest_runtime_get_email_clipboard ();
3823 if (modest_email_clipboard_cleared (e_clipboard)) {
3824 GtkTextBuffer *buffer;
3825 GtkClipboard *clipboard;
3827 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3828 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3829 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3830 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3831 ModestMailOperation *mail_op;
3832 TnyFolder *src_folder = NULL;
3833 TnyList *data = NULL;
3835 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3836 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3837 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3838 _CS("ckct_nw_pasting"));
3839 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3840 mail_op = modest_mail_operation_new (G_OBJECT (window));
3841 if (helper->banner != NULL) {
3842 g_object_ref (G_OBJECT (helper->banner));
3843 gtk_widget_show (GTK_WIDGET (helper->banner));
3847 modest_mail_operation_get_msgs_full (mail_op,
3849 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3851 paste_as_attachment_free);
3855 g_object_unref (data);
3857 g_object_unref (src_folder);
3860 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3861 ModestEmailClipboard *clipboard = NULL;
3862 TnyFolder *src_folder = NULL;
3863 TnyFolderStore *folder_store = NULL;
3864 TnyList *data = NULL;
3865 gboolean delete = FALSE;
3867 /* Check clipboard source */
3868 clipboard = modest_runtime_get_email_clipboard ();
3869 if (modest_email_clipboard_cleared (clipboard))
3872 /* Get elements to paste */
3873 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3875 /* Create a new mail operation */
3876 mail_op = modest_mail_operation_new (G_OBJECT(window));
3878 /* Get destination folder */
3879 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3881 /* transfer messages */
3885 /* Ask for user confirmation */
3887 modest_ui_actions_msgs_move_to_confirmation (window,
3888 TNY_FOLDER (folder_store),
3892 if (response == GTK_RESPONSE_OK) {
3893 /* Launch notification */
3894 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3895 _CS("ckct_nw_pasting"));
3896 if (inf_note != NULL) {
3897 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3898 gtk_widget_show (GTK_WIDGET(inf_note));
3901 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3902 modest_mail_operation_xfer_msgs (mail_op,
3904 TNY_FOLDER (folder_store),
3906 destroy_information_note,
3909 g_object_unref (mail_op);
3912 } else if (src_folder != NULL) {
3913 /* Launch notification */
3914 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3915 _CS("ckct_nw_pasting"));
3916 if (inf_note != NULL) {
3917 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3918 gtk_widget_show (GTK_WIDGET(inf_note));
3921 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3922 modest_mail_operation_xfer_folder (mail_op,
3926 destroy_folder_information_note,
3932 g_object_unref (data);
3933 if (src_folder != NULL)
3934 g_object_unref (src_folder);
3935 if (folder_store != NULL)
3936 g_object_unref (folder_store);
3942 modest_ui_actions_on_select_all (GtkAction *action,
3943 ModestWindow *window)
3945 GtkWidget *focused_widget;
3947 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3948 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3949 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3950 } else if (GTK_IS_LABEL (focused_widget)) {
3951 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3952 } else if (GTK_IS_EDITABLE (focused_widget)) {
3953 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3954 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3955 GtkTextBuffer *buffer;
3956 GtkTextIter start, end;
3958 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3959 gtk_text_buffer_get_start_iter (buffer, &start);
3960 gtk_text_buffer_get_end_iter (buffer, &end);
3961 gtk_text_buffer_select_range (buffer, &start, &end);
3962 } else if (GTK_IS_HTML (focused_widget)) {
3963 gtk_html_select_all (GTK_HTML (focused_widget));
3969 modest_ui_actions_on_mark_as_read (GtkAction *action,
3970 ModestWindow *window)
3972 g_return_if_fail (MODEST_IS_WINDOW(window));
3974 /* Mark each header as read */
3975 do_headers_action (window, headers_action_mark_as_read, NULL);
3979 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3980 ModestWindow *window)
3982 g_return_if_fail (MODEST_IS_WINDOW(window));
3984 /* Mark each header as read */
3985 do_headers_action (window, headers_action_mark_as_unread, NULL);
3989 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3990 GtkRadioAction *selected,
3991 ModestWindow *window)
3995 value = gtk_radio_action_get_current_value (selected);
3996 if (MODEST_IS_WINDOW (window)) {
3997 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4002 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4003 GtkRadioAction *selected,
4004 ModestWindow *window)
4006 TnyHeaderFlags flags;
4007 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4009 flags = gtk_radio_action_get_current_value (selected);
4010 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4014 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4015 GtkRadioAction *selected,
4016 ModestWindow *window)
4020 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4022 file_format = gtk_radio_action_get_current_value (selected);
4023 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4028 modest_ui_actions_on_zoom_plus (GtkAction *action,
4029 ModestWindow *window)
4031 g_return_if_fail (MODEST_IS_WINDOW (window));
4033 modest_window_zoom_plus (MODEST_WINDOW (window));
4037 modest_ui_actions_on_zoom_minus (GtkAction *action,
4038 ModestWindow *window)
4040 g_return_if_fail (MODEST_IS_WINDOW (window));
4042 modest_window_zoom_minus (MODEST_WINDOW (window));
4046 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4047 ModestWindow *window)
4049 ModestWindowMgr *mgr;
4050 gboolean fullscreen, active;
4051 g_return_if_fail (MODEST_IS_WINDOW (window));
4053 mgr = modest_runtime_get_window_mgr ();
4055 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4056 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4058 if (active != fullscreen) {
4059 modest_window_mgr_set_fullscreen_mode (mgr, active);
4060 #ifndef MODEST_TOOLKIT_HILDON2
4061 gtk_window_present (GTK_WINDOW (window));
4067 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4068 ModestWindow *window)
4070 ModestWindowMgr *mgr;
4071 gboolean fullscreen;
4073 g_return_if_fail (MODEST_IS_WINDOW (window));
4075 mgr = modest_runtime_get_window_mgr ();
4076 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4077 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4079 #ifndef MODEST_TOOLKIT_HILDON2
4080 gtk_window_present (GTK_WINDOW (window));
4085 * Used by modest_ui_actions_on_details to call do_headers_action
4088 headers_action_show_details (TnyHeader *header,
4089 ModestWindow *window,
4093 gboolean async_retrieval;
4096 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4097 async_retrieval = TRUE;
4098 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4100 async_retrieval = FALSE;
4102 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4104 g_object_unref (msg);
4108 * Show the header details in a ModestDetailsDialog widget
4111 modest_ui_actions_on_details (GtkAction *action,
4114 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4118 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4122 header = tny_msg_get_header (msg);
4124 headers_action_show_details (header, win, NULL);
4125 g_object_unref (header);
4127 g_object_unref (msg);
4128 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4130 GtkWidget *header_view;
4132 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4133 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4135 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4137 g_object_unref (folder);
4143 modest_ui_actions_on_limit_error (GtkAction *action,
4146 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4148 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4153 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4154 ModestMsgEditWindow *window)
4156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4158 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4162 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4163 ModestMsgEditWindow *window)
4165 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4167 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4172 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4173 ModestWindow *window)
4175 gboolean active, fullscreen = FALSE;
4176 ModestWindowMgr *mgr;
4178 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4180 /* Check if we want to toggle the toolbar view in fullscreen
4182 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4183 "ViewShowToolbarFullScreen")) {
4187 /* Toggle toolbar */
4188 mgr = modest_runtime_get_window_mgr ();
4189 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4193 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4194 ModestMsgEditWindow *window)
4196 modest_msg_edit_window_select_font (window);
4201 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4202 const gchar *display_name,
4205 /* don't update the display name if it was already set;
4206 * updating the display name apparently is expensive */
4207 const gchar* old_name = gtk_window_get_title (window);
4209 if (display_name == NULL)
4212 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4213 return; /* don't do anything */
4215 /* This is usually used to change the title of the main window, which
4216 * is the one that holds the folder view. Note that this change can
4217 * happen even when the widget doesn't have the focus. */
4218 gtk_window_set_title (window, display_name);
4223 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4225 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4226 modest_msg_edit_window_select_contacts (window);
4230 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4232 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4233 modest_msg_edit_window_check_names (window, FALSE);
4238 on_move_to_dialog_response (GtkDialog *dialog,
4242 GtkWidget *parent_win;
4243 MoveToInfo *helper = NULL;
4244 ModestFolderView *folder_view;
4245 gboolean unset_edit_mode = FALSE;
4247 helper = (MoveToInfo *) user_data;
4249 parent_win = (GtkWidget *) helper->win;
4250 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4251 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4253 TnyFolderStore *dst_folder;
4254 TnyFolderStore *selected;
4256 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4257 selected = modest_folder_view_get_selected (folder_view);
4258 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
4259 g_object_unref (selected);
4261 case GTK_RESPONSE_NONE:
4262 case GTK_RESPONSE_CANCEL:
4263 case GTK_RESPONSE_DELETE_EVENT:
4265 case GTK_RESPONSE_OK:
4266 dst_folder = modest_folder_view_get_selected (folder_view);
4268 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4269 /* Clean list to move used for filtering */
4270 modest_folder_view_set_list_to_move (folder_view, NULL);
4272 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4275 GTK_WINDOW (parent_win));
4277 /* if the user selected a root folder
4278 (account) then do not perform any action */
4279 if (TNY_IS_ACCOUNT (dst_folder)) {
4280 g_signal_stop_emission_by_name (dialog, "response");
4284 /* Clean list to move used for filtering */
4285 modest_folder_view_set_list_to_move (folder_view, NULL);
4287 /* Moving from headers window in edit mode */
4288 modest_ui_actions_on_window_move_to (NULL, helper->list,
4290 MODEST_WINDOW (parent_win));
4294 g_object_unref (dst_folder);
4296 unset_edit_mode = TRUE;
4299 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4302 /* Free the helper and exit */
4304 g_object_unref (helper->list);
4305 if (unset_edit_mode) {
4306 #ifdef MODEST_TOOLKIT_HILDON2
4307 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4310 g_slice_free (MoveToInfo, helper);
4311 gtk_widget_destroy (GTK_WIDGET (dialog));
4315 create_move_to_dialog (GtkWindow *win,
4316 GtkWidget *folder_view,
4317 TnyList *list_to_move)
4319 GtkWidget *dialog, *tree_view = NULL;
4321 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4324 /* It could happen that we're trying to move a message from a
4325 window (msg window for example) after the main window was
4326 closed, so we can not just get the model of the folder
4328 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4329 const gchar *visible_id = NULL;
4331 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4332 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4333 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4334 MODEST_FOLDER_VIEW(tree_view));
4337 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4339 /* Show the same account than the one that is shown in the main window */
4340 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4343 const gchar *active_account_name = NULL;
4344 ModestAccountMgr *mgr = NULL;
4345 ModestAccountSettings *settings = NULL;
4346 ModestServerAccountSettings *store_settings = NULL;
4348 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4349 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4350 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4351 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4353 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4354 mgr = modest_runtime_get_account_mgr ();
4355 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4358 const gchar *store_account_name;
4359 store_settings = modest_account_settings_get_store_settings (settings);
4360 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4362 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4363 store_account_name);
4364 g_object_unref (store_settings);
4365 g_object_unref (settings);
4369 /* we keep a pointer to the embedded folder view, so we can
4370 * retrieve it with get_folder_view_from_move_to_dialog (see
4371 * above) later (needed for focus handling)
4373 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4375 /* Hide special folders */
4377 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4379 gtk_widget_show (GTK_WIDGET (tree_view));
4385 * Shows a confirmation dialog to the user when we're moving messages
4386 * from a remote server to the local storage. Returns the dialog
4387 * response. If it's other kind of movement then it always returns
4390 * This one is used by the next functions:
4391 * modest_ui_actions_on_paste - commented out
4392 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4395 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4396 TnyFolder *dest_folder,
4400 gint response = GTK_RESPONSE_OK;
4401 TnyAccount *account = NULL;
4402 TnyFolder *src_folder = NULL;
4403 TnyIterator *iter = NULL;
4404 TnyHeader *header = NULL;
4406 /* return with OK if the destination is a remote folder */
4407 if (modest_tny_folder_is_remote_folder (dest_folder))
4408 return GTK_RESPONSE_OK;
4410 /* Get source folder */
4411 iter = tny_list_create_iterator (headers);
4412 header = TNY_HEADER (tny_iterator_get_current (iter));
4414 src_folder = tny_header_get_folder (header);
4415 g_object_unref (header);
4417 g_object_unref (iter);
4419 /* if no src_folder, message may be an attahcment */
4420 if (src_folder == NULL)
4421 return GTK_RESPONSE_CANCEL;
4423 /* If the source is a local or MMC folder */
4424 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4425 g_object_unref (src_folder);
4426 return GTK_RESPONSE_OK;
4429 /* Get the account */
4430 account = tny_folder_get_account (src_folder);
4432 /* now if offline we ask the user */
4433 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4434 response = GTK_RESPONSE_OK;
4436 response = GTK_RESPONSE_CANCEL;
4439 g_object_unref (src_folder);
4440 g_object_unref (account);
4446 move_to_helper_destroyer (gpointer user_data)
4448 MoveToHelper *helper = (MoveToHelper *) user_data;
4450 /* Close the "Pasting" information banner */
4451 if (helper->banner) {
4452 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4453 g_object_unref (helper->banner);
4455 if (gtk_tree_row_reference_valid (helper->reference)) {
4456 gtk_tree_row_reference_free (helper->reference);
4457 helper->reference = NULL;
4463 move_to_cb (ModestMailOperation *mail_op,
4466 MoveToHelper *helper = (MoveToHelper *) user_data;
4467 GObject *object = modest_mail_operation_get_source (mail_op);
4469 /* Note that the operation could have failed, in that case do
4471 if (modest_mail_operation_get_status (mail_op) !=
4472 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4475 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4476 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4478 if (!modest_msg_view_window_select_next_message (self) &&
4479 !modest_msg_view_window_select_previous_message (self)) {
4480 /* No more messages to view, so close this window */
4481 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4484 g_object_unref (object);
4487 /* Destroy the helper */
4488 move_to_helper_destroyer (helper);
4492 folder_move_to_cb (ModestMailOperation *mail_op,
4493 TnyFolder *new_folder,
4498 object = modest_mail_operation_get_source (mail_op);
4500 move_to_cb (mail_op, user_data);
4505 msgs_move_to_cb (ModestMailOperation *mail_op,
4508 move_to_cb (mail_op, user_data);
4512 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4515 GObject *win = NULL;
4516 const GError *error;
4517 TnyAccount *account = NULL;
4519 win = modest_mail_operation_get_source (mail_op);
4520 error = modest_mail_operation_get_error (mail_op);
4522 if (TNY_IS_FOLDER (user_data))
4523 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4524 else if (TNY_IS_ACCOUNT (user_data))
4525 account = g_object_ref (user_data);
4527 /* If it's not a disk full error then show a generic error */
4528 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4529 (GtkWidget *) win, (GError *) error,
4531 modest_platform_run_information_dialog ((GtkWindow *) win,
4532 _("mail_in_ui_folder_move_target_error"),
4535 g_object_unref (account);
4537 g_object_unref (win);
4542 * Checks if we need a connection to do the transfer and if the user
4543 * wants to connect to complete it
4546 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
4547 TnyFolderStore *src_folder,
4549 TnyFolder *dst_folder,
4550 gboolean delete_originals,
4551 gboolean *need_connection,
4554 TnyAccount *src_account;
4555 gint uncached_msgs = 0;
4557 /* We don't need any further check if
4559 * 1- the source folder is local OR
4560 * 2- the device is already online
4562 if (!modest_tny_folder_store_is_remote (src_folder) ||
4563 tny_device_is_online (modest_runtime_get_device())) {
4564 *need_connection = FALSE;
4569 /* We must ask for a connection when
4571 * - the message(s) is not already cached OR
4572 * - the message(s) is cached but the leave_on_server setting
4573 * is FALSE (because we need to sync the source folder to
4574 * delete the message from the server (for IMAP we could do it
4575 * offline, it'll take place the next time we get a
4578 uncached_msgs = header_list_count_uncached_msgs (headers);
4579 src_account = get_account_from_folder_store (src_folder);
4580 if (uncached_msgs > 0) {
4584 *need_connection = TRUE;
4585 num_headers = tny_list_get_length (headers);
4586 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4588 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
4589 GTK_RESPONSE_CANCEL) {
4595 /* The transfer is possible and the user wants to */
4598 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4599 const gchar *account_name;
4600 gboolean leave_on_server;
4602 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4603 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4606 if (leave_on_server == TRUE) {
4607 *need_connection = FALSE;
4609 *need_connection = TRUE;
4612 *need_connection = FALSE;
4617 g_object_unref (src_account);
4621 xfer_messages_error_handler (ModestMailOperation *mail_op,
4625 const GError *error;
4626 TnyAccount *account;
4628 win = modest_mail_operation_get_source (mail_op);
4629 error = modest_mail_operation_get_error (mail_op);
4631 /* We cannot get the account from the mail op as that is the
4632 source account and for checking memory full conditions we
4633 need the destination one */
4634 account = TNY_ACCOUNT (user_data);
4637 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4638 (GtkWidget *) win, (GError*) error,
4639 account, _KR("cerm_memory_card_full"))) {
4640 modest_platform_run_information_dialog ((GtkWindow *) win,
4641 _("mail_in_ui_folder_move_target_error"),
4645 g_object_unref (win);
4649 TnyFolderStore *dst_folder;
4654 * Utility function that transfer messages from both the main window
4655 * and the msg view window when using the "Move to" dialog
4658 xfer_messages_performer (gboolean canceled,
4660 GtkWindow *parent_window,
4661 TnyAccount *account,
4664 ModestWindow *win = MODEST_WINDOW (parent_window);
4665 TnyAccount *dst_account = NULL;
4666 gboolean dst_forbids_message_add = FALSE;
4667 XferMsgsHelper *helper;
4668 MoveToHelper *movehelper;
4669 ModestMailOperation *mail_op;
4671 helper = (XferMsgsHelper *) user_data;
4673 if (canceled || err) {
4674 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4675 (GtkWidget *) parent_window, err,
4677 /* Show the proper error message */
4678 modest_ui_actions_on_account_connection_error (parent_window, account);
4683 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4685 /* tinymail will return NULL for local folders it seems */
4686 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4687 modest_tny_account_get_protocol_type (dst_account),
4688 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4690 if (dst_forbids_message_add) {
4691 modest_platform_information_banner (GTK_WIDGET (win),
4693 ngettext("mail_in_ui_folder_move_target_error",
4694 "mail_in_ui_folder_move_targets_error",
4695 tny_list_get_length (helper->headers)));
4699 movehelper = g_new0 (MoveToHelper, 1);
4702 /* Perform the mail operation */
4703 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4704 xfer_messages_error_handler,
4705 g_object_ref (dst_account),
4707 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4710 modest_mail_operation_xfer_msgs (mail_op,
4712 TNY_FOLDER (helper->dst_folder),
4717 g_object_unref (G_OBJECT (mail_op));
4720 g_object_unref (dst_account);
4721 g_object_unref (helper->dst_folder);
4722 g_object_unref (helper->headers);
4723 g_slice_free (XferMsgsHelper, helper);
4727 TnyFolder *src_folder;
4728 TnyFolderStore *dst_folder;
4729 gboolean delete_original;
4730 GtkWidget *folder_view;
4734 on_move_folder_cb (gboolean canceled,
4736 GtkWindow *parent_window,
4737 TnyAccount *account,
4740 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4741 GtkTreeSelection *sel;
4742 ModestMailOperation *mail_op = NULL;
4744 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4745 /* Note that the connection process can fail due to
4746 memory low conditions as it can not successfully
4747 store the summary */
4748 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4749 (GtkWidget*) parent_window, err,
4751 g_debug ("Error connecting when trying to move a folder");
4753 g_object_unref (G_OBJECT (info->src_folder));
4754 g_object_unref (G_OBJECT (info->dst_folder));
4759 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4760 #ifndef MODEST_TOOLKIT_HILDON2
4761 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4762 _CS("ckct_nw_pasting"));
4763 if (helper->banner != NULL) {
4764 g_object_ref (helper->banner);
4765 gtk_widget_show (GTK_WIDGET(helper->banner));
4768 /* Clean folder on header view before moving it */
4769 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4770 gtk_tree_selection_unselect_all (sel);
4772 /* Let gtk events run. We need that the folder
4773 view frees its reference to the source
4774 folder *before* issuing the mail operation
4775 so we need the signal handler of selection
4776 changed to happen before the mail
4778 while (gtk_events_pending ())
4779 gtk_main_iteration (); */
4782 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4783 modest_ui_actions_move_folder_error_handler,
4784 g_object_ref (info->dst_folder), g_object_unref);
4785 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4788 modest_mail_operation_xfer_folder (mail_op,
4789 TNY_FOLDER (info->src_folder),
4791 info->delete_original,
4794 g_object_unref (G_OBJECT (info->src_folder));
4796 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4799 /* Unref mail operation */
4800 g_object_unref (G_OBJECT (mail_op));
4801 g_object_unref (G_OBJECT (info->dst_folder));
4806 get_account_from_folder_store (TnyFolderStore *folder_store)
4808 if (TNY_IS_ACCOUNT (folder_store))
4809 return g_object_ref (folder_store);
4811 return tny_folder_get_account (TNY_FOLDER (folder_store));
4815 * UI handler for the "Move to" action when invoked from the
4816 * ModestFolderWindow
4819 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4820 TnyFolderStore *dst_folder,
4824 TnyFolderStore *src_folder = NULL;
4825 TnyIterator *iterator;
4827 if (tny_list_get_length (selection) != 1)
4830 iterator = tny_list_create_iterator (selection);
4831 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
4832 g_object_unref (iterator);
4835 gboolean do_xfer = TRUE;
4837 /* Allow only to transfer folders to the local root folder */
4838 if (TNY_IS_ACCOUNT (dst_folder) &&
4839 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
4840 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
4843 modest_platform_run_information_dialog (win,
4844 _("mail_in_ui_folder_move_target_error"),
4846 } else if (!TNY_IS_FOLDER (src_folder)) {
4847 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4852 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4853 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4855 info->src_folder = g_object_ref (src_folder);
4856 info->dst_folder = g_object_ref (dst_folder);
4857 info->delete_original = TRUE;
4858 info->folder_view = folder_view;
4860 connect_info->callback = on_move_folder_cb;
4861 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
4862 connect_info->data = info;
4864 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4865 TNY_FOLDER_STORE (src_folder),
4870 g_object_unref (src_folder);
4875 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
4876 TnyFolder *src_folder,
4878 TnyFolder *dst_folder)
4880 gboolean need_connection = TRUE;
4881 gboolean do_xfer = TRUE;
4882 XferMsgsHelper *helper;
4884 g_return_if_fail (TNY_IS_FOLDER (src_folder));
4885 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4886 g_return_if_fail (TNY_IS_LIST (headers));
4888 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
4889 headers, TNY_FOLDER (dst_folder),
4890 TRUE, &need_connection,
4893 /* If we don't want to transfer just return */
4897 /* Create the helper */
4898 helper = g_slice_new (XferMsgsHelper);
4899 helper->dst_folder = g_object_ref (dst_folder);
4900 helper->headers = g_object_ref (headers);
4902 if (need_connection) {
4903 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4904 connect_info->callback = xfer_messages_performer;
4905 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4906 connect_info->data = helper;
4908 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4909 TNY_FOLDER_STORE (src_folder),
4912 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
4913 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
4914 src_account, helper);
4915 g_object_unref (src_account);
4920 * UI handler for the "Move to" action when invoked from the
4921 * ModestMsgViewWindow
4924 modest_ui_actions_on_window_move_to (GtkAction *action,
4926 TnyFolderStore *dst_folder,
4929 TnyFolder *src_folder = NULL;
4931 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4934 TnyHeader *header = NULL;
4937 iter = tny_list_create_iterator (headers);
4938 header = (TnyHeader *) tny_iterator_get_current (iter);
4939 src_folder = tny_header_get_folder (header);
4941 /* Transfer the messages */
4942 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
4944 TNY_FOLDER (dst_folder));
4947 g_object_unref (header);
4948 g_object_unref (iter);
4949 g_object_unref (src_folder);
4954 modest_ui_actions_on_move_to (GtkAction *action,
4957 modest_ui_actions_on_edit_mode_move_to (win);
4961 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
4963 GtkWidget *dialog = NULL;
4964 MoveToInfo *helper = NULL;
4965 TnyList *list_to_move;
4967 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
4970 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
4975 if (tny_list_get_length (list_to_move) < 1) {
4976 g_object_unref (list_to_move);
4980 /* Create and run the dialog */
4981 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
4982 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
4983 GTK_WINDOW (dialog),
4987 helper = g_slice_new0 (MoveToInfo);
4988 helper->list = list_to_move;
4991 /* Listen to response signal */
4992 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
4994 /* Show the dialog */
4995 gtk_widget_show (dialog);
5001 * Calls #HeadersFunc for each header already selected in the main
5002 * window or the message currently being shown in the msg view window
5005 do_headers_action (ModestWindow *win,
5009 TnyList *headers_list = NULL;
5010 TnyIterator *iter = NULL;
5011 TnyHeader *header = NULL;
5012 TnyFolder *folder = NULL;
5015 headers_list = get_selected_headers (win);
5019 /* Get the folder */
5020 iter = tny_list_create_iterator (headers_list);
5021 header = TNY_HEADER (tny_iterator_get_current (iter));
5023 folder = tny_header_get_folder (header);
5024 g_object_unref (header);
5027 /* Call the function for each header */
5028 while (!tny_iterator_is_done (iter)) {
5029 header = TNY_HEADER (tny_iterator_get_current (iter));
5030 func (header, win, user_data);
5031 g_object_unref (header);
5032 tny_iterator_next (iter);
5035 /* Trick: do a poke status in order to speed up the signaling
5038 tny_folder_poke_status (folder);
5039 g_object_unref (folder);
5043 g_object_unref (iter);
5044 g_object_unref (headers_list);
5048 modest_ui_actions_view_attachment (GtkAction *action,
5049 ModestWindow *window)
5051 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5052 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5054 /* not supported window for this action */
5055 g_return_if_reached ();
5060 modest_ui_actions_save_attachments (GtkAction *action,
5061 ModestWindow *window)
5063 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5065 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5068 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5070 /* not supported window for this action */
5071 g_return_if_reached ();
5076 modest_ui_actions_remove_attachments (GtkAction *action,
5077 ModestWindow *window)
5079 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5080 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5082 /* not supported window for this action */
5083 g_return_if_reached ();
5088 modest_ui_actions_on_settings (GtkAction *action,
5093 dialog = modest_platform_get_global_settings_dialog ();
5094 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5095 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5096 gtk_widget_show_all (dialog);
5098 gtk_dialog_run (GTK_DIALOG (dialog));
5100 gtk_widget_destroy (dialog);
5104 modest_ui_actions_on_help (GtkAction *action,
5107 /* Help app is not available at all in fremantle */
5108 #ifndef MODEST_TOOLKIT_HILDON2
5109 const gchar *help_id;
5111 g_return_if_fail (win && GTK_IS_WINDOW(win));
5113 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5116 modest_platform_show_help (GTK_WINDOW (win), help_id);
5121 modest_ui_actions_on_csm_help (GtkAction *action,
5124 /* Help app is not available at all in fremantle */
5128 retrieve_contents_cb (ModestMailOperation *mail_op,
5135 /* We only need this callback to show an error in case of
5136 memory low condition */
5137 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5138 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5143 retrieve_msg_contents_performer (gboolean canceled,
5145 GtkWindow *parent_window,
5146 TnyAccount *account,
5149 ModestMailOperation *mail_op;
5150 TnyList *headers = TNY_LIST (user_data);
5152 if (err || canceled) {
5153 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5154 (GtkWidget *) parent_window, err,
5159 /* Create mail operation */
5160 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5161 modest_ui_actions_disk_operations_error_handler,
5163 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5164 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5167 g_object_unref (mail_op);
5169 g_object_unref (headers);
5170 g_object_unref (account);
5174 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5175 ModestWindow *window)
5177 TnyList *headers = NULL;
5178 TnyAccount *account = NULL;
5179 TnyIterator *iter = NULL;
5180 TnyHeader *header = NULL;
5181 TnyFolder *folder = NULL;
5184 headers = get_selected_headers (window);
5188 /* Pick the account */
5189 iter = tny_list_create_iterator (headers);
5190 header = TNY_HEADER (tny_iterator_get_current (iter));
5191 folder = tny_header_get_folder (header);
5192 account = tny_folder_get_account (folder);
5193 g_object_unref (folder);
5194 g_object_unref (header);
5195 g_object_unref (iter);
5197 /* Connect and perform the message retrieval */
5198 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5199 g_object_ref (account),
5200 retrieve_msg_contents_performer,
5201 g_object_ref (headers));
5204 g_object_unref (account);
5205 g_object_unref (headers);
5209 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5211 g_return_if_fail (MODEST_IS_WINDOW (window));
5214 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5218 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5220 g_return_if_fail (MODEST_IS_WINDOW (window));
5223 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5227 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5228 ModestWindow *window)
5230 g_return_if_fail (MODEST_IS_WINDOW (window));
5233 modest_ui_actions_check_menu_dimming_rules (window);
5237 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5238 ModestWindow *window)
5240 g_return_if_fail (MODEST_IS_WINDOW (window));
5243 modest_ui_actions_check_menu_dimming_rules (window);
5247 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5248 ModestWindow *window)
5250 g_return_if_fail (MODEST_IS_WINDOW (window));
5253 modest_ui_actions_check_menu_dimming_rules (window);
5257 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5258 ModestWindow *window)
5260 g_return_if_fail (MODEST_IS_WINDOW (window));
5263 modest_ui_actions_check_menu_dimming_rules (window);
5267 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5268 ModestWindow *window)
5270 g_return_if_fail (MODEST_IS_WINDOW (window));
5273 modest_ui_actions_check_menu_dimming_rules (window);
5277 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5278 ModestWindow *window)
5280 g_return_if_fail (MODEST_IS_WINDOW (window));
5283 modest_ui_actions_check_menu_dimming_rules (window);
5287 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5288 ModestWindow *window)
5290 g_return_if_fail (MODEST_IS_WINDOW (window));
5293 modest_ui_actions_check_menu_dimming_rules (window);
5297 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5298 ModestWindow *window)
5300 g_return_if_fail (MODEST_IS_WINDOW (window));
5303 modest_ui_actions_check_menu_dimming_rules (window);
5307 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5308 ModestWindow *window)
5310 g_return_if_fail (MODEST_IS_WINDOW (window));
5313 modest_ui_actions_check_menu_dimming_rules (window);
5317 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5319 g_return_if_fail (MODEST_IS_WINDOW (window));
5321 /* we check for low-mem; in that case, show a warning, and don't allow
5324 if (modest_platform_check_memory_low (window, TRUE))
5327 modest_platform_show_search_messages (GTK_WINDOW (window));
5331 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5333 g_return_if_fail (MODEST_IS_WINDOW (win));
5336 /* we check for low-mem; in that case, show a warning, and don't allow
5337 * for the addressbook
5339 if (modest_platform_check_memory_low (win, TRUE))
5343 modest_platform_show_addressbook (GTK_WINDOW (win));
5348 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5349 ModestWindow *window)
5352 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5354 if (GTK_IS_TOGGLE_ACTION (action))
5355 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5359 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5365 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5371 const gchar* server_name = NULL;
5372 TnyTransportAccount *transport;
5373 gchar *message = NULL;
5374 ModestProtocol *protocol;
5376 /* Don't show anything if the user cancelled something or the
5377 * send receive request is not interactive. Authentication
5378 * errors are managed by the account store so no need to show
5379 * a dialog here again */
5380 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5381 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5382 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5386 /* Get the server name. Note that we could be using a
5387 connection specific transport account */
5388 transport = (TnyTransportAccount *)
5389 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5391 ModestTnyAccountStore *acc_store;
5392 const gchar *acc_name;
5393 TnyTransportAccount *conn_specific;
5395 acc_store = modest_runtime_get_account_store();
5396 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5397 conn_specific = (TnyTransportAccount *)
5398 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5399 if (conn_specific) {
5400 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5401 g_object_unref (conn_specific);
5403 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5405 g_object_unref (transport);
5409 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5410 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5411 tny_account_get_proto (TNY_ACCOUNT (transport)));
5413 g_warning ("%s: Account with no proto", __FUNCTION__);
5417 /* Show the appropriate message text for the GError: */
5418 switch (err->code) {
5419 case TNY_SERVICE_ERROR_CONNECT:
5420 message = modest_protocol_get_translation (protocol,
5421 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5424 case TNY_SERVICE_ERROR_SEND:
5425 message = g_strdup (_CS("sfil_ib_unable_to_send"));
5427 case TNY_SERVICE_ERROR_UNAVAILABLE:
5428 message = modest_protocol_get_translation (protocol,
5429 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5433 g_warning ("%s: unexpected ERROR %d",
5434 __FUNCTION__, err->code);
5435 message = g_strdup (_CS("sfil_ib_unable_to_send"));
5439 modest_platform_run_information_dialog (NULL, message, FALSE);
5444 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5449 ModestWindow *top_window = NULL;
5450 ModestWindowMgr *mgr = NULL;
5451 GtkWidget *header_view = NULL;
5452 TnyFolder *selected_folder = NULL;
5453 TnyFolderType folder_type;
5455 mgr = modest_runtime_get_window_mgr ();
5456 top_window = modest_window_mgr_get_current_top (mgr);
5461 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5462 header_view = (GtkWidget *)
5463 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5466 /* Get selected folder */
5468 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5469 if (!selected_folder)
5472 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5473 #if GTK_CHECK_VERSION(2, 8, 0)
5474 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5475 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5476 GtkTreeViewColumn *tree_column;
5478 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5479 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5481 gtk_tree_view_column_queue_resize (tree_column);
5483 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5484 gtk_widget_queue_draw (header_view);
5487 #ifndef MODEST_TOOLKIT_HILDON2
5488 /* Rerun dimming rules, because the message could become deletable for example */
5489 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5490 MODEST_DIMMING_RULES_TOOLBAR);
5491 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5492 MODEST_DIMMING_RULES_MENU);
5496 g_object_unref (selected_folder);
5500 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5501 TnyAccount *account)
5503 ModestProtocolType protocol_type;
5504 ModestProtocol *protocol;
5505 gchar *error_note = NULL;
5507 protocol_type = modest_tny_account_get_protocol_type (account);
5508 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5511 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5512 if (error_note == NULL) {
5513 g_warning ("%s: This should not be reached", __FUNCTION__);
5515 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
5516 g_free (error_note);
5521 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5525 TnyFolderStore *folder = NULL;
5526 TnyAccount *account = NULL;
5527 ModestProtocolType proto;
5528 ModestProtocol *protocol;
5529 TnyHeader *header = NULL;
5531 if (MODEST_IS_HEADER_WINDOW (win)) {
5532 GtkWidget *header_view;
5533 TnyList* headers = NULL;
5535 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5536 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5537 if (!headers || tny_list_get_length (headers) == 0) {
5539 g_object_unref (headers);
5542 iter = tny_list_create_iterator (headers);
5543 header = TNY_HEADER (tny_iterator_get_current (iter));
5545 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5547 g_warning ("List should contain headers");
5549 g_object_unref (iter);
5550 g_object_unref (headers);
5551 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5552 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5554 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5557 if (!header || !folder)
5560 /* Get the account type */
5561 account = tny_folder_get_account (TNY_FOLDER (folder));
5562 proto = modest_tny_account_get_protocol_type (account);
5563 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5566 subject = tny_header_dup_subject (header);
5567 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5571 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5577 g_object_unref (account);
5579 g_object_unref (folder);
5581 g_object_unref (header);
5587 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5588 const gchar *account_name,
5589 const gchar *account_title)
5591 ModestAccountMgr *account_mgr;
5594 ModestProtocol *protocol;
5595 gboolean removed = FALSE;
5597 g_return_val_if_fail (account_name, FALSE);
5598 g_return_val_if_fail (account_title, FALSE);
5600 account_mgr = modest_runtime_get_account_mgr();
5602 /* The warning text depends on the account type: */
5603 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5604 modest_account_mgr_get_store_protocol (account_mgr,
5606 txt = modest_protocol_get_translation (protocol,
5607 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5610 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5612 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5616 if (response == GTK_RESPONSE_OK) {
5617 /* Remove account. If it succeeds then it also removes
5618 the account from the ModestAccountView: */
5619 gboolean is_default = FALSE;
5620 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5621 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5623 g_free (default_account_name);
5625 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5627 /* Close all email notifications, we cannot
5628 distinguish if the notification belongs to
5629 this account or not, so for safety reasons
5630 we remove them all */
5631 modest_platform_remove_new_mail_notifications (FALSE);
5633 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5640 on_fetch_images_performer (gboolean canceled,
5642 GtkWindow *parent_window,
5643 TnyAccount *account,
5646 if (err || canceled) {
5647 /* Show an unable to retrieve images ??? */
5651 /* Note that the user could have closed the window while connecting */
5652 if (GTK_WIDGET_VISIBLE (parent_window))
5653 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5654 g_object_unref ((GObject *) user_data);
5658 modest_ui_actions_on_fetch_images (GtkAction *action,
5659 ModestWindow *window)
5661 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5663 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5665 on_fetch_images_performer,
5666 g_object_ref (window));
5670 modest_ui_actions_on_reload_message (const gchar *msg_id)
5672 ModestWindow *window = NULL;
5674 g_return_if_fail (msg_id && msg_id[0] != '\0');
5675 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5681 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5684 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5687 /** Check whether any connections are active, and cancel them if
5689 * Returns TRUE is there was no problem,
5690 * or if an operation was cancelled so we can continue.
5691 * Returns FALSE if the user chose to cancel his request instead.
5695 modest_ui_actions_check_for_active_account (ModestWindow *self,
5696 const gchar* account_name)
5698 ModestTnySendQueue *send_queue;
5699 ModestTnyAccountStore *acc_store;
5700 ModestMailOperationQueue* queue;
5701 TnyConnectionStatus store_conn_status;
5702 TnyAccount *store_account = NULL, *transport_account = NULL;
5703 gboolean retval = TRUE, sending = FALSE;
5705 acc_store = modest_runtime_get_account_store ();
5706 queue = modest_runtime_get_mail_operation_queue ();
5709 modest_tny_account_store_get_server_account (acc_store,
5711 TNY_ACCOUNT_TYPE_STORE);
5713 /* This could happen if the account was deleted before the
5714 call to this function */
5719 modest_tny_account_store_get_server_account (acc_store,
5721 TNY_ACCOUNT_TYPE_TRANSPORT);
5723 /* This could happen if the account was deleted before the
5724 call to this function */
5725 if (!transport_account) {
5726 g_object_unref (store_account);
5730 /* If the transport account was not used yet, then the send
5731 queue could not exist (it's created on demand) */
5732 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5733 if (TNY_IS_SEND_QUEUE (send_queue))
5734 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5736 store_conn_status = tny_account_get_connection_status (store_account);
5737 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5740 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
5741 _("emev_nc_disconnect_account"));
5742 if (response == GTK_RESPONSE_OK) {
5751 /* FIXME: We should only cancel those of this account */
5752 modest_mail_operation_queue_cancel_all (queue);
5754 /* Also disconnect the account */
5755 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5756 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5757 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5761 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5767 g_object_unref (store_account);
5768 g_object_unref (transport_account);