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-msg-view-window.h>
64 #include <widgets/modest-account-view-window.h>
65 #include <widgets/modest-details-dialog.h>
66 #include <widgets/modest-attachments-view.h>
67 #include "widgets/modest-folder-view.h"
68 #include "widgets/modest-global-settings-dialog.h"
69 #include "modest-account-mgr-helpers.h"
70 #include "modest-mail-operation.h"
71 #include "modest-text-utils.h"
72 #include <modest-widget-memory.h>
73 #include <tny-error.h>
74 #include <tny-simple-list.h>
75 #include <tny-msg-view.h>
76 #include <tny-device.h>
77 #include <tny-merge-folder.h>
78 #include <widgets/modest-toolkit-utils.h>
79 #include <tny-camel-bs-msg.h>
80 #include <tny-camel-bs-mime-part.h>
83 #include <gtkhtml/gtkhtml.h>
85 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
87 typedef struct _GetMsgAsyncHelper {
89 ModestMailOperation *mail_op;
96 typedef enum _ReplyForwardAction {
100 } ReplyForwardAction;
102 typedef struct _ReplyForwardHelper {
103 guint reply_forward_type;
104 ReplyForwardAction action;
107 GtkWidget *parent_window;
110 } ReplyForwardHelper;
112 typedef struct _MoveToHelper {
113 GtkTreeRowReference *reference;
117 typedef struct _PasteAsAttachmentHelper {
118 ModestMsgEditWindow *window;
120 } PasteAsAttachmentHelper;
128 * The do_headers_action uses this kind of functions to perform some
129 * action to each member of a list of headers
131 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
133 static void do_headers_action (ModestWindow *win,
137 static void open_msg_cb (ModestMailOperation *mail_op,
144 static void reply_forward_cb (ModestMailOperation *mail_op,
151 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
153 static gint header_list_count_uncached_msgs (TnyList *header_list);
155 static gboolean connect_to_get_msg (ModestWindow *win,
156 gint num_of_uncached_msgs,
157 TnyAccount *account);
159 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
161 static void do_create_folder (ModestWindow *window,
162 TnyFolderStore *parent_folder,
163 const gchar *suggested_name);
165 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
167 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
168 TnyFolderStore *dst_folder,
172 static void modest_ui_actions_on_window_move_to (GtkAction *action,
173 TnyList *list_to_move,
174 TnyFolderStore *dst_folder,
178 * This function checks whether a TnyFolderStore is a pop account
181 remote_folder_has_leave_on_server (TnyFolderStore *folder)
186 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
188 account = get_account_from_folder_store (folder);
189 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
190 modest_tny_account_get_protocol_type (account)));
191 g_object_unref (account);
196 /* FIXME: this should be merged with the similar code in modest-account-view-window */
197 /* Show the account creation wizard dialog.
198 * returns: TRUE if an account was created. FALSE if the user cancelled.
201 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
203 gboolean result = FALSE;
205 gint dialog_response;
207 /* there is no such wizard yet */
208 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
209 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
213 ModestWindowMgr *mgr;
215 mgr = modest_runtime_get_window_mgr ();
217 window_list = modest_window_mgr_get_window_list (mgr);
218 if (window_list == NULL) {
219 win = MODEST_WINDOW (modest_accounts_window_new ());
220 if (modest_window_mgr_register_window (mgr, win, NULL)) {
221 gtk_widget_show_all (GTK_WIDGET (win));
223 gtk_widget_destroy (GTK_WIDGET (win));
228 g_list_free (window_list);
233 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
234 gtk_window_set_transient_for (GTK_WINDOW (wizard), toplevel);
237 /* make sure the mainwindow is visible. We need to present the
238 wizard again to give it the focus back. show_all are needed
239 in order to get the widgets properly drawn (MainWindow main
240 paned won't be in its right position and the dialog will be
243 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
244 gtk_widget_destroy (GTK_WIDGET (wizard));
245 if (gtk_events_pending ())
246 gtk_main_iteration ();
248 if (dialog_response == GTK_RESPONSE_CANCEL) {
251 /* Check whether an account was created: */
252 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
259 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
263 const gchar *authors[] = {
264 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
267 about = gtk_about_dialog_new ();
268 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
269 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
270 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
271 _("Copyright (c) 2006, Nokia Corporation\n"
272 "All rights reserved."));
273 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
274 _("a modest e-mail client\n\n"
275 "design and implementation: Dirk-Jan C. Binnema\n"
276 "contributions from the fine people at KC and Ig\n"
277 "uses the tinymail email framework written by Philip van Hoof"));
278 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
279 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
281 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
282 gtk_window_set_transient_for (GTK_WINDOW (about), toplevel);
283 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
285 gtk_dialog_run (GTK_DIALOG (about));
286 gtk_widget_destroy(about);
290 * Gets the list of currently selected messages. If the win is the
291 * main window, then it returns a newly allocated list of the headers
292 * selected in the header view. If win is the msg view window, then
293 * the value returned is a list with just a single header.
295 * The caller of this funcion must free the list.
298 get_selected_headers (ModestWindow *win)
300 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
301 /* for MsgViewWindows, we simply return a list with one element */
303 TnyList *list = NULL;
305 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
306 if (header != NULL) {
307 list = tny_simple_list_new ();
308 tny_list_prepend (list, G_OBJECT(header));
309 g_object_unref (G_OBJECT(header));
313 } else if (MODEST_IS_HEADER_WINDOW (win)) {
314 GtkWidget *header_view;
316 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
317 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
324 headers_action_mark_as_read (TnyHeader *header,
328 TnyHeaderFlags flags;
330 g_return_if_fail (TNY_IS_HEADER(header));
332 flags = tny_header_get_flags (header);
333 if (flags & TNY_HEADER_FLAG_SEEN) return;
334 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
338 headers_action_mark_as_unread (TnyHeader *header,
342 TnyHeaderFlags flags;
344 g_return_if_fail (TNY_IS_HEADER(header));
346 flags = tny_header_get_flags (header);
347 if (flags & TNY_HEADER_FLAG_SEEN) {
348 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
352 /** After deleing a message that is currently visible in a window,
353 * show the next message from the list, or close the window if there are no more messages.
356 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
358 /* Close msg view window or select next */
359 if (!modest_msg_view_window_select_next_message (win) &&
360 !modest_msg_view_window_select_previous_message (win)) {
362 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
368 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
370 modest_ui_actions_on_edit_mode_delete_message (win);
374 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
376 TnyList *header_list = NULL;
377 TnyIterator *iter = NULL;
378 TnyHeader *header = NULL;
379 gchar *message = NULL;
382 ModestWindowMgr *mgr;
383 gboolean retval = TRUE;
385 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
387 /* Get the headers, either from the header view (if win is the main window),
388 * or from the message view window: */
389 header_list = get_selected_headers (win);
390 if (!header_list) return FALSE;
392 /* Check if any of the headers are already opened, or in the process of being opened */
395 if (tny_list_get_length(header_list) == 1) {
396 iter = tny_list_create_iterator (header_list);
397 header = TNY_HEADER (tny_iterator_get_current (iter));
400 subject = tny_header_dup_subject (header);
402 subject = g_strdup (_("mail_va_no_subject"));
403 desc = g_strdup_printf ("%s", subject);
405 g_object_unref (header);
408 g_object_unref (iter);
410 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
411 tny_list_get_length(header_list)), desc);
413 /* Confirmation dialog */
414 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (win))),
417 if (response == GTK_RESPONSE_OK) {
418 GtkTreeSelection *sel = NULL;
419 GList *sel_list = NULL;
420 ModestMailOperation *mail_op = NULL;
422 /* Find last selected row */
424 /* Disable window dimming management */
425 modest_window_disable_dimming (win);
427 /* Remove each header. If it's a view window header_view == NULL */
428 mail_op = modest_mail_operation_new ((GObject *) win);
429 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
431 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
432 g_object_unref (mail_op);
434 /* Enable window dimming management */
436 gtk_tree_selection_unselect_all (sel);
438 modest_window_enable_dimming (win);
440 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
441 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
443 /* Get main window */
444 mgr = modest_runtime_get_window_mgr ();
447 /* Update toolbar dimming state */
448 modest_ui_actions_check_menu_dimming_rules (win);
449 modest_ui_actions_check_toolbar_dimming_rules (win);
452 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
453 g_list_free (sel_list);
462 g_object_unref (header_list);
470 /* delete either message or folder, based on where we are */
472 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
474 g_return_if_fail (MODEST_IS_WINDOW(win));
476 /* Check first if the header view has the focus */
477 modest_ui_actions_on_delete_message (action, win);
481 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
483 ModestWindowMgr *mgr = NULL;
485 #ifdef MODEST_PLATFORM_MAEMO
486 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
487 #endif /* MODEST_PLATFORM_MAEMO */
489 g_debug ("closing down, clearing %d item(s) from operation queue",
490 modest_mail_operation_queue_num_elements
491 (modest_runtime_get_mail_operation_queue()));
493 /* cancel all outstanding operations */
494 modest_mail_operation_queue_cancel_all
495 (modest_runtime_get_mail_operation_queue());
497 g_debug ("queue has been cleared");
500 /* Check if there are opened editing windows */
501 mgr = modest_runtime_get_window_mgr ();
502 modest_window_mgr_close_all_windows (mgr);
504 /* note: when modest-tny-account-store is finalized,
505 it will automatically set all network connections
508 /* gtk_main_quit (); */
512 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
516 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
518 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
519 /* gtk_widget_destroy (GTK_WIDGET (win)); */
520 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
521 /* gboolean ret_value; */
522 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
523 /* } else if (MODEST_IS_WINDOW (win)) { */
524 /* gtk_widget_destroy (GTK_WIDGET (win)); */
526 /* g_return_if_reached (); */
531 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
533 if (MODEST_IS_MSG_VIEW_WINDOW (win))
534 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
535 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
536 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
540 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
542 GtkClipboard *clipboard = NULL;
543 gchar *selection = NULL;
545 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
546 selection = gtk_clipboard_wait_for_text (clipboard);
549 modest_address_book_add_address (selection, (GtkWindow *) win);
555 modest_ui_actions_on_new_account (GtkAction *action,
556 ModestWindow *window)
558 if (!modest_ui_actions_run_account_setup_wizard (window)) {
559 g_debug ("%s: wizard was already running", __FUNCTION__);
564 modest_ui_actions_on_accounts (GtkAction *action,
567 /* This is currently only implemented for Maemo */
568 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
569 if (!modest_ui_actions_run_account_setup_wizard (win))
570 g_debug ("%s: wizard was already running", __FUNCTION__);
574 /* Show the list of accounts */
575 GtkWindow *win_toplevel, *acc_toplevel;
576 GtkWidget *account_win;
578 account_win = modest_account_view_window_new ();
579 acc_toplevel = (GtkWindow *) gtk_widget_get_toplevel (account_win);
581 /* The accounts dialog must be modal */
582 win_toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
583 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), acc_toplevel, win_toplevel);
584 modest_utils_show_dialog_and_forget (win_toplevel, GTK_DIALOG (account_win));
589 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
591 /* Create the window if necessary: */
592 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
593 modest_connection_specific_smtp_window_fill_with_connections (
594 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
595 modest_runtime_get_account_mgr());
597 /* Show the window: */
598 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
599 GTK_WINDOW (specific_window), (GtkWindow *) win);
600 gtk_widget_show (specific_window);
604 count_part_size (const gchar *part)
606 GnomeVFSURI *vfs_uri;
607 gchar *escaped_filename;
609 GnomeVFSFileInfo *info;
612 /* Estimation of attachment size if we cannot get it from file info */
615 vfs_uri = gnome_vfs_uri_new (part);
617 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
618 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
619 g_free (escaped_filename);
620 gnome_vfs_uri_unref (vfs_uri);
622 info = gnome_vfs_file_info_new ();
624 if (gnome_vfs_get_file_info (part,
626 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
628 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
633 gnome_vfs_file_info_unref (info);
639 count_parts_size (GSList *parts)
644 for (node = parts; node != NULL; node = g_slist_next (node)) {
645 result += count_part_size ((const gchar *) node->data);
652 modest_ui_actions_compose_msg(ModestWindow *win,
655 const gchar *bcc_str,
656 const gchar *subject_str,
657 const gchar *body_str,
659 gboolean set_as_modified)
661 gchar *account_name = NULL;
662 const gchar *mailbox;
664 TnyAccount *account = NULL;
665 TnyFolder *folder = NULL;
666 gchar *from_str = NULL, *signature = NULL, *body = NULL;
667 gchar *recipient = NULL;
668 gboolean use_signature = FALSE;
669 ModestWindow *msg_win = NULL;
670 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
671 ModestTnyAccountStore *store = modest_runtime_get_account_store();
672 GnomeVFSFileSize total_size, allowed_size;
673 guint64 available_disk, expected_size, parts_size;
676 /* we check for low-mem */
677 if (modest_platform_check_memory_low (win, TRUE))
680 available_disk = modest_utils_get_available_space (NULL);
681 parts_count = g_slist_length (attachments);
682 parts_size = count_parts_size (attachments);
683 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
685 /* Double check: disk full condition or message too big */
686 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
687 expected_size > available_disk) {
688 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
689 modest_platform_system_banner (NULL, NULL, msg);
695 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
696 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
697 modest_platform_run_information_dialog (toplevel,
698 _("mail_ib_error_attachment_size"),
705 account_name = g_strdup (modest_window_get_active_account(win));
707 account_name = modest_account_mgr_get_default_account(mgr);
710 g_printerr ("modest: no account found\n");
715 mailbox = modest_window_get_active_mailbox (win);
718 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
720 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
723 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
725 g_printerr ("modest: failed to find Drafts folder\n");
728 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
730 g_printerr ("modest: failed get from string for '%s'\n", account_name);
734 recipient = modest_text_utils_get_email_address (from_str);
735 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
737 if (body_str != NULL) {
738 body = use_signature ? g_strconcat(body_str, "\n",
739 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
740 "\n", signature, NULL) : g_strdup(body_str);
743 gchar *gray_color_markup = NULL, *color_begin = NULL, *color_end = NULL;
746 if (gtk_style_lookup_color (GTK_WIDGET (win)->style, "SecondaryTextColor", &color))
747 gray_color_markup = modest_text_utils_get_color_string (&color);
748 if (!gray_color_markup)
749 gray_color_markup = g_strdup ("#999999");
751 color_begin = g_strdup_printf ("<font color=\"%s\">", gray_color_markup);
752 color_end = "</font>";
754 body = use_signature ? g_strconcat("<br/>\n", color_begin,
755 MODEST_TEXT_UTILS_SIGNATURE_MARKER, "<br/>\n",
756 signature, color_end, NULL) : g_strdup("");
758 g_free (gray_color_markup);
759 g_free (color_begin);
762 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
763 NULL, NULL, body, NULL, NULL, NULL, NULL, NULL);
765 g_printerr ("modest: failed to create new msg\n");
769 /* Create and register edit window */
770 /* This is destroyed by TODO. */
772 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
773 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
775 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
776 gtk_widget_destroy (GTK_WIDGET (msg_win));
779 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
780 gtk_widget_show_all (GTK_WIDGET (msg_win));
782 while (attachments) {
783 GnomeVFSFileSize att_size;
785 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
786 attachments->data, allowed_size);
787 total_size += att_size;
789 if (att_size > allowed_size) {
790 g_debug ("%s: total size: %u",
791 __FUNCTION__, (unsigned int)total_size);
794 allowed_size -= att_size;
796 attachments = g_slist_next(attachments);
803 g_free (account_name);
805 g_object_unref (G_OBJECT(account));
807 g_object_unref (G_OBJECT(folder));
809 g_object_unref (G_OBJECT(msg));
813 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
815 /* if there are no accounts yet, just show the wizard */
816 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
817 if (!modest_ui_actions_run_account_setup_wizard (win))
820 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
825 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
829 ModestMailOperationStatus status;
831 /* If there is no message or the operation was not successful */
832 status = modest_mail_operation_get_status (mail_op);
833 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
836 /* If it's a memory low issue, then show a banner */
837 error = modest_mail_operation_get_error (mail_op);
838 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
839 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
840 GtkWindow *toplevel = NULL;
841 GObject *source = modest_mail_operation_get_source (mail_op);
843 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (source));
844 modest_platform_run_information_dialog (toplevel,
845 _KR("memr_ib_operation_disabled"),
847 g_object_unref (source);
850 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
851 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
852 gchar *subject, *msg, *format = NULL;
855 subject = (header) ? tny_header_dup_subject (header) : NULL;
857 subject = g_strdup (_("mail_va_no_subject"));
859 account = modest_mail_operation_get_account (mail_op);
861 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
862 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
865 if (tny_account_get_connection_status (account) ==
866 TNY_CONNECTION_STATUS_CONNECTED) {
868 format = modest_protocol_get_translation (protocol,
869 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
872 format = modest_protocol_get_translation (protocol,
873 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
876 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
877 tny_account_get_hostname (account));
880 g_object_unref (account);
885 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
887 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
891 msg = g_strdup_printf (format, subject);
892 modest_platform_run_information_dialog (NULL, msg, FALSE);
898 /* Remove the header from the preregistered uids */
899 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
917 ModestWindow *caller_window;
918 OpenMsgBannerInfo *banner_info;
919 GtkTreeRowReference *rowref;
923 open_msg_banner_idle (gpointer userdata)
925 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
927 gdk_threads_enter ();
928 banner_info->idle_handler = 0;
929 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
930 if (banner_info->banner)
931 g_object_ref (banner_info->banner);
933 gdk_threads_leave ();
939 get_header_view_from_window (ModestWindow *window)
941 GtkWidget *header_view;
943 if (MODEST_IS_HEADER_WINDOW (window)){
944 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
953 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
956 gchar *account = NULL;
957 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
962 folder = tny_header_get_folder (header);
963 /* Gets folder type (OUTBOX headers will be opened in edit window */
964 if (modest_tny_folder_is_local_folder (folder)) {
965 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
966 if (folder_type == TNY_FOLDER_TYPE_INVALID)
967 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
970 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
971 TnyTransportAccount *traccount = NULL;
972 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
973 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
975 ModestTnySendQueue *send_queue = NULL;
976 ModestTnySendQueueStatus status;
978 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
979 TNY_ACCOUNT(traccount)));
980 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
981 if (TNY_IS_SEND_QUEUE (send_queue)) {
982 msg_id = modest_tny_send_queue_get_msg_id (header);
983 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
985 /* Only open messages in outbox with the editor if they are in Failed state */
986 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
990 /* In Fremantle we can not
991 open any message from
992 outbox which is not in
997 g_object_unref(traccount);
999 g_warning("Cannot get transport account for message in outbox!!");
1001 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1002 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1006 TnyAccount *acc = tny_folder_get_account (folder);
1009 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1010 g_object_unref (acc);
1014 g_object_unref (folder);
1020 open_msg_cb (ModestMailOperation *mail_op,
1027 ModestWindowMgr *mgr = NULL;
1028 ModestWindow *parent_win = NULL;
1029 ModestWindow *win = NULL;
1030 gchar *account = NULL;
1031 gboolean open_in_editor = FALSE;
1033 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1035 /* Do nothing if there was any problem with the mail
1036 operation. The error will be shown by the error_handler of
1037 the mail operation */
1038 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1041 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1043 /* Mark header as read */
1044 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1046 account = get_info_from_header (header, &open_in_editor, &can_open);
1050 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1052 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1054 if (open_in_editor) {
1055 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1056 gchar *from_header = NULL, *acc_name;
1057 gchar *mailbox = NULL;
1059 from_header = tny_header_dup_from (header);
1061 /* we cannot edit without a valid account... */
1062 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1063 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1064 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1066 g_free (from_header);
1071 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1072 g_free (from_header);
1078 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1082 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1083 const gchar *mailbox = NULL;
1085 if (parent_win && MODEST_IS_WINDOW (parent_win))
1086 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1088 if (helper->rowref && helper->model) {
1089 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1090 helper->model, helper->rowref);
1092 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1097 /* Register and show new window */
1099 mgr = modest_runtime_get_window_mgr ();
1100 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1101 gtk_widget_destroy (GTK_WIDGET (win));
1104 gtk_widget_show_all (GTK_WIDGET(win));
1111 g_object_unref (parent_win);
1115 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1118 const GError *error;
1119 GObject *win = NULL;
1120 ModestMailOperationStatus status;
1122 win = modest_mail_operation_get_source (mail_op);
1123 error = modest_mail_operation_get_error (mail_op);
1124 status = modest_mail_operation_get_status (mail_op);
1126 /* If the mail op has been cancelled then it's not an error:
1127 don't show any message */
1128 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1129 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1130 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1131 (GError *) error, account)) {
1132 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1133 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1135 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1136 modest_platform_information_banner ((GtkWidget *) win,
1137 NULL, _("emev_ui_imap_inbox_select_error"));
1138 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1139 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1140 modest_platform_information_banner ((GtkWidget *) win,
1141 NULL, _CS_UNABLE_TO_OPEN_FILE_NOT_FOUND);
1142 } else if (user_data) {
1143 modest_platform_information_banner ((GtkWidget *) win,
1147 g_object_unref (account);
1151 g_object_unref (win);
1155 * Returns the account a list of headers belongs to. It returns a
1156 * *new* reference so don't forget to unref it
1159 get_account_from_header_list (TnyList *headers)
1161 TnyAccount *account = NULL;
1163 if (tny_list_get_length (headers) > 0) {
1164 TnyIterator *iter = tny_list_create_iterator (headers);
1165 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1166 TnyFolder *folder = tny_header_get_folder (header);
1169 g_object_unref (header);
1171 while (!tny_iterator_is_done (iter)) {
1172 header = TNY_HEADER (tny_iterator_get_current (iter));
1173 folder = tny_header_get_folder (header);
1176 g_object_unref (header);
1178 tny_iterator_next (iter);
1183 account = tny_folder_get_account (folder);
1184 g_object_unref (folder);
1188 g_object_unref (header);
1190 g_object_unref (iter);
1196 get_account_from_header (TnyHeader *header)
1198 TnyAccount *account = NULL;
1201 folder = tny_header_get_folder (header);
1204 account = tny_folder_get_account (folder);
1205 g_object_unref (folder);
1211 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1213 if (helper->caller_window)
1214 helper->caller_window = NULL;
1218 open_msg_helper_destroyer (gpointer user_data)
1220 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1222 if (helper->caller_window) {
1223 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1224 helper->caller_window = NULL;
1227 if (helper->banner_info) {
1228 g_free (helper->banner_info->message);
1229 if (helper->banner_info->idle_handler > 0) {
1230 g_source_remove (helper->banner_info->idle_handler);
1231 helper->banner_info->idle_handler = 0;
1233 if (helper->banner_info->banner != NULL) {
1234 gtk_widget_destroy (helper->banner_info->banner);
1235 g_object_unref (helper->banner_info->banner);
1236 helper->banner_info->banner = NULL;
1238 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1239 helper->banner_info = NULL;
1241 g_object_unref (helper->model);
1242 g_object_unref (helper->header);
1243 gtk_tree_row_reference_free (helper->rowref);
1244 g_slice_free (OpenMsgHelper, helper);
1248 open_msg_performer(gboolean canceled,
1250 ModestWindow *parent_window,
1251 TnyAccount *account,
1254 ModestMailOperation *mail_op = NULL;
1255 gchar *error_msg = NULL;
1256 ModestProtocolType proto;
1257 TnyConnectionStatus status;
1258 OpenMsgHelper *helper = NULL;
1259 ModestProtocol *protocol;
1260 ModestProtocolRegistry *protocol_registry;
1263 helper = (OpenMsgHelper *) user_data;
1265 status = tny_account_get_connection_status (account);
1266 if (err || canceled || helper->caller_window == NULL) {
1267 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1268 /* Free the helper */
1269 open_msg_helper_destroyer (helper);
1271 /* In disk full conditions we could get this error here */
1272 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1273 (GtkWidget *) parent_window, err,
1279 /* Get the error message depending on the protocol */
1280 proto = modest_tny_account_get_protocol_type (account);
1281 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1282 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1285 protocol_registry = modest_runtime_get_protocol_registry ();
1286 subject = tny_header_dup_subject (helper->header);
1288 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1289 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1293 if (error_msg == NULL) {
1294 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1299 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1302 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1303 g_free (account_name);
1304 open_msg_helper_destroyer (helper);
1309 ModestWindow *window;
1310 GtkWidget *header_view;
1313 header_view = get_header_view_from_window (parent_window);
1314 uid = modest_tny_folder_get_header_unique_id (helper->header);
1316 const gchar *mailbox = NULL;
1317 mailbox = modest_window_get_active_mailbox (parent_window);
1318 window = modest_msg_view_window_new_from_header_view
1319 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1320 if (window != NULL) {
1321 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1323 gtk_widget_destroy (GTK_WIDGET (window));
1325 gtk_widget_show_all (GTK_WIDGET(window));
1329 g_free (account_name);
1331 open_msg_helper_destroyer (helper);
1334 g_free (account_name);
1335 /* Create the mail operation */
1337 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1338 modest_ui_actions_disk_operations_error_handler,
1339 g_strdup (error_msg), g_free);
1340 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1346 headers = TNY_LIST (tny_simple_list_new ());
1347 tny_list_prepend (headers, G_OBJECT (helper->header));
1348 modest_mail_operation_get_msgs_full (mail_op,
1352 open_msg_helper_destroyer);
1353 g_object_unref (headers);
1360 g_object_unref (mail_op);
1361 g_object_unref (account);
1365 * This function is used by both modest_ui_actions_on_open and
1366 * modest_ui_actions_on_header_activated. This way we always do the
1367 * same when trying to open messages.
1370 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1372 ModestWindowMgr *mgr = NULL;
1373 TnyAccount *account;
1374 gboolean cached = FALSE;
1376 GtkWidget *header_view = NULL;
1377 OpenMsgHelper *helper;
1378 ModestWindow *window;
1380 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1382 mgr = modest_runtime_get_window_mgr ();
1385 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1386 if (header_view == NULL)
1389 /* Get the account */
1390 account = get_account_from_header (header);
1395 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1397 /* Do not open again the message and present the
1398 window to the user */
1401 #ifndef MODEST_TOOLKIT_HILDON2
1402 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
1403 gtk_window_present (toplevel);
1406 /* the header has been registered already, we don't do
1407 * anything but wait for the window to come up*/
1408 g_debug ("header %p already registered, waiting for window", header);
1413 /* Open each message */
1414 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1416 /* Allways download if we are online. */
1417 if (!tny_device_is_online (modest_runtime_get_device ())) {
1419 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1421 /* If ask for user permission to download the messages */
1422 response = modest_platform_run_confirmation_dialog (toplevel,
1423 _("mcen_nc_get_msg"));
1425 /* End if the user does not want to continue */
1426 if (response == GTK_RESPONSE_CANCEL) {
1432 /* We register the window for opening */
1433 modest_window_mgr_register_header (mgr, header, NULL);
1435 /* Create the helper. We need to get a reference to the model
1436 here because it could change while the message is readed
1437 (the user could switch between folders) */
1438 helper = g_slice_new (OpenMsgHelper);
1439 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1440 helper->caller_window = win;
1441 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1442 helper->header = g_object_ref (header);
1443 helper->rowref = gtk_tree_row_reference_copy (rowref);
1444 helper->banner_info = NULL;
1446 /* Connect to the account and perform */
1448 modest_platform_connect_and_perform (win, TRUE, g_object_ref (account),
1449 open_msg_performer, helper);
1451 /* Call directly the performer, do not need to connect */
1452 open_msg_performer (FALSE, NULL, win,
1453 g_object_ref (account), helper);
1458 g_object_unref (account);
1462 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1469 /* we check for low-mem; in that case, show a warning, and don't allow
1472 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1476 headers = get_selected_headers (win);
1480 headers_count = tny_list_get_length (headers);
1481 if (headers_count != 1) {
1482 if (headers_count > 1) {
1483 /* Don't allow activation if there are more than one message selected */
1484 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1487 g_object_unref (headers);
1491 iter = tny_list_create_iterator (headers);
1492 header = TNY_HEADER (tny_iterator_get_current (iter));
1493 g_object_unref (iter);
1497 open_msg_from_header (header, NULL, win);
1498 g_object_unref (header);
1501 g_object_unref(headers);
1505 rf_helper_window_closed (gpointer data,
1508 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1510 helper->parent_window = NULL;
1513 static ReplyForwardHelper*
1514 create_reply_forward_helper (ReplyForwardAction action,
1516 guint reply_forward_type,
1520 ReplyForwardHelper *rf_helper = NULL;
1521 const gchar *active_acc = modest_window_get_active_account (win);
1522 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1524 rf_helper = g_slice_new0 (ReplyForwardHelper);
1525 rf_helper->reply_forward_type = reply_forward_type;
1526 rf_helper->action = action;
1527 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1528 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1529 rf_helper->account_name = (active_acc) ?
1530 g_strdup (active_acc) :
1531 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1532 rf_helper->mailbox = g_strdup (active_mailbox);
1534 rf_helper->parts = g_object_ref (parts);
1536 rf_helper->parts = NULL;
1538 /* Note that window could be destroyed just AFTER calling
1539 register_window so we must ensure that this pointer does
1540 not hold invalid references */
1541 if (rf_helper->parent_window)
1542 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1543 rf_helper_window_closed, rf_helper);
1549 free_reply_forward_helper (gpointer data)
1551 ReplyForwardHelper *helper;
1553 helper = (ReplyForwardHelper *) data;
1554 g_free (helper->account_name);
1555 g_free (helper->mailbox);
1557 g_object_unref (helper->header);
1559 g_object_unref (helper->parts);
1560 if (helper->parent_window)
1561 g_object_weak_unref (G_OBJECT (helper->parent_window),
1562 rf_helper_window_closed, helper);
1563 g_slice_free (ReplyForwardHelper, helper);
1567 reply_forward_cb (ModestMailOperation *mail_op,
1574 TnyMsg *new_msg = NULL;
1575 ReplyForwardHelper *rf_helper;
1576 ModestWindow *msg_win = NULL;
1577 ModestEditType edit_type;
1579 TnyAccount *account = NULL;
1580 ModestWindowMgr *mgr = NULL;
1581 gchar *signature = NULL;
1582 gboolean use_signature;
1585 /* If there was any error. The mail operation could be NULL,
1586 this means that we already have the message downloaded and
1587 that we didn't do a mail operation to retrieve it */
1588 rf_helper = (ReplyForwardHelper *) user_data;
1589 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1592 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1593 rf_helper->account_name, rf_helper->mailbox);
1594 recipient = modest_text_utils_get_email_address (from);
1595 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1600 /* Create reply mail */
1601 switch (rf_helper->action) {
1602 /* Use the msg_header to ensure that we have all the
1603 information. The summary can lack some data */
1604 TnyHeader *msg_header;
1606 msg_header = tny_msg_get_header (msg);
1608 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1609 (use_signature) ? signature : NULL,
1610 rf_helper->reply_forward_type,
1611 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1612 g_object_unref (msg_header);
1614 case ACTION_REPLY_TO_ALL:
1615 msg_header = tny_msg_get_header (msg);
1617 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1618 (use_signature) ? signature : NULL,
1619 rf_helper->reply_forward_type,
1620 MODEST_TNY_MSG_REPLY_MODE_ALL);
1621 edit_type = MODEST_EDIT_TYPE_REPLY;
1622 g_object_unref (msg_header);
1624 case ACTION_FORWARD:
1626 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1627 rf_helper->reply_forward_type);
1628 edit_type = MODEST_EDIT_TYPE_FORWARD;
1631 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1633 g_return_if_reached ();
1641 g_warning ("%s: failed to create message\n", __FUNCTION__);
1645 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1646 rf_helper->account_name,
1647 TNY_ACCOUNT_TYPE_STORE);
1649 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1653 /* Create and register the windows */
1654 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1655 mgr = modest_runtime_get_window_mgr ();
1656 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1658 /* Note that register_window could have deleted the account */
1659 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1660 gdouble parent_zoom;
1662 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1663 modest_window_set_zoom (msg_win, parent_zoom);
1666 /* Show edit window */
1667 gtk_widget_show_all (GTK_WIDGET (msg_win));
1670 /* We always unregister the header because the message is
1671 forwarded or replied so the original one is no longer
1673 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1676 g_object_unref (G_OBJECT (new_msg));
1678 g_object_unref (G_OBJECT (account));
1679 free_reply_forward_helper (rf_helper);
1682 /* Checks a list of headers. If any of them are not currently
1683 * downloaded (CACHED) then returns TRUE else returns FALSE.
1686 header_list_count_uncached_msgs (TnyList *header_list)
1689 gint uncached_messages = 0;
1691 iter = tny_list_create_iterator (header_list);
1692 while (!tny_iterator_is_done (iter)) {
1695 header = TNY_HEADER (tny_iterator_get_current (iter));
1697 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1698 uncached_messages ++;
1699 g_object_unref (header);
1702 tny_iterator_next (iter);
1704 g_object_unref (iter);
1706 return uncached_messages;
1709 /* Returns FALSE if the user does not want to download the
1710 * messages. Returns TRUE if the user allowed the download.
1713 connect_to_get_msg (ModestWindow *win,
1714 gint num_of_uncached_msgs,
1715 TnyAccount *account)
1717 GtkResponseType response;
1718 GtkWindow *toplevel;
1720 /* Allways download if we are online. */
1721 if (tny_device_is_online (modest_runtime_get_device ()))
1724 /* If offline, then ask for user permission to download the messages */
1725 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1726 response = modest_platform_run_confirmation_dialog (toplevel,
1727 ngettext("mcen_nc_get_msg",
1729 num_of_uncached_msgs));
1731 if (response == GTK_RESPONSE_CANCEL)
1734 return modest_platform_connect_and_wait(toplevel, account);
1738 reply_forward_performer (gboolean canceled,
1740 ModestWindow *parent_window,
1741 TnyAccount *account,
1744 ReplyForwardHelper *rf_helper = NULL;
1745 ModestMailOperation *mail_op;
1747 rf_helper = (ReplyForwardHelper *) user_data;
1749 if (canceled || err) {
1750 free_reply_forward_helper (rf_helper);
1754 /* Retrieve the message */
1755 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1756 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1757 modest_ui_actions_disk_operations_error_handler,
1759 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1760 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1763 g_object_unref(mail_op);
1767 all_parts_retrieved (TnyMimePart *part)
1769 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1772 TnyList *pending_parts;
1773 TnyIterator *iterator;
1774 gboolean all_retrieved = TRUE;
1776 pending_parts = TNY_LIST (tny_simple_list_new ());
1777 tny_mime_part_get_parts (part, pending_parts);
1778 iterator = tny_list_create_iterator (pending_parts);
1779 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1782 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1784 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1785 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1787 all_retrieved = FALSE;
1790 g_object_unref (child);
1791 tny_iterator_next (iterator);
1793 g_object_unref (iterator);
1794 g_object_unref (pending_parts);
1795 return all_retrieved;
1800 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1803 TnyIterator *iterator;
1805 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
1806 tny_list_append (list, G_OBJECT (part));
1808 parts = TNY_LIST (tny_simple_list_new ());
1809 tny_mime_part_get_parts (part, parts);
1810 for (iterator = tny_list_create_iterator (parts);
1811 !tny_iterator_is_done (iterator);
1812 tny_iterator_next (iterator)) {
1815 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1816 forward_pending_parts_helper (child, list);
1817 g_object_unref (child);
1819 g_object_unref (iterator);
1820 g_object_unref (parts);
1824 forward_pending_parts (TnyMsg *msg)
1826 TnyList *result = TNY_LIST (tny_simple_list_new ());
1827 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
1828 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
1835 * Common code for the reply and forward actions
1838 reply_forward (ReplyForwardAction action, ModestWindow *win)
1840 ReplyForwardHelper *rf_helper = NULL;
1841 guint reply_forward_type;
1843 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1845 /* we check for low-mem; in that case, show a warning, and don't allow
1846 * reply/forward (because it could potentially require a lot of memory */
1847 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1851 /* we need an account when editing */
1852 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1853 if (!modest_ui_actions_run_account_setup_wizard (win))
1857 reply_forward_type =
1858 modest_conf_get_int (modest_runtime_get_conf (),
1859 (action == ACTION_FORWARD) ?
1860 MODEST_CONF_FORWARD_TYPE :
1861 MODEST_CONF_REPLY_TYPE,
1864 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1866 TnyHeader *header = NULL;
1867 /* Get header and message. Do not free them here, the
1868 reply_forward_cb must do it */
1869 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1870 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1872 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
1874 rf_helper = create_reply_forward_helper (action, win,
1875 reply_forward_type, header, NULL);
1876 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1878 gboolean do_download = TRUE;
1880 if (msg && header && action == ACTION_FORWARD) {
1881 /* Not all parts retrieved. Then we have to retrieve them all before
1882 * creating the forward message */
1883 if (!tny_device_is_online (modest_runtime_get_device ())) {
1885 GtkWindow *toplevel;
1887 /* If ask for user permission to download the messages */
1888 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1889 response = modest_platform_run_confirmation_dialog (toplevel,
1890 ngettext("mcen_nc_get_msg",
1894 /* End if the user does not want to continue */
1895 if (response == GTK_RESPONSE_CANCEL)
1896 do_download = FALSE;
1900 TnyList *pending_parts;
1902 TnyAccount *account;
1905 pending_parts = forward_pending_parts (msg);
1906 rf_helper = create_reply_forward_helper (action, win,
1907 reply_forward_type, header, pending_parts);
1908 g_object_unref (pending_parts);
1910 folder = tny_header_get_folder (header);
1911 account = tny_folder_get_account (folder);
1912 modest_platform_connect_and_perform (win,
1914 reply_forward_performer,
1916 g_object_unref (folder);
1917 g_object_unref (account);
1921 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1926 g_object_unref (msg);
1928 g_object_unref (header);
1930 TnyHeader *header = NULL;
1932 gboolean do_retrieve = TRUE;
1933 TnyList *header_list = NULL;
1935 header_list = get_selected_headers (win);
1938 /* Check that only one message is selected for replying */
1939 if (tny_list_get_length (header_list) != 1) {
1940 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1941 NULL, _("mcen_ib_select_one_message"));
1942 g_object_unref (header_list);
1946 /* Only reply/forward to one message */
1947 iter = tny_list_create_iterator (header_list);
1948 header = TNY_HEADER (tny_iterator_get_current (iter));
1949 g_object_unref (iter);
1951 /* Retrieve messages */
1952 do_retrieve = (action == ACTION_FORWARD) ||
1953 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1956 TnyAccount *account = NULL;
1957 TnyFolder *folder = NULL;
1958 gdouble download = TRUE;
1959 guint uncached_msgs = 0;
1961 folder = tny_header_get_folder (header);
1963 goto do_retrieve_frees;
1964 account = tny_folder_get_account (folder);
1966 goto do_retrieve_frees;
1968 uncached_msgs = header_list_count_uncached_msgs (header_list);
1970 if (uncached_msgs > 0) {
1971 /* Allways download if we are online. */
1972 if (!tny_device_is_online (modest_runtime_get_device ())) {
1974 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1976 /* If ask for user permission to download the messages */
1977 response = modest_platform_run_confirmation_dialog (toplevel,
1978 ngettext("mcen_nc_get_msg",
1982 /* End if the user does not want to continue */
1983 if (response == GTK_RESPONSE_CANCEL)
1990 rf_helper = create_reply_forward_helper (action, win,
1991 reply_forward_type, header, NULL);
1992 if (uncached_msgs > 0) {
1993 modest_platform_connect_and_perform (win,
1995 reply_forward_performer,
1998 reply_forward_performer (FALSE, NULL, win,
1999 account, rf_helper);
2004 g_object_unref (account);
2006 g_object_unref (folder);
2008 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2011 g_object_unref (header_list);
2012 g_object_unref (header);
2017 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2019 g_return_if_fail (MODEST_IS_WINDOW(win));
2021 reply_forward (ACTION_REPLY, win);
2025 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2027 g_return_if_fail (MODEST_IS_WINDOW(win));
2029 reply_forward (ACTION_FORWARD, win);
2033 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2035 g_return_if_fail (MODEST_IS_WINDOW(win));
2037 reply_forward (ACTION_REPLY_TO_ALL, win);
2041 modest_ui_actions_on_next (GtkAction *action,
2042 ModestWindow *window)
2044 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2045 modest_msg_view_window_select_next_message (
2046 MODEST_MSG_VIEW_WINDOW (window));
2048 g_return_if_reached ();
2053 modest_ui_actions_on_prev (GtkAction *action,
2054 ModestWindow *window)
2056 g_return_if_fail (MODEST_IS_WINDOW(window));
2058 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2059 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2061 g_return_if_reached ();
2066 modest_ui_actions_on_sort (GtkAction *action,
2067 ModestWindow *window)
2069 GtkWidget *header_view = NULL;
2071 g_return_if_fail (MODEST_IS_WINDOW(window));
2073 if (MODEST_IS_HEADER_WINDOW (window)) {
2074 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2078 modest_platform_information_banner (NULL, NULL, _CS_NOTHING_TO_SORT);
2083 /* Show sorting dialog */
2084 modest_utils_run_sort_dialog (MODEST_WINDOW (window), MODEST_SORT_HEADERS);
2088 sync_folder_cb (ModestMailOperation *mail_op,
2092 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2094 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2095 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2097 /* We must clear first, because otherwise set_folder will ignore */
2098 /* the change as the folders are the same */
2099 modest_header_view_clear (header_view);
2100 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2102 g_object_unref (parent);
2105 g_object_unref (header_view);
2109 idle_refresh_folder (gpointer source)
2111 ModestHeaderView *header_view = NULL;
2113 /* If the window still exists */
2114 if (!GTK_IS_WIDGET (source) ||
2115 !GTK_WIDGET_VISIBLE (source))
2118 /* Refresh the current view */
2119 if (MODEST_IS_HEADER_WINDOW (source))
2120 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2122 TnyFolder *folder = modest_header_view_get_folder (header_view);
2124 /* Sync the folder status */
2125 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2126 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2127 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2128 g_object_unref (folder);
2129 g_object_unref (mail_op);
2137 update_account_cb (ModestMailOperation *self,
2138 TnyList *new_headers,
2142 gboolean show_visual_notifications;
2144 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2145 show_visual_notifications = (top) ? FALSE : TRUE;
2147 /* Notify new messages have been downloaded. If the
2148 send&receive was invoked by the user then do not show any
2149 visual notification, only play a sound and activate the LED
2150 (for the Maemo version) */
2151 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2153 /* We only notify about really new messages (not seen) we get */
2154 TnyList *actually_new_list;
2155 TnyIterator *iterator;
2156 actually_new_list = TNY_LIST (tny_simple_list_new ());
2157 for (iterator = tny_list_create_iterator (new_headers);
2158 !tny_iterator_is_done (iterator);
2159 tny_iterator_next (iterator)) {
2161 TnyHeaderFlags flags;
2162 header = TNY_HEADER (tny_iterator_get_current (iterator));
2163 flags = tny_header_get_flags (header);
2165 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2166 /* Messages are ordered from most
2167 recent to oldest. But we want to
2168 show notifications starting from
2169 the oldest message. That's why we
2171 tny_list_prepend (actually_new_list, G_OBJECT (header));
2173 g_object_unref (header);
2175 g_object_unref (iterator);
2177 if (tny_list_get_length (actually_new_list) > 0) {
2178 GList *new_headers_list = NULL;
2180 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2182 /* Send notifications */
2183 if (new_headers_list) {
2184 modest_platform_on_new_headers_received (new_headers_list,
2185 show_visual_notifications);
2187 modest_utils_free_notification_list (new_headers_list);
2190 g_object_unref (actually_new_list);
2194 /* Refresh the current folder in an idle. We do this
2195 in order to avoid refresh cancelations if the
2196 currently viewed folder is the inbox */
2197 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2198 idle_refresh_folder,
2205 TnyAccount *account;
2207 gchar *account_name;
2208 gboolean poke_status;
2209 gboolean interactive;
2210 ModestMailOperation *mail_op;
2214 do_send_receive_performer (gboolean canceled,
2216 ModestWindow *parent_window,
2217 TnyAccount *account,
2220 SendReceiveInfo *info;
2222 info = (SendReceiveInfo *) user_data;
2224 if (err || canceled) {
2225 /* In disk full conditions we could get this error here */
2226 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2227 (GtkWidget *) parent_window, err,
2230 if (info->mail_op) {
2231 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2238 /* Send & receive. */
2239 modest_mail_operation_update_account (info->mail_op, info->account_name,
2240 info->poke_status, info->interactive,
2241 update_account_cb, info->win);
2246 g_object_unref (G_OBJECT (info->mail_op));
2247 if (info->account_name)
2248 g_free (info->account_name);
2250 g_object_unref (info->win);
2252 g_object_unref (info->account);
2253 g_slice_free (SendReceiveInfo, info);
2257 * This function performs the send & receive required actions. The
2258 * window is used to create the mail operation. Typically it should
2259 * always be the main window, but we pass it as argument in order to
2263 modest_ui_actions_do_send_receive (const gchar *account_name,
2264 gboolean force_connection,
2265 gboolean poke_status,
2266 gboolean interactive,
2269 gchar *acc_name = NULL;
2270 SendReceiveInfo *info;
2271 ModestTnyAccountStore *acc_store;
2272 TnyAccount *account;
2274 /* If no account name was provided then get the current account, and if
2275 there is no current account then pick the default one: */
2276 if (!account_name) {
2278 acc_name = g_strdup (modest_window_get_active_account (win));
2280 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2282 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2286 acc_name = g_strdup (account_name);
2289 acc_store = modest_runtime_get_account_store ();
2290 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2294 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2298 /* Do not automatically refresh accounts that are flagged as
2299 NO_AUTO_UPDATE. This could be useful for accounts that
2300 handle their own update times */
2302 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2303 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2304 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2305 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2307 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2308 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2309 g_object_unref (account);
2316 /* Create the info for the connect and perform */
2317 info = g_slice_new (SendReceiveInfo);
2318 info->account_name = acc_name;
2319 info->win = (win) ? g_object_ref (win) : NULL;
2320 info->poke_status = poke_status;
2321 info->interactive = interactive;
2322 info->account = account;
2323 /* We need to create the operation here, because otherwise it
2324 could happen that the queue emits the queue-empty signal
2325 while we're trying to connect the account */
2326 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2327 modest_ui_actions_disk_operations_error_handler,
2329 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2331 /* Invoke the connect and perform */
2332 modest_platform_connect_and_perform (win, force_connection, info->account,
2333 do_send_receive_performer, info);
2338 modest_ui_actions_do_cancel_send (const gchar *account_name,
2341 TnyTransportAccount *transport_account;
2342 TnySendQueue *send_queue = NULL;
2343 GError *error = NULL;
2345 /* Get transport account */
2347 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2348 (modest_runtime_get_account_store(),
2350 TNY_ACCOUNT_TYPE_TRANSPORT));
2351 if (!transport_account) {
2352 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2357 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2358 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2359 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2360 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2361 "modest: could not find send queue for account\n");
2363 /* Cancel the current send */
2364 tny_account_cancel (TNY_ACCOUNT (transport_account));
2366 /* Suspend all pending messages */
2367 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2371 if (transport_account != NULL)
2372 g_object_unref (G_OBJECT (transport_account));
2376 modest_ui_actions_cancel_send_all (ModestWindow *win)
2378 GSList *account_names, *iter;
2380 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2383 iter = account_names;
2385 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2386 iter = g_slist_next (iter);
2389 modest_account_mgr_free_account_names (account_names);
2390 account_names = NULL;
2394 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2397 /* Check if accounts exist */
2398 gboolean accounts_exist =
2399 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2401 /* If not, allow the user to create an account before trying to send/receive. */
2402 if (!accounts_exist)
2403 modest_ui_actions_on_accounts (NULL, win);
2405 /* Cancel all sending operaitons */
2406 modest_ui_actions_cancel_send_all (win);
2410 * Refreshes all accounts. This function will be used by automatic
2414 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2415 gboolean force_connection,
2416 gboolean poke_status,
2417 gboolean interactive)
2419 GSList *account_names, *iter;
2421 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2424 iter = account_names;
2426 modest_ui_actions_do_send_receive ((const char*) iter->data,
2428 poke_status, interactive, win);
2429 iter = g_slist_next (iter);
2432 modest_account_mgr_free_account_names (account_names);
2433 account_names = NULL;
2437 * Handler of the click on Send&Receive button in the main toolbar
2440 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2442 /* Check if accounts exist */
2443 gboolean accounts_exist;
2446 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2448 /* If not, allow the user to create an account before trying to send/receive. */
2449 if (!accounts_exist)
2450 modest_ui_actions_on_accounts (NULL, win);
2452 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2453 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2454 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2456 const gchar *active_account;
2457 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2459 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2466 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2469 ModestWindow *window)
2471 GtkTreeRowReference *rowref;
2473 g_return_if_fail (MODEST_IS_WINDOW(window));
2474 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2475 g_return_if_fail (TNY_IS_HEADER (header));
2477 if (modest_header_view_count_selected_headers (header_view) > 1) {
2478 /* Don't allow activation if there are more than one message selected */
2479 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2483 /* we check for low-mem; in that case, show a warning, and don't allow
2484 * activating headers
2486 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2490 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2491 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2492 gtk_tree_row_reference_free (rowref);
2496 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2502 GtkWindow *toplevel;
2504 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
2505 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2507 online = tny_device_is_online (modest_runtime_get_device());
2510 /* already online -- the item is simply not there... */
2511 dialog = gtk_message_dialog_new (toplevel,
2513 GTK_MESSAGE_WARNING,
2515 _("The %s you selected cannot be found"),
2517 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2518 gtk_dialog_run (GTK_DIALOG(dialog));
2520 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2523 _("mcen_bd_dialog_cancel"),
2524 GTK_RESPONSE_REJECT,
2525 _("mcen_bd_dialog_ok"),
2526 GTK_RESPONSE_ACCEPT,
2528 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2529 "Do you want to get online?"), item);
2530 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2531 gtk_label_new (txt), FALSE, FALSE, 0);
2532 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2535 gtk_window_set_default_size ((GtkWindow *) dialog, 300, 300);
2536 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2537 /* TODO: Comment about why is this commented out: */
2538 /* modest_platform_connect_and_wait (); */
2541 gtk_widget_destroy (dialog);
2545 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2548 /* g_debug ("%s %s", __FUNCTION__, link); */
2553 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2556 modest_platform_activate_uri (link);
2560 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2563 modest_platform_show_uri_popup (link);
2567 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2570 /* we check for low-mem; in that case, show a warning, and don't allow
2571 * viewing attachments
2573 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2576 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2580 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2581 const gchar *address,
2584 /* g_debug ("%s %s", __FUNCTION__, address); */
2588 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2589 TnyMsg *saved_draft,
2592 ModestMsgEditWindow *edit_window;
2594 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2596 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2598 /* Set draft is there was no error */
2599 if (!modest_mail_operation_get_error (mail_op))
2600 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2602 g_object_unref(edit_window);
2606 enough_space_for_message (ModestMsgEditWindow *edit_window,
2609 guint64 available_disk, expected_size;
2614 available_disk = modest_utils_get_available_space (NULL);
2615 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2616 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2621 /* Double check: disk full condition or message too big */
2622 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2623 expected_size > available_disk) {
2624 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2625 modest_platform_information_banner (NULL, NULL, msg);
2632 * djcb: if we're in low-memory state, we only allow for
2633 * saving messages smaller than
2634 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2635 * should still allow for sending anything critical...
2637 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2638 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2642 * djcb: we also make sure that the attachments are smaller than the max size
2643 * this is for the case where we'd try to forward a message with attachments
2644 * bigger than our max allowed size, or sending an message from drafts which
2645 * somehow got past our checks when attaching.
2647 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2648 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) edit_window);
2649 modest_platform_run_information_dialog (toplevel,
2650 _("mail_ib_error_attachment_size"),
2659 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2661 TnyTransportAccount *transport_account;
2662 ModestMailOperation *mail_operation;
2664 gchar *account_name;
2665 ModestAccountMgr *account_mgr;
2666 gboolean had_error = FALSE;
2668 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2670 data = modest_msg_edit_window_get_msg_data (edit_window);
2673 if (!enough_space_for_message (edit_window, data)) {
2674 modest_msg_edit_window_free_msg_data (edit_window, data);
2678 account_name = g_strdup (data->account_name);
2679 account_mgr = modest_runtime_get_account_mgr();
2681 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2683 account_name = modest_account_mgr_get_default_account (account_mgr);
2684 if (!account_name) {
2685 g_printerr ("modest: no account found\n");
2686 modest_msg_edit_window_free_msg_data (edit_window, data);
2690 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2691 account_name = g_strdup (data->account_name);
2695 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2696 (modest_runtime_get_account_store (),
2698 TNY_ACCOUNT_TYPE_TRANSPORT));
2699 if (!transport_account) {
2700 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2701 g_free (account_name);
2702 modest_msg_edit_window_free_msg_data (edit_window, data);
2706 /* Create the mail operation */
2707 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2709 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2711 modest_mail_operation_save_to_drafts (mail_operation,
2723 data->priority_flags,
2726 on_save_to_drafts_cb,
2727 g_object_ref(edit_window));
2729 /* In hildon2 we always show the information banner on saving to drafts.
2730 * It will be a system information banner in this case.
2732 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2733 modest_platform_information_banner (NULL, NULL, text);
2735 modest_msg_edit_window_set_modified (edit_window, FALSE);
2738 g_free (account_name);
2739 g_object_unref (G_OBJECT (transport_account));
2740 g_object_unref (G_OBJECT (mail_operation));
2742 modest_msg_edit_window_free_msg_data (edit_window, data);
2748 /* For instance, when clicking the Send toolbar button when editing a message: */
2750 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2752 TnyTransportAccount *transport_account = NULL;
2753 gboolean had_error = FALSE, add_to_contacts;
2755 ModestAccountMgr *account_mgr;
2756 gchar *account_name;
2757 ModestMailOperation *mail_operation;
2760 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2762 /* Check whether to automatically add new contacts to addressbook or not */
2763 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
2764 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
2765 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
2768 data = modest_msg_edit_window_get_msg_data (edit_window);
2770 recipients = g_strconcat (data->to?data->to:"",
2771 data->cc?data->cc:"",
2772 data->bcc?data->bcc:"",
2774 if (recipients == NULL || recipients[0] == '\0') {
2775 /* Empty subject -> no send */
2776 g_free (recipients);
2777 modest_msg_edit_window_free_msg_data (edit_window, data);
2780 g_free (recipients);
2783 if (!enough_space_for_message (edit_window, data)) {
2784 modest_msg_edit_window_free_msg_data (edit_window, data);
2788 account_mgr = modest_runtime_get_account_mgr();
2789 account_name = g_strdup (data->account_name);
2791 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2794 account_name = modest_account_mgr_get_default_account (account_mgr);
2796 if (!account_name) {
2797 modest_msg_edit_window_free_msg_data (edit_window, data);
2798 /* Run account setup wizard */
2799 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2804 /* Get the currently-active transport account for this modest account: */
2805 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2807 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2808 (modest_runtime_get_account_store (),
2809 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2812 if (!transport_account) {
2813 modest_msg_edit_window_free_msg_data (edit_window, data);
2814 /* Run account setup wizard */
2815 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2820 /* Create the mail operation */
2821 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2822 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2824 modest_mail_operation_send_new_mail (mail_operation,
2838 data->priority_flags);
2840 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2841 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2843 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2844 const GError *error = modest_mail_operation_get_error (mail_operation);
2845 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2846 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2847 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2848 modest_platform_information_banner (NULL, NULL, _CS_NOT_ENOUGH_MEMORY);
2854 g_free (account_name);
2855 g_object_unref (G_OBJECT (transport_account));
2856 g_object_unref (G_OBJECT (mail_operation));
2858 modest_msg_edit_window_free_msg_data (edit_window, data);
2861 modest_msg_edit_window_set_sent (edit_window, TRUE);
2863 /* Save settings and close the window: */
2864 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2871 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2872 ModestMsgEditWindow *window)
2874 ModestMsgEditFormatState *format_state = NULL;
2876 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2877 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2879 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2882 format_state = modest_msg_edit_window_get_format_state (window);
2883 g_return_if_fail (format_state != NULL);
2885 format_state->bold = gtk_toggle_action_get_active (action);
2886 modest_msg_edit_window_set_format_state (window, format_state);
2887 g_free (format_state);
2892 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2893 ModestMsgEditWindow *window)
2895 ModestMsgEditFormatState *format_state = NULL;
2897 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2898 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2900 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2903 format_state = modest_msg_edit_window_get_format_state (window);
2904 g_return_if_fail (format_state != NULL);
2906 format_state->italics = gtk_toggle_action_get_active (action);
2907 modest_msg_edit_window_set_format_state (window, format_state);
2908 g_free (format_state);
2913 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2914 ModestMsgEditWindow *window)
2916 ModestMsgEditFormatState *format_state = NULL;
2918 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2919 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2921 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2924 format_state = modest_msg_edit_window_get_format_state (window);
2925 g_return_if_fail (format_state != NULL);
2927 format_state->bullet = gtk_toggle_action_get_active (action);
2928 modest_msg_edit_window_set_format_state (window, format_state);
2929 g_free (format_state);
2934 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2935 GtkRadioAction *selected,
2936 ModestMsgEditWindow *window)
2938 ModestMsgEditFormatState *format_state = NULL;
2939 GtkJustification value;
2941 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2943 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2946 value = gtk_radio_action_get_current_value (selected);
2948 format_state = modest_msg_edit_window_get_format_state (window);
2949 g_return_if_fail (format_state != NULL);
2951 format_state->justification = value;
2952 modest_msg_edit_window_set_format_state (window, format_state);
2953 g_free (format_state);
2957 modest_ui_actions_on_select_editor_color (GtkAction *action,
2958 ModestMsgEditWindow *window)
2960 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2961 g_return_if_fail (GTK_IS_ACTION (action));
2963 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2966 modest_msg_edit_window_select_color (window);
2970 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2971 ModestMsgEditWindow *window)
2973 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2974 g_return_if_fail (GTK_IS_ACTION (action));
2976 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2982 modest_ui_actions_on_insert_image (GObject *object,
2983 ModestMsgEditWindow *window)
2985 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2988 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2991 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2994 modest_msg_edit_window_insert_image (window);
2998 modest_ui_actions_on_attach_file (GtkAction *action,
2999 ModestMsgEditWindow *window)
3001 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3002 g_return_if_fail (GTK_IS_ACTION (action));
3004 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3007 modest_msg_edit_window_offer_attach_file (window);
3011 modest_ui_actions_on_remove_attachments (GtkAction *action,
3012 ModestMsgEditWindow *window)
3014 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3016 modest_msg_edit_window_remove_attachments (window, NULL);
3020 do_create_folder_cb (ModestMailOperation *mail_op,
3021 TnyFolderStore *parent_folder,
3022 TnyFolder *new_folder,
3025 gchar *suggested_name = (gchar *) user_data;
3026 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3027 const GError *error;
3029 error = modest_mail_operation_get_error (mail_op);
3031 gboolean disk_full = FALSE;
3032 TnyAccount *account;
3033 /* Show an error. If there was some problem writing to
3034 disk, show it, otherwise show the generic folder
3035 create error. We do it here and not in an error
3036 handler because the call to do_create_folder will
3037 stop the main loop in a gtk_dialog_run and then,
3038 the message won't be shown until that dialog is
3040 account = modest_mail_operation_get_account (mail_op);
3043 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3044 (GtkWidget *) source_win,
3047 _("mail_in_ui_folder_create_error_memory"));
3048 g_object_unref (account);
3051 /* Show an error and try again if there is no
3052 full memory condition */
3053 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3054 _("mail_in_ui_folder_create_error"));
3055 do_create_folder ((ModestWindow *) source_win,
3056 parent_folder, (const gchar *) suggested_name);
3060 /* the 'source_win' is either the ModestWindow, or the 'Move to folder'-dialog
3061 * FIXME: any other? */
3062 GtkWidget *folder_view;
3064 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3065 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3067 /* Select the newly created folder. It could happen
3068 that the widget is no longer there (i.e. the window
3069 has been destroyed, so we need to check this */
3071 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3073 g_object_unref (new_folder);
3075 /* Free. Note that the first time it'll be NULL so noop */
3076 g_free (suggested_name);
3077 g_object_unref (source_win);
3082 TnyFolderStore *parent;
3083 } CreateFolderConnect;
3086 do_create_folder_performer (gboolean canceled,
3088 ModestWindow *parent_window,
3089 TnyAccount *account,
3092 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3093 ModestMailOperation *mail_op;
3095 if (canceled || err) {
3096 /* In disk full conditions we could get this error here */
3097 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3098 (GtkWidget *) parent_window, err,
3099 NULL, _("mail_in_ui_folder_create_error_memory"));
3101 /* This happens if we have selected the outbox folder
3103 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3104 TNY_IS_MERGE_FOLDER (helper->parent)) {
3105 /* Show an error and retry */
3106 modest_platform_information_banner ((GtkWidget *) parent_window,
3108 _("mail_in_ui_folder_create_error"));
3110 do_create_folder (parent_window, helper->parent, helper->folder_name);
3116 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3117 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3119 modest_mail_operation_create_folder (mail_op,
3121 (const gchar *) helper->folder_name,
3122 do_create_folder_cb,
3123 g_strdup (helper->folder_name));
3124 g_object_unref (mail_op);
3128 g_object_unref (helper->parent);
3129 if (helper->folder_name)
3130 g_free (helper->folder_name);
3131 g_slice_free (CreateFolderConnect, helper);
3136 do_create_folder (ModestWindow *parent_window,
3137 TnyFolderStore *suggested_parent,
3138 const gchar *suggested_name)
3141 gchar *folder_name = NULL;
3142 TnyFolderStore *parent_folder = NULL;
3143 GtkWindow *toplevel;
3145 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
3146 result = modest_platform_run_new_folder_dialog (toplevel,
3148 (gchar *) suggested_name,
3152 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3153 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3154 helper->folder_name = g_strdup (folder_name);
3155 helper->parent = g_object_ref (parent_folder);
3157 modest_platform_connect_if_remote_and_perform (parent_window,
3160 do_create_folder_performer,
3165 g_free (folder_name);
3167 g_object_unref (parent_folder);
3171 modest_ui_actions_create_folder(GtkWindow *parent_window,
3172 GtkWidget *folder_view,
3173 TnyFolderStore *parent_folder)
3175 if (!parent_folder) {
3176 ModestTnyAccountStore *acc_store;
3178 acc_store = modest_runtime_get_account_store ();
3180 parent_folder = (TnyFolderStore *)
3181 modest_tny_account_store_get_local_folders_account (acc_store);
3184 if (parent_folder) {
3185 do_create_folder (MODEST_WINDOW (parent_window), parent_folder, NULL);
3186 g_object_unref (parent_folder);
3191 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3194 g_return_if_fail (MODEST_IS_WINDOW(window));
3196 if (MODEST_IS_FOLDER_WINDOW (window)) {
3197 GtkWidget *folder_view;
3198 GtkWindow *toplevel;
3200 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3201 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
3202 modest_ui_actions_create_folder (toplevel, folder_view, NULL);
3204 g_assert_not_reached ();
3209 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3212 const GError *error = NULL;
3213 gchar *message = NULL;
3215 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3217 /* Get error message */
3218 error = modest_mail_operation_get_error (mail_op);
3220 g_return_if_reached ();
3222 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3223 (GError *) error, account);
3225 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3226 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3227 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3228 message = _CS_FOLDER_ALREADY_EXISTS;
3229 } else if (error->domain == TNY_ERROR_DOMAIN &&
3230 error->code == TNY_SERVICE_ERROR_STATE) {
3231 /* This means that the folder is already in use (a
3232 message is opened for example */
3233 message = _("emev_ni_internal_error");
3235 message = _CS_UNABLE_TO_RENAME;
3238 /* We don't set a parent for the dialog because the dialog
3239 will be destroyed so the banner won't appear */
3240 modest_platform_information_banner (NULL, NULL, message);
3243 g_object_unref (account);
3249 TnyFolderStore *folder;
3254 on_rename_folder_cb (ModestMailOperation *mail_op,
3255 TnyFolder *new_folder,
3258 ModestFolderView *folder_view;
3260 /* If the window was closed when renaming a folder, or if
3261 * it's not a main window this will happen */
3262 if (!MODEST_IS_FOLDER_VIEW (user_data))
3265 folder_view = MODEST_FOLDER_VIEW (user_data);
3266 /* Note that if the rename fails new_folder will be NULL */
3268 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3270 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3274 on_rename_folder_performer (gboolean canceled,
3276 ModestWindow *parent_window,
3277 TnyAccount *account,
3280 ModestMailOperation *mail_op = NULL;
3281 GtkTreeSelection *sel = NULL;
3282 GtkWidget *folder_view = NULL;
3283 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3285 if (canceled || err) {
3286 /* In disk full conditions we could get this error here */
3287 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3288 (GtkWidget *) parent_window, err,
3293 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3294 modest_ui_actions_rename_folder_error_handler,
3295 parent_window, NULL);
3297 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3299 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3300 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3301 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3304 /* Clear the folders view */
3305 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3306 gtk_tree_selection_unselect_all (sel);
3308 /* Actually rename the folder */
3309 modest_mail_operation_rename_folder (mail_op,
3310 TNY_FOLDER (data->folder),
3311 (const gchar *) (data->new_name),
3312 on_rename_folder_cb,
3314 g_object_unref (mail_op);
3317 g_object_unref (data->folder);
3318 g_free (data->new_name);
3323 modest_ui_actions_on_rename_folder (GtkAction *action,
3324 ModestWindow *window)
3326 modest_ui_actions_on_edit_mode_rename_folder (window);
3330 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3332 TnyFolderStore *folder;
3333 GtkWidget *folder_view;
3334 gboolean do_rename = TRUE;
3336 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3338 if (MODEST_IS_FOLDER_WINDOW (window)) {
3339 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3344 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3349 if (TNY_IS_FOLDER (folder)) {
3350 gchar *folder_name = NULL;
3352 const gchar *current_name;
3353 TnyFolderStore *parent;
3355 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3356 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3357 response = modest_platform_run_rename_folder_dialog (MODEST_WINDOW (window),
3358 parent, current_name,
3360 g_object_unref (parent);
3362 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3365 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3366 rename_folder_data->folder = g_object_ref (folder);
3367 rename_folder_data->new_name = folder_name;
3368 modest_platform_connect_if_remote_and_perform (window, TRUE,
3369 folder, on_rename_folder_performer, rename_folder_data);
3372 g_object_unref (folder);
3377 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3380 GObject *win = modest_mail_operation_get_source (mail_op);
3381 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
3383 modest_platform_run_information_dialog (toplevel,
3384 _("mail_in_ui_folder_delete_error"),
3386 g_object_unref (win);
3390 TnyFolderStore *folder;
3391 gboolean move_to_trash;
3395 on_delete_folder_cb (gboolean canceled,
3397 ModestWindow *parent_window,
3398 TnyAccount *account,
3401 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3402 GtkWidget *folder_view;
3403 ModestMailOperation *mail_op;
3404 GtkTreeSelection *sel;
3405 ModestWindow *modest_window;
3407 #ifdef MODEST_TOOLKIT_HILDON2
3408 modest_window = (ModestWindow*) parent_window;
3410 if (MODEST_IS_SHELL (parent_window)) {
3411 modest_window = modest_shell_peek_window (MODEST_SHELL (parent_window));
3413 modest_window = NULL;
3417 if (!MODEST_IS_WINDOW(modest_window) || canceled || (err!=NULL)) {
3418 /* Note that the connection process can fail due to
3419 memory low conditions as it can not successfully
3420 store the summary */
3421 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3422 (GtkWidget*) parent_window, err,
3424 g_debug ("Error connecting when trying to delete a folder");
3425 g_object_unref (G_OBJECT (info->folder));
3430 if (MODEST_IS_FOLDER_WINDOW (modest_window)) {
3431 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (modest_window)));
3433 g_object_unref (G_OBJECT (info->folder));
3438 /* Unselect the folder before deleting it to free the headers */
3439 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3440 gtk_tree_selection_unselect_all (sel);
3442 /* Create the mail operation */
3444 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3445 modest_ui_actions_delete_folder_error_handler,
3448 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3450 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3452 g_object_unref (mail_op);
3453 g_object_unref (info->folder);
3458 delete_folder (ModestWindow *window, gboolean move_to_trash)
3460 TnyFolderStore *folder;
3461 GtkWidget *folder_view;
3465 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3467 if (MODEST_IS_FOLDER_WINDOW (window)) {
3468 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3475 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3480 /* Show an error if it's an account */
3481 if (!TNY_IS_FOLDER (folder)) {
3482 modest_platform_run_information_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3483 _("mail_in_ui_folder_delete_error"),
3485 g_object_unref (G_OBJECT (folder));
3490 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3491 tny_folder_get_name (TNY_FOLDER (folder)));
3492 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3493 (const gchar *) message);
3496 if (response == GTK_RESPONSE_OK) {
3497 TnyAccount *account = NULL;
3498 DeleteFolderInfo *info = NULL;
3499 info = g_new0(DeleteFolderInfo, 1);
3500 info->folder = g_object_ref (folder);
3501 info->move_to_trash = move_to_trash;
3503 account = tny_folder_get_account (TNY_FOLDER (folder));
3504 modest_platform_connect_if_remote_and_perform (window,
3506 TNY_FOLDER_STORE (account),
3507 on_delete_folder_cb, info);
3508 g_object_unref (account);
3509 g_object_unref (folder);
3517 modest_ui_actions_on_delete_folder (GtkAction *action,
3518 ModestWindow *window)
3520 modest_ui_actions_on_edit_mode_delete_folder (window);
3524 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3526 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3528 return delete_folder (window, FALSE);
3532 typedef struct _PasswordDialogFields {
3533 GtkWidget *username;
3534 GtkWidget *password;
3536 } PasswordDialogFields;
3539 password_dialog_check_field (GtkEditable *editable,
3540 PasswordDialogFields *fields)
3543 gboolean any_value_empty = FALSE;
3545 value = modest_entry_get_text (fields->username);
3546 if ((value == NULL) || value[0] == '\0') {
3547 any_value_empty = TRUE;
3549 value = modest_entry_get_text (fields->password);
3550 if ((value == NULL) || value[0] == '\0') {
3551 any_value_empty = TRUE;
3553 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3557 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3558 const gchar* server_account_name,
3563 ModestWindow *window)
3565 g_return_if_fail(server_account_name);
3566 gboolean completed = FALSE;
3567 PasswordDialogFields *fields = NULL;
3569 /* Initalize output parameters: */
3576 #ifndef MODEST_TOOLKIT_GTK
3577 /* Maemo uses a different (awkward) button order,
3578 * It should probably just use gtk_alternative_dialog_button_order ().
3580 #ifdef MODEST_TOOLKIT_HILDON2
3582 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3586 GTK_RESPONSE_ACCEPT,
3588 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3589 HILDON_MARGIN_DOUBLE);
3592 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3595 _("mcen_bd_dialog_ok"),
3596 GTK_RESPONSE_ACCEPT,
3597 _("mcen_bd_dialog_cancel"),
3598 GTK_RESPONSE_REJECT,
3600 #endif /* MODEST_TOOLKIT_HILDON2 */
3603 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3607 GTK_RESPONSE_REJECT,
3609 GTK_RESPONSE_ACCEPT,
3611 #endif /* MODEST_TOOLKIT_GTK */
3613 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3615 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3616 modest_runtime_get_account_mgr(), server_account_name);
3617 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3618 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3621 gtk_widget_destroy (dialog);
3625 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3626 GtkWidget *label = gtk_label_new (txt);
3627 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3629 g_free (server_name);
3630 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3635 gchar *initial_username = modest_account_mgr_get_server_account_username (
3636 modest_runtime_get_account_mgr(), server_account_name);
3638 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3639 if (initial_username)
3640 modest_entry_set_text (entry_username, initial_username);
3642 /* Dim this if a connection has ever succeeded with this username,
3643 * as per the UI spec: */
3644 /* const gboolean username_known = */
3645 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3646 /* modest_runtime_get_account_mgr(), server_account_name); */
3647 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3649 /* We drop the username sensitive code and disallow changing it here
3650 * as tinymail does not support really changing the username in the callback
3652 gtk_widget_set_sensitive (entry_username, FALSE);
3654 /* Auto-capitalization is the default, so let's turn it off: */
3655 #ifdef MAEMO_CHANGES
3656 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3659 /* Create a size group to be used by all captions.
3660 * Note that HildonCaption does not create a default size group if we do not specify one.
3661 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3662 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3664 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3665 _("mail_fi_username"), FALSE,
3667 gtk_widget_show (entry_username);
3668 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3669 FALSE, FALSE, MODEST_MARGIN_HALF);
3670 gtk_widget_show (caption);
3673 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3674 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3675 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3677 /* Auto-capitalization is the default, so let's turn it off: */
3678 #ifdef MAEMO_CHANGES
3679 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3680 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3683 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3684 _("mail_fi_password"), FALSE,
3686 gtk_widget_show (entry_password);
3687 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3688 FALSE, FALSE, MODEST_MARGIN_HALF);
3689 gtk_widget_show (caption);
3690 g_object_unref (sizegroup);
3692 if (initial_username != NULL)
3693 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3695 /* This is not in the Maemo UI spec:
3696 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3697 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3701 fields = g_slice_new0 (PasswordDialogFields);
3702 fields->username = entry_username;
3703 fields->password = entry_password;
3704 fields->dialog = dialog;
3706 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3707 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3708 password_dialog_check_field (NULL, fields);
3710 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3712 while (!completed) {
3714 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3716 *username = g_strdup (modest_entry_get_text (entry_username));
3718 /* Note that an empty field becomes the "" string */
3719 if (*username && strlen (*username) > 0) {
3720 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3721 server_account_name,
3725 const gboolean username_was_changed =
3726 (strcmp (*username, initial_username) != 0);
3727 if (username_was_changed) {
3728 g_warning ("%s: tinymail does not yet support changing the "
3729 "username in the get_password() callback.\n", __FUNCTION__);
3735 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3736 _("mcen_ib_username_pw_incorrect"));
3742 *password = g_strdup (modest_entry_get_text (entry_password));
3744 /* We do not save the password in the configuration,
3745 * because this function is only called for passwords that should
3746 * not be remembered:
3747 modest_server_account_set_password (
3748 modest_runtime_get_account_mgr(), server_account_name,
3765 /* This is not in the Maemo UI spec:
3766 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3772 g_free (initial_username);
3773 gtk_widget_destroy (dialog);
3774 g_slice_free (PasswordDialogFields, fields);
3776 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3780 modest_ui_actions_on_cut (GtkAction *action,
3781 ModestWindow *window)
3783 GtkWidget *focused_widget;
3784 GtkClipboard *clipboard;
3786 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3787 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3788 if (GTK_IS_EDITABLE (focused_widget)) {
3789 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3790 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3791 gtk_clipboard_store (clipboard);
3792 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3793 GtkTextBuffer *buffer;
3795 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3796 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3797 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3798 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3799 gtk_clipboard_store (clipboard);
3801 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3802 TnyList *header_list = modest_header_view_get_selected_headers (
3803 MODEST_HEADER_VIEW (focused_widget));
3804 gboolean continue_download = FALSE;
3805 gint num_of_unc_msgs;
3807 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3809 if (num_of_unc_msgs) {
3810 TnyAccount *account = get_account_from_header_list (header_list);
3812 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3813 g_object_unref (account);
3817 if (num_of_unc_msgs == 0 || continue_download) {
3818 /* modest_platform_information_banner (
3819 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3820 modest_header_view_cut_selection (
3821 MODEST_HEADER_VIEW (focused_widget));
3824 g_object_unref (header_list);
3825 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3826 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3831 modest_ui_actions_on_copy (GtkAction *action,
3832 ModestWindow *window)
3834 GtkClipboard *clipboard;
3835 GtkWidget *focused_widget;
3836 gboolean copied = TRUE;
3838 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3839 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3841 if (GTK_IS_LABEL (focused_widget)) {
3843 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3844 gtk_clipboard_set_text (clipboard, selection, -1);
3846 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3847 gtk_clipboard_store (clipboard);
3848 } else if (GTK_IS_EDITABLE (focused_widget)) {
3849 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3850 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3851 gtk_clipboard_store (clipboard);
3852 } else if (GTK_IS_HTML (focused_widget)) {
3855 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3856 if ((sel == NULL) || (sel[0] == '\0')) {
3859 gtk_html_copy (GTK_HTML (focused_widget));
3860 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3861 gtk_clipboard_store (clipboard);
3863 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3864 GtkTextBuffer *buffer;
3865 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3866 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3867 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3868 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3869 gtk_clipboard_store (clipboard);
3871 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3872 TnyList *header_list = modest_header_view_get_selected_headers (
3873 MODEST_HEADER_VIEW (focused_widget));
3874 gboolean continue_download = FALSE;
3875 gint num_of_unc_msgs;
3877 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3879 if (num_of_unc_msgs) {
3880 TnyAccount *account = get_account_from_header_list (header_list);
3882 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3883 g_object_unref (account);
3887 if (num_of_unc_msgs == 0 || continue_download) {
3888 modest_platform_information_banner (
3889 NULL, NULL, _CS_GETTING_ITEMS);
3890 modest_header_view_copy_selection (
3891 MODEST_HEADER_VIEW (focused_widget));
3895 g_object_unref (header_list);
3897 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3898 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3901 /* Show information banner if there was a copy to clipboard */
3903 modest_platform_information_banner (
3904 NULL, NULL, _CS_COPIED);
3908 modest_ui_actions_on_undo (GtkAction *action,
3909 ModestWindow *window)
3911 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3912 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3914 g_return_if_reached ();
3919 modest_ui_actions_on_redo (GtkAction *action,
3920 ModestWindow *window)
3922 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3923 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3926 g_return_if_reached ();
3932 destroy_information_note (ModestMailOperation *mail_op,
3935 /* destroy information note */
3936 gtk_widget_destroy (GTK_WIDGET(user_data));
3940 destroy_folder_information_note (ModestMailOperation *mail_op,
3941 TnyFolder *new_folder,
3944 /* destroy information note */
3945 gtk_widget_destroy (GTK_WIDGET(user_data));
3950 paste_as_attachment_free (gpointer data)
3952 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3954 if (helper->banner) {
3955 gtk_widget_destroy (helper->banner);
3956 g_object_unref (helper->banner);
3962 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3967 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3968 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3973 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3978 modest_ui_actions_on_paste (GtkAction *action,
3979 ModestWindow *window)
3981 GtkWidget *focused_widget = NULL;
3982 GtkWidget *inf_note = NULL;
3983 ModestMailOperation *mail_op = NULL;
3985 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3986 if (GTK_IS_EDITABLE (focused_widget)) {
3987 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3988 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3989 ModestEmailClipboard *e_clipboard = NULL;
3990 e_clipboard = modest_runtime_get_email_clipboard ();
3991 if (modest_email_clipboard_cleared (e_clipboard)) {
3992 GtkTextBuffer *buffer;
3993 GtkClipboard *clipboard;
3995 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3996 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3997 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3998 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3999 ModestMailOperation *mail_op;
4000 TnyFolder *src_folder = NULL;
4001 TnyList *data = NULL;
4003 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4004 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4005 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4007 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4008 mail_op = modest_mail_operation_new (G_OBJECT (window));
4009 if (helper->banner != NULL) {
4010 g_object_ref (G_OBJECT (helper->banner));
4011 gtk_widget_show (GTK_WIDGET (helper->banner));
4015 modest_mail_operation_get_msgs_full (mail_op,
4017 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4019 paste_as_attachment_free);
4023 g_object_unref (data);
4025 g_object_unref (src_folder);
4028 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4029 ModestEmailClipboard *clipboard = NULL;
4030 TnyFolder *src_folder = NULL;
4031 TnyFolderStore *folder_store = NULL;
4032 TnyList *data = NULL;
4033 gboolean delete = FALSE;
4035 /* Check clipboard source */
4036 clipboard = modest_runtime_get_email_clipboard ();
4037 if (modest_email_clipboard_cleared (clipboard))
4040 /* Get elements to paste */
4041 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4043 /* Create a new mail operation */
4044 mail_op = modest_mail_operation_new (G_OBJECT(window));
4046 /* Get destination folder */
4047 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4049 /* transfer messages */
4053 /* Ask for user confirmation */
4055 modest_ui_actions_msgs_move_to_confirmation (window,
4056 TNY_FOLDER (folder_store),
4060 if (response == GTK_RESPONSE_OK) {
4061 /* Launch notification */
4062 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4064 if (inf_note != NULL) {
4065 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4066 gtk_widget_show (GTK_WIDGET(inf_note));
4069 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4070 modest_mail_operation_xfer_msgs (mail_op,
4072 TNY_FOLDER (folder_store),
4074 destroy_information_note,
4077 g_object_unref (mail_op);
4080 } else if (src_folder != NULL) {
4081 /* Launch notification */
4082 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4084 if (inf_note != NULL) {
4085 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4086 gtk_widget_show (GTK_WIDGET(inf_note));
4089 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4090 modest_mail_operation_xfer_folder (mail_op,
4094 destroy_folder_information_note,
4100 g_object_unref (data);
4101 if (src_folder != NULL)
4102 g_object_unref (src_folder);
4103 if (folder_store != NULL)
4104 g_object_unref (folder_store);
4110 modest_ui_actions_on_select_all (GtkAction *action,
4111 ModestWindow *window)
4113 GtkWidget *focused_widget;
4115 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4116 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4117 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4118 } else if (GTK_IS_LABEL (focused_widget)) {
4119 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4120 } else if (GTK_IS_EDITABLE (focused_widget)) {
4121 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4122 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4123 GtkTextBuffer *buffer;
4124 GtkTextIter start, end;
4126 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4127 gtk_text_buffer_get_start_iter (buffer, &start);
4128 gtk_text_buffer_get_end_iter (buffer, &end);
4129 gtk_text_buffer_select_range (buffer, &start, &end);
4130 } else if (GTK_IS_HTML (focused_widget)) {
4131 gtk_html_select_all (GTK_HTML (focused_widget));
4137 modest_ui_actions_on_mark_as_read (GtkAction *action,
4138 ModestWindow *window)
4140 g_return_if_fail (MODEST_IS_WINDOW(window));
4142 /* Mark each header as read */
4143 do_headers_action (window, headers_action_mark_as_read, NULL);
4147 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4148 ModestWindow *window)
4150 g_return_if_fail (MODEST_IS_WINDOW(window));
4152 /* Mark each header as read */
4153 do_headers_action (window, headers_action_mark_as_unread, NULL);
4157 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4158 GtkRadioAction *selected,
4159 ModestWindow *window)
4163 value = gtk_radio_action_get_current_value (selected);
4164 if (MODEST_IS_WINDOW (window)) {
4165 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4170 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4171 GtkRadioAction *selected,
4172 ModestWindow *window)
4174 TnyHeaderFlags flags;
4175 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4177 flags = gtk_radio_action_get_current_value (selected);
4178 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4182 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4183 GtkRadioAction *selected,
4184 ModestWindow *window)
4188 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4190 file_format = gtk_radio_action_get_current_value (selected);
4191 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4196 modest_ui_actions_on_zoom_plus (GtkAction *action,
4197 ModestWindow *window)
4199 g_return_if_fail (MODEST_IS_WINDOW (window));
4201 modest_window_zoom_plus (MODEST_WINDOW (window));
4205 modest_ui_actions_on_zoom_minus (GtkAction *action,
4206 ModestWindow *window)
4208 g_return_if_fail (MODEST_IS_WINDOW (window));
4210 modest_window_zoom_minus (MODEST_WINDOW (window));
4214 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4215 ModestWindow *window)
4217 ModestWindowMgr *mgr;
4218 gboolean fullscreen, active;
4219 g_return_if_fail (MODEST_IS_WINDOW (window));
4221 mgr = modest_runtime_get_window_mgr ();
4223 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4224 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4226 if (active != fullscreen) {
4227 modest_window_mgr_set_fullscreen_mode (mgr, active);
4228 #ifndef MODEST_TOOLKIT_HILDON2
4229 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4230 gtk_window_present (toplevel);
4236 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4237 ModestWindow *window)
4239 ModestWindowMgr *mgr;
4240 gboolean fullscreen;
4242 g_return_if_fail (MODEST_IS_WINDOW (window));
4244 mgr = modest_runtime_get_window_mgr ();
4245 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4246 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4251 * Used by modest_ui_actions_on_details to call do_headers_action
4254 headers_action_show_details (TnyHeader *header,
4255 ModestWindow *window,
4259 gboolean async_retrieval;
4260 GtkWindow *toplevel;
4263 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4264 async_retrieval = TRUE;
4265 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4266 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4268 async_retrieval = FALSE;
4270 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4271 modest_platform_run_header_details_dialog (toplevel, header, async_retrieval, msg);
4273 g_object_unref (msg);
4277 * Show the header details in a ModestDetailsDialog widget
4280 modest_ui_actions_on_details (GtkAction *action,
4283 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4287 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4291 header = tny_msg_get_header (msg);
4293 headers_action_show_details (header, win, NULL);
4294 g_object_unref (header);
4296 g_object_unref (msg);
4297 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4299 GtkWidget *header_view;
4301 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4302 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4304 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4306 modest_platform_run_folder_details_dialog (toplevel, folder);
4307 g_object_unref (folder);
4313 modest_ui_actions_on_limit_error (GtkAction *action,
4316 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4318 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS_MAXIMUM_CHARACTERS_REACHED);
4323 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4324 ModestMsgEditWindow *window)
4326 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4328 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4332 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4333 ModestMsgEditWindow *window)
4335 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4337 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4342 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4343 ModestWindow *window)
4345 gboolean active, fullscreen = FALSE;
4346 ModestWindowMgr *mgr;
4348 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4350 /* Check if we want to toggle the toolbar view in fullscreen
4352 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4353 "ViewShowToolbarFullScreen")) {
4357 /* Toggle toolbar */
4358 mgr = modest_runtime_get_window_mgr ();
4359 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4363 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4364 ModestMsgEditWindow *window)
4366 modest_msg_edit_window_select_font (window);
4371 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4372 const gchar *display_name,
4375 /* don't update the display name if it was already set;
4376 * updating the display name apparently is expensive */
4377 const gchar* old_name = gtk_window_get_title (window);
4379 if (display_name == NULL)
4382 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4383 return; /* don't do anything */
4385 /* This is usually used to change the title of the main window, which
4386 * is the one that holds the folder view. Note that this change can
4387 * happen even when the widget doesn't have the focus. */
4388 gtk_window_set_title (window, display_name);
4393 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4395 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4396 modest_msg_edit_window_select_contacts (window);
4400 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4402 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4403 modest_msg_edit_window_check_names (window, FALSE);
4408 on_move_to_dialog_response (GtkDialog *dialog,
4412 GtkWidget *parent_win;
4413 MoveToInfo *helper = NULL;
4414 ModestFolderView *folder_view;
4415 gboolean unset_edit_mode = FALSE;
4417 helper = (MoveToInfo *) user_data;
4419 parent_win = (GtkWidget *) helper->win;
4420 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4421 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4423 TnyFolderStore *dst_folder;
4424 TnyFolderStore *selected;
4426 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4427 selected = modest_folder_view_get_selected (folder_view);
4428 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4429 g_object_unref (selected);
4431 case GTK_RESPONSE_NONE:
4432 case GTK_RESPONSE_CANCEL:
4433 case GTK_RESPONSE_DELETE_EVENT:
4435 case GTK_RESPONSE_OK:
4436 dst_folder = modest_folder_view_get_selected (folder_view);
4438 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4439 /* Clean list to move used for filtering */
4440 modest_folder_view_set_list_to_move (folder_view, NULL);
4442 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4445 MODEST_WINDOW (parent_win));
4447 /* if the user selected a root folder
4448 (account) then do not perform any action */
4449 if (TNY_IS_ACCOUNT (dst_folder)) {
4450 g_signal_stop_emission_by_name (dialog, "response");
4454 /* Clean list to move used for filtering */
4455 modest_folder_view_set_list_to_move (folder_view, NULL);
4457 /* Moving from headers window in edit mode */
4458 modest_ui_actions_on_window_move_to (NULL, helper->list,
4460 MODEST_WINDOW (parent_win));
4464 g_object_unref (dst_folder);
4466 unset_edit_mode = TRUE;
4469 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4472 /* Free the helper and exit */
4474 g_object_unref (helper->list);
4475 if (unset_edit_mode) {
4476 #ifdef MODEST_TOOLKIT_HILDON2
4477 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4480 g_slice_free (MoveToInfo, helper);
4481 gtk_widget_destroy (GTK_WIDGET (dialog));
4485 create_move_to_dialog (GtkWindow *win,
4486 GtkWidget *folder_view,
4487 TnyList *list_to_move)
4489 GtkWidget *dialog, *tree_view = NULL;
4491 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4494 /* It could happen that we're trying to move a message from a
4495 window (msg window for example) after the main window was
4496 closed, so we can not just get the model of the folder
4498 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4499 const gchar *visible_id = NULL;
4501 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4502 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4503 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4504 MODEST_FOLDER_VIEW(tree_view));
4507 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4509 /* Show the same account than the one that is shown in the main window */
4510 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4513 const gchar *active_account_name = NULL;
4514 ModestAccountMgr *mgr = NULL;
4515 ModestAccountSettings *settings = NULL;
4516 ModestServerAccountSettings *store_settings = NULL;
4518 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4519 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4520 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4521 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4523 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4524 mgr = modest_runtime_get_account_mgr ();
4525 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4528 const gchar *store_account_name;
4529 store_settings = modest_account_settings_get_store_settings (settings);
4530 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4532 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4533 store_account_name);
4534 g_object_unref (store_settings);
4535 g_object_unref (settings);
4539 /* we keep a pointer to the embedded folder view, so we can
4540 * retrieve it with get_folder_view_from_move_to_dialog (see
4541 * above) later (needed for focus handling)
4543 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4545 /* Hide special folders */
4547 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4549 gtk_widget_show (GTK_WIDGET (tree_view));
4555 * Shows a confirmation dialog to the user when we're moving messages
4556 * from a remote server to the local storage. Returns the dialog
4557 * response. If it's other kind of movement then it always returns
4560 * This one is used by the next functions:
4561 * modest_ui_actions_on_paste - commented out
4562 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4565 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4566 TnyFolder *dest_folder,
4570 gint response = GTK_RESPONSE_OK;
4571 TnyAccount *account = NULL;
4572 TnyFolder *src_folder = NULL;
4573 TnyIterator *iter = NULL;
4574 TnyHeader *header = NULL;
4576 /* return with OK if the destination is a remote folder */
4577 if (modest_tny_folder_is_remote_folder (dest_folder))
4578 return GTK_RESPONSE_OK;
4580 /* Get source folder */
4581 iter = tny_list_create_iterator (headers);
4582 header = TNY_HEADER (tny_iterator_get_current (iter));
4584 src_folder = tny_header_get_folder (header);
4585 g_object_unref (header);
4587 g_object_unref (iter);
4589 /* if no src_folder, message may be an attahcment */
4590 if (src_folder == NULL)
4591 return GTK_RESPONSE_CANCEL;
4593 /* If the source is a local or MMC folder */
4594 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4595 g_object_unref (src_folder);
4596 return GTK_RESPONSE_OK;
4599 /* Get the account */
4600 account = tny_folder_get_account (src_folder);
4602 /* now if offline we ask the user */
4603 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4604 response = GTK_RESPONSE_OK;
4606 response = GTK_RESPONSE_CANCEL;
4609 g_object_unref (src_folder);
4610 g_object_unref (account);
4616 move_to_helper_destroyer (gpointer user_data)
4618 MoveToHelper *helper = (MoveToHelper *) user_data;
4620 /* Close the "Pasting" information banner */
4621 if (helper->banner) {
4622 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4623 g_object_unref (helper->banner);
4625 if (gtk_tree_row_reference_valid (helper->reference)) {
4626 gtk_tree_row_reference_free (helper->reference);
4627 helper->reference = NULL;
4633 move_to_cb (ModestMailOperation *mail_op,
4636 MoveToHelper *helper = (MoveToHelper *) user_data;
4637 GObject *object = modest_mail_operation_get_source (mail_op);
4639 /* Note that the operation could have failed, in that case do
4641 if (modest_mail_operation_get_status (mail_op) !=
4642 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4645 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4646 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4648 if (!modest_msg_view_window_select_next_message (self) &&
4649 !modest_msg_view_window_select_previous_message (self)) {
4650 /* No more messages to view, so close this window */
4651 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4654 g_object_unref (object);
4657 /* Destroy the helper */
4658 move_to_helper_destroyer (helper);
4662 folder_move_to_cb (ModestMailOperation *mail_op,
4663 TnyFolder *new_folder,
4668 object = modest_mail_operation_get_source (mail_op);
4670 move_to_cb (mail_op, user_data);
4675 msgs_move_to_cb (ModestMailOperation *mail_op,
4678 move_to_cb (mail_op, user_data);
4682 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4685 GObject *win = NULL;
4686 const GError *error;
4687 TnyAccount *account = NULL;
4689 win = modest_mail_operation_get_source (mail_op);
4690 error = modest_mail_operation_get_error (mail_op);
4692 if (TNY_IS_FOLDER (user_data))
4693 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4694 else if (TNY_IS_ACCOUNT (user_data))
4695 account = g_object_ref (user_data);
4697 /* If it's not a disk full error then show a generic error */
4698 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4699 (GtkWidget *) win, (GError *) error,
4701 modest_platform_run_information_dialog ((GtkWindow *) win,
4702 _("mail_in_ui_folder_move_target_error"),
4705 g_object_unref (account);
4707 g_object_unref (win);
4712 * Checks if we need a connection to do the transfer and if the user
4713 * wants to connect to complete it
4716 modest_ui_actions_xfer_messages_check (ModestWindow *parent_window,
4717 TnyFolderStore *src_folder,
4719 TnyFolder *dst_folder,
4720 gboolean delete_originals,
4721 gboolean *need_connection,
4724 TnyAccount *src_account;
4725 gint uncached_msgs = 0;
4727 /* We don't need any further check if
4729 * 1- the source folder is local OR
4730 * 2- the device is already online
4732 if (!modest_tny_folder_store_is_remote (src_folder) ||
4733 tny_device_is_online (modest_runtime_get_device())) {
4734 *need_connection = FALSE;
4739 /* We must ask for a connection when
4741 * - the message(s) is not already cached OR
4742 * - the message(s) is cached but the leave_on_server setting
4743 * is FALSE (because we need to sync the source folder to
4744 * delete the message from the server (for IMAP we could do it
4745 * offline, it'll take place the next time we get a
4748 uncached_msgs = header_list_count_uncached_msgs (headers);
4749 src_account = get_account_from_folder_store (src_folder);
4750 if (uncached_msgs > 0) {
4753 GtkWindow *toplevel;
4755 *need_connection = TRUE;
4756 num_headers = tny_list_get_length (headers);
4757 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4758 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
4760 if (modest_platform_run_confirmation_dialog (toplevel, msg) ==
4761 GTK_RESPONSE_CANCEL) {
4767 /* The transfer is possible and the user wants to */
4770 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4771 const gchar *account_name;
4772 gboolean leave_on_server;
4774 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4775 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4778 if (leave_on_server == TRUE) {
4779 *need_connection = FALSE;
4781 *need_connection = TRUE;
4784 *need_connection = FALSE;
4789 g_object_unref (src_account);
4793 xfer_messages_error_handler (ModestMailOperation *mail_op,
4797 const GError *error;
4798 TnyAccount *account;
4800 win = modest_mail_operation_get_source (mail_op);
4801 error = modest_mail_operation_get_error (mail_op);
4803 /* We cannot get the account from the mail op as that is the
4804 source account and for checking memory full conditions we
4805 need the destination one */
4806 account = TNY_ACCOUNT (user_data);
4809 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4810 (GtkWidget *) win, (GError*) error,
4811 account, _KR("cerm_memory_card_full"))) {
4812 modest_platform_run_information_dialog ((GtkWindow *) win,
4813 _("mail_in_ui_folder_move_target_error"),
4817 g_object_unref (win);
4821 TnyFolderStore *dst_folder;
4826 * Utility function that transfer messages from both the main window
4827 * and the msg view window when using the "Move to" dialog
4830 xfer_messages_performer (gboolean canceled,
4832 ModestWindow *parent_window,
4833 TnyAccount *account,
4836 TnyAccount *dst_account = NULL;
4837 gboolean dst_forbids_message_add = FALSE;
4838 XferMsgsHelper *helper;
4839 MoveToHelper *movehelper;
4840 ModestMailOperation *mail_op;
4842 helper = (XferMsgsHelper *) user_data;
4844 if (canceled || err) {
4845 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4846 (GtkWidget *) parent_window, err,
4848 /* Show the proper error message */
4849 modest_ui_actions_on_account_connection_error (parent_window, account);
4854 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4856 /* tinymail will return NULL for local folders it seems */
4857 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4858 modest_tny_account_get_protocol_type (dst_account),
4859 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4861 if (dst_forbids_message_add) {
4862 modest_platform_information_banner (GTK_WIDGET (parent_window),
4864 ngettext("mail_in_ui_folder_move_target_error",
4865 "mail_in_ui_folder_move_targets_error",
4866 tny_list_get_length (helper->headers)));
4870 movehelper = g_new0 (MoveToHelper, 1);
4873 /* Perform the mail operation */
4874 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4875 xfer_messages_error_handler,
4876 g_object_ref (dst_account),
4878 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4881 modest_mail_operation_xfer_msgs (mail_op,
4883 TNY_FOLDER (helper->dst_folder),
4888 g_object_unref (G_OBJECT (mail_op));
4891 g_object_unref (dst_account);
4892 g_object_unref (helper->dst_folder);
4893 g_object_unref (helper->headers);
4894 g_slice_free (XferMsgsHelper, helper);
4898 TnyFolder *src_folder;
4899 TnyFolderStore *dst_folder;
4900 gboolean delete_original;
4901 GtkWidget *folder_view;
4905 on_move_folder_cb (gboolean canceled,
4907 ModestWindow *parent_window,
4908 TnyAccount *account,
4911 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4912 GtkTreeSelection *sel;
4913 ModestMailOperation *mail_op = NULL;
4915 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4916 /* Note that the connection process can fail due to
4917 memory low conditions as it can not successfully
4918 store the summary */
4919 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4920 (GtkWidget*) parent_window, err,
4922 g_debug ("Error connecting when trying to move a folder");
4924 g_object_unref (G_OBJECT (info->src_folder));
4925 g_object_unref (G_OBJECT (info->dst_folder));
4930 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4931 #ifndef MODEST_TOOLKIT_HILDON2
4932 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4934 if (helper->banner != NULL) {
4935 g_object_ref (helper->banner);
4936 gtk_widget_show (GTK_WIDGET(helper->banner));
4939 /* Clean folder on header view before moving it */
4940 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4941 gtk_tree_selection_unselect_all (sel);
4943 /* Let gtk events run. We need that the folder
4944 view frees its reference to the source
4945 folder *before* issuing the mail operation
4946 so we need the signal handler of selection
4947 changed to happen before the mail
4949 while (gtk_events_pending ())
4950 gtk_main_iteration (); */
4953 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4954 modest_ui_actions_move_folder_error_handler,
4955 g_object_ref (info->dst_folder), g_object_unref);
4956 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4959 modest_mail_operation_xfer_folder (mail_op,
4960 TNY_FOLDER (info->src_folder),
4962 info->delete_original,
4965 g_object_unref (G_OBJECT (info->src_folder));
4967 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4970 /* Unref mail operation */
4971 g_object_unref (G_OBJECT (mail_op));
4972 g_object_unref (G_OBJECT (info->dst_folder));
4977 get_account_from_folder_store (TnyFolderStore *folder_store)
4979 if (TNY_IS_ACCOUNT (folder_store))
4980 return g_object_ref (folder_store);
4982 return tny_folder_get_account (TNY_FOLDER (folder_store));
4986 * UI handler for the "Move to" action when invoked from the
4987 * ModestFolderWindow
4990 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4991 TnyFolderStore *dst_folder,
4995 TnyFolderStore *src_folder = NULL;
4996 TnyIterator *iterator;
4998 if (tny_list_get_length (selection) != 1)
5001 iterator = tny_list_create_iterator (selection);
5002 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5003 g_object_unref (iterator);
5006 gboolean do_xfer = TRUE;
5008 /* Allow only to transfer folders to the local root folder */
5009 if (TNY_IS_ACCOUNT (dst_folder) &&
5010 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5011 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5012 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5016 modest_platform_run_information_dialog (toplevel,
5017 _("mail_in_ui_folder_move_target_error"),
5019 } else if (!TNY_IS_FOLDER (src_folder)) {
5020 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5025 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5026 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5028 info->src_folder = g_object_ref (src_folder);
5029 info->dst_folder = g_object_ref (dst_folder);
5030 info->delete_original = TRUE;
5031 info->folder_view = folder_view;
5033 connect_info->callback = on_move_folder_cb;
5034 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5035 connect_info->data = info;
5037 modest_platform_double_connect_and_perform(win, TRUE,
5038 TNY_FOLDER_STORE (src_folder),
5043 g_object_unref (src_folder);
5048 modest_ui_actions_transfer_messages_helper (ModestWindow *win,
5049 TnyFolder *src_folder,
5051 TnyFolder *dst_folder)
5053 gboolean need_connection = TRUE;
5054 gboolean do_xfer = TRUE;
5055 XferMsgsHelper *helper;
5057 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5058 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5059 g_return_if_fail (TNY_IS_LIST (headers));
5061 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5062 headers, TNY_FOLDER (dst_folder),
5063 TRUE, &need_connection,
5066 /* If we don't want to transfer just return */
5070 /* Create the helper */
5071 helper = g_slice_new (XferMsgsHelper);
5072 helper->dst_folder = g_object_ref (dst_folder);
5073 helper->headers = g_object_ref (headers);
5075 if (need_connection) {
5076 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5077 connect_info->callback = xfer_messages_performer;
5078 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5079 connect_info->data = helper;
5081 modest_platform_double_connect_and_perform(win, TRUE,
5082 TNY_FOLDER_STORE (src_folder),
5085 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5086 xfer_messages_performer (FALSE, NULL, win,
5087 src_account, helper);
5088 g_object_unref (src_account);
5093 * UI handler for the "Move to" action when invoked from the
5094 * ModestMsgViewWindow
5097 modest_ui_actions_on_window_move_to (GtkAction *action,
5099 TnyFolderStore *dst_folder,
5102 TnyFolder *src_folder = NULL;
5104 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5107 TnyHeader *header = NULL;
5110 iter = tny_list_create_iterator (headers);
5111 header = (TnyHeader *) tny_iterator_get_current (iter);
5112 src_folder = tny_header_get_folder (header);
5114 /* Transfer the messages */
5115 modest_ui_actions_transfer_messages_helper (win, src_folder,
5117 TNY_FOLDER (dst_folder));
5120 g_object_unref (header);
5121 g_object_unref (iter);
5122 g_object_unref (src_folder);
5127 modest_ui_actions_on_move_to (GtkAction *action,
5130 modest_ui_actions_on_edit_mode_move_to (win);
5134 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5136 GtkWidget *dialog = NULL;
5137 GtkWindow *toplevel = NULL;
5138 MoveToInfo *helper = NULL;
5139 TnyList *list_to_move;
5141 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5144 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5149 if (tny_list_get_length (list_to_move) < 1) {
5150 g_object_unref (list_to_move);
5154 /* Create and run the dialog */
5155 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5156 dialog = create_move_to_dialog (toplevel, NULL, list_to_move);
5157 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5158 GTK_WINDOW (dialog),
5162 helper = g_slice_new0 (MoveToInfo);
5163 helper->list = list_to_move;
5166 /* Listen to response signal */
5167 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5169 /* Show the dialog */
5170 gtk_widget_show (dialog);
5176 * Calls #HeadersFunc for each header already selected in the main
5177 * window or the message currently being shown in the msg view window
5180 do_headers_action (ModestWindow *win,
5184 TnyList *headers_list = NULL;
5185 TnyIterator *iter = NULL;
5186 TnyHeader *header = NULL;
5187 TnyFolder *folder = NULL;
5190 headers_list = get_selected_headers (win);
5194 /* Get the folder */
5195 iter = tny_list_create_iterator (headers_list);
5196 header = TNY_HEADER (tny_iterator_get_current (iter));
5198 folder = tny_header_get_folder (header);
5199 g_object_unref (header);
5202 /* Call the function for each header */
5203 while (!tny_iterator_is_done (iter)) {
5204 header = TNY_HEADER (tny_iterator_get_current (iter));
5205 func (header, win, user_data);
5206 g_object_unref (header);
5207 tny_iterator_next (iter);
5210 /* Trick: do a poke status in order to speed up the signaling
5213 tny_folder_poke_status (folder);
5214 g_object_unref (folder);
5218 g_object_unref (iter);
5219 g_object_unref (headers_list);
5223 modest_ui_actions_view_attachment (GtkAction *action,
5224 ModestWindow *window)
5226 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5227 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5229 /* not supported window for this action */
5230 g_return_if_reached ();
5235 modest_ui_actions_save_attachments (GtkAction *action,
5236 ModestWindow *window)
5238 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5240 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5243 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5245 /* not supported window for this action */
5246 g_return_if_reached ();
5251 modest_ui_actions_remove_attachments (GtkAction *action,
5252 ModestWindow *window)
5254 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5255 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5257 /* not supported window for this action */
5258 g_return_if_reached ();
5263 modest_ui_actions_on_settings (GtkAction *action,
5267 GtkWindow *toplevel;
5269 dialog = modest_platform_get_global_settings_dialog ();
5270 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5271 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5272 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5273 gtk_widget_show_all (dialog);
5275 gtk_dialog_run (GTK_DIALOG (dialog));
5277 gtk_widget_destroy (dialog);
5281 modest_ui_actions_on_help (GtkAction *action,
5284 /* Help app is not available at all in fremantle */
5285 #ifndef MODEST_TOOLKIT_HILDON2
5286 const gchar *help_id;
5288 g_return_if_fail (win && GTK_IS_WINDOW(win));
5290 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5293 modest_platform_show_help (win, help_id);
5298 modest_ui_actions_on_csm_help (GtkAction *action,
5301 /* Help app is not available at all in fremantle */
5305 retrieve_contents_cb (ModestMailOperation *mail_op,
5312 /* We only need this callback to show an error in case of
5313 memory low condition */
5314 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5315 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5320 retrieve_msg_contents_performer (gboolean canceled,
5322 ModestWindow *parent_window,
5323 TnyAccount *account,
5326 ModestMailOperation *mail_op;
5327 TnyList *headers = TNY_LIST (user_data);
5329 if (err || canceled) {
5330 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5331 (GtkWidget *) parent_window, err,
5336 /* Create mail operation */
5337 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5338 modest_ui_actions_disk_operations_error_handler,
5340 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5341 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5344 g_object_unref (mail_op);
5346 g_object_unref (headers);
5347 g_object_unref (account);
5351 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5352 ModestWindow *window)
5354 TnyList *headers = NULL;
5355 TnyAccount *account = NULL;
5356 TnyIterator *iter = NULL;
5357 TnyHeader *header = NULL;
5358 TnyFolder *folder = NULL;
5361 headers = get_selected_headers (window);
5365 /* Pick the account */
5366 iter = tny_list_create_iterator (headers);
5367 header = TNY_HEADER (tny_iterator_get_current (iter));
5368 folder = tny_header_get_folder (header);
5369 account = tny_folder_get_account (folder);
5370 g_object_unref (folder);
5371 g_object_unref (header);
5372 g_object_unref (iter);
5374 /* Connect and perform the message retrieval */
5375 modest_platform_connect_and_perform (window, TRUE,
5376 g_object_ref (account),
5377 retrieve_msg_contents_performer,
5378 g_object_ref (headers));
5381 g_object_unref (account);
5382 g_object_unref (headers);
5386 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5388 g_return_if_fail (MODEST_IS_WINDOW (window));
5391 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5395 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5397 g_return_if_fail (MODEST_IS_WINDOW (window));
5400 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5404 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5405 ModestWindow *window)
5407 g_return_if_fail (MODEST_IS_WINDOW (window));
5410 modest_ui_actions_check_menu_dimming_rules (window);
5414 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5415 ModestWindow *window)
5417 g_return_if_fail (MODEST_IS_WINDOW (window));
5420 modest_ui_actions_check_menu_dimming_rules (window);
5424 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5425 ModestWindow *window)
5427 g_return_if_fail (MODEST_IS_WINDOW (window));
5430 modest_ui_actions_check_menu_dimming_rules (window);
5434 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5435 ModestWindow *window)
5437 g_return_if_fail (MODEST_IS_WINDOW (window));
5440 modest_ui_actions_check_menu_dimming_rules (window);
5444 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5445 ModestWindow *window)
5447 g_return_if_fail (MODEST_IS_WINDOW (window));
5450 modest_ui_actions_check_menu_dimming_rules (window);
5454 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5455 ModestWindow *window)
5457 g_return_if_fail (MODEST_IS_WINDOW (window));
5460 modest_ui_actions_check_menu_dimming_rules (window);
5464 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5465 ModestWindow *window)
5467 g_return_if_fail (MODEST_IS_WINDOW (window));
5470 modest_ui_actions_check_menu_dimming_rules (window);
5474 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5475 ModestWindow *window)
5477 g_return_if_fail (MODEST_IS_WINDOW (window));
5480 modest_ui_actions_check_menu_dimming_rules (window);
5484 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5485 ModestWindow *window)
5487 g_return_if_fail (MODEST_IS_WINDOW (window));
5490 modest_ui_actions_check_menu_dimming_rules (window);
5494 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5496 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
5498 g_return_if_fail (MODEST_IS_WINDOW (window));
5500 /* we check for low-mem; in that case, show a warning, and don't allow
5503 if (modest_platform_check_memory_low (window, TRUE))
5506 modest_platform_show_search_messages (toplevel);
5510 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5512 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5514 g_return_if_fail (MODEST_IS_WINDOW (win));
5516 /* we check for low-mem; in that case, show a warning, and don't allow
5517 * for the addressbook
5519 if (modest_platform_check_memory_low (win, TRUE))
5522 modest_platform_show_addressbook (toplevel);
5527 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5528 ModestWindow *window)
5531 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5533 if (GTK_IS_TOGGLE_ACTION (action))
5534 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5538 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5544 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5550 const gchar* server_name = NULL;
5551 TnyTransportAccount *transport;
5552 gchar *message = NULL;
5553 ModestProtocol *protocol;
5555 /* Don't show anything if the user cancelled something or the
5556 * send receive request is not interactive. Authentication
5557 * errors are managed by the account store so no need to show
5558 * a dialog here again */
5559 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5560 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5561 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5565 /* Get the server name. Note that we could be using a
5566 connection specific transport account */
5567 transport = (TnyTransportAccount *)
5568 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5570 ModestTnyAccountStore *acc_store;
5571 const gchar *acc_name;
5572 TnyTransportAccount *conn_specific;
5574 acc_store = modest_runtime_get_account_store();
5575 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5576 conn_specific = (TnyTransportAccount *)
5577 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5578 if (conn_specific) {
5579 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5580 g_object_unref (conn_specific);
5582 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5584 g_object_unref (transport);
5588 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5589 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5590 tny_account_get_proto (TNY_ACCOUNT (transport)));
5592 g_warning ("%s: Account with no proto", __FUNCTION__);
5596 /* Show the appropriate message text for the GError: */
5597 switch (err->code) {
5598 case TNY_SERVICE_ERROR_CONNECT:
5599 message = modest_protocol_get_translation (protocol,
5600 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5603 case TNY_SERVICE_ERROR_SEND:
5604 message = g_strdup (_CS_UNABLE_TO_SEND);
5606 case TNY_SERVICE_ERROR_UNAVAILABLE:
5607 message = modest_protocol_get_translation (protocol,
5608 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5612 g_warning ("%s: unexpected ERROR %d",
5613 __FUNCTION__, err->code);
5614 message = g_strdup (_CS_UNABLE_TO_SEND);
5618 modest_platform_run_information_dialog (NULL, message, FALSE);
5623 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5628 ModestWindow *top_window = NULL;
5629 ModestWindowMgr *mgr = NULL;
5630 GtkWidget *header_view = NULL;
5631 TnyFolder *selected_folder = NULL;
5632 TnyFolderType folder_type;
5634 mgr = modest_runtime_get_window_mgr ();
5635 top_window = modest_window_mgr_get_current_top (mgr);
5640 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5641 header_view = (GtkWidget *)
5642 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5645 /* Get selected folder */
5647 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5648 if (!selected_folder)
5651 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5652 #if GTK_CHECK_VERSION(2, 8, 0)
5653 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5654 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5655 GtkTreeViewColumn *tree_column;
5657 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5658 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5660 gtk_tree_view_column_queue_resize (tree_column);
5662 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5663 gtk_widget_queue_draw (header_view);
5666 #ifndef MODEST_TOOLKIT_HILDON2
5667 /* Rerun dimming rules, because the message could become deletable for example */
5668 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5669 MODEST_DIMMING_RULES_TOOLBAR);
5670 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5671 MODEST_DIMMING_RULES_MENU);
5675 g_object_unref (selected_folder);
5679 modest_ui_actions_on_account_connection_error (ModestWindow *parent_window,
5680 TnyAccount *account)
5682 ModestProtocolType protocol_type;
5683 ModestProtocol *protocol;
5684 gchar *error_note = NULL;
5686 protocol_type = modest_tny_account_get_protocol_type (account);
5687 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5690 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5691 if (error_note == NULL) {
5692 g_warning ("%s: This should not be reached", __FUNCTION__);
5694 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
5695 modest_platform_run_information_dialog (toplevel, error_note, FALSE);
5696 g_free (error_note);
5701 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5705 TnyFolderStore *folder = NULL;
5706 TnyAccount *account = NULL;
5707 ModestProtocolType proto;
5708 ModestProtocol *protocol;
5709 TnyHeader *header = NULL;
5711 if (MODEST_IS_HEADER_WINDOW (win)) {
5712 GtkWidget *header_view;
5713 TnyList* headers = NULL;
5715 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5716 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5717 if (!headers || tny_list_get_length (headers) == 0) {
5719 g_object_unref (headers);
5722 iter = tny_list_create_iterator (headers);
5723 header = TNY_HEADER (tny_iterator_get_current (iter));
5725 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5727 g_warning ("List should contain headers");
5729 g_object_unref (iter);
5730 g_object_unref (headers);
5731 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5732 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5734 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5737 if (!header || !folder)
5740 /* Get the account type */
5741 account = tny_folder_get_account (TNY_FOLDER (folder));
5742 proto = modest_tny_account_get_protocol_type (account);
5743 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5746 subject = tny_header_dup_subject (header);
5747 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5751 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5757 g_object_unref (account);
5759 g_object_unref (folder);
5761 g_object_unref (header);
5767 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5768 const gchar *account_name,
5769 const gchar *account_title)
5771 ModestAccountMgr *account_mgr;
5774 ModestProtocol *protocol;
5775 gboolean removed = FALSE;
5777 g_return_val_if_fail (account_name, FALSE);
5778 g_return_val_if_fail (account_title, FALSE);
5780 account_mgr = modest_runtime_get_account_mgr();
5782 /* The warning text depends on the account type: */
5783 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5784 modest_account_mgr_get_store_protocol (account_mgr,
5786 txt = modest_protocol_get_translation (protocol,
5787 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5790 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5792 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5796 if (response == GTK_RESPONSE_OK) {
5797 /* Remove account. If it succeeds then it also removes
5798 the account from the ModestAccountView: */
5799 gboolean is_default = FALSE;
5800 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5801 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5803 g_free (default_account_name);
5805 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5807 #ifdef MODEST_TOOLKIT_HILDON2
5808 hildon_gtk_window_take_screenshot (parent_window, FALSE);
5810 /* Close all email notifications, we cannot
5811 distinguish if the notification belongs to
5812 this account or not, so for safety reasons
5813 we remove them all */
5814 modest_platform_remove_new_mail_notifications (FALSE);
5816 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5823 on_fetch_images_performer (gboolean canceled,
5825 ModestWindow *parent_window,
5826 TnyAccount *account,
5829 if (err || canceled) {
5830 /* Show an unable to retrieve images ??? */
5834 /* Note that the user could have closed the window while connecting */
5835 if (GTK_WIDGET_VISIBLE (parent_window))
5836 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5837 g_object_unref ((GObject *) user_data);
5841 modest_ui_actions_on_fetch_images (GtkAction *action,
5842 ModestWindow *window)
5844 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5846 modest_platform_connect_and_perform (window, TRUE,
5848 on_fetch_images_performer,
5849 g_object_ref (window));
5853 modest_ui_actions_on_reload_message (const gchar *msg_id)
5855 ModestWindow *window = NULL;
5857 g_return_if_fail (msg_id && msg_id[0] != '\0');
5858 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5864 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5867 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5870 /** Check whether any connections are active, and cancel them if
5872 * Returns TRUE is there was no problem,
5873 * or if an operation was cancelled so we can continue.
5874 * Returns FALSE if the user chose to cancel his request instead.
5878 modest_ui_actions_check_for_active_account (ModestWindow *self,
5879 const gchar* account_name)
5881 ModestTnySendQueue *send_queue;
5882 ModestTnyAccountStore *acc_store;
5883 ModestMailOperationQueue* queue;
5884 TnyConnectionStatus store_conn_status;
5885 TnyAccount *store_account = NULL, *transport_account = NULL;
5886 gboolean retval = TRUE, sending = FALSE;
5888 acc_store = modest_runtime_get_account_store ();
5889 queue = modest_runtime_get_mail_operation_queue ();
5892 modest_tny_account_store_get_server_account (acc_store,
5894 TNY_ACCOUNT_TYPE_STORE);
5896 /* This could happen if the account was deleted before the
5897 call to this function */
5902 modest_tny_account_store_get_server_account (acc_store,
5904 TNY_ACCOUNT_TYPE_TRANSPORT);
5906 /* This could happen if the account was deleted before the
5907 call to this function */
5908 if (!transport_account) {
5909 g_object_unref (store_account);
5913 /* If the transport account was not used yet, then the send
5914 queue could not exist (it's created on demand) */
5915 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5916 if (TNY_IS_SEND_QUEUE (send_queue))
5917 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5919 store_conn_status = tny_account_get_connection_status (store_account);
5920 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5923 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
5924 _("emev_nc_disconnect_account"));
5925 if (response == GTK_RESPONSE_OK) {
5934 /* FIXME: We should only cancel those of this account */
5935 modest_mail_operation_queue_cancel_all (queue);
5937 /* Also disconnect the account */
5938 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5939 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5940 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5944 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5950 g_object_unref (store_account);
5951 g_object_unref (transport_account);