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 *toplevel, *account_win;
569 account_win = GTK_WINDOW (modest_account_view_window_new ());
570 toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (win)));
572 /* The accounts dialog must be modal */
573 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
574 modest_utils_show_dialog_and_forget (toplevel, GTK_DIALOG (account_win));
579 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
581 /* This is currently only implemented for Maemo,
582 * because it requires an API (libconic) to detect different connection
585 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
587 /* Create the window if necessary: */
588 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
589 modest_connection_specific_smtp_window_fill_with_connections (
590 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
591 modest_runtime_get_account_mgr());
593 /* Show the window: */
594 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
595 GTK_WINDOW (specific_window), (GtkWindow *) win);
596 gtk_widget_show (specific_window);
597 #endif /* !MODEST_TOOLKIT_GTK */
601 count_part_size (const gchar *part)
603 GnomeVFSURI *vfs_uri;
604 gchar *escaped_filename;
606 GnomeVFSFileInfo *info;
609 /* Estimation of attachment size if we cannot get it from file info */
612 vfs_uri = gnome_vfs_uri_new (part);
614 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
615 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
616 g_free (escaped_filename);
617 gnome_vfs_uri_unref (vfs_uri);
619 info = gnome_vfs_file_info_new ();
621 if (gnome_vfs_get_file_info (part,
623 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
625 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
630 gnome_vfs_file_info_unref (info);
636 count_parts_size (GSList *parts)
641 for (node = parts; node != NULL; node = g_slist_next (node)) {
642 result += count_part_size ((const gchar *) node->data);
649 modest_ui_actions_compose_msg(ModestWindow *win,
652 const gchar *bcc_str,
653 const gchar *subject_str,
654 const gchar *body_str,
656 gboolean set_as_modified)
658 gchar *account_name = NULL;
659 const gchar *mailbox;
661 TnyAccount *account = NULL;
662 TnyFolder *folder = NULL;
663 gchar *from_str = NULL, *signature = NULL, *body = NULL;
664 gchar *recipient = NULL;
665 gboolean use_signature = FALSE;
666 ModestWindow *msg_win = NULL;
667 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
668 ModestTnyAccountStore *store = modest_runtime_get_account_store();
669 GnomeVFSFileSize total_size, allowed_size;
670 guint64 available_disk, expected_size, parts_size;
673 /* we check for low-mem */
674 if (modest_platform_check_memory_low (win, TRUE))
677 available_disk = modest_utils_get_available_space (NULL);
678 parts_count = g_slist_length (attachments);
679 parts_size = count_parts_size (attachments);
680 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
682 /* Double check: disk full condition or message too big */
683 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
684 expected_size > available_disk) {
685 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
686 modest_platform_system_banner (NULL, NULL, msg);
692 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
693 modest_platform_run_information_dialog (
695 _("mail_ib_error_attachment_size"),
702 account_name = g_strdup (modest_window_get_active_account(win));
704 account_name = modest_account_mgr_get_default_account(mgr);
707 g_printerr ("modest: no account found\n");
712 mailbox = modest_window_get_active_mailbox (win);
715 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
717 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
720 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
722 g_printerr ("modest: failed to find Drafts folder\n");
725 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
727 g_printerr ("modest: failed get from string for '%s'\n", account_name);
731 recipient = modest_text_utils_get_email_address (from_str);
732 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
734 if (body_str != NULL) {
735 body = use_signature ? g_strconcat(body_str, "\n",
736 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
737 "\n", signature, NULL) : g_strdup(body_str);
739 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
740 "\n", signature, NULL) : g_strdup("");
743 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
745 g_printerr ("modest: failed to create new msg\n");
749 /* Create and register edit window */
750 /* This is destroyed by TODO. */
752 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
753 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
755 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
756 gtk_widget_destroy (GTK_WIDGET (msg_win));
759 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
760 gtk_widget_show_all (GTK_WIDGET (msg_win));
762 while (attachments) {
763 GnomeVFSFileSize att_size;
765 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
766 attachments->data, allowed_size);
767 total_size += att_size;
769 if (att_size > allowed_size) {
770 g_debug ("%s: total size: %u",
771 __FUNCTION__, (unsigned int)total_size);
774 allowed_size -= att_size;
776 attachments = g_slist_next(attachments);
783 g_free (account_name);
785 g_object_unref (G_OBJECT(account));
787 g_object_unref (G_OBJECT(folder));
789 g_object_unref (G_OBJECT(msg));
793 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
795 /* if there are no accounts yet, just show the wizard */
796 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
797 if (!modest_ui_actions_run_account_setup_wizard (win))
800 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
805 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
809 ModestMailOperationStatus status;
811 /* If there is no message or the operation was not successful */
812 status = modest_mail_operation_get_status (mail_op);
813 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
816 /* If it's a memory low issue, then show a banner */
817 error = modest_mail_operation_get_error (mail_op);
818 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
819 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
820 GObject *source = modest_mail_operation_get_source (mail_op);
821 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
822 _KR("memr_ib_operation_disabled"),
824 g_object_unref (source);
827 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
828 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
829 gchar *subject, *msg, *format = NULL;
832 subject = (header) ? tny_header_dup_subject (header) : NULL;
834 subject = g_strdup (_("mail_va_no_subject"));
836 account = modest_mail_operation_get_account (mail_op);
838 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
839 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
842 if (tny_account_get_connection_status (account) ==
843 TNY_CONNECTION_STATUS_CONNECTED) {
845 format = modest_protocol_get_translation (protocol,
846 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
849 format = modest_protocol_get_translation (protocol,
850 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
853 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
854 tny_account_get_hostname (account));
857 g_object_unref (account);
862 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
864 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
868 msg = g_strdup_printf (format, subject);
869 modest_platform_run_information_dialog (NULL, msg, FALSE);
875 /* Remove the header from the preregistered uids */
876 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
894 ModestWindow *caller_window;
895 OpenMsgBannerInfo *banner_info;
896 GtkTreeRowReference *rowref;
900 open_msg_banner_idle (gpointer userdata)
902 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
904 gdk_threads_enter ();
905 banner_info->idle_handler = 0;
906 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
907 if (banner_info->banner)
908 g_object_ref (banner_info->banner);
910 gdk_threads_leave ();
916 get_header_view_from_window (ModestWindow *window)
918 GtkWidget *header_view;
920 if (MODEST_IS_HEADER_WINDOW (window)){
921 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
930 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
933 gchar *account = NULL;
934 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
939 folder = tny_header_get_folder (header);
940 /* Gets folder type (OUTBOX headers will be opened in edit window */
941 if (modest_tny_folder_is_local_folder (folder)) {
942 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
943 if (folder_type == TNY_FOLDER_TYPE_INVALID)
944 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
947 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
948 TnyTransportAccount *traccount = NULL;
949 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
950 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
952 ModestTnySendQueue *send_queue = NULL;
953 ModestTnySendQueueStatus status;
955 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
956 TNY_ACCOUNT(traccount)));
957 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
958 if (TNY_IS_SEND_QUEUE (send_queue)) {
959 msg_id = modest_tny_send_queue_get_msg_id (header);
960 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
962 /* Only open messages in outbox with the editor if they are in Failed state */
963 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
967 /* In Fremantle we can not
968 open any message from
969 outbox which is not in
974 g_object_unref(traccount);
976 g_warning("Cannot get transport account for message in outbox!!");
978 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
979 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
983 TnyAccount *acc = tny_folder_get_account (folder);
986 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
987 g_object_unref (acc);
991 g_object_unref (folder);
997 open_msg_cb (ModestMailOperation *mail_op,
1004 ModestWindowMgr *mgr = NULL;
1005 ModestWindow *parent_win = NULL;
1006 ModestWindow *win = NULL;
1007 gchar *account = NULL;
1008 gboolean open_in_editor = FALSE;
1010 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1012 /* Do nothing if there was any problem with the mail
1013 operation. The error will be shown by the error_handler of
1014 the mail operation */
1015 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1018 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1020 /* Mark header as read */
1021 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1023 account = get_info_from_header (header, &open_in_editor, &can_open);
1027 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1029 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1031 if (open_in_editor) {
1032 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1033 gchar *from_header = NULL, *acc_name;
1034 gchar *mailbox = NULL;
1036 from_header = tny_header_dup_from (header);
1038 /* we cannot edit without a valid account... */
1039 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1040 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1041 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1043 g_free (from_header);
1048 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1049 g_free (from_header);
1055 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1059 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1060 const gchar *mailbox = NULL;
1062 if (parent_win && MODEST_IS_WINDOW (parent_win))
1063 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1065 if (helper->rowref && helper->model) {
1066 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1067 helper->model, helper->rowref);
1069 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1074 /* Register and show new window */
1076 mgr = modest_runtime_get_window_mgr ();
1077 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1078 gtk_widget_destroy (GTK_WIDGET (win));
1081 gtk_widget_show_all (GTK_WIDGET(win));
1088 g_object_unref (parent_win);
1092 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1095 const GError *error;
1096 GObject *win = NULL;
1097 ModestMailOperationStatus status;
1099 win = modest_mail_operation_get_source (mail_op);
1100 error = modest_mail_operation_get_error (mail_op);
1101 status = modest_mail_operation_get_status (mail_op);
1103 /* If the mail op has been cancelled then it's not an error:
1104 don't show any message */
1105 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1106 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1107 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1108 (GError *) error, account)) {
1109 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1110 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1112 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1113 modest_platform_information_banner ((GtkWidget *) win,
1114 NULL, _("emev_ui_imap_inbox_select_error"));
1115 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1116 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1117 modest_platform_information_banner ((GtkWidget *) win,
1118 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1119 } else if (user_data) {
1120 modest_platform_information_banner ((GtkWidget *) win,
1124 g_object_unref (account);
1128 g_object_unref (win);
1132 * Returns the account a list of headers belongs to. It returns a
1133 * *new* reference so don't forget to unref it
1136 get_account_from_header_list (TnyList *headers)
1138 TnyAccount *account = NULL;
1140 if (tny_list_get_length (headers) > 0) {
1141 TnyIterator *iter = tny_list_create_iterator (headers);
1142 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1143 TnyFolder *folder = tny_header_get_folder (header);
1146 g_object_unref (header);
1148 while (!tny_iterator_is_done (iter)) {
1149 header = TNY_HEADER (tny_iterator_get_current (iter));
1150 folder = tny_header_get_folder (header);
1153 g_object_unref (header);
1155 tny_iterator_next (iter);
1160 account = tny_folder_get_account (folder);
1161 g_object_unref (folder);
1165 g_object_unref (header);
1167 g_object_unref (iter);
1173 get_account_from_header (TnyHeader *header)
1175 TnyAccount *account = NULL;
1178 folder = tny_header_get_folder (header);
1181 account = tny_folder_get_account (folder);
1182 g_object_unref (folder);
1188 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1190 if (helper->caller_window)
1191 helper->caller_window = NULL;
1195 open_msg_helper_destroyer (gpointer user_data)
1197 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1199 if (helper->caller_window) {
1200 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1201 helper->caller_window = NULL;
1204 if (helper->banner_info) {
1205 g_free (helper->banner_info->message);
1206 if (helper->banner_info->idle_handler > 0) {
1207 g_source_remove (helper->banner_info->idle_handler);
1208 helper->banner_info->idle_handler = 0;
1210 if (helper->banner_info->banner != NULL) {
1211 gtk_widget_destroy (helper->banner_info->banner);
1212 g_object_unref (helper->banner_info->banner);
1213 helper->banner_info->banner = NULL;
1215 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1216 helper->banner_info = NULL;
1218 g_object_unref (helper->model);
1219 g_object_unref (helper->header);
1220 gtk_tree_row_reference_free (helper->rowref);
1221 g_slice_free (OpenMsgHelper, helper);
1225 open_msg_performer(gboolean canceled,
1227 GtkWindow *parent_window,
1228 TnyAccount *account,
1231 ModestMailOperation *mail_op = NULL;
1232 gchar *error_msg = NULL;
1233 ModestProtocolType proto;
1234 TnyConnectionStatus status;
1235 OpenMsgHelper *helper = NULL;
1236 ModestProtocol *protocol;
1237 ModestProtocolRegistry *protocol_registry;
1240 helper = (OpenMsgHelper *) user_data;
1242 status = tny_account_get_connection_status (account);
1243 if (err || canceled || helper->caller_window == NULL) {
1244 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1245 /* Free the helper */
1246 open_msg_helper_destroyer (helper);
1248 /* In disk full conditions we could get this error here */
1249 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1250 (GtkWidget *) parent_window, err,
1256 /* Get the error message depending on the protocol */
1257 proto = modest_tny_account_get_protocol_type (account);
1258 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1259 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1262 protocol_registry = modest_runtime_get_protocol_registry ();
1263 subject = tny_header_dup_subject (helper->header);
1265 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1266 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1270 if (error_msg == NULL) {
1271 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1276 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1279 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1280 g_free (account_name);
1281 open_msg_helper_destroyer (helper);
1286 ModestWindow *window;
1287 GtkWidget *header_view;
1290 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1291 uid = modest_tny_folder_get_header_unique_id (helper->header);
1293 const gchar *mailbox = NULL;
1294 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1295 window = modest_msg_view_window_new_from_header_view
1296 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1297 if (window != NULL) {
1298 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1300 gtk_widget_destroy (GTK_WIDGET (window));
1302 gtk_widget_show_all (GTK_WIDGET(window));
1306 g_free (account_name);
1308 open_msg_helper_destroyer (helper);
1311 g_free (account_name);
1312 /* Create the mail operation */
1314 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1315 modest_ui_actions_disk_operations_error_handler,
1316 g_strdup (error_msg), g_free);
1317 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1323 headers = TNY_LIST (tny_simple_list_new ());
1324 tny_list_prepend (headers, G_OBJECT (helper->header));
1325 modest_mail_operation_get_msgs_full (mail_op,
1329 open_msg_helper_destroyer);
1330 g_object_unref (headers);
1337 g_object_unref (mail_op);
1338 g_object_unref (account);
1342 * This function is used by both modest_ui_actions_on_open and
1343 * modest_ui_actions_on_header_activated. This way we always do the
1344 * same when trying to open messages.
1347 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1349 ModestWindowMgr *mgr = NULL;
1350 TnyAccount *account;
1351 gboolean cached = FALSE;
1353 GtkWidget *header_view = NULL;
1354 OpenMsgHelper *helper;
1355 ModestWindow *window;
1357 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1359 mgr = modest_runtime_get_window_mgr ();
1362 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1363 if (header_view == NULL)
1366 /* Get the account */
1367 account = get_account_from_header (header);
1372 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1374 /* Do not open again the message and present the
1375 window to the user */
1378 #ifndef MODEST_TOOLKIT_HILDON2
1379 gtk_window_present (GTK_WINDOW (window));
1382 /* the header has been registered already, we don't do
1383 * anything but wait for the window to come up*/
1384 g_debug ("header %p already registered, waiting for window", header);
1389 /* Open each message */
1390 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1392 /* Allways download if we are online. */
1393 if (!tny_device_is_online (modest_runtime_get_device ())) {
1396 /* If ask for user permission to download the messages */
1397 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1398 _("mcen_nc_get_msg"));
1400 /* End if the user does not want to continue */
1401 if (response == GTK_RESPONSE_CANCEL) {
1407 /* We register the window for opening */
1408 modest_window_mgr_register_header (mgr, header, NULL);
1410 /* Create the helper. We need to get a reference to the model
1411 here because it could change while the message is readed
1412 (the user could switch between folders) */
1413 helper = g_slice_new (OpenMsgHelper);
1414 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1415 helper->caller_window = win;
1416 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1417 helper->header = g_object_ref (header);
1418 helper->rowref = gtk_tree_row_reference_copy (rowref);
1419 helper->banner_info = NULL;
1421 /* Connect to the account and perform */
1423 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1424 open_msg_performer, helper);
1426 /* Call directly the performer, do not need to connect */
1427 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1428 g_object_ref (account), helper);
1433 g_object_unref (account);
1437 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1444 /* we check for low-mem; in that case, show a warning, and don't allow
1447 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1451 headers = get_selected_headers (win);
1455 headers_count = tny_list_get_length (headers);
1456 if (headers_count != 1) {
1457 if (headers_count > 1) {
1458 /* Don't allow activation if there are more than one message selected */
1459 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1462 g_object_unref (headers);
1466 iter = tny_list_create_iterator (headers);
1467 header = TNY_HEADER (tny_iterator_get_current (iter));
1468 g_object_unref (iter);
1472 open_msg_from_header (header, NULL, win);
1473 g_object_unref (header);
1476 g_object_unref(headers);
1480 rf_helper_window_closed (gpointer data,
1483 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1485 helper->parent_window = NULL;
1488 static ReplyForwardHelper*
1489 create_reply_forward_helper (ReplyForwardAction action,
1491 guint reply_forward_type,
1494 ReplyForwardHelper *rf_helper = NULL;
1495 const gchar *active_acc = modest_window_get_active_account (win);
1496 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1498 rf_helper = g_slice_new0 (ReplyForwardHelper);
1499 rf_helper->reply_forward_type = reply_forward_type;
1500 rf_helper->action = action;
1501 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1502 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1503 rf_helper->account_name = (active_acc) ?
1504 g_strdup (active_acc) :
1505 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1506 rf_helper->mailbox = g_strdup (active_mailbox);
1508 /* Note that window could be destroyed just AFTER calling
1509 register_window so we must ensure that this pointer does
1510 not hold invalid references */
1511 if (rf_helper->parent_window)
1512 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1513 rf_helper_window_closed, rf_helper);
1519 free_reply_forward_helper (gpointer data)
1521 ReplyForwardHelper *helper;
1523 helper = (ReplyForwardHelper *) data;
1524 g_free (helper->account_name);
1525 g_free (helper->mailbox);
1527 g_object_unref (helper->header);
1528 if (helper->parent_window)
1529 g_object_weak_unref (G_OBJECT (helper->parent_window),
1530 rf_helper_window_closed, helper);
1531 g_slice_free (ReplyForwardHelper, helper);
1535 reply_forward_cb (ModestMailOperation *mail_op,
1542 TnyMsg *new_msg = NULL;
1543 ReplyForwardHelper *rf_helper;
1544 ModestWindow *msg_win = NULL;
1545 ModestEditType edit_type;
1547 TnyAccount *account = NULL;
1548 ModestWindowMgr *mgr = NULL;
1549 gchar *signature = NULL;
1550 gboolean use_signature;
1553 /* If there was any error. The mail operation could be NULL,
1554 this means that we already have the message downloaded and
1555 that we didn't do a mail operation to retrieve it */
1556 rf_helper = (ReplyForwardHelper *) user_data;
1557 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1560 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1561 rf_helper->account_name, rf_helper->mailbox);
1562 recipient = modest_text_utils_get_email_address (from);
1563 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1568 /* Create reply mail */
1569 switch (rf_helper->action) {
1570 /* Use the msg_header to ensure that we have all the
1571 information. The summary can lack some data */
1572 TnyHeader *msg_header;
1574 msg_header = tny_msg_get_header (msg);
1576 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1577 (use_signature) ? signature : NULL,
1578 rf_helper->reply_forward_type,
1579 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1580 g_object_unref (msg_header);
1582 case ACTION_REPLY_TO_ALL:
1583 msg_header = tny_msg_get_header (msg);
1585 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1586 (use_signature) ? signature : NULL,
1587 rf_helper->reply_forward_type,
1588 MODEST_TNY_MSG_REPLY_MODE_ALL);
1589 edit_type = MODEST_EDIT_TYPE_REPLY;
1590 g_object_unref (msg_header);
1592 case ACTION_FORWARD:
1594 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1595 rf_helper->reply_forward_type);
1596 edit_type = MODEST_EDIT_TYPE_FORWARD;
1599 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1601 g_return_if_reached ();
1609 g_warning ("%s: failed to create message\n", __FUNCTION__);
1613 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1614 rf_helper->account_name,
1615 TNY_ACCOUNT_TYPE_STORE);
1617 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1621 /* Create and register the windows */
1622 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1623 mgr = modest_runtime_get_window_mgr ();
1624 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1626 /* Note that register_window could have deleted the account */
1627 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1628 gdouble parent_zoom;
1630 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1631 modest_window_set_zoom (msg_win, parent_zoom);
1634 /* Show edit window */
1635 gtk_widget_show_all (GTK_WIDGET (msg_win));
1638 /* We always unregister the header because the message is
1639 forwarded or replied so the original one is no longer
1641 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1644 g_object_unref (G_OBJECT (new_msg));
1646 g_object_unref (G_OBJECT (account));
1647 free_reply_forward_helper (rf_helper);
1650 /* Checks a list of headers. If any of them are not currently
1651 * downloaded (CACHED) then returns TRUE else returns FALSE.
1654 header_list_count_uncached_msgs (TnyList *header_list)
1657 gint uncached_messages = 0;
1659 iter = tny_list_create_iterator (header_list);
1660 while (!tny_iterator_is_done (iter)) {
1663 header = TNY_HEADER (tny_iterator_get_current (iter));
1665 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1666 uncached_messages ++;
1667 g_object_unref (header);
1670 tny_iterator_next (iter);
1672 g_object_unref (iter);
1674 return uncached_messages;
1677 /* Returns FALSE if the user does not want to download the
1678 * messages. Returns TRUE if the user allowed the download.
1681 connect_to_get_msg (ModestWindow *win,
1682 gint num_of_uncached_msgs,
1683 TnyAccount *account)
1685 GtkResponseType response;
1687 /* Allways download if we are online. */
1688 if (tny_device_is_online (modest_runtime_get_device ()))
1691 /* If offline, then ask for user permission to download the messages */
1692 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1693 ngettext("mcen_nc_get_msg",
1695 num_of_uncached_msgs));
1697 if (response == GTK_RESPONSE_CANCEL)
1700 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1704 reply_forward_performer (gboolean canceled,
1706 GtkWindow *parent_window,
1707 TnyAccount *account,
1710 ReplyForwardHelper *rf_helper = NULL;
1711 ModestMailOperation *mail_op;
1713 rf_helper = (ReplyForwardHelper *) user_data;
1715 if (canceled || err) {
1716 free_reply_forward_helper (rf_helper);
1720 /* Retrieve the message */
1721 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1722 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1723 modest_ui_actions_disk_operations_error_handler,
1725 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1726 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1729 g_object_unref(mail_op);
1733 * Common code for the reply and forward actions
1736 reply_forward (ReplyForwardAction action, ModestWindow *win)
1738 ReplyForwardHelper *rf_helper = NULL;
1739 guint reply_forward_type;
1741 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1743 /* we check for low-mem; in that case, show a warning, and don't allow
1744 * reply/forward (because it could potentially require a lot of memory */
1745 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1749 /* we need an account when editing */
1750 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1751 if (!modest_ui_actions_run_account_setup_wizard (win))
1755 reply_forward_type =
1756 modest_conf_get_int (modest_runtime_get_conf (),
1757 (action == ACTION_FORWARD) ?
1758 MODEST_CONF_FORWARD_TYPE :
1759 MODEST_CONF_REPLY_TYPE,
1762 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1764 TnyHeader *header = NULL;
1765 /* Get header and message. Do not free them here, the
1766 reply_forward_cb must do it */
1767 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1768 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1770 if (msg && header) {
1772 rf_helper = create_reply_forward_helper (action, win,
1773 reply_forward_type, header);
1774 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1776 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1780 g_object_unref (msg);
1782 g_object_unref (header);
1784 TnyHeader *header = NULL;
1786 gboolean do_retrieve = TRUE;
1787 TnyList *header_list = NULL;
1789 header_list = get_selected_headers (win);
1792 /* Check that only one message is selected for replying */
1793 if (tny_list_get_length (header_list) != 1) {
1794 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1795 NULL, _("mcen_ib_select_one_message"));
1796 g_object_unref (header_list);
1800 /* Only reply/forward to one message */
1801 iter = tny_list_create_iterator (header_list);
1802 header = TNY_HEADER (tny_iterator_get_current (iter));
1803 g_object_unref (iter);
1805 /* Retrieve messages */
1806 do_retrieve = (action == ACTION_FORWARD) ||
1807 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1810 TnyAccount *account = NULL;
1811 TnyFolder *folder = NULL;
1812 gdouble download = TRUE;
1813 guint uncached_msgs = 0;
1815 folder = tny_header_get_folder (header);
1817 goto do_retrieve_frees;
1818 account = tny_folder_get_account (folder);
1820 goto do_retrieve_frees;
1822 uncached_msgs = header_list_count_uncached_msgs (header_list);
1824 if (uncached_msgs > 0) {
1825 /* Allways download if we are online. */
1826 if (!tny_device_is_online (modest_runtime_get_device ())) {
1829 /* If ask for user permission to download the messages */
1830 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1831 ngettext("mcen_nc_get_msg",
1835 /* End if the user does not want to continue */
1836 if (response == GTK_RESPONSE_CANCEL)
1843 rf_helper = create_reply_forward_helper (action, win,
1844 reply_forward_type, header);
1845 if (uncached_msgs > 0) {
1846 modest_platform_connect_and_perform (GTK_WINDOW (win),
1848 reply_forward_performer,
1851 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1852 account, rf_helper);
1857 g_object_unref (account);
1859 g_object_unref (folder);
1861 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
1864 g_object_unref (header_list);
1865 g_object_unref (header);
1870 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1872 g_return_if_fail (MODEST_IS_WINDOW(win));
1874 reply_forward (ACTION_REPLY, win);
1878 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1880 g_return_if_fail (MODEST_IS_WINDOW(win));
1882 reply_forward (ACTION_FORWARD, win);
1886 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1888 g_return_if_fail (MODEST_IS_WINDOW(win));
1890 reply_forward (ACTION_REPLY_TO_ALL, win);
1894 modest_ui_actions_on_next (GtkAction *action,
1895 ModestWindow *window)
1897 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1898 modest_msg_view_window_select_next_message (
1899 MODEST_MSG_VIEW_WINDOW (window));
1901 g_return_if_reached ();
1906 modest_ui_actions_on_prev (GtkAction *action,
1907 ModestWindow *window)
1909 g_return_if_fail (MODEST_IS_WINDOW(window));
1911 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1912 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1914 g_return_if_reached ();
1919 modest_ui_actions_on_sort (GtkAction *action,
1920 ModestWindow *window)
1922 GtkWidget *header_view = NULL;
1924 g_return_if_fail (MODEST_IS_WINDOW(window));
1926 if (MODEST_IS_HEADER_WINDOW (window)) {
1927 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1931 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1936 /* Show sorting dialog */
1937 modest_utils_run_sort_dialog (MODEST_WINDOW (window), MODEST_SORT_HEADERS);
1941 sync_folder_cb (ModestMailOperation *mail_op,
1945 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
1947 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
1948 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1950 /* We must clear first, because otherwise set_folder will ignore */
1951 /* the change as the folders are the same */
1952 modest_header_view_clear (header_view);
1953 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
1955 g_object_unref (parent);
1958 g_object_unref (header_view);
1962 idle_refresh_folder (gpointer source)
1964 ModestHeaderView *header_view = NULL;
1966 /* If the window still exists */
1967 if (!GTK_IS_WIDGET (source) ||
1968 !GTK_WIDGET_VISIBLE (source))
1971 /* Refresh the current view */
1972 if (MODEST_IS_HEADER_WINDOW (source))
1973 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
1975 TnyFolder *folder = modest_header_view_get_folder (header_view);
1977 /* Sync the folder status */
1978 ModestMailOperation *mail_op = modest_mail_operation_new (source);
1979 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1980 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
1981 g_object_unref (folder);
1982 g_object_unref (mail_op);
1990 update_account_cb (ModestMailOperation *self,
1991 TnyList *new_headers,
1995 gboolean show_visual_notifications;
1997 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
1998 show_visual_notifications = (top) ? FALSE : TRUE;
2000 /* Notify new messages have been downloaded. If the
2001 send&receive was invoked by the user then do not show any
2002 visual notification, only play a sound and activate the LED
2003 (for the Maemo version) */
2004 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2006 /* We only notify about really new messages (not seen) we get */
2007 TnyList *actually_new_list;
2008 TnyIterator *iterator;
2009 actually_new_list = TNY_LIST (tny_simple_list_new ());
2010 for (iterator = tny_list_create_iterator (new_headers);
2011 !tny_iterator_is_done (iterator);
2012 tny_iterator_next (iterator)) {
2014 TnyHeaderFlags flags;
2015 header = TNY_HEADER (tny_iterator_get_current (iterator));
2016 flags = tny_header_get_flags (header);
2018 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2019 /* Messages are ordered from most
2020 recent to oldest. But we want to
2021 show notifications starting from
2022 the oldest message. That's why we
2024 tny_list_prepend (actually_new_list, G_OBJECT (header));
2026 g_object_unref (header);
2028 g_object_unref (iterator);
2030 if (tny_list_get_length (actually_new_list) > 0) {
2031 GList *new_headers_list = NULL;
2033 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2035 /* Send notifications */
2036 if (new_headers_list) {
2037 modest_platform_on_new_headers_received (new_headers_list,
2038 show_visual_notifications);
2040 modest_utils_free_notification_list (new_headers_list);
2043 g_object_unref (actually_new_list);
2047 /* Refresh the current folder in an idle. We do this
2048 in order to avoid refresh cancelations if the
2049 currently viewed folder is the inbox */
2050 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2051 idle_refresh_folder,
2058 TnyAccount *account;
2060 gchar *account_name;
2061 gboolean poke_status;
2062 gboolean interactive;
2063 ModestMailOperation *mail_op;
2067 do_send_receive_performer (gboolean canceled,
2069 GtkWindow *parent_window,
2070 TnyAccount *account,
2073 SendReceiveInfo *info;
2075 info = (SendReceiveInfo *) user_data;
2077 if (err || canceled) {
2078 /* In disk full conditions we could get this error here */
2079 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2080 (GtkWidget *) parent_window, err,
2083 if (info->mail_op) {
2084 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2091 /* Send & receive. */
2092 modest_mail_operation_update_account (info->mail_op, info->account_name,
2093 info->poke_status, info->interactive,
2094 update_account_cb, info->win);
2099 g_object_unref (G_OBJECT (info->mail_op));
2100 if (info->account_name)
2101 g_free (info->account_name);
2103 g_object_unref (info->win);
2105 g_object_unref (info->account);
2106 g_slice_free (SendReceiveInfo, info);
2110 * This function performs the send & receive required actions. The
2111 * window is used to create the mail operation. Typically it should
2112 * always be the main window, but we pass it as argument in order to
2116 modest_ui_actions_do_send_receive (const gchar *account_name,
2117 gboolean force_connection,
2118 gboolean poke_status,
2119 gboolean interactive,
2122 gchar *acc_name = NULL;
2123 SendReceiveInfo *info;
2124 ModestTnyAccountStore *acc_store;
2125 TnyAccount *account;
2127 /* If no account name was provided then get the current account, and if
2128 there is no current account then pick the default one: */
2129 if (!account_name) {
2131 acc_name = g_strdup (modest_window_get_active_account (win));
2133 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2135 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2139 acc_name = g_strdup (account_name);
2142 acc_store = modest_runtime_get_account_store ();
2143 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2147 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2151 /* Do not automatically refresh accounts that are flagged as
2152 NO_AUTO_UPDATE. This could be useful for accounts that
2153 handle their own update times */
2155 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2156 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2157 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2158 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2160 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2161 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2162 g_object_unref (account);
2169 /* Create the info for the connect and perform */
2170 info = g_slice_new (SendReceiveInfo);
2171 info->account_name = acc_name;
2172 info->win = (win) ? g_object_ref (win) : NULL;
2173 info->poke_status = poke_status;
2174 info->interactive = interactive;
2175 info->account = account;
2176 /* We need to create the operation here, because otherwise it
2177 could happen that the queue emits the queue-empty signal
2178 while we're trying to connect the account */
2179 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2180 modest_ui_actions_disk_operations_error_handler,
2182 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2184 /* Invoke the connect and perform */
2185 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2186 force_connection, info->account,
2187 do_send_receive_performer, info);
2192 modest_ui_actions_do_cancel_send (const gchar *account_name,
2195 TnyTransportAccount *transport_account;
2196 TnySendQueue *send_queue = NULL;
2197 GError *error = NULL;
2199 /* Get transport account */
2201 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2202 (modest_runtime_get_account_store(),
2204 TNY_ACCOUNT_TYPE_TRANSPORT));
2205 if (!transport_account) {
2206 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2211 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2212 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2213 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2214 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2215 "modest: could not find send queue for account\n");
2217 /* Cancel the current send */
2218 tny_account_cancel (TNY_ACCOUNT (transport_account));
2220 /* Suspend all pending messages */
2221 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2225 if (transport_account != NULL)
2226 g_object_unref (G_OBJECT (transport_account));
2230 modest_ui_actions_cancel_send_all (ModestWindow *win)
2232 GSList *account_names, *iter;
2234 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2237 iter = account_names;
2239 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2240 iter = g_slist_next (iter);
2243 modest_account_mgr_free_account_names (account_names);
2244 account_names = NULL;
2248 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2251 /* Check if accounts exist */
2252 gboolean accounts_exist =
2253 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2255 /* If not, allow the user to create an account before trying to send/receive. */
2256 if (!accounts_exist)
2257 modest_ui_actions_on_accounts (NULL, win);
2259 /* Cancel all sending operaitons */
2260 modest_ui_actions_cancel_send_all (win);
2264 * Refreshes all accounts. This function will be used by automatic
2268 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2269 gboolean force_connection,
2270 gboolean poke_status,
2271 gboolean interactive)
2273 GSList *account_names, *iter;
2275 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2278 iter = account_names;
2280 modest_ui_actions_do_send_receive ((const char*) iter->data,
2282 poke_status, interactive, win);
2283 iter = g_slist_next (iter);
2286 modest_account_mgr_free_account_names (account_names);
2287 account_names = NULL;
2291 * Handler of the click on Send&Receive button in the main toolbar
2294 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2296 /* Check if accounts exist */
2297 gboolean accounts_exist;
2300 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2302 /* If not, allow the user to create an account before trying to send/receive. */
2303 if (!accounts_exist)
2304 modest_ui_actions_on_accounts (NULL, win);
2306 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2307 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2308 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2310 const gchar *active_account;
2311 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2313 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2320 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2323 ModestWindow *window)
2325 GtkTreeRowReference *rowref;
2327 g_return_if_fail (MODEST_IS_WINDOW(window));
2328 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2329 g_return_if_fail (TNY_IS_HEADER (header));
2331 if (modest_header_view_count_selected_headers (header_view) > 1) {
2332 /* Don't allow activation if there are more than one message selected */
2333 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2337 /* we check for low-mem; in that case, show a warning, and don't allow
2338 * activating headers
2340 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2344 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2345 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2346 gtk_tree_row_reference_free (rowref);
2350 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2357 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2359 online = tny_device_is_online (modest_runtime_get_device());
2362 /* already online -- the item is simply not there... */
2363 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2365 GTK_MESSAGE_WARNING,
2367 _("The %s you selected cannot be found"),
2369 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2370 gtk_dialog_run (GTK_DIALOG(dialog));
2372 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2375 _("mcen_bd_dialog_cancel"),
2376 GTK_RESPONSE_REJECT,
2377 _("mcen_bd_dialog_ok"),
2378 GTK_RESPONSE_ACCEPT,
2380 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2381 "Do you want to get online?"), item);
2382 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2383 gtk_label_new (txt), FALSE, FALSE, 0);
2384 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2387 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2388 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2389 /* TODO: Comment about why is this commented out: */
2390 /* modest_platform_connect_and_wait (); */
2393 gtk_widget_destroy (dialog);
2397 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2400 /* g_debug ("%s %s", __FUNCTION__, link); */
2405 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2408 modest_platform_activate_uri (link);
2412 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2415 modest_platform_show_uri_popup (link);
2419 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2422 /* we check for low-mem; in that case, show a warning, and don't allow
2423 * viewing attachments
2425 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2428 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2432 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2433 const gchar *address,
2436 /* g_debug ("%s %s", __FUNCTION__, address); */
2440 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2441 TnyMsg *saved_draft,
2444 ModestMsgEditWindow *edit_window;
2446 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2448 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2450 /* Set draft is there was no error */
2451 if (!modest_mail_operation_get_error (mail_op))
2452 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2454 g_object_unref(edit_window);
2458 enough_space_for_message (ModestMsgEditWindow *edit_window,
2461 guint64 available_disk, expected_size;
2466 available_disk = modest_utils_get_available_space (NULL);
2467 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2468 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2473 /* Double check: disk full condition or message too big */
2474 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2475 expected_size > available_disk) {
2476 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2477 modest_platform_information_banner (NULL, NULL, msg);
2484 * djcb: if we're in low-memory state, we only allow for
2485 * saving messages smaller than
2486 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2487 * should still allow for sending anything critical...
2489 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2490 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2494 * djcb: we also make sure that the attachments are smaller than the max size
2495 * this is for the case where we'd try to forward a message with attachments
2496 * bigger than our max allowed size, or sending an message from drafts which
2497 * somehow got past our checks when attaching.
2499 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2500 modest_platform_run_information_dialog (
2501 GTK_WINDOW(edit_window),
2502 _("mail_ib_error_attachment_size"),
2511 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2513 TnyTransportAccount *transport_account;
2514 ModestMailOperation *mail_operation;
2516 gchar *account_name;
2517 ModestAccountMgr *account_mgr;
2518 gboolean had_error = FALSE;
2520 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2522 data = modest_msg_edit_window_get_msg_data (edit_window);
2525 if (!enough_space_for_message (edit_window, data)) {
2526 modest_msg_edit_window_free_msg_data (edit_window, data);
2530 account_name = g_strdup (data->account_name);
2531 account_mgr = modest_runtime_get_account_mgr();
2533 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2535 account_name = modest_account_mgr_get_default_account (account_mgr);
2536 if (!account_name) {
2537 g_printerr ("modest: no account found\n");
2538 modest_msg_edit_window_free_msg_data (edit_window, data);
2542 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2543 account_name = g_strdup (data->account_name);
2547 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2548 (modest_runtime_get_account_store (),
2550 TNY_ACCOUNT_TYPE_TRANSPORT));
2551 if (!transport_account) {
2552 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2553 g_free (account_name);
2554 modest_msg_edit_window_free_msg_data (edit_window, data);
2558 /* Create the mail operation */
2559 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2561 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2563 modest_mail_operation_save_to_drafts (mail_operation,
2575 data->priority_flags,
2578 on_save_to_drafts_cb,
2579 g_object_ref(edit_window));
2581 /* In hildon2 we always show the information banner on saving to drafts.
2582 * It will be a system information banner in this case.
2584 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2585 modest_platform_information_banner (NULL, NULL, text);
2587 modest_msg_edit_window_set_modified (edit_window, FALSE);
2590 g_free (account_name);
2591 g_object_unref (G_OBJECT (transport_account));
2592 g_object_unref (G_OBJECT (mail_operation));
2594 modest_msg_edit_window_free_msg_data (edit_window, data);
2600 /* For instance, when clicking the Send toolbar button when editing a message: */
2602 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2604 TnyTransportAccount *transport_account = NULL;
2605 gboolean had_error = FALSE, add_to_contacts;
2607 ModestAccountMgr *account_mgr;
2608 gchar *account_name;
2609 ModestMailOperation *mail_operation;
2612 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2614 /* Check whether to automatically add new contacts to addressbook or not */
2615 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
2616 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
2617 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
2620 data = modest_msg_edit_window_get_msg_data (edit_window);
2622 recipients = g_strconcat (data->to?data->to:"",
2623 data->cc?data->cc:"",
2624 data->bcc?data->bcc:"",
2626 if (recipients == NULL || recipients[0] == '\0') {
2627 /* Empty subject -> no send */
2628 g_free (recipients);
2629 modest_msg_edit_window_free_msg_data (edit_window, data);
2632 g_free (recipients);
2635 if (!enough_space_for_message (edit_window, data)) {
2636 modest_msg_edit_window_free_msg_data (edit_window, data);
2640 account_mgr = modest_runtime_get_account_mgr();
2641 account_name = g_strdup (data->account_name);
2643 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2646 account_name = modest_account_mgr_get_default_account (account_mgr);
2648 if (!account_name) {
2649 modest_msg_edit_window_free_msg_data (edit_window, data);
2650 /* Run account setup wizard */
2651 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2656 /* Get the currently-active transport account for this modest account: */
2657 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2659 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2660 (modest_runtime_get_account_store (),
2661 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2664 if (!transport_account) {
2665 modest_msg_edit_window_free_msg_data (edit_window, data);
2666 /* Run account setup wizard */
2667 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2672 /* Create the mail operation */
2673 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2674 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2676 modest_mail_operation_send_new_mail (mail_operation,
2690 data->priority_flags);
2692 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2693 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2695 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2696 const GError *error = modest_mail_operation_get_error (mail_operation);
2697 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2698 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2699 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2700 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2706 g_free (account_name);
2707 g_object_unref (G_OBJECT (transport_account));
2708 g_object_unref (G_OBJECT (mail_operation));
2710 modest_msg_edit_window_free_msg_data (edit_window, data);
2713 modest_msg_edit_window_set_sent (edit_window, TRUE);
2715 /* Save settings and close the window: */
2716 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2723 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2724 ModestMsgEditWindow *window)
2726 ModestMsgEditFormatState *format_state = NULL;
2728 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2729 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2731 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2734 format_state = modest_msg_edit_window_get_format_state (window);
2735 g_return_if_fail (format_state != NULL);
2737 format_state->bold = gtk_toggle_action_get_active (action);
2738 modest_msg_edit_window_set_format_state (window, format_state);
2739 g_free (format_state);
2744 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2745 ModestMsgEditWindow *window)
2747 ModestMsgEditFormatState *format_state = NULL;
2749 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2750 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2752 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2755 format_state = modest_msg_edit_window_get_format_state (window);
2756 g_return_if_fail (format_state != NULL);
2758 format_state->italics = gtk_toggle_action_get_active (action);
2759 modest_msg_edit_window_set_format_state (window, format_state);
2760 g_free (format_state);
2765 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2766 ModestMsgEditWindow *window)
2768 ModestMsgEditFormatState *format_state = NULL;
2770 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2771 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2773 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2776 format_state = modest_msg_edit_window_get_format_state (window);
2777 g_return_if_fail (format_state != NULL);
2779 format_state->bullet = gtk_toggle_action_get_active (action);
2780 modest_msg_edit_window_set_format_state (window, format_state);
2781 g_free (format_state);
2786 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2787 GtkRadioAction *selected,
2788 ModestMsgEditWindow *window)
2790 ModestMsgEditFormatState *format_state = NULL;
2791 GtkJustification value;
2793 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2795 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2798 value = gtk_radio_action_get_current_value (selected);
2800 format_state = modest_msg_edit_window_get_format_state (window);
2801 g_return_if_fail (format_state != NULL);
2803 format_state->justification = value;
2804 modest_msg_edit_window_set_format_state (window, format_state);
2805 g_free (format_state);
2809 modest_ui_actions_on_select_editor_color (GtkAction *action,
2810 ModestMsgEditWindow *window)
2812 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2813 g_return_if_fail (GTK_IS_ACTION (action));
2815 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2818 modest_msg_edit_window_select_color (window);
2822 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2823 ModestMsgEditWindow *window)
2825 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2826 g_return_if_fail (GTK_IS_ACTION (action));
2828 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2834 modest_ui_actions_on_insert_image (GObject *object,
2835 ModestMsgEditWindow *window)
2837 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2840 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2843 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2846 modest_msg_edit_window_insert_image (window);
2850 modest_ui_actions_on_attach_file (GtkAction *action,
2851 ModestMsgEditWindow *window)
2853 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2854 g_return_if_fail (GTK_IS_ACTION (action));
2856 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2859 modest_msg_edit_window_offer_attach_file (window);
2863 modest_ui_actions_on_remove_attachments (GtkAction *action,
2864 ModestMsgEditWindow *window)
2866 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2868 modest_msg_edit_window_remove_attachments (window, NULL);
2872 do_create_folder_cb (ModestMailOperation *mail_op,
2873 TnyFolderStore *parent_folder,
2874 TnyFolder *new_folder,
2877 gchar *suggested_name = (gchar *) user_data;
2878 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
2879 const GError *error;
2881 error = modest_mail_operation_get_error (mail_op);
2883 gboolean disk_full = FALSE;
2884 TnyAccount *account;
2885 /* Show an error. If there was some problem writing to
2886 disk, show it, otherwise show the generic folder
2887 create error. We do it here and not in an error
2888 handler because the call to do_create_folder will
2889 stop the main loop in a gtk_dialog_run and then,
2890 the message won't be shown until that dialog is
2892 account = modest_mail_operation_get_account (mail_op);
2895 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2896 (GtkWidget *) source_win,
2899 _("mail_in_ui_folder_create_error_memory"));
2900 g_object_unref (account);
2903 /* Show an error and try again if there is no
2904 full memory condition */
2905 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
2906 _("mail_in_ui_folder_create_error"));
2907 do_create_folder ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (source_win)),
2908 parent_folder, (const gchar *) suggested_name);
2912 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
2913 * FIXME: any other? */
2914 GtkWidget *folder_view;
2916 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
2917 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
2919 /* Select the newly created folder. It could happen
2920 that the widget is no longer there (i.e. the window
2921 has been destroyed, so we need to check this */
2923 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
2925 g_object_unref (new_folder);
2927 /* Free. Note that the first time it'll be NULL so noop */
2928 g_free (suggested_name);
2929 g_object_unref (source_win);
2934 TnyFolderStore *parent;
2935 } CreateFolderConnect;
2938 do_create_folder_performer (gboolean canceled,
2940 GtkWindow *parent_window,
2941 TnyAccount *account,
2944 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
2945 ModestMailOperation *mail_op;
2947 if (canceled || err) {
2948 /* In disk full conditions we could get this error here */
2949 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2950 (GtkWidget *) parent_window, err,
2951 NULL, _("mail_in_ui_folder_create_error_memory"));
2953 /* This happens if we have selected the outbox folder
2955 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
2956 TNY_IS_MERGE_FOLDER (helper->parent)) {
2957 /* Show an error and retry */
2958 modest_platform_information_banner ((GtkWidget *) parent_window,
2960 _("mail_in_ui_folder_create_error"));
2962 do_create_folder (parent_window, helper->parent, helper->folder_name);
2968 mail_op = modest_mail_operation_new ((GObject *) parent_window);
2969 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2971 modest_mail_operation_create_folder (mail_op,
2973 (const gchar *) helper->folder_name,
2974 do_create_folder_cb,
2975 g_strdup (helper->folder_name));
2976 g_object_unref (mail_op);
2980 g_object_unref (helper->parent);
2981 if (helper->folder_name)
2982 g_free (helper->folder_name);
2983 g_slice_free (CreateFolderConnect, helper);
2988 do_create_folder (GtkWindow *parent_window,
2989 TnyFolderStore *suggested_parent,
2990 const gchar *suggested_name)
2993 gchar *folder_name = NULL;
2994 TnyFolderStore *parent_folder = NULL;
2996 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2998 (gchar *) suggested_name,
3002 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3003 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3004 helper->folder_name = g_strdup (folder_name);
3005 helper->parent = g_object_ref (parent_folder);
3007 modest_platform_connect_if_remote_and_perform (parent_window,
3010 do_create_folder_performer,
3015 g_free (folder_name);
3017 g_object_unref (parent_folder);
3021 modest_ui_actions_create_folder(GtkWindow *parent_window,
3022 GtkWidget *folder_view,
3023 TnyFolderStore *parent_folder)
3025 if (!parent_folder) {
3026 ModestTnyAccountStore *acc_store;
3028 acc_store = modest_runtime_get_account_store ();
3030 parent_folder = (TnyFolderStore *)
3031 modest_tny_account_store_get_local_folders_account (acc_store);
3034 if (parent_folder) {
3035 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3036 g_object_unref (parent_folder);
3041 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3044 g_return_if_fail (MODEST_IS_WINDOW(window));
3046 if (MODEST_IS_FOLDER_WINDOW (window)) {
3047 GtkWidget *folder_view;
3048 GtkWindow *toplevel;
3050 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3051 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
3052 modest_ui_actions_create_folder (toplevel, folder_view, NULL);
3054 g_assert_not_reached ();
3059 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3062 const GError *error = NULL;
3063 gchar *message = NULL;
3065 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3067 /* Get error message */
3068 error = modest_mail_operation_get_error (mail_op);
3070 g_return_if_reached ();
3072 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3073 (GError *) error, account);
3075 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3076 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3077 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3078 message = _CS("ckdg_ib_folder_already_exists");
3079 } else if (error->domain == TNY_ERROR_DOMAIN &&
3080 error->code == TNY_SERVICE_ERROR_STATE) {
3081 /* This means that the folder is already in use (a
3082 message is opened for example */
3083 message = _("emev_ni_internal_error");
3085 message = _CS("ckdg_ib_unable_to_rename");
3088 /* We don't set a parent for the dialog because the dialog
3089 will be destroyed so the banner won't appear */
3090 modest_platform_information_banner (NULL, NULL, message);
3093 g_object_unref (account);
3099 TnyFolderStore *folder;
3104 on_rename_folder_cb (ModestMailOperation *mail_op,
3105 TnyFolder *new_folder,
3108 ModestFolderView *folder_view;
3110 /* If the window was closed when renaming a folder, or if
3111 * it's not a main window this will happen */
3112 if (!MODEST_IS_FOLDER_VIEW (user_data))
3115 folder_view = MODEST_FOLDER_VIEW (user_data);
3116 /* Note that if the rename fails new_folder will be NULL */
3118 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3120 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3124 on_rename_folder_performer (gboolean canceled,
3126 GtkWindow *parent_window,
3127 TnyAccount *account,
3130 ModestMailOperation *mail_op = NULL;
3131 GtkTreeSelection *sel = NULL;
3132 GtkWidget *folder_view = NULL;
3133 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3135 if (canceled || err) {
3136 /* In disk full conditions we could get this error here */
3137 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3138 (GtkWidget *) parent_window, err,
3143 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3144 modest_ui_actions_rename_folder_error_handler,
3145 parent_window, NULL);
3147 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3149 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3150 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3151 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3154 /* Clear the folders view */
3155 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3156 gtk_tree_selection_unselect_all (sel);
3158 /* Actually rename the folder */
3159 modest_mail_operation_rename_folder (mail_op,
3160 TNY_FOLDER (data->folder),
3161 (const gchar *) (data->new_name),
3162 on_rename_folder_cb,
3164 g_object_unref (mail_op);
3167 g_object_unref (data->folder);
3168 g_free (data->new_name);
3173 modest_ui_actions_on_rename_folder (GtkAction *action,
3174 ModestWindow *window)
3176 modest_ui_actions_on_edit_mode_rename_folder (window);
3180 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3182 TnyFolderStore *folder;
3183 GtkWidget *folder_view;
3184 gboolean do_rename = TRUE;
3186 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3188 if (MODEST_IS_FOLDER_WINDOW (window)) {
3189 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3194 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3199 if (TNY_IS_FOLDER (folder)) {
3200 gchar *folder_name = NULL;
3202 const gchar *current_name;
3203 TnyFolderStore *parent;
3205 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3206 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3207 response = modest_platform_run_rename_folder_dialog (MODEST_WINDOW (window),
3208 parent, current_name,
3210 g_object_unref (parent);
3212 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3215 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3216 rename_folder_data->folder = g_object_ref (folder);
3217 rename_folder_data->new_name = folder_name;
3218 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3219 folder, on_rename_folder_performer, rename_folder_data);
3222 g_object_unref (folder);
3227 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3230 GObject *win = modest_mail_operation_get_source (mail_op);
3232 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3233 _("mail_in_ui_folder_delete_error"),
3235 g_object_unref (win);
3239 TnyFolderStore *folder;
3240 gboolean move_to_trash;
3244 on_delete_folder_cb (gboolean canceled,
3246 GtkWindow *parent_window,
3247 TnyAccount *account,
3250 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3251 GtkWidget *folder_view;
3252 ModestMailOperation *mail_op;
3253 GtkTreeSelection *sel;
3255 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3256 /* Note that the connection process can fail due to
3257 memory low conditions as it can not successfully
3258 store the summary */
3259 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3260 (GtkWidget*) parent_window, err,
3262 g_debug ("Error connecting when trying to delete a folder");
3263 g_object_unref (G_OBJECT (info->folder));
3268 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3269 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3271 g_object_unref (G_OBJECT (info->folder));
3276 /* Unselect the folder before deleting it to free the headers */
3277 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3278 gtk_tree_selection_unselect_all (sel);
3280 /* Create the mail operation */
3282 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3283 modest_ui_actions_delete_folder_error_handler,
3286 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3288 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3290 g_object_unref (mail_op);
3291 g_object_unref (info->folder);
3296 delete_folder (ModestWindow *window, gboolean move_to_trash)
3298 TnyFolderStore *folder;
3299 GtkWidget *folder_view;
3303 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3305 if (MODEST_IS_FOLDER_WINDOW (window)) {
3306 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3313 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3318 /* Show an error if it's an account */
3319 if (!TNY_IS_FOLDER (folder)) {
3320 modest_platform_run_information_dialog (GTK_WINDOW (window),
3321 _("mail_in_ui_folder_delete_error"),
3323 g_object_unref (G_OBJECT (folder));
3328 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3329 tny_folder_get_name (TNY_FOLDER (folder)));
3330 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3331 (const gchar *) message);
3334 if (response == GTK_RESPONSE_OK) {
3335 TnyAccount *account = NULL;
3336 DeleteFolderInfo *info = NULL;
3337 info = g_new0(DeleteFolderInfo, 1);
3338 info->folder = g_object_ref (folder);
3339 info->move_to_trash = move_to_trash;
3341 account = tny_folder_get_account (TNY_FOLDER (folder));
3342 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3344 TNY_FOLDER_STORE (account),
3345 on_delete_folder_cb, info);
3346 g_object_unref (account);
3347 g_object_unref (folder);
3355 modest_ui_actions_on_delete_folder (GtkAction *action,
3356 ModestWindow *window)
3358 modest_ui_actions_on_edit_mode_delete_folder (window);
3362 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3364 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3366 return delete_folder (window, FALSE);
3370 typedef struct _PasswordDialogFields {
3371 GtkWidget *username;
3372 GtkWidget *password;
3374 } PasswordDialogFields;
3377 password_dialog_check_field (GtkEditable *editable,
3378 PasswordDialogFields *fields)
3381 gboolean any_value_empty = FALSE;
3383 value = modest_entry_get_text (fields->username);
3384 if ((value == NULL) || value[0] == '\0') {
3385 any_value_empty = TRUE;
3387 value = modest_entry_get_text (fields->password);
3388 if ((value == NULL) || value[0] == '\0') {
3389 any_value_empty = TRUE;
3391 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3395 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3396 const gchar* server_account_name,
3401 ModestMainWindow *main_window)
3403 g_return_if_fail(server_account_name);
3404 gboolean completed = FALSE;
3405 PasswordDialogFields *fields = NULL;
3407 /* Initalize output parameters: */
3414 #ifndef MODEST_TOOLKIT_GTK
3415 /* Maemo uses a different (awkward) button order,
3416 * It should probably just use gtk_alternative_dialog_button_order ().
3418 #ifdef MODEST_TOOLKIT_HILDON2
3420 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3424 GTK_RESPONSE_ACCEPT,
3426 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3427 HILDON_MARGIN_DOUBLE);
3430 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3433 _("mcen_bd_dialog_ok"),
3434 GTK_RESPONSE_ACCEPT,
3435 _("mcen_bd_dialog_cancel"),
3436 GTK_RESPONSE_REJECT,
3438 #endif /* MODEST_TOOLKIT_HILDON2 */
3441 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3445 GTK_RESPONSE_REJECT,
3447 GTK_RESPONSE_ACCEPT,
3449 #endif /* MODEST_TOOLKIT_GTK */
3451 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3453 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3454 modest_runtime_get_account_mgr(), server_account_name);
3455 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3456 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3459 gtk_widget_destroy (dialog);
3463 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3464 GtkWidget *label = gtk_label_new (txt);
3465 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3467 g_free (server_name);
3468 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3473 gchar *initial_username = modest_account_mgr_get_server_account_username (
3474 modest_runtime_get_account_mgr(), server_account_name);
3476 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3477 if (initial_username)
3478 modest_entry_set_text (entry_username, initial_username);
3480 /* Dim this if a connection has ever succeeded with this username,
3481 * as per the UI spec: */
3482 /* const gboolean username_known = */
3483 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3484 /* modest_runtime_get_account_mgr(), server_account_name); */
3485 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3487 /* We drop the username sensitive code and disallow changing it here
3488 * as tinymail does not support really changing the username in the callback
3490 gtk_widget_set_sensitive (entry_username, FALSE);
3492 /* Auto-capitalization is the default, so let's turn it off: */
3493 #ifdef MAEMO_CHANGES
3494 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3497 /* Create a size group to be used by all captions.
3498 * Note that HildonCaption does not create a default size group if we do not specify one.
3499 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3500 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3502 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3503 _("mail_fi_username"), FALSE,
3505 gtk_widget_show (entry_username);
3506 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3507 FALSE, FALSE, MODEST_MARGIN_HALF);
3508 gtk_widget_show (caption);
3511 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3512 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3513 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3515 /* Auto-capitalization is the default, so let's turn it off: */
3516 #ifdef MAEMO_CHANGES
3517 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3518 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3521 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3522 _("mail_fi_password"), FALSE,
3524 gtk_widget_show (entry_password);
3525 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3526 FALSE, FALSE, MODEST_MARGIN_HALF);
3527 gtk_widget_show (caption);
3528 g_object_unref (sizegroup);
3530 if (initial_username != NULL)
3531 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3533 /* This is not in the Maemo UI spec:
3534 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3535 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3539 fields = g_slice_new0 (PasswordDialogFields);
3540 fields->username = entry_username;
3541 fields->password = entry_password;
3542 fields->dialog = dialog;
3544 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3545 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3546 password_dialog_check_field (NULL, fields);
3548 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3550 while (!completed) {
3552 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3554 *username = g_strdup (modest_entry_get_text (entry_username));
3556 /* Note that an empty field becomes the "" string */
3557 if (*username && strlen (*username) > 0) {
3558 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3559 server_account_name,
3563 const gboolean username_was_changed =
3564 (strcmp (*username, initial_username) != 0);
3565 if (username_was_changed) {
3566 g_warning ("%s: tinymail does not yet support changing the "
3567 "username in the get_password() callback.\n", __FUNCTION__);
3573 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3574 _("mcen_ib_username_pw_incorrect"));
3580 *password = g_strdup (modest_entry_get_text (entry_password));
3582 /* We do not save the password in the configuration,
3583 * because this function is only called for passwords that should
3584 * not be remembered:
3585 modest_server_account_set_password (
3586 modest_runtime_get_account_mgr(), server_account_name,
3603 /* This is not in the Maemo UI spec:
3604 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3610 g_free (initial_username);
3611 gtk_widget_destroy (dialog);
3612 g_slice_free (PasswordDialogFields, fields);
3614 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3618 modest_ui_actions_on_cut (GtkAction *action,
3619 ModestWindow *window)
3621 GtkWidget *focused_widget;
3622 GtkClipboard *clipboard;
3624 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3625 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3626 if (GTK_IS_EDITABLE (focused_widget)) {
3627 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3628 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3629 gtk_clipboard_store (clipboard);
3630 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3631 GtkTextBuffer *buffer;
3633 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3634 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3635 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3636 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3637 gtk_clipboard_store (clipboard);
3639 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3640 TnyList *header_list = modest_header_view_get_selected_headers (
3641 MODEST_HEADER_VIEW (focused_widget));
3642 gboolean continue_download = FALSE;
3643 gint num_of_unc_msgs;
3645 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3647 if (num_of_unc_msgs) {
3648 TnyAccount *account = get_account_from_header_list (header_list);
3650 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3651 g_object_unref (account);
3655 if (num_of_unc_msgs == 0 || continue_download) {
3656 /* modest_platform_information_banner (
3657 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3658 modest_header_view_cut_selection (
3659 MODEST_HEADER_VIEW (focused_widget));
3662 g_object_unref (header_list);
3663 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3664 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3669 modest_ui_actions_on_copy (GtkAction *action,
3670 ModestWindow *window)
3672 GtkClipboard *clipboard;
3673 GtkWidget *focused_widget;
3674 gboolean copied = TRUE;
3676 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3677 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3679 if (GTK_IS_LABEL (focused_widget)) {
3681 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3682 gtk_clipboard_set_text (clipboard, selection, -1);
3684 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3685 gtk_clipboard_store (clipboard);
3686 } else if (GTK_IS_EDITABLE (focused_widget)) {
3687 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3688 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3689 gtk_clipboard_store (clipboard);
3690 } else if (GTK_IS_HTML (focused_widget)) {
3693 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3694 if ((sel == NULL) || (sel[0] == '\0')) {
3697 gtk_html_copy (GTK_HTML (focused_widget));
3698 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3699 gtk_clipboard_store (clipboard);
3701 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3702 GtkTextBuffer *buffer;
3703 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3704 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3705 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3706 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3707 gtk_clipboard_store (clipboard);
3709 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3710 TnyList *header_list = modest_header_view_get_selected_headers (
3711 MODEST_HEADER_VIEW (focused_widget));
3712 gboolean continue_download = FALSE;
3713 gint num_of_unc_msgs;
3715 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3717 if (num_of_unc_msgs) {
3718 TnyAccount *account = get_account_from_header_list (header_list);
3720 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3721 g_object_unref (account);
3725 if (num_of_unc_msgs == 0 || continue_download) {
3726 modest_platform_information_banner (
3727 NULL, NULL, _CS("mcen_ib_getting_items"));
3728 modest_header_view_copy_selection (
3729 MODEST_HEADER_VIEW (focused_widget));
3733 g_object_unref (header_list);
3735 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3736 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3739 /* Show information banner if there was a copy to clipboard */
3741 modest_platform_information_banner (
3742 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3746 modest_ui_actions_on_undo (GtkAction *action,
3747 ModestWindow *window)
3749 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3750 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3752 g_return_if_reached ();
3757 modest_ui_actions_on_redo (GtkAction *action,
3758 ModestWindow *window)
3760 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3761 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3764 g_return_if_reached ();
3770 destroy_information_note (ModestMailOperation *mail_op,
3773 /* destroy information note */
3774 gtk_widget_destroy (GTK_WIDGET(user_data));
3778 destroy_folder_information_note (ModestMailOperation *mail_op,
3779 TnyFolder *new_folder,
3782 /* destroy information note */
3783 gtk_widget_destroy (GTK_WIDGET(user_data));
3788 paste_as_attachment_free (gpointer data)
3790 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3792 if (helper->banner) {
3793 gtk_widget_destroy (helper->banner);
3794 g_object_unref (helper->banner);
3800 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3805 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3806 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3811 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3816 modest_ui_actions_on_paste (GtkAction *action,
3817 ModestWindow *window)
3819 GtkWidget *focused_widget = NULL;
3820 GtkWidget *inf_note = NULL;
3821 ModestMailOperation *mail_op = NULL;
3823 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3824 if (GTK_IS_EDITABLE (focused_widget)) {
3825 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3826 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3827 ModestEmailClipboard *e_clipboard = NULL;
3828 e_clipboard = modest_runtime_get_email_clipboard ();
3829 if (modest_email_clipboard_cleared (e_clipboard)) {
3830 GtkTextBuffer *buffer;
3831 GtkClipboard *clipboard;
3833 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3834 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3835 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3836 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3837 ModestMailOperation *mail_op;
3838 TnyFolder *src_folder = NULL;
3839 TnyList *data = NULL;
3841 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3842 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3843 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3844 _CS("ckct_nw_pasting"));
3845 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3846 mail_op = modest_mail_operation_new (G_OBJECT (window));
3847 if (helper->banner != NULL) {
3848 g_object_ref (G_OBJECT (helper->banner));
3849 gtk_widget_show (GTK_WIDGET (helper->banner));
3853 modest_mail_operation_get_msgs_full (mail_op,
3855 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3857 paste_as_attachment_free);
3861 g_object_unref (data);
3863 g_object_unref (src_folder);
3866 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3867 ModestEmailClipboard *clipboard = NULL;
3868 TnyFolder *src_folder = NULL;
3869 TnyFolderStore *folder_store = NULL;
3870 TnyList *data = NULL;
3871 gboolean delete = FALSE;
3873 /* Check clipboard source */
3874 clipboard = modest_runtime_get_email_clipboard ();
3875 if (modest_email_clipboard_cleared (clipboard))
3878 /* Get elements to paste */
3879 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3881 /* Create a new mail operation */
3882 mail_op = modest_mail_operation_new (G_OBJECT(window));
3884 /* Get destination folder */
3885 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3887 /* transfer messages */
3891 /* Ask for user confirmation */
3893 modest_ui_actions_msgs_move_to_confirmation (window,
3894 TNY_FOLDER (folder_store),
3898 if (response == GTK_RESPONSE_OK) {
3899 /* Launch notification */
3900 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3901 _CS("ckct_nw_pasting"));
3902 if (inf_note != NULL) {
3903 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3904 gtk_widget_show (GTK_WIDGET(inf_note));
3907 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3908 modest_mail_operation_xfer_msgs (mail_op,
3910 TNY_FOLDER (folder_store),
3912 destroy_information_note,
3915 g_object_unref (mail_op);
3918 } else if (src_folder != NULL) {
3919 /* Launch notification */
3920 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3921 _CS("ckct_nw_pasting"));
3922 if (inf_note != NULL) {
3923 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3924 gtk_widget_show (GTK_WIDGET(inf_note));
3927 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3928 modest_mail_operation_xfer_folder (mail_op,
3932 destroy_folder_information_note,
3938 g_object_unref (data);
3939 if (src_folder != NULL)
3940 g_object_unref (src_folder);
3941 if (folder_store != NULL)
3942 g_object_unref (folder_store);
3948 modest_ui_actions_on_select_all (GtkAction *action,
3949 ModestWindow *window)
3951 GtkWidget *focused_widget;
3953 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3954 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3955 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3956 } else if (GTK_IS_LABEL (focused_widget)) {
3957 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3958 } else if (GTK_IS_EDITABLE (focused_widget)) {
3959 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3960 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3961 GtkTextBuffer *buffer;
3962 GtkTextIter start, end;
3964 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3965 gtk_text_buffer_get_start_iter (buffer, &start);
3966 gtk_text_buffer_get_end_iter (buffer, &end);
3967 gtk_text_buffer_select_range (buffer, &start, &end);
3968 } else if (GTK_IS_HTML (focused_widget)) {
3969 gtk_html_select_all (GTK_HTML (focused_widget));
3975 modest_ui_actions_on_mark_as_read (GtkAction *action,
3976 ModestWindow *window)
3978 g_return_if_fail (MODEST_IS_WINDOW(window));
3980 /* Mark each header as read */
3981 do_headers_action (window, headers_action_mark_as_read, NULL);
3985 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3986 ModestWindow *window)
3988 g_return_if_fail (MODEST_IS_WINDOW(window));
3990 /* Mark each header as read */
3991 do_headers_action (window, headers_action_mark_as_unread, NULL);
3995 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3996 GtkRadioAction *selected,
3997 ModestWindow *window)
4001 value = gtk_radio_action_get_current_value (selected);
4002 if (MODEST_IS_WINDOW (window)) {
4003 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4008 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4009 GtkRadioAction *selected,
4010 ModestWindow *window)
4012 TnyHeaderFlags flags;
4013 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4015 flags = gtk_radio_action_get_current_value (selected);
4016 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4020 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4021 GtkRadioAction *selected,
4022 ModestWindow *window)
4026 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4028 file_format = gtk_radio_action_get_current_value (selected);
4029 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4034 modest_ui_actions_on_zoom_plus (GtkAction *action,
4035 ModestWindow *window)
4037 g_return_if_fail (MODEST_IS_WINDOW (window));
4039 modest_window_zoom_plus (MODEST_WINDOW (window));
4043 modest_ui_actions_on_zoom_minus (GtkAction *action,
4044 ModestWindow *window)
4046 g_return_if_fail (MODEST_IS_WINDOW (window));
4048 modest_window_zoom_minus (MODEST_WINDOW (window));
4052 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4053 ModestWindow *window)
4055 ModestWindowMgr *mgr;
4056 gboolean fullscreen, active;
4057 g_return_if_fail (MODEST_IS_WINDOW (window));
4059 mgr = modest_runtime_get_window_mgr ();
4061 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4062 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4064 if (active != fullscreen) {
4065 modest_window_mgr_set_fullscreen_mode (mgr, active);
4066 #ifndef MODEST_TOOLKIT_HILDON2
4067 gtk_window_present (GTK_WINDOW (window));
4073 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4074 ModestWindow *window)
4076 ModestWindowMgr *mgr;
4077 gboolean fullscreen;
4079 g_return_if_fail (MODEST_IS_WINDOW (window));
4081 mgr = modest_runtime_get_window_mgr ();
4082 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4083 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4088 * Used by modest_ui_actions_on_details to call do_headers_action
4091 headers_action_show_details (TnyHeader *header,
4092 ModestWindow *window,
4096 gboolean async_retrieval;
4099 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4100 async_retrieval = TRUE;
4101 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4103 async_retrieval = FALSE;
4105 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4107 g_object_unref (msg);
4111 * Show the header details in a ModestDetailsDialog widget
4114 modest_ui_actions_on_details (GtkAction *action,
4117 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4121 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4125 header = tny_msg_get_header (msg);
4127 headers_action_show_details (header, win, NULL);
4128 g_object_unref (header);
4130 g_object_unref (msg);
4131 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4133 GtkWidget *header_view;
4135 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4136 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4138 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4140 modest_platform_run_folder_details_dialog (toplevel, folder);
4141 g_object_unref (folder);
4147 modest_ui_actions_on_limit_error (GtkAction *action,
4150 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4152 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4157 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4158 ModestMsgEditWindow *window)
4160 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4162 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4166 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4167 ModestMsgEditWindow *window)
4169 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4171 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4176 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4177 ModestWindow *window)
4179 gboolean active, fullscreen = FALSE;
4180 ModestWindowMgr *mgr;
4182 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4184 /* Check if we want to toggle the toolbar view in fullscreen
4186 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4187 "ViewShowToolbarFullScreen")) {
4191 /* Toggle toolbar */
4192 mgr = modest_runtime_get_window_mgr ();
4193 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4197 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4198 ModestMsgEditWindow *window)
4200 modest_msg_edit_window_select_font (window);
4205 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4206 const gchar *display_name,
4209 /* don't update the display name if it was already set;
4210 * updating the display name apparently is expensive */
4211 const gchar* old_name = gtk_window_get_title (window);
4213 if (display_name == NULL)
4216 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4217 return; /* don't do anything */
4219 /* This is usually used to change the title of the main window, which
4220 * is the one that holds the folder view. Note that this change can
4221 * happen even when the widget doesn't have the focus. */
4222 gtk_window_set_title (window, display_name);
4227 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4229 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4230 modest_msg_edit_window_select_contacts (window);
4234 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4236 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4237 modest_msg_edit_window_check_names (window, FALSE);
4242 on_move_to_dialog_response (GtkDialog *dialog,
4246 GtkWidget *parent_win;
4247 MoveToInfo *helper = NULL;
4248 ModestFolderView *folder_view;
4249 gboolean unset_edit_mode = FALSE;
4251 helper = (MoveToInfo *) user_data;
4253 parent_win = (GtkWidget *) helper->win;
4254 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4255 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4257 TnyFolderStore *dst_folder;
4258 TnyFolderStore *selected;
4260 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4261 selected = modest_folder_view_get_selected (folder_view);
4262 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4263 g_object_unref (selected);
4265 case GTK_RESPONSE_NONE:
4266 case GTK_RESPONSE_CANCEL:
4267 case GTK_RESPONSE_DELETE_EVENT:
4269 case GTK_RESPONSE_OK:
4270 dst_folder = modest_folder_view_get_selected (folder_view);
4272 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4273 /* Clean list to move used for filtering */
4274 modest_folder_view_set_list_to_move (folder_view, NULL);
4276 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4279 GTK_WINDOW (parent_win));
4281 /* if the user selected a root folder
4282 (account) then do not perform any action */
4283 if (TNY_IS_ACCOUNT (dst_folder)) {
4284 g_signal_stop_emission_by_name (dialog, "response");
4288 /* Clean list to move used for filtering */
4289 modest_folder_view_set_list_to_move (folder_view, NULL);
4291 /* Moving from headers window in edit mode */
4292 modest_ui_actions_on_window_move_to (NULL, helper->list,
4294 MODEST_WINDOW (parent_win));
4298 g_object_unref (dst_folder);
4300 unset_edit_mode = TRUE;
4303 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4306 /* Free the helper and exit */
4308 g_object_unref (helper->list);
4309 if (unset_edit_mode) {
4310 #ifdef MODEST_TOOLKIT_HILDON2
4311 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4314 g_slice_free (MoveToInfo, helper);
4315 gtk_widget_destroy (GTK_WIDGET (dialog));
4319 create_move_to_dialog (GtkWindow *win,
4320 GtkWidget *folder_view,
4321 TnyList *list_to_move)
4323 GtkWidget *dialog, *tree_view = NULL;
4325 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4328 /* It could happen that we're trying to move a message from a
4329 window (msg window for example) after the main window was
4330 closed, so we can not just get the model of the folder
4332 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4333 const gchar *visible_id = NULL;
4335 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4336 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4337 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4338 MODEST_FOLDER_VIEW(tree_view));
4341 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4343 /* Show the same account than the one that is shown in the main window */
4344 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4347 const gchar *active_account_name = NULL;
4348 ModestAccountMgr *mgr = NULL;
4349 ModestAccountSettings *settings = NULL;
4350 ModestServerAccountSettings *store_settings = NULL;
4352 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4353 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4354 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4355 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4357 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4358 mgr = modest_runtime_get_account_mgr ();
4359 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4362 const gchar *store_account_name;
4363 store_settings = modest_account_settings_get_store_settings (settings);
4364 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4366 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4367 store_account_name);
4368 g_object_unref (store_settings);
4369 g_object_unref (settings);
4373 /* we keep a pointer to the embedded folder view, so we can
4374 * retrieve it with get_folder_view_from_move_to_dialog (see
4375 * above) later (needed for focus handling)
4377 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4379 /* Hide special folders */
4381 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4383 gtk_widget_show (GTK_WIDGET (tree_view));
4389 * Shows a confirmation dialog to the user when we're moving messages
4390 * from a remote server to the local storage. Returns the dialog
4391 * response. If it's other kind of movement then it always returns
4394 * This one is used by the next functions:
4395 * modest_ui_actions_on_paste - commented out
4396 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4399 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4400 TnyFolder *dest_folder,
4404 gint response = GTK_RESPONSE_OK;
4405 TnyAccount *account = NULL;
4406 TnyFolder *src_folder = NULL;
4407 TnyIterator *iter = NULL;
4408 TnyHeader *header = NULL;
4410 /* return with OK if the destination is a remote folder */
4411 if (modest_tny_folder_is_remote_folder (dest_folder))
4412 return GTK_RESPONSE_OK;
4414 /* Get source folder */
4415 iter = tny_list_create_iterator (headers);
4416 header = TNY_HEADER (tny_iterator_get_current (iter));
4418 src_folder = tny_header_get_folder (header);
4419 g_object_unref (header);
4421 g_object_unref (iter);
4423 /* if no src_folder, message may be an attahcment */
4424 if (src_folder == NULL)
4425 return GTK_RESPONSE_CANCEL;
4427 /* If the source is a local or MMC folder */
4428 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4429 g_object_unref (src_folder);
4430 return GTK_RESPONSE_OK;
4433 /* Get the account */
4434 account = tny_folder_get_account (src_folder);
4436 /* now if offline we ask the user */
4437 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4438 response = GTK_RESPONSE_OK;
4440 response = GTK_RESPONSE_CANCEL;
4443 g_object_unref (src_folder);
4444 g_object_unref (account);
4450 move_to_helper_destroyer (gpointer user_data)
4452 MoveToHelper *helper = (MoveToHelper *) user_data;
4454 /* Close the "Pasting" information banner */
4455 if (helper->banner) {
4456 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4457 g_object_unref (helper->banner);
4459 if (gtk_tree_row_reference_valid (helper->reference)) {
4460 gtk_tree_row_reference_free (helper->reference);
4461 helper->reference = NULL;
4467 move_to_cb (ModestMailOperation *mail_op,
4470 MoveToHelper *helper = (MoveToHelper *) user_data;
4471 GObject *object = modest_mail_operation_get_source (mail_op);
4473 /* Note that the operation could have failed, in that case do
4475 if (modest_mail_operation_get_status (mail_op) !=
4476 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4479 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4480 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4482 if (!modest_msg_view_window_select_next_message (self) &&
4483 !modest_msg_view_window_select_previous_message (self)) {
4484 /* No more messages to view, so close this window */
4485 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4488 g_object_unref (object);
4491 /* Destroy the helper */
4492 move_to_helper_destroyer (helper);
4496 folder_move_to_cb (ModestMailOperation *mail_op,
4497 TnyFolder *new_folder,
4502 object = modest_mail_operation_get_source (mail_op);
4504 move_to_cb (mail_op, user_data);
4509 msgs_move_to_cb (ModestMailOperation *mail_op,
4512 move_to_cb (mail_op, user_data);
4516 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4519 GObject *win = NULL;
4520 const GError *error;
4521 TnyAccount *account = NULL;
4523 win = modest_mail_operation_get_source (mail_op);
4524 error = modest_mail_operation_get_error (mail_op);
4526 if (TNY_IS_FOLDER (user_data))
4527 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4528 else if (TNY_IS_ACCOUNT (user_data))
4529 account = g_object_ref (user_data);
4531 /* If it's not a disk full error then show a generic error */
4532 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4533 (GtkWidget *) win, (GError *) error,
4535 modest_platform_run_information_dialog ((GtkWindow *) win,
4536 _("mail_in_ui_folder_move_target_error"),
4539 g_object_unref (account);
4541 g_object_unref (win);
4546 * Checks if we need a connection to do the transfer and if the user
4547 * wants to connect to complete it
4550 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
4551 TnyFolderStore *src_folder,
4553 TnyFolder *dst_folder,
4554 gboolean delete_originals,
4555 gboolean *need_connection,
4558 TnyAccount *src_account;
4559 gint uncached_msgs = 0;
4561 /* We don't need any further check if
4563 * 1- the source folder is local OR
4564 * 2- the device is already online
4566 if (!modest_tny_folder_store_is_remote (src_folder) ||
4567 tny_device_is_online (modest_runtime_get_device())) {
4568 *need_connection = FALSE;
4573 /* We must ask for a connection when
4575 * - the message(s) is not already cached OR
4576 * - the message(s) is cached but the leave_on_server setting
4577 * is FALSE (because we need to sync the source folder to
4578 * delete the message from the server (for IMAP we could do it
4579 * offline, it'll take place the next time we get a
4582 uncached_msgs = header_list_count_uncached_msgs (headers);
4583 src_account = get_account_from_folder_store (src_folder);
4584 if (uncached_msgs > 0) {
4588 *need_connection = TRUE;
4589 num_headers = tny_list_get_length (headers);
4590 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4592 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
4593 GTK_RESPONSE_CANCEL) {
4599 /* The transfer is possible and the user wants to */
4602 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4603 const gchar *account_name;
4604 gboolean leave_on_server;
4606 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4607 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4610 if (leave_on_server == TRUE) {
4611 *need_connection = FALSE;
4613 *need_connection = TRUE;
4616 *need_connection = FALSE;
4621 g_object_unref (src_account);
4625 xfer_messages_error_handler (ModestMailOperation *mail_op,
4629 const GError *error;
4630 TnyAccount *account;
4632 win = modest_mail_operation_get_source (mail_op);
4633 error = modest_mail_operation_get_error (mail_op);
4635 /* We cannot get the account from the mail op as that is the
4636 source account and for checking memory full conditions we
4637 need the destination one */
4638 account = TNY_ACCOUNT (user_data);
4641 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4642 (GtkWidget *) win, (GError*) error,
4643 account, _KR("cerm_memory_card_full"))) {
4644 modest_platform_run_information_dialog ((GtkWindow *) win,
4645 _("mail_in_ui_folder_move_target_error"),
4649 g_object_unref (win);
4653 TnyFolderStore *dst_folder;
4658 * Utility function that transfer messages from both the main window
4659 * and the msg view window when using the "Move to" dialog
4662 xfer_messages_performer (gboolean canceled,
4664 GtkWindow *parent_window,
4665 TnyAccount *account,
4668 ModestWindow *win = MODEST_WINDOW (parent_window);
4669 TnyAccount *dst_account = NULL;
4670 gboolean dst_forbids_message_add = FALSE;
4671 XferMsgsHelper *helper;
4672 MoveToHelper *movehelper;
4673 ModestMailOperation *mail_op;
4675 helper = (XferMsgsHelper *) user_data;
4677 if (canceled || err) {
4678 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4679 (GtkWidget *) parent_window, err,
4681 /* Show the proper error message */
4682 modest_ui_actions_on_account_connection_error (parent_window, account);
4687 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4689 /* tinymail will return NULL for local folders it seems */
4690 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4691 modest_tny_account_get_protocol_type (dst_account),
4692 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4694 if (dst_forbids_message_add) {
4695 modest_platform_information_banner (GTK_WIDGET (win),
4697 ngettext("mail_in_ui_folder_move_target_error",
4698 "mail_in_ui_folder_move_targets_error",
4699 tny_list_get_length (helper->headers)));
4703 movehelper = g_new0 (MoveToHelper, 1);
4706 /* Perform the mail operation */
4707 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4708 xfer_messages_error_handler,
4709 g_object_ref (dst_account),
4711 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4714 modest_mail_operation_xfer_msgs (mail_op,
4716 TNY_FOLDER (helper->dst_folder),
4721 g_object_unref (G_OBJECT (mail_op));
4724 g_object_unref (dst_account);
4725 g_object_unref (helper->dst_folder);
4726 g_object_unref (helper->headers);
4727 g_slice_free (XferMsgsHelper, helper);
4731 TnyFolder *src_folder;
4732 TnyFolderStore *dst_folder;
4733 gboolean delete_original;
4734 GtkWidget *folder_view;
4738 on_move_folder_cb (gboolean canceled,
4740 GtkWindow *parent_window,
4741 TnyAccount *account,
4744 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4745 GtkTreeSelection *sel;
4746 ModestMailOperation *mail_op = NULL;
4748 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4749 /* Note that the connection process can fail due to
4750 memory low conditions as it can not successfully
4751 store the summary */
4752 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4753 (GtkWidget*) parent_window, err,
4755 g_debug ("Error connecting when trying to move a folder");
4757 g_object_unref (G_OBJECT (info->src_folder));
4758 g_object_unref (G_OBJECT (info->dst_folder));
4763 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4764 #ifndef MODEST_TOOLKIT_HILDON2
4765 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4766 _CS("ckct_nw_pasting"));
4767 if (helper->banner != NULL) {
4768 g_object_ref (helper->banner);
4769 gtk_widget_show (GTK_WIDGET(helper->banner));
4772 /* Clean folder on header view before moving it */
4773 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4774 gtk_tree_selection_unselect_all (sel);
4776 /* Let gtk events run. We need that the folder
4777 view frees its reference to the source
4778 folder *before* issuing the mail operation
4779 so we need the signal handler of selection
4780 changed to happen before the mail
4782 while (gtk_events_pending ())
4783 gtk_main_iteration (); */
4786 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4787 modest_ui_actions_move_folder_error_handler,
4788 g_object_ref (info->dst_folder), g_object_unref);
4789 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4792 modest_mail_operation_xfer_folder (mail_op,
4793 TNY_FOLDER (info->src_folder),
4795 info->delete_original,
4798 g_object_unref (G_OBJECT (info->src_folder));
4800 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4803 /* Unref mail operation */
4804 g_object_unref (G_OBJECT (mail_op));
4805 g_object_unref (G_OBJECT (info->dst_folder));
4810 get_account_from_folder_store (TnyFolderStore *folder_store)
4812 if (TNY_IS_ACCOUNT (folder_store))
4813 return g_object_ref (folder_store);
4815 return tny_folder_get_account (TNY_FOLDER (folder_store));
4819 * UI handler for the "Move to" action when invoked from the
4820 * ModestFolderWindow
4823 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4824 TnyFolderStore *dst_folder,
4828 TnyFolderStore *src_folder = NULL;
4829 TnyIterator *iterator;
4831 if (tny_list_get_length (selection) != 1)
4834 iterator = tny_list_create_iterator (selection);
4835 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
4836 g_object_unref (iterator);
4839 gboolean do_xfer = TRUE;
4841 /* Allow only to transfer folders to the local root folder */
4842 if (TNY_IS_ACCOUNT (dst_folder) &&
4843 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
4844 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
4847 modest_platform_run_information_dialog (win,
4848 _("mail_in_ui_folder_move_target_error"),
4850 } else if (!TNY_IS_FOLDER (src_folder)) {
4851 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4856 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4857 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4859 info->src_folder = g_object_ref (src_folder);
4860 info->dst_folder = g_object_ref (dst_folder);
4861 info->delete_original = TRUE;
4862 info->folder_view = folder_view;
4864 connect_info->callback = on_move_folder_cb;
4865 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
4866 connect_info->data = info;
4868 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4869 TNY_FOLDER_STORE (src_folder),
4874 g_object_unref (src_folder);
4879 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
4880 TnyFolder *src_folder,
4882 TnyFolder *dst_folder)
4884 gboolean need_connection = TRUE;
4885 gboolean do_xfer = TRUE;
4886 XferMsgsHelper *helper;
4888 g_return_if_fail (TNY_IS_FOLDER (src_folder));
4889 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4890 g_return_if_fail (TNY_IS_LIST (headers));
4892 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
4893 headers, TNY_FOLDER (dst_folder),
4894 TRUE, &need_connection,
4897 /* If we don't want to transfer just return */
4901 /* Create the helper */
4902 helper = g_slice_new (XferMsgsHelper);
4903 helper->dst_folder = g_object_ref (dst_folder);
4904 helper->headers = g_object_ref (headers);
4906 if (need_connection) {
4907 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4908 connect_info->callback = xfer_messages_performer;
4909 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4910 connect_info->data = helper;
4912 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4913 TNY_FOLDER_STORE (src_folder),
4916 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
4917 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
4918 src_account, helper);
4919 g_object_unref (src_account);
4924 * UI handler for the "Move to" action when invoked from the
4925 * ModestMsgViewWindow
4928 modest_ui_actions_on_window_move_to (GtkAction *action,
4930 TnyFolderStore *dst_folder,
4933 TnyFolder *src_folder = NULL;
4935 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4938 TnyHeader *header = NULL;
4941 iter = tny_list_create_iterator (headers);
4942 header = (TnyHeader *) tny_iterator_get_current (iter);
4943 src_folder = tny_header_get_folder (header);
4945 /* Transfer the messages */
4946 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
4948 TNY_FOLDER (dst_folder));
4951 g_object_unref (header);
4952 g_object_unref (iter);
4953 g_object_unref (src_folder);
4958 modest_ui_actions_on_move_to (GtkAction *action,
4961 modest_ui_actions_on_edit_mode_move_to (win);
4965 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
4967 GtkWidget *dialog = NULL;
4968 MoveToInfo *helper = NULL;
4969 TnyList *list_to_move;
4971 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
4974 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
4979 if (tny_list_get_length (list_to_move) < 1) {
4980 g_object_unref (list_to_move);
4984 /* Create and run the dialog */
4985 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
4986 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
4987 GTK_WINDOW (dialog),
4991 helper = g_slice_new0 (MoveToInfo);
4992 helper->list = list_to_move;
4995 /* Listen to response signal */
4996 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
4998 /* Show the dialog */
4999 gtk_widget_show (dialog);
5005 * Calls #HeadersFunc for each header already selected in the main
5006 * window or the message currently being shown in the msg view window
5009 do_headers_action (ModestWindow *win,
5013 TnyList *headers_list = NULL;
5014 TnyIterator *iter = NULL;
5015 TnyHeader *header = NULL;
5016 TnyFolder *folder = NULL;
5019 headers_list = get_selected_headers (win);
5023 /* Get the folder */
5024 iter = tny_list_create_iterator (headers_list);
5025 header = TNY_HEADER (tny_iterator_get_current (iter));
5027 folder = tny_header_get_folder (header);
5028 g_object_unref (header);
5031 /* Call the function for each header */
5032 while (!tny_iterator_is_done (iter)) {
5033 header = TNY_HEADER (tny_iterator_get_current (iter));
5034 func (header, win, user_data);
5035 g_object_unref (header);
5036 tny_iterator_next (iter);
5039 /* Trick: do a poke status in order to speed up the signaling
5042 tny_folder_poke_status (folder);
5043 g_object_unref (folder);
5047 g_object_unref (iter);
5048 g_object_unref (headers_list);
5052 modest_ui_actions_view_attachment (GtkAction *action,
5053 ModestWindow *window)
5055 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5056 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5058 /* not supported window for this action */
5059 g_return_if_reached ();
5064 modest_ui_actions_save_attachments (GtkAction *action,
5065 ModestWindow *window)
5067 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5069 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5072 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5074 /* not supported window for this action */
5075 g_return_if_reached ();
5080 modest_ui_actions_remove_attachments (GtkAction *action,
5081 ModestWindow *window)
5083 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5084 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5086 /* not supported window for this action */
5087 g_return_if_reached ();
5092 modest_ui_actions_on_settings (GtkAction *action,
5096 GtkWindow *toplevel;
5098 dialog = modest_platform_get_global_settings_dialog ();
5099 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5100 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5101 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5102 gtk_widget_show_all (dialog);
5104 gtk_dialog_run (GTK_DIALOG (dialog));
5106 gtk_widget_destroy (dialog);
5110 modest_ui_actions_on_help (GtkAction *action,
5113 /* Help app is not available at all in fremantle */
5114 #ifndef MODEST_TOOLKIT_HILDON2
5115 const gchar *help_id;
5117 g_return_if_fail (win && GTK_IS_WINDOW(win));
5119 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5122 modest_platform_show_help (GTK_WINDOW (win), help_id);
5127 modest_ui_actions_on_csm_help (GtkAction *action,
5130 /* Help app is not available at all in fremantle */
5134 retrieve_contents_cb (ModestMailOperation *mail_op,
5141 /* We only need this callback to show an error in case of
5142 memory low condition */
5143 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5144 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5149 retrieve_msg_contents_performer (gboolean canceled,
5151 GtkWindow *parent_window,
5152 TnyAccount *account,
5155 ModestMailOperation *mail_op;
5156 TnyList *headers = TNY_LIST (user_data);
5158 if (err || canceled) {
5159 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5160 (GtkWidget *) parent_window, err,
5165 /* Create mail operation */
5166 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5167 modest_ui_actions_disk_operations_error_handler,
5169 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5170 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5173 g_object_unref (mail_op);
5175 g_object_unref (headers);
5176 g_object_unref (account);
5180 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5181 ModestWindow *window)
5183 TnyList *headers = NULL;
5184 TnyAccount *account = NULL;
5185 TnyIterator *iter = NULL;
5186 TnyHeader *header = NULL;
5187 TnyFolder *folder = NULL;
5190 headers = get_selected_headers (window);
5194 /* Pick the account */
5195 iter = tny_list_create_iterator (headers);
5196 header = TNY_HEADER (tny_iterator_get_current (iter));
5197 folder = tny_header_get_folder (header);
5198 account = tny_folder_get_account (folder);
5199 g_object_unref (folder);
5200 g_object_unref (header);
5201 g_object_unref (iter);
5203 /* Connect and perform the message retrieval */
5204 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5205 g_object_ref (account),
5206 retrieve_msg_contents_performer,
5207 g_object_ref (headers));
5210 g_object_unref (account);
5211 g_object_unref (headers);
5215 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5217 g_return_if_fail (MODEST_IS_WINDOW (window));
5220 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5224 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5226 g_return_if_fail (MODEST_IS_WINDOW (window));
5229 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5233 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5234 ModestWindow *window)
5236 g_return_if_fail (MODEST_IS_WINDOW (window));
5239 modest_ui_actions_check_menu_dimming_rules (window);
5243 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5244 ModestWindow *window)
5246 g_return_if_fail (MODEST_IS_WINDOW (window));
5249 modest_ui_actions_check_menu_dimming_rules (window);
5253 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5254 ModestWindow *window)
5256 g_return_if_fail (MODEST_IS_WINDOW (window));
5259 modest_ui_actions_check_menu_dimming_rules (window);
5263 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5264 ModestWindow *window)
5266 g_return_if_fail (MODEST_IS_WINDOW (window));
5269 modest_ui_actions_check_menu_dimming_rules (window);
5273 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5274 ModestWindow *window)
5276 g_return_if_fail (MODEST_IS_WINDOW (window));
5279 modest_ui_actions_check_menu_dimming_rules (window);
5283 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5284 ModestWindow *window)
5286 g_return_if_fail (MODEST_IS_WINDOW (window));
5289 modest_ui_actions_check_menu_dimming_rules (window);
5293 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5294 ModestWindow *window)
5296 g_return_if_fail (MODEST_IS_WINDOW (window));
5299 modest_ui_actions_check_menu_dimming_rules (window);
5303 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5304 ModestWindow *window)
5306 g_return_if_fail (MODEST_IS_WINDOW (window));
5309 modest_ui_actions_check_menu_dimming_rules (window);
5313 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5314 ModestWindow *window)
5316 g_return_if_fail (MODEST_IS_WINDOW (window));
5319 modest_ui_actions_check_menu_dimming_rules (window);
5323 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5325 g_return_if_fail (MODEST_IS_WINDOW (window));
5327 /* we check for low-mem; in that case, show a warning, and don't allow
5330 if (modest_platform_check_memory_low (window, TRUE))
5333 modest_platform_show_search_messages (GTK_WINDOW (window));
5337 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5339 g_return_if_fail (MODEST_IS_WINDOW (win));
5342 /* we check for low-mem; in that case, show a warning, and don't allow
5343 * for the addressbook
5345 if (modest_platform_check_memory_low (win, TRUE))
5349 modest_platform_show_addressbook (GTK_WINDOW (win));
5354 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5355 ModestWindow *window)
5358 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5360 if (GTK_IS_TOGGLE_ACTION (action))
5361 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5365 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5371 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5377 const gchar* server_name = NULL;
5378 TnyTransportAccount *transport;
5379 gchar *message = NULL;
5380 ModestProtocol *protocol;
5382 /* Don't show anything if the user cancelled something or the
5383 * send receive request is not interactive. Authentication
5384 * errors are managed by the account store so no need to show
5385 * a dialog here again */
5386 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5387 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5388 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5392 /* Get the server name. Note that we could be using a
5393 connection specific transport account */
5394 transport = (TnyTransportAccount *)
5395 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5397 ModestTnyAccountStore *acc_store;
5398 const gchar *acc_name;
5399 TnyTransportAccount *conn_specific;
5401 acc_store = modest_runtime_get_account_store();
5402 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5403 conn_specific = (TnyTransportAccount *)
5404 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5405 if (conn_specific) {
5406 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5407 g_object_unref (conn_specific);
5409 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5411 g_object_unref (transport);
5415 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5416 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5417 tny_account_get_proto (TNY_ACCOUNT (transport)));
5419 g_warning ("%s: Account with no proto", __FUNCTION__);
5423 /* Show the appropriate message text for the GError: */
5424 switch (err->code) {
5425 case TNY_SERVICE_ERROR_CONNECT:
5426 message = modest_protocol_get_translation (protocol,
5427 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5430 case TNY_SERVICE_ERROR_SEND:
5431 message = g_strdup (_CS("sfil_ib_unable_to_send"));
5433 case TNY_SERVICE_ERROR_UNAVAILABLE:
5434 message = modest_protocol_get_translation (protocol,
5435 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5439 g_warning ("%s: unexpected ERROR %d",
5440 __FUNCTION__, err->code);
5441 message = g_strdup (_CS("sfil_ib_unable_to_send"));
5445 modest_platform_run_information_dialog (NULL, message, FALSE);
5450 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5455 ModestWindow *top_window = NULL;
5456 ModestWindowMgr *mgr = NULL;
5457 GtkWidget *header_view = NULL;
5458 TnyFolder *selected_folder = NULL;
5459 TnyFolderType folder_type;
5461 mgr = modest_runtime_get_window_mgr ();
5462 top_window = modest_window_mgr_get_current_top (mgr);
5467 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5468 header_view = (GtkWidget *)
5469 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5472 /* Get selected folder */
5474 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5475 if (!selected_folder)
5478 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5479 #if GTK_CHECK_VERSION(2, 8, 0)
5480 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5481 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5482 GtkTreeViewColumn *tree_column;
5484 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5485 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5487 gtk_tree_view_column_queue_resize (tree_column);
5489 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5490 gtk_widget_queue_draw (header_view);
5493 #ifndef MODEST_TOOLKIT_HILDON2
5494 /* Rerun dimming rules, because the message could become deletable for example */
5495 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5496 MODEST_DIMMING_RULES_TOOLBAR);
5497 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5498 MODEST_DIMMING_RULES_MENU);
5502 g_object_unref (selected_folder);
5506 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5507 TnyAccount *account)
5509 ModestProtocolType protocol_type;
5510 ModestProtocol *protocol;
5511 gchar *error_note = NULL;
5513 protocol_type = modest_tny_account_get_protocol_type (account);
5514 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5517 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5518 if (error_note == NULL) {
5519 g_warning ("%s: This should not be reached", __FUNCTION__);
5521 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
5522 g_free (error_note);
5527 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5531 TnyFolderStore *folder = NULL;
5532 TnyAccount *account = NULL;
5533 ModestProtocolType proto;
5534 ModestProtocol *protocol;
5535 TnyHeader *header = NULL;
5537 if (MODEST_IS_HEADER_WINDOW (win)) {
5538 GtkWidget *header_view;
5539 TnyList* headers = NULL;
5541 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5542 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5543 if (!headers || tny_list_get_length (headers) == 0) {
5545 g_object_unref (headers);
5548 iter = tny_list_create_iterator (headers);
5549 header = TNY_HEADER (tny_iterator_get_current (iter));
5551 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5553 g_warning ("List should contain headers");
5555 g_object_unref (iter);
5556 g_object_unref (headers);
5557 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5558 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5560 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5563 if (!header || !folder)
5566 /* Get the account type */
5567 account = tny_folder_get_account (TNY_FOLDER (folder));
5568 proto = modest_tny_account_get_protocol_type (account);
5569 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5572 subject = tny_header_dup_subject (header);
5573 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5577 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5583 g_object_unref (account);
5585 g_object_unref (folder);
5587 g_object_unref (header);
5593 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5594 const gchar *account_name,
5595 const gchar *account_title)
5597 ModestAccountMgr *account_mgr;
5600 ModestProtocol *protocol;
5601 gboolean removed = FALSE;
5603 g_return_val_if_fail (account_name, FALSE);
5604 g_return_val_if_fail (account_title, FALSE);
5606 account_mgr = modest_runtime_get_account_mgr();
5608 /* The warning text depends on the account type: */
5609 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5610 modest_account_mgr_get_store_protocol (account_mgr,
5612 txt = modest_protocol_get_translation (protocol,
5613 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5616 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5618 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5622 if (response == GTK_RESPONSE_OK) {
5623 /* Remove account. If it succeeds then it also removes
5624 the account from the ModestAccountView: */
5625 gboolean is_default = FALSE;
5626 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5627 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5629 g_free (default_account_name);
5631 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5633 /* Close all email notifications, we cannot
5634 distinguish if the notification belongs to
5635 this account or not, so for safety reasons
5636 we remove them all */
5637 modest_platform_remove_new_mail_notifications (FALSE);
5639 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5646 on_fetch_images_performer (gboolean canceled,
5648 GtkWindow *parent_window,
5649 TnyAccount *account,
5652 if (err || canceled) {
5653 /* Show an unable to retrieve images ??? */
5657 /* Note that the user could have closed the window while connecting */
5658 if (GTK_WIDGET_VISIBLE (parent_window))
5659 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5660 g_object_unref ((GObject *) user_data);
5664 modest_ui_actions_on_fetch_images (GtkAction *action,
5665 ModestWindow *window)
5667 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5669 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5671 on_fetch_images_performer,
5672 g_object_ref (window));
5676 modest_ui_actions_on_reload_message (const gchar *msg_id)
5678 ModestWindow *window = NULL;
5680 g_return_if_fail (msg_id && msg_id[0] != '\0');
5681 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5687 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5690 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5693 /** Check whether any connections are active, and cancel them if
5695 * Returns TRUE is there was no problem,
5696 * or if an operation was cancelled so we can continue.
5697 * Returns FALSE if the user chose to cancel his request instead.
5701 modest_ui_actions_check_for_active_account (ModestWindow *self,
5702 const gchar* account_name)
5704 ModestTnySendQueue *send_queue;
5705 ModestTnyAccountStore *acc_store;
5706 ModestMailOperationQueue* queue;
5707 TnyConnectionStatus store_conn_status;
5708 TnyAccount *store_account = NULL, *transport_account = NULL;
5709 gboolean retval = TRUE, sending = FALSE;
5711 acc_store = modest_runtime_get_account_store ();
5712 queue = modest_runtime_get_mail_operation_queue ();
5715 modest_tny_account_store_get_server_account (acc_store,
5717 TNY_ACCOUNT_TYPE_STORE);
5719 /* This could happen if the account was deleted before the
5720 call to this function */
5725 modest_tny_account_store_get_server_account (acc_store,
5727 TNY_ACCOUNT_TYPE_TRANSPORT);
5729 /* This could happen if the account was deleted before the
5730 call to this function */
5731 if (!transport_account) {
5732 g_object_unref (store_account);
5736 /* If the transport account was not used yet, then the send
5737 queue could not exist (it's created on demand) */
5738 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5739 if (TNY_IS_SEND_QUEUE (send_queue))
5740 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5742 store_conn_status = tny_account_get_connection_status (store_account);
5743 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5746 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
5747 _("emev_nc_disconnect_account"));
5748 if (response == GTK_RESPONSE_OK) {
5757 /* FIXME: We should only cancel those of this account */
5758 modest_mail_operation_queue_cancel_all (queue);
5760 /* Also disconnect the account */
5761 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5762 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5763 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5767 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5773 g_object_unref (store_account);
5774 g_object_unref (transport_account);