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 (win && gtk_style_lookup_color (gtk_widget_get_style ((GtkWidget *) win),
747 "SecondaryTextColor", &color))
748 gray_color_markup = modest_text_utils_get_color_string (&color);
749 if (!gray_color_markup)
750 gray_color_markup = g_strdup ("#babababababa");
752 color_begin = g_strdup_printf ("<font color=\"%s\">", gray_color_markup);
753 color_end = "</font>";
755 body = use_signature ? g_strconcat("<br/>\n", color_begin,
756 MODEST_TEXT_UTILS_SIGNATURE_MARKER, "<br/>\n",
757 signature, color_end, NULL) : g_strdup("");
759 g_free (gray_color_markup);
760 g_free (color_begin);
763 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
764 NULL, NULL, body, NULL, NULL, NULL, NULL, NULL);
766 g_printerr ("modest: failed to create new msg\n");
770 /* Create and register edit window */
771 /* This is destroyed by TODO. */
773 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
774 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
776 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
777 gtk_widget_destroy (GTK_WIDGET (msg_win));
780 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
781 gtk_widget_show_all (GTK_WIDGET (msg_win));
783 while (attachments) {
784 GnomeVFSFileSize att_size;
786 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
787 attachments->data, allowed_size);
788 total_size += att_size;
790 if (att_size > allowed_size) {
791 g_debug ("%s: total size: %u",
792 __FUNCTION__, (unsigned int)total_size);
795 allowed_size -= att_size;
797 attachments = g_slist_next(attachments);
804 g_free (account_name);
806 g_object_unref (G_OBJECT(account));
808 g_object_unref (G_OBJECT(folder));
810 g_object_unref (G_OBJECT(msg));
814 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
816 /* if there are no accounts yet, just show the wizard */
817 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
818 if (!modest_ui_actions_run_account_setup_wizard (win))
821 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
826 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
830 ModestMailOperationStatus status;
832 /* If there is no message or the operation was not successful */
833 status = modest_mail_operation_get_status (mail_op);
834 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
837 /* If it's a memory low issue, then show a banner */
838 error = modest_mail_operation_get_error (mail_op);
839 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
840 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
841 GtkWindow *toplevel = NULL;
842 GObject *source = modest_mail_operation_get_source (mail_op);
844 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (source));
845 modest_platform_run_information_dialog (toplevel,
846 _KR("memr_ib_operation_disabled"),
848 g_object_unref (source);
851 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
852 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
853 gchar *subject, *msg, *format = NULL;
856 subject = (header) ? tny_header_dup_subject (header) : NULL;
858 subject = g_strdup (_("mail_va_no_subject"));
860 account = modest_mail_operation_get_account (mail_op);
862 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
863 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
866 if (tny_account_get_connection_status (account) ==
867 TNY_CONNECTION_STATUS_CONNECTED) {
869 format = modest_protocol_get_translation (protocol,
870 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
873 format = modest_protocol_get_translation (protocol,
874 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
877 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
878 tny_account_get_hostname (account));
881 g_object_unref (account);
886 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
888 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
892 msg = g_strdup_printf (format, subject);
893 modest_platform_run_information_dialog (NULL, msg, FALSE);
899 /* Remove the header from the preregistered uids */
900 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
918 ModestWindow *caller_window;
919 OpenMsgBannerInfo *banner_info;
920 GtkTreeRowReference *rowref;
924 open_msg_banner_idle (gpointer userdata)
926 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
928 gdk_threads_enter ();
929 banner_info->idle_handler = 0;
930 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
931 if (banner_info->banner)
932 g_object_ref (banner_info->banner);
934 gdk_threads_leave ();
940 get_header_view_from_window (ModestWindow *window)
942 GtkWidget *header_view;
944 if (MODEST_IS_HEADER_WINDOW (window)){
945 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
954 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
957 gchar *account = NULL;
958 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
963 folder = tny_header_get_folder (header);
964 /* Gets folder type (OUTBOX headers will be opened in edit window */
965 if (modest_tny_folder_is_local_folder (folder)) {
966 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
967 if (folder_type == TNY_FOLDER_TYPE_INVALID)
968 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
971 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
972 TnyTransportAccount *traccount = NULL;
973 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
974 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
976 ModestTnySendQueue *send_queue = NULL;
977 ModestTnySendQueueStatus status;
979 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
980 TNY_ACCOUNT(traccount)));
981 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
982 if (TNY_IS_SEND_QUEUE (send_queue)) {
983 msg_id = modest_tny_send_queue_get_msg_id (header);
984 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
986 /* Only open messages in outbox with the editor if they are in Failed state */
987 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
991 /* In Fremantle we can not
992 open any message from
993 outbox which is not in
998 g_object_unref(traccount);
1000 g_warning("Cannot get transport account for message in outbox!!");
1002 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1003 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1007 TnyAccount *acc = tny_folder_get_account (folder);
1010 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1011 g_object_unref (acc);
1015 g_object_unref (folder);
1021 open_msg_cb (ModestMailOperation *mail_op,
1028 ModestWindowMgr *mgr = NULL;
1029 ModestWindow *parent_win = NULL;
1030 ModestWindow *win = NULL;
1031 gchar *account = NULL;
1032 gboolean open_in_editor = FALSE;
1034 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1036 /* Do nothing if there was any problem with the mail
1037 operation. The error will be shown by the error_handler of
1038 the mail operation */
1039 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1042 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1044 /* Mark header as read */
1045 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1047 account = get_info_from_header (header, &open_in_editor, &can_open);
1051 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1053 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1055 if (open_in_editor) {
1056 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1057 gchar *from_header = NULL, *acc_name;
1058 gchar *mailbox = NULL;
1060 from_header = tny_header_dup_from (header);
1062 /* we cannot edit without a valid account... */
1063 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1064 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1065 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1067 g_free (from_header);
1072 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1073 g_free (from_header);
1079 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1083 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1084 const gchar *mailbox = NULL;
1086 if (parent_win && MODEST_IS_WINDOW (parent_win))
1087 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1089 if (helper->rowref && helper->model) {
1090 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1091 helper->model, helper->rowref);
1093 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1098 /* Register and show new window */
1100 mgr = modest_runtime_get_window_mgr ();
1101 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1102 gtk_widget_destroy (GTK_WIDGET (win));
1105 gtk_widget_show_all (GTK_WIDGET(win));
1112 g_object_unref (parent_win);
1116 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1119 const GError *error;
1120 GObject *win = NULL;
1121 ModestMailOperationStatus status;
1123 win = modest_mail_operation_get_source (mail_op);
1124 error = modest_mail_operation_get_error (mail_op);
1125 status = modest_mail_operation_get_status (mail_op);
1127 /* If the mail op has been cancelled then it's not an error:
1128 don't show any message */
1129 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1130 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1131 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1132 (GError *) error, account)) {
1133 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1134 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1136 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1137 modest_platform_information_banner ((GtkWidget *) win,
1138 NULL, _("emev_ui_imap_inbox_select_error"));
1139 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1140 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1141 modest_platform_information_banner ((GtkWidget *) win,
1142 NULL, _CS_UNABLE_TO_OPEN_FILE_NOT_FOUND);
1143 } else if (user_data) {
1144 modest_platform_information_banner ((GtkWidget *) win,
1148 g_object_unref (account);
1152 g_object_unref (win);
1156 * Returns the account a list of headers belongs to. It returns a
1157 * *new* reference so don't forget to unref it
1160 get_account_from_header_list (TnyList *headers)
1162 TnyAccount *account = NULL;
1164 if (tny_list_get_length (headers) > 0) {
1165 TnyIterator *iter = tny_list_create_iterator (headers);
1166 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1167 TnyFolder *folder = tny_header_get_folder (header);
1170 g_object_unref (header);
1172 while (!tny_iterator_is_done (iter)) {
1173 header = TNY_HEADER (tny_iterator_get_current (iter));
1174 folder = tny_header_get_folder (header);
1177 g_object_unref (header);
1179 tny_iterator_next (iter);
1184 account = tny_folder_get_account (folder);
1185 g_object_unref (folder);
1189 g_object_unref (header);
1191 g_object_unref (iter);
1197 get_account_from_header (TnyHeader *header)
1199 TnyAccount *account = NULL;
1202 folder = tny_header_get_folder (header);
1205 account = tny_folder_get_account (folder);
1206 g_object_unref (folder);
1212 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1214 if (helper->caller_window)
1215 helper->caller_window = NULL;
1219 open_msg_helper_destroyer (gpointer user_data)
1221 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1223 if (helper->caller_window) {
1224 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1225 helper->caller_window = NULL;
1228 if (helper->banner_info) {
1229 g_free (helper->banner_info->message);
1230 if (helper->banner_info->idle_handler > 0) {
1231 g_source_remove (helper->banner_info->idle_handler);
1232 helper->banner_info->idle_handler = 0;
1234 if (helper->banner_info->banner != NULL) {
1235 gtk_widget_destroy (helper->banner_info->banner);
1236 g_object_unref (helper->banner_info->banner);
1237 helper->banner_info->banner = NULL;
1239 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1240 helper->banner_info = NULL;
1242 g_object_unref (helper->model);
1243 g_object_unref (helper->header);
1244 gtk_tree_row_reference_free (helper->rowref);
1245 g_slice_free (OpenMsgHelper, helper);
1249 open_msg_performer(gboolean canceled,
1251 ModestWindow *parent_window,
1252 TnyAccount *account,
1255 ModestMailOperation *mail_op = NULL;
1256 gchar *error_msg = NULL;
1257 ModestProtocolType proto;
1258 TnyConnectionStatus status;
1259 OpenMsgHelper *helper = NULL;
1260 ModestProtocol *protocol;
1261 ModestProtocolRegistry *protocol_registry;
1264 helper = (OpenMsgHelper *) user_data;
1266 status = tny_account_get_connection_status (account);
1267 if (err || canceled || helper->caller_window == NULL) {
1268 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1269 /* Free the helper */
1270 open_msg_helper_destroyer (helper);
1272 /* In disk full conditions we could get this error here */
1273 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1274 (GtkWidget *) parent_window, err,
1280 /* Get the error message depending on the protocol */
1281 proto = modest_tny_account_get_protocol_type (account);
1282 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1283 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1286 protocol_registry = modest_runtime_get_protocol_registry ();
1287 subject = tny_header_dup_subject (helper->header);
1289 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1290 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1294 if (error_msg == NULL) {
1295 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1300 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1302 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
1303 !g_strcmp0 (account_name, MODEST_MMC_ACCOUNT_ID)) {
1304 g_free (account_name);
1305 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1309 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1310 g_free (account_name);
1311 open_msg_helper_destroyer (helper);
1316 ModestWindow *window;
1317 GtkWidget *header_view;
1320 header_view = get_header_view_from_window (parent_window);
1321 uid = modest_tny_folder_get_header_unique_id (helper->header);
1323 const gchar *mailbox = NULL;
1324 mailbox = modest_window_get_active_mailbox (parent_window);
1325 window = modest_msg_view_window_new_from_header_view
1326 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1327 if (window != NULL) {
1328 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1330 gtk_widget_destroy (GTK_WIDGET (window));
1332 gtk_widget_show_all (GTK_WIDGET(window));
1336 g_free (account_name);
1338 open_msg_helper_destroyer (helper);
1341 g_free (account_name);
1342 /* Create the mail operation */
1344 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1345 modest_ui_actions_disk_operations_error_handler,
1346 g_strdup (error_msg), g_free);
1347 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1353 headers = TNY_LIST (tny_simple_list_new ());
1354 tny_list_prepend (headers, G_OBJECT (helper->header));
1355 modest_mail_operation_get_msgs_full (mail_op,
1359 open_msg_helper_destroyer);
1360 g_object_unref (headers);
1367 g_object_unref (mail_op);
1368 g_object_unref (account);
1372 * This function is used by both modest_ui_actions_on_open and
1373 * modest_ui_actions_on_header_activated. This way we always do the
1374 * same when trying to open messages.
1377 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1379 ModestWindowMgr *mgr = NULL;
1380 TnyAccount *account;
1381 gboolean cached = FALSE;
1383 GtkWidget *header_view = NULL;
1384 OpenMsgHelper *helper;
1385 ModestWindow *window;
1387 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1389 mgr = modest_runtime_get_window_mgr ();
1392 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1393 if (header_view == NULL)
1396 /* Get the account */
1397 account = get_account_from_header (header);
1402 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1404 /* Do not open again the message and present the
1405 window to the user */
1408 #ifndef MODEST_TOOLKIT_HILDON2
1409 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
1410 gtk_window_present (toplevel);
1413 /* the header has been registered already, we don't do
1414 * anything but wait for the window to come up*/
1415 g_debug ("header %p already registered, waiting for window", header);
1420 /* Open each message */
1421 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1423 /* Allways download if we are online. */
1424 if (!tny_device_is_online (modest_runtime_get_device ())) {
1426 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1428 /* If ask for user permission to download the messages */
1429 response = modest_platform_run_confirmation_dialog (toplevel,
1430 _("mcen_nc_get_msg"));
1432 /* End if the user does not want to continue */
1433 if (response == GTK_RESPONSE_CANCEL) {
1439 /* We register the window for opening */
1440 modest_window_mgr_register_header (mgr, header, NULL);
1442 /* Create the helper. We need to get a reference to the model
1443 here because it could change while the message is readed
1444 (the user could switch between folders) */
1445 helper = g_slice_new (OpenMsgHelper);
1446 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1447 helper->caller_window = win;
1448 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1449 helper->header = g_object_ref (header);
1450 helper->rowref = gtk_tree_row_reference_copy (rowref);
1451 helper->banner_info = NULL;
1453 /* Connect to the account and perform */
1455 modest_platform_connect_and_perform (win, TRUE, g_object_ref (account),
1456 open_msg_performer, helper);
1458 /* Call directly the performer, do not need to connect */
1459 open_msg_performer (FALSE, NULL, win,
1460 g_object_ref (account), helper);
1465 g_object_unref (account);
1469 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1476 /* we check for low-mem; in that case, show a warning, and don't allow
1479 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1483 headers = get_selected_headers (win);
1487 headers_count = tny_list_get_length (headers);
1488 if (headers_count != 1) {
1489 if (headers_count > 1) {
1490 /* Don't allow activation if there are more than one message selected */
1491 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1494 g_object_unref (headers);
1498 iter = tny_list_create_iterator (headers);
1499 header = TNY_HEADER (tny_iterator_get_current (iter));
1500 g_object_unref (iter);
1504 open_msg_from_header (header, NULL, win);
1505 g_object_unref (header);
1508 g_object_unref(headers);
1512 rf_helper_window_closed (gpointer data,
1515 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1517 helper->parent_window = NULL;
1520 static ReplyForwardHelper*
1521 create_reply_forward_helper (ReplyForwardAction action,
1523 guint reply_forward_type,
1527 ReplyForwardHelper *rf_helper = NULL;
1528 const gchar *active_acc = modest_window_get_active_account (win);
1529 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1531 rf_helper = g_slice_new0 (ReplyForwardHelper);
1532 rf_helper->reply_forward_type = reply_forward_type;
1533 rf_helper->action = action;
1534 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1535 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1536 rf_helper->account_name = (active_acc) ?
1537 g_strdup (active_acc) :
1538 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1539 rf_helper->mailbox = g_strdup (active_mailbox);
1541 rf_helper->parts = g_object_ref (parts);
1543 rf_helper->parts = NULL;
1545 /* Note that window could be destroyed just AFTER calling
1546 register_window so we must ensure that this pointer does
1547 not hold invalid references */
1548 if (rf_helper->parent_window)
1549 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1550 rf_helper_window_closed, rf_helper);
1556 free_reply_forward_helper (gpointer data)
1558 ReplyForwardHelper *helper;
1560 helper = (ReplyForwardHelper *) data;
1561 g_free (helper->account_name);
1562 g_free (helper->mailbox);
1564 g_object_unref (helper->header);
1566 g_object_unref (helper->parts);
1567 if (helper->parent_window)
1568 g_object_weak_unref (G_OBJECT (helper->parent_window),
1569 rf_helper_window_closed, helper);
1570 g_slice_free (ReplyForwardHelper, helper);
1574 reply_forward_cb (ModestMailOperation *mail_op,
1581 TnyMsg *new_msg = NULL;
1582 ReplyForwardHelper *rf_helper;
1583 ModestWindow *msg_win = NULL;
1584 ModestEditType edit_type;
1586 TnyAccount *account = NULL;
1587 ModestWindowMgr *mgr = NULL;
1588 gchar *signature = NULL;
1589 gboolean use_signature;
1592 /* If there was any error. The mail operation could be NULL,
1593 this means that we already have the message downloaded and
1594 that we didn't do a mail operation to retrieve it */
1595 rf_helper = (ReplyForwardHelper *) user_data;
1596 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1599 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1600 rf_helper->account_name, rf_helper->mailbox);
1601 recipient = modest_text_utils_get_email_address (from);
1602 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1607 /* Create reply mail */
1608 switch (rf_helper->action) {
1609 /* Use the msg_header to ensure that we have all the
1610 information. The summary can lack some data */
1611 TnyHeader *msg_header;
1613 msg_header = tny_msg_get_header (msg);
1615 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1616 (use_signature) ? signature : NULL,
1617 rf_helper->reply_forward_type,
1618 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1619 g_object_unref (msg_header);
1621 case ACTION_REPLY_TO_ALL:
1622 msg_header = tny_msg_get_header (msg);
1624 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1625 (use_signature) ? signature : NULL,
1626 rf_helper->reply_forward_type,
1627 MODEST_TNY_MSG_REPLY_MODE_ALL);
1628 edit_type = MODEST_EDIT_TYPE_REPLY;
1629 g_object_unref (msg_header);
1631 case ACTION_FORWARD:
1633 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1634 rf_helper->reply_forward_type);
1635 edit_type = MODEST_EDIT_TYPE_FORWARD;
1638 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1640 g_return_if_reached ();
1648 g_warning ("%s: failed to create message\n", __FUNCTION__);
1652 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1653 rf_helper->account_name,
1654 TNY_ACCOUNT_TYPE_STORE);
1656 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1660 /* Create and register the windows */
1661 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1662 mgr = modest_runtime_get_window_mgr ();
1663 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1665 /* Note that register_window could have deleted the account */
1666 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1667 gdouble parent_zoom;
1669 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1670 modest_window_set_zoom (msg_win, parent_zoom);
1673 /* Show edit window */
1674 gtk_widget_show_all (GTK_WIDGET (msg_win));
1677 /* We always unregister the header because the message is
1678 forwarded or replied so the original one is no longer
1680 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1683 g_object_unref (G_OBJECT (new_msg));
1685 g_object_unref (G_OBJECT (account));
1686 free_reply_forward_helper (rf_helper);
1689 /* Checks a list of headers. If any of them are not currently
1690 * downloaded (CACHED) then returns TRUE else returns FALSE.
1693 header_list_count_uncached_msgs (TnyList *header_list)
1696 gint uncached_messages = 0;
1698 iter = tny_list_create_iterator (header_list);
1699 while (!tny_iterator_is_done (iter)) {
1702 header = TNY_HEADER (tny_iterator_get_current (iter));
1704 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1705 uncached_messages ++;
1706 g_object_unref (header);
1709 tny_iterator_next (iter);
1711 g_object_unref (iter);
1713 return uncached_messages;
1716 /* Returns FALSE if the user does not want to download the
1717 * messages. Returns TRUE if the user allowed the download.
1720 connect_to_get_msg (ModestWindow *win,
1721 gint num_of_uncached_msgs,
1722 TnyAccount *account)
1724 GtkResponseType response;
1725 GtkWindow *toplevel;
1727 /* Allways download if we are online. */
1728 if (tny_device_is_online (modest_runtime_get_device ()))
1731 /* If offline, then ask for user permission to download the messages */
1732 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1733 response = modest_platform_run_confirmation_dialog (toplevel,
1734 ngettext("mcen_nc_get_msg",
1736 num_of_uncached_msgs));
1738 if (response == GTK_RESPONSE_CANCEL)
1741 return modest_platform_connect_and_wait(toplevel, account);
1745 reply_forward_performer (gboolean canceled,
1747 ModestWindow *parent_window,
1748 TnyAccount *account,
1751 ReplyForwardHelper *rf_helper = NULL;
1752 ModestMailOperation *mail_op;
1754 rf_helper = (ReplyForwardHelper *) user_data;
1756 if (canceled || err) {
1757 free_reply_forward_helper (rf_helper);
1761 /* Retrieve the message */
1762 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1763 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1764 modest_ui_actions_disk_operations_error_handler,
1766 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1767 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1770 g_object_unref(mail_op);
1774 all_parts_retrieved (TnyMimePart *part)
1776 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1779 TnyList *pending_parts;
1780 TnyIterator *iterator;
1781 gboolean all_retrieved = TRUE;
1783 pending_parts = TNY_LIST (tny_simple_list_new ());
1784 tny_mime_part_get_parts (part, pending_parts);
1785 iterator = tny_list_create_iterator (pending_parts);
1786 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1789 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1791 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1792 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1794 all_retrieved = FALSE;
1797 g_object_unref (child);
1798 tny_iterator_next (iterator);
1800 g_object_unref (iterator);
1801 g_object_unref (pending_parts);
1802 return all_retrieved;
1807 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1810 TnyIterator *iterator;
1812 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
1813 tny_list_append (list, G_OBJECT (part));
1815 parts = TNY_LIST (tny_simple_list_new ());
1816 tny_mime_part_get_parts (part, parts);
1817 for (iterator = tny_list_create_iterator (parts);
1818 !tny_iterator_is_done (iterator);
1819 tny_iterator_next (iterator)) {
1822 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1823 forward_pending_parts_helper (child, list);
1824 g_object_unref (child);
1826 g_object_unref (iterator);
1827 g_object_unref (parts);
1831 forward_pending_parts (TnyMsg *msg)
1833 TnyList *result = TNY_LIST (tny_simple_list_new ());
1834 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
1835 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
1842 * Common code for the reply and forward actions
1845 reply_forward (ReplyForwardAction action, ModestWindow *win)
1847 ReplyForwardHelper *rf_helper = NULL;
1848 guint reply_forward_type;
1850 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1852 /* we check for low-mem; in that case, show a warning, and don't allow
1853 * reply/forward (because it could potentially require a lot of memory */
1854 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1858 /* we need an account when editing */
1859 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1860 if (!modest_ui_actions_run_account_setup_wizard (win))
1864 reply_forward_type =
1865 modest_conf_get_int (modest_runtime_get_conf (),
1866 (action == ACTION_FORWARD) ?
1867 MODEST_CONF_FORWARD_TYPE :
1868 MODEST_CONF_REPLY_TYPE,
1871 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1873 TnyHeader *header = NULL;
1874 /* Get header and message. Do not free them here, the
1875 reply_forward_cb must do it */
1876 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1877 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1879 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
1881 rf_helper = create_reply_forward_helper (action, win,
1882 reply_forward_type, header, NULL);
1883 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1885 gboolean do_download = TRUE;
1887 if (msg && header && action == ACTION_FORWARD) {
1888 /* Not all parts retrieved. Then we have to retrieve them all before
1889 * creating the forward message */
1890 if (!tny_device_is_online (modest_runtime_get_device ())) {
1892 GtkWindow *toplevel;
1894 /* If ask for user permission to download the messages */
1895 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1896 response = modest_platform_run_confirmation_dialog (toplevel,
1897 ngettext("mcen_nc_get_msg",
1901 /* End if the user does not want to continue */
1902 if (response == GTK_RESPONSE_CANCEL)
1903 do_download = FALSE;
1907 TnyList *pending_parts;
1909 TnyAccount *account;
1912 pending_parts = forward_pending_parts (msg);
1913 rf_helper = create_reply_forward_helper (action, win,
1914 reply_forward_type, header, pending_parts);
1915 g_object_unref (pending_parts);
1917 folder = tny_header_get_folder (header);
1918 account = tny_folder_get_account (folder);
1919 modest_platform_connect_and_perform (win,
1921 reply_forward_performer,
1923 g_object_unref (folder);
1924 g_object_unref (account);
1928 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1933 g_object_unref (msg);
1935 g_object_unref (header);
1937 TnyHeader *header = NULL;
1939 gboolean do_retrieve = TRUE;
1940 TnyList *header_list = NULL;
1942 header_list = get_selected_headers (win);
1945 /* Check that only one message is selected for replying */
1946 if (tny_list_get_length (header_list) != 1) {
1947 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1948 NULL, _("mcen_ib_select_one_message"));
1949 g_object_unref (header_list);
1953 /* Only reply/forward to one message */
1954 iter = tny_list_create_iterator (header_list);
1955 header = TNY_HEADER (tny_iterator_get_current (iter));
1956 g_object_unref (iter);
1958 /* Retrieve messages */
1959 do_retrieve = (action == ACTION_FORWARD) ||
1960 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1963 TnyAccount *account = NULL;
1964 TnyFolder *folder = NULL;
1965 gdouble download = TRUE;
1966 guint uncached_msgs = 0;
1968 folder = tny_header_get_folder (header);
1970 goto do_retrieve_frees;
1971 account = tny_folder_get_account (folder);
1973 goto do_retrieve_frees;
1975 uncached_msgs = header_list_count_uncached_msgs (header_list);
1977 if (uncached_msgs > 0) {
1978 /* Allways download if we are online. */
1979 if (!tny_device_is_online (modest_runtime_get_device ())) {
1981 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1983 /* If ask for user permission to download the messages */
1984 response = modest_platform_run_confirmation_dialog (toplevel,
1985 ngettext("mcen_nc_get_msg",
1989 /* End if the user does not want to continue */
1990 if (response == GTK_RESPONSE_CANCEL)
1997 rf_helper = create_reply_forward_helper (action, win,
1998 reply_forward_type, header, NULL);
1999 if (uncached_msgs > 0) {
2000 modest_platform_connect_and_perform (win,
2002 reply_forward_performer,
2005 reply_forward_performer (FALSE, NULL, win,
2006 account, rf_helper);
2011 g_object_unref (account);
2013 g_object_unref (folder);
2015 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2018 g_object_unref (header_list);
2019 g_object_unref (header);
2024 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2026 g_return_if_fail (MODEST_IS_WINDOW(win));
2028 reply_forward (ACTION_REPLY, win);
2032 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2034 g_return_if_fail (MODEST_IS_WINDOW(win));
2036 reply_forward (ACTION_FORWARD, win);
2040 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2042 g_return_if_fail (MODEST_IS_WINDOW(win));
2044 reply_forward (ACTION_REPLY_TO_ALL, win);
2048 modest_ui_actions_on_next (GtkAction *action,
2049 ModestWindow *window)
2051 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2052 modest_msg_view_window_select_next_message (
2053 MODEST_MSG_VIEW_WINDOW (window));
2055 g_return_if_reached ();
2060 modest_ui_actions_on_prev (GtkAction *action,
2061 ModestWindow *window)
2063 g_return_if_fail (MODEST_IS_WINDOW(window));
2065 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2066 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2068 g_return_if_reached ();
2073 modest_ui_actions_on_sort (GtkAction *action,
2074 ModestWindow *window)
2076 GtkWidget *header_view = NULL;
2078 g_return_if_fail (MODEST_IS_WINDOW(window));
2080 if (MODEST_IS_HEADER_WINDOW (window)) {
2081 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2085 modest_platform_information_banner (NULL, NULL, _CS_NOTHING_TO_SORT);
2090 /* Show sorting dialog */
2091 modest_utils_run_sort_dialog (MODEST_WINDOW (window), MODEST_SORT_HEADERS);
2095 sync_folder_cb (ModestMailOperation *mail_op,
2099 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2101 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2102 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2104 /* We must clear first, because otherwise set_folder will ignore */
2105 /* the change as the folders are the same */
2106 modest_header_view_clear (header_view);
2107 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2109 g_object_unref (parent);
2112 g_object_unref (header_view);
2116 idle_refresh_folder (gpointer source)
2118 ModestHeaderView *header_view = NULL;
2120 /* If the window still exists */
2121 if (!GTK_IS_WIDGET (source) ||
2122 !GTK_WIDGET_VISIBLE (source))
2125 /* Refresh the current view */
2126 if (MODEST_IS_HEADER_WINDOW (source))
2127 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2129 TnyFolder *folder = modest_header_view_get_folder (header_view);
2131 /* Sync the folder status */
2132 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2133 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2134 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2135 g_object_unref (folder);
2136 g_object_unref (mail_op);
2144 update_account_cb (ModestMailOperation *self,
2145 TnyList *new_headers,
2149 gboolean show_visual_notifications;
2151 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2152 show_visual_notifications = (top) ? FALSE : TRUE;
2154 /* Notify new messages have been downloaded. If the
2155 send&receive was invoked by the user then do not show any
2156 visual notification, only play a sound and activate the LED
2157 (for the Maemo version) */
2158 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2160 /* We only notify about really new messages (not seen) we get */
2161 TnyList *actually_new_list;
2162 TnyIterator *iterator;
2163 actually_new_list = TNY_LIST (tny_simple_list_new ());
2164 for (iterator = tny_list_create_iterator (new_headers);
2165 !tny_iterator_is_done (iterator);
2166 tny_iterator_next (iterator)) {
2168 TnyHeaderFlags flags;
2169 header = TNY_HEADER (tny_iterator_get_current (iterator));
2170 flags = tny_header_get_flags (header);
2172 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2173 /* Messages are ordered from most
2174 recent to oldest. But we want to
2175 show notifications starting from
2176 the oldest message. That's why we
2178 tny_list_prepend (actually_new_list, G_OBJECT (header));
2180 g_object_unref (header);
2182 g_object_unref (iterator);
2184 if (tny_list_get_length (actually_new_list) > 0) {
2185 GList *new_headers_list = NULL;
2187 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2189 /* Send notifications */
2190 if (new_headers_list) {
2191 modest_platform_on_new_headers_received (new_headers_list,
2192 show_visual_notifications);
2194 modest_utils_free_notification_list (new_headers_list);
2197 g_object_unref (actually_new_list);
2201 /* Refresh the current folder in an idle. We do this
2202 in order to avoid refresh cancelations if the
2203 currently viewed folder is the inbox */
2204 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2205 idle_refresh_folder,
2212 TnyAccount *account;
2214 gchar *account_name;
2215 gboolean poke_status;
2216 gboolean interactive;
2217 ModestMailOperation *mail_op;
2221 do_send_receive_performer (gboolean canceled,
2223 ModestWindow *parent_window,
2224 TnyAccount *account,
2227 SendReceiveInfo *info;
2229 info = (SendReceiveInfo *) user_data;
2231 if (err || canceled) {
2232 /* In disk full conditions we could get this error here */
2233 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2234 (GtkWidget *) parent_window, err,
2237 if (info->mail_op) {
2238 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2245 /* Send & receive. */
2246 modest_mail_operation_update_account (info->mail_op, info->account_name,
2247 info->poke_status, info->interactive,
2248 update_account_cb, info->win);
2253 g_object_unref (G_OBJECT (info->mail_op));
2254 if (info->account_name)
2255 g_free (info->account_name);
2257 g_object_unref (info->win);
2259 g_object_unref (info->account);
2260 g_slice_free (SendReceiveInfo, info);
2264 * This function performs the send & receive required actions. The
2265 * window is used to create the mail operation. Typically it should
2266 * always be the main window, but we pass it as argument in order to
2270 modest_ui_actions_do_send_receive (const gchar *account_name,
2271 gboolean force_connection,
2272 gboolean poke_status,
2273 gboolean interactive,
2276 gchar *acc_name = NULL;
2277 SendReceiveInfo *info;
2278 ModestTnyAccountStore *acc_store;
2279 TnyAccount *account;
2281 /* If no account name was provided then get the current account, and if
2282 there is no current account then pick the default one: */
2283 if (!account_name) {
2285 acc_name = g_strdup (modest_window_get_active_account (win));
2287 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2289 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2293 acc_name = g_strdup (account_name);
2296 acc_store = modest_runtime_get_account_store ();
2297 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2301 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2305 /* Do not automatically refresh accounts that are flagged as
2306 NO_AUTO_UPDATE. This could be useful for accounts that
2307 handle their own update times */
2309 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2310 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2311 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2312 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2314 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2315 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2316 g_object_unref (account);
2323 /* Create the info for the connect and perform */
2324 info = g_slice_new (SendReceiveInfo);
2325 info->account_name = acc_name;
2326 info->win = (win) ? g_object_ref (win) : NULL;
2327 info->poke_status = poke_status;
2328 info->interactive = interactive;
2329 info->account = account;
2330 /* We need to create the operation here, because otherwise it
2331 could happen that the queue emits the queue-empty signal
2332 while we're trying to connect the account */
2333 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2334 modest_ui_actions_disk_operations_error_handler,
2336 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2338 /* Invoke the connect and perform */
2339 modest_platform_connect_and_perform (win, force_connection, info->account,
2340 do_send_receive_performer, info);
2345 modest_ui_actions_do_cancel_send (const gchar *account_name,
2348 TnyTransportAccount *transport_account;
2349 TnySendQueue *send_queue = NULL;
2350 GError *error = NULL;
2352 /* Get transport account */
2354 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2355 (modest_runtime_get_account_store(),
2357 TNY_ACCOUNT_TYPE_TRANSPORT));
2358 if (!transport_account) {
2359 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2364 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2365 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2366 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2367 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2368 "modest: could not find send queue for account\n");
2370 /* Cancel the current send */
2371 tny_account_cancel (TNY_ACCOUNT (transport_account));
2373 /* Suspend all pending messages */
2374 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2378 if (transport_account != NULL)
2379 g_object_unref (G_OBJECT (transport_account));
2383 modest_ui_actions_cancel_send_all (ModestWindow *win)
2385 GSList *account_names, *iter;
2387 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2390 iter = account_names;
2392 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2393 iter = g_slist_next (iter);
2396 modest_account_mgr_free_account_names (account_names);
2397 account_names = NULL;
2401 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2404 /* Check if accounts exist */
2405 gboolean accounts_exist =
2406 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2408 /* If not, allow the user to create an account before trying to send/receive. */
2409 if (!accounts_exist)
2410 modest_ui_actions_on_accounts (NULL, win);
2412 /* Cancel all sending operaitons */
2413 modest_ui_actions_cancel_send_all (win);
2417 * Refreshes all accounts. This function will be used by automatic
2421 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2422 gboolean force_connection,
2423 gboolean poke_status,
2424 gboolean interactive)
2426 GSList *account_names, *iter;
2428 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2431 iter = account_names;
2433 modest_ui_actions_do_send_receive ((const char*) iter->data,
2435 poke_status, interactive, win);
2436 iter = g_slist_next (iter);
2439 modest_account_mgr_free_account_names (account_names);
2440 account_names = NULL;
2444 * Handler of the click on Send&Receive button in the main toolbar
2447 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2449 /* Check if accounts exist */
2450 gboolean accounts_exist;
2453 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2455 /* If not, allow the user to create an account before trying to send/receive. */
2456 if (!accounts_exist)
2457 modest_ui_actions_on_accounts (NULL, win);
2459 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2460 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2461 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2463 const gchar *active_account;
2464 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2466 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2473 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2476 ModestWindow *window)
2478 GtkTreeRowReference *rowref;
2480 g_return_if_fail (MODEST_IS_WINDOW(window));
2481 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2482 g_return_if_fail (TNY_IS_HEADER (header));
2484 if (modest_header_view_count_selected_headers (header_view) > 1) {
2485 /* Don't allow activation if there are more than one message selected */
2486 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2490 /* we check for low-mem; in that case, show a warning, and don't allow
2491 * activating headers
2493 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2497 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2498 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2499 gtk_tree_row_reference_free (rowref);
2503 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2509 GtkWindow *toplevel;
2511 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
2512 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2514 online = tny_device_is_online (modest_runtime_get_device());
2517 /* already online -- the item is simply not there... */
2518 dialog = gtk_message_dialog_new (toplevel,
2520 GTK_MESSAGE_WARNING,
2522 _("The %s you selected cannot be found"),
2524 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2525 gtk_dialog_run (GTK_DIALOG(dialog));
2527 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2530 _("mcen_bd_dialog_cancel"),
2531 GTK_RESPONSE_REJECT,
2532 _("mcen_bd_dialog_ok"),
2533 GTK_RESPONSE_ACCEPT,
2535 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2536 "Do you want to get online?"), item);
2537 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2538 gtk_label_new (txt), FALSE, FALSE, 0);
2539 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2542 gtk_window_set_default_size ((GtkWindow *) dialog, 300, 300);
2543 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2544 /* TODO: Comment about why is this commented out: */
2545 /* modest_platform_connect_and_wait (); */
2548 gtk_widget_destroy (dialog);
2552 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2555 /* g_debug ("%s %s", __FUNCTION__, link); */
2560 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2563 modest_platform_activate_uri (link);
2567 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2570 modest_platform_show_uri_popup (link);
2574 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2577 /* we check for low-mem; in that case, show a warning, and don't allow
2578 * viewing attachments
2580 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2583 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2587 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2588 const gchar *address,
2591 /* g_debug ("%s %s", __FUNCTION__, address); */
2595 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2596 TnyMsg *saved_draft,
2599 ModestMsgEditWindow *edit_window;
2601 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2603 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2605 /* Set draft is there was no error */
2606 if (!modest_mail_operation_get_error (mail_op))
2607 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2609 g_object_unref(edit_window);
2613 enough_space_for_message (ModestMsgEditWindow *edit_window,
2616 guint64 available_disk, expected_size;
2621 available_disk = modest_utils_get_available_space (NULL);
2622 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2623 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2628 /* Double check: disk full condition or message too big */
2629 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2630 expected_size > available_disk) {
2631 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2632 modest_platform_information_banner (NULL, NULL, msg);
2639 * djcb: if we're in low-memory state, we only allow for
2640 * saving messages smaller than
2641 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2642 * should still allow for sending anything critical...
2644 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2645 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2649 * djcb: we also make sure that the attachments are smaller than the max size
2650 * this is for the case where we'd try to forward a message with attachments
2651 * bigger than our max allowed size, or sending an message from drafts which
2652 * somehow got past our checks when attaching.
2654 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2655 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) edit_window);
2656 modest_platform_run_information_dialog (toplevel,
2657 _("mail_ib_error_attachment_size"),
2666 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2668 TnyTransportAccount *transport_account;
2669 ModestMailOperation *mail_operation;
2671 gchar *account_name;
2672 ModestAccountMgr *account_mgr;
2673 gboolean had_error = FALSE;
2675 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2677 data = modest_msg_edit_window_get_msg_data (edit_window);
2680 if (!enough_space_for_message (edit_window, data)) {
2681 modest_msg_edit_window_free_msg_data (edit_window, data);
2685 account_name = g_strdup (data->account_name);
2686 account_mgr = modest_runtime_get_account_mgr();
2688 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2690 account_name = modest_account_mgr_get_default_account (account_mgr);
2691 if (!account_name) {
2692 g_printerr ("modest: no account found\n");
2693 modest_msg_edit_window_free_msg_data (edit_window, data);
2697 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2698 account_name = g_strdup (data->account_name);
2702 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2703 (modest_runtime_get_account_store (),
2705 TNY_ACCOUNT_TYPE_TRANSPORT));
2706 if (!transport_account) {
2707 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2708 g_free (account_name);
2709 modest_msg_edit_window_free_msg_data (edit_window, data);
2713 /* Create the mail operation */
2714 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2716 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2718 modest_mail_operation_save_to_drafts (mail_operation,
2730 data->priority_flags,
2733 on_save_to_drafts_cb,
2734 g_object_ref(edit_window));
2736 /* In hildon2 we always show the information banner on saving to drafts.
2737 * It will be a system information banner in this case.
2739 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2740 modest_platform_information_banner (NULL, NULL, text);
2742 modest_msg_edit_window_set_modified (edit_window, FALSE);
2745 g_free (account_name);
2746 g_object_unref (G_OBJECT (transport_account));
2747 g_object_unref (G_OBJECT (mail_operation));
2749 modest_msg_edit_window_free_msg_data (edit_window, data);
2755 /* For instance, when clicking the Send toolbar button when editing a message: */
2757 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2759 TnyTransportAccount *transport_account = NULL;
2760 gboolean had_error = FALSE, add_to_contacts;
2762 ModestAccountMgr *account_mgr;
2763 gchar *account_name;
2764 ModestMailOperation *mail_operation;
2767 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2769 /* Check whether to automatically add new contacts to addressbook or not */
2770 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
2771 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
2772 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
2775 data = modest_msg_edit_window_get_msg_data (edit_window);
2777 recipients = g_strconcat (data->to?data->to:"",
2778 data->cc?data->cc:"",
2779 data->bcc?data->bcc:"",
2781 if (recipients == NULL || recipients[0] == '\0') {
2782 /* Empty subject -> no send */
2783 g_free (recipients);
2784 modest_msg_edit_window_free_msg_data (edit_window, data);
2787 g_free (recipients);
2790 if (!enough_space_for_message (edit_window, data)) {
2791 modest_msg_edit_window_free_msg_data (edit_window, data);
2795 account_mgr = modest_runtime_get_account_mgr();
2796 account_name = g_strdup (data->account_name);
2798 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2801 account_name = modest_account_mgr_get_default_account (account_mgr);
2803 if (!account_name) {
2804 modest_msg_edit_window_free_msg_data (edit_window, data);
2805 /* Run account setup wizard */
2806 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2811 /* Get the currently-active transport account for this modest account: */
2812 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2814 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2815 (modest_runtime_get_account_store (),
2816 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2819 if (!transport_account) {
2820 modest_msg_edit_window_free_msg_data (edit_window, data);
2821 /* Run account setup wizard */
2822 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2827 /* Create the mail operation */
2828 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2829 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2831 modest_mail_operation_send_new_mail (mail_operation,
2845 data->priority_flags);
2847 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2848 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2850 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2851 const GError *error = modest_mail_operation_get_error (mail_operation);
2852 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2853 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2854 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2855 modest_platform_information_banner (NULL, NULL, _CS_NOT_ENOUGH_MEMORY);
2861 g_free (account_name);
2862 g_object_unref (G_OBJECT (transport_account));
2863 g_object_unref (G_OBJECT (mail_operation));
2865 modest_msg_edit_window_free_msg_data (edit_window, data);
2868 modest_msg_edit_window_set_sent (edit_window, TRUE);
2870 /* Save settings and close the window: */
2871 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2878 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2879 ModestMsgEditWindow *window)
2881 ModestMsgEditFormatState *format_state = NULL;
2883 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2884 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2886 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2889 format_state = modest_msg_edit_window_get_format_state (window);
2890 g_return_if_fail (format_state != NULL);
2892 format_state->bold = gtk_toggle_action_get_active (action);
2893 modest_msg_edit_window_set_format_state (window, format_state);
2894 g_free (format_state);
2899 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2900 ModestMsgEditWindow *window)
2902 ModestMsgEditFormatState *format_state = NULL;
2904 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2905 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2907 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2910 format_state = modest_msg_edit_window_get_format_state (window);
2911 g_return_if_fail (format_state != NULL);
2913 format_state->italics = gtk_toggle_action_get_active (action);
2914 modest_msg_edit_window_set_format_state (window, format_state);
2915 g_free (format_state);
2920 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2921 ModestMsgEditWindow *window)
2923 ModestMsgEditFormatState *format_state = NULL;
2925 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2926 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2928 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2931 format_state = modest_msg_edit_window_get_format_state (window);
2932 g_return_if_fail (format_state != NULL);
2934 format_state->bullet = gtk_toggle_action_get_active (action);
2935 modest_msg_edit_window_set_format_state (window, format_state);
2936 g_free (format_state);
2941 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2942 GtkRadioAction *selected,
2943 ModestMsgEditWindow *window)
2945 ModestMsgEditFormatState *format_state = NULL;
2946 GtkJustification value;
2948 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2950 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2953 value = gtk_radio_action_get_current_value (selected);
2955 format_state = modest_msg_edit_window_get_format_state (window);
2956 g_return_if_fail (format_state != NULL);
2958 format_state->justification = value;
2959 modest_msg_edit_window_set_format_state (window, format_state);
2960 g_free (format_state);
2964 modest_ui_actions_on_select_editor_color (GtkAction *action,
2965 ModestMsgEditWindow *window)
2967 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2968 g_return_if_fail (GTK_IS_ACTION (action));
2970 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2973 modest_msg_edit_window_select_color (window);
2977 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2978 ModestMsgEditWindow *window)
2980 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2981 g_return_if_fail (GTK_IS_ACTION (action));
2983 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2989 modest_ui_actions_on_insert_image (GObject *object,
2990 ModestMsgEditWindow *window)
2992 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2995 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2998 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3001 modest_msg_edit_window_insert_image (window);
3005 modest_ui_actions_on_attach_file (GtkAction *action,
3006 ModestMsgEditWindow *window)
3008 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3009 g_return_if_fail (GTK_IS_ACTION (action));
3011 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3014 modest_msg_edit_window_offer_attach_file (window);
3018 modest_ui_actions_on_remove_attachments (GtkAction *action,
3019 ModestMsgEditWindow *window)
3021 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3023 modest_msg_edit_window_remove_attachments (window, NULL);
3027 do_create_folder_cb (ModestMailOperation *mail_op,
3028 TnyFolderStore *parent_folder,
3029 TnyFolder *new_folder,
3032 gchar *suggested_name = (gchar *) user_data;
3033 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3034 const GError *error;
3036 error = modest_mail_operation_get_error (mail_op);
3038 gboolean disk_full = FALSE;
3039 TnyAccount *account;
3040 /* Show an error. If there was some problem writing to
3041 disk, show it, otherwise show the generic folder
3042 create error. We do it here and not in an error
3043 handler because the call to do_create_folder will
3044 stop the main loop in a gtk_dialog_run and then,
3045 the message won't be shown until that dialog is
3047 account = modest_mail_operation_get_account (mail_op);
3050 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3051 (GtkWidget *) source_win,
3054 _("mail_in_ui_folder_create_error_memory"));
3055 g_object_unref (account);
3058 /* Show an error and try again if there is no
3059 full memory condition */
3060 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3061 _("mail_in_ui_folder_create_error"));
3062 do_create_folder ((ModestWindow *) source_win,
3063 parent_folder, (const gchar *) suggested_name);
3067 /* the 'source_win' is either the ModestWindow, or the 'Move to folder'-dialog
3068 * FIXME: any other? */
3069 GtkWidget *folder_view;
3071 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3072 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3074 /* Select the newly created folder. It could happen
3075 that the widget is no longer there (i.e. the window
3076 has been destroyed, so we need to check this */
3078 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3080 g_object_unref (new_folder);
3082 /* Free. Note that the first time it'll be NULL so noop */
3083 g_free (suggested_name);
3084 g_object_unref (source_win);
3089 TnyFolderStore *parent;
3090 } CreateFolderConnect;
3093 do_create_folder_performer (gboolean canceled,
3095 ModestWindow *parent_window,
3096 TnyAccount *account,
3099 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3100 ModestMailOperation *mail_op;
3102 if (canceled || err) {
3103 /* In disk full conditions we could get this error here */
3104 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3105 (GtkWidget *) parent_window, err,
3106 NULL, _("mail_in_ui_folder_create_error_memory"));
3108 /* This happens if we have selected the outbox folder
3110 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3111 TNY_IS_MERGE_FOLDER (helper->parent)) {
3112 /* Show an error and retry */
3113 modest_platform_information_banner ((GtkWidget *) parent_window,
3115 _("mail_in_ui_folder_create_error"));
3117 do_create_folder (parent_window, helper->parent, helper->folder_name);
3123 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3124 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3126 modest_mail_operation_create_folder (mail_op,
3128 (const gchar *) helper->folder_name,
3129 do_create_folder_cb,
3130 g_strdup (helper->folder_name));
3131 g_object_unref (mail_op);
3135 g_object_unref (helper->parent);
3136 if (helper->folder_name)
3137 g_free (helper->folder_name);
3138 g_slice_free (CreateFolderConnect, helper);
3143 do_create_folder (ModestWindow *parent_window,
3144 TnyFolderStore *suggested_parent,
3145 const gchar *suggested_name)
3148 gchar *folder_name = NULL;
3149 TnyFolderStore *parent_folder = NULL;
3150 GtkWindow *toplevel;
3152 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
3153 result = modest_platform_run_new_folder_dialog (toplevel,
3155 (gchar *) suggested_name,
3159 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3160 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3161 helper->folder_name = g_strdup (folder_name);
3162 helper->parent = g_object_ref (parent_folder);
3164 modest_platform_connect_if_remote_and_perform (parent_window,
3167 do_create_folder_performer,
3172 g_free (folder_name);
3174 g_object_unref (parent_folder);
3178 modest_ui_actions_create_folder(GtkWindow *parent_window,
3179 GtkWidget *folder_view,
3180 TnyFolderStore *parent_folder)
3182 if (!parent_folder) {
3183 ModestTnyAccountStore *acc_store;
3185 acc_store = modest_runtime_get_account_store ();
3187 parent_folder = (TnyFolderStore *)
3188 modest_tny_account_store_get_local_folders_account (acc_store);
3191 if (parent_folder) {
3192 do_create_folder (MODEST_WINDOW (parent_window), parent_folder, NULL);
3193 g_object_unref (parent_folder);
3198 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3201 g_return_if_fail (MODEST_IS_WINDOW(window));
3203 if (MODEST_IS_FOLDER_WINDOW (window)) {
3204 GtkWidget *folder_view;
3205 GtkWindow *toplevel;
3207 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3208 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
3209 modest_ui_actions_create_folder (toplevel, folder_view, NULL);
3211 g_assert_not_reached ();
3216 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3219 const GError *error = NULL;
3220 gchar *message = NULL;
3222 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3224 /* Get error message */
3225 error = modest_mail_operation_get_error (mail_op);
3227 g_return_if_reached ();
3229 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3230 (GError *) error, account);
3232 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3233 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3234 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3235 message = _CS_FOLDER_ALREADY_EXISTS;
3236 } else if (error->domain == TNY_ERROR_DOMAIN &&
3237 error->code == TNY_SERVICE_ERROR_STATE) {
3238 /* This means that the folder is already in use (a
3239 message is opened for example */
3240 message = _("emev_ni_internal_error");
3242 message = _CS_UNABLE_TO_RENAME;
3245 /* We don't set a parent for the dialog because the dialog
3246 will be destroyed so the banner won't appear */
3247 modest_platform_information_banner (NULL, NULL, message);
3250 g_object_unref (account);
3256 TnyFolderStore *folder;
3261 on_rename_folder_cb (ModestMailOperation *mail_op,
3262 TnyFolder *new_folder,
3265 ModestFolderView *folder_view;
3267 /* If the window was closed when renaming a folder, or if
3268 * it's not a main window this will happen */
3269 if (!MODEST_IS_FOLDER_VIEW (user_data))
3272 folder_view = MODEST_FOLDER_VIEW (user_data);
3273 /* Note that if the rename fails new_folder will be NULL */
3275 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3277 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3281 on_rename_folder_performer (gboolean canceled,
3283 ModestWindow *parent_window,
3284 TnyAccount *account,
3287 ModestMailOperation *mail_op = NULL;
3288 GtkTreeSelection *sel = NULL;
3289 GtkWidget *folder_view = NULL;
3290 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3292 if (canceled || err) {
3293 /* In disk full conditions we could get this error here */
3294 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3295 (GtkWidget *) parent_window, err,
3300 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3301 modest_ui_actions_rename_folder_error_handler,
3302 parent_window, NULL);
3304 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3306 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3307 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3308 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3311 /* Clear the folders view */
3312 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3313 gtk_tree_selection_unselect_all (sel);
3315 /* Actually rename the folder */
3316 modest_mail_operation_rename_folder (mail_op,
3317 TNY_FOLDER (data->folder),
3318 (const gchar *) (data->new_name),
3319 on_rename_folder_cb,
3321 g_object_unref (mail_op);
3324 g_object_unref (data->folder);
3325 g_free (data->new_name);
3330 modest_ui_actions_on_rename_folder (GtkAction *action,
3331 ModestWindow *window)
3333 modest_ui_actions_on_edit_mode_rename_folder (window);
3337 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3339 TnyFolderStore *folder;
3340 GtkWidget *folder_view;
3341 gboolean do_rename = TRUE;
3343 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3345 if (MODEST_IS_FOLDER_WINDOW (window)) {
3346 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3351 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3356 if (TNY_IS_FOLDER (folder)) {
3357 gchar *folder_name = NULL;
3359 const gchar *current_name;
3360 TnyFolderStore *parent;
3362 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3363 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3364 response = modest_platform_run_rename_folder_dialog (MODEST_WINDOW (window),
3365 parent, current_name,
3367 g_object_unref (parent);
3369 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3372 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3373 rename_folder_data->folder = g_object_ref (folder);
3374 rename_folder_data->new_name = folder_name;
3375 modest_platform_connect_if_remote_and_perform (window, TRUE,
3376 folder, on_rename_folder_performer, rename_folder_data);
3379 g_object_unref (folder);
3384 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3387 GObject *win = modest_mail_operation_get_source (mail_op);
3388 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
3390 modest_platform_run_information_dialog (toplevel,
3391 _("mail_in_ui_folder_delete_error"),
3393 g_object_unref (win);
3397 TnyFolderStore *folder;
3398 gboolean move_to_trash;
3402 on_delete_folder_cb (gboolean canceled,
3404 ModestWindow *parent_window,
3405 TnyAccount *account,
3408 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3409 GtkWidget *folder_view;
3410 ModestMailOperation *mail_op;
3411 GtkTreeSelection *sel;
3412 ModestWindow *modest_window;
3414 #ifdef MODEST_TOOLKIT_HILDON2
3415 modest_window = (ModestWindow*) parent_window;
3417 if (MODEST_IS_SHELL (parent_window)) {
3418 modest_window = modest_shell_peek_window (MODEST_SHELL (parent_window));
3420 modest_window = NULL;
3424 if (!MODEST_IS_WINDOW(modest_window) || canceled || (err!=NULL)) {
3425 /* Note that the connection process can fail due to
3426 memory low conditions as it can not successfully
3427 store the summary */
3428 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3429 (GtkWidget*) parent_window, err,
3431 g_debug ("Error connecting when trying to delete a folder");
3432 g_object_unref (G_OBJECT (info->folder));
3437 if (MODEST_IS_FOLDER_WINDOW (modest_window)) {
3438 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (modest_window)));
3440 g_object_unref (G_OBJECT (info->folder));
3445 /* Unselect the folder before deleting it to free the headers */
3446 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3447 gtk_tree_selection_unselect_all (sel);
3449 /* Create the mail operation */
3451 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3452 modest_ui_actions_delete_folder_error_handler,
3455 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3457 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3459 g_object_unref (mail_op);
3460 g_object_unref (info->folder);
3465 delete_folder (ModestWindow *window, gboolean move_to_trash)
3467 TnyFolderStore *folder;
3468 GtkWidget *folder_view;
3472 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3474 if (MODEST_IS_FOLDER_WINDOW (window)) {
3475 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3482 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3487 /* Show an error if it's an account */
3488 if (!TNY_IS_FOLDER (folder)) {
3489 modest_platform_run_information_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3490 _("mail_in_ui_folder_delete_error"),
3492 g_object_unref (G_OBJECT (folder));
3497 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3498 tny_folder_get_name (TNY_FOLDER (folder)));
3499 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3500 (const gchar *) message);
3503 if (response == GTK_RESPONSE_OK) {
3504 TnyAccount *account = NULL;
3505 DeleteFolderInfo *info = NULL;
3506 info = g_new0(DeleteFolderInfo, 1);
3507 info->folder = g_object_ref (folder);
3508 info->move_to_trash = move_to_trash;
3510 account = tny_folder_get_account (TNY_FOLDER (folder));
3511 modest_platform_connect_if_remote_and_perform (window,
3513 TNY_FOLDER_STORE (account),
3514 on_delete_folder_cb, info);
3515 g_object_unref (account);
3516 g_object_unref (folder);
3524 modest_ui_actions_on_delete_folder (GtkAction *action,
3525 ModestWindow *window)
3527 modest_ui_actions_on_edit_mode_delete_folder (window);
3531 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3533 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3535 return delete_folder (window, FALSE);
3539 typedef struct _PasswordDialogFields {
3540 GtkWidget *username;
3541 GtkWidget *password;
3543 } PasswordDialogFields;
3546 password_dialog_check_field (GtkEditable *editable,
3547 PasswordDialogFields *fields)
3550 gboolean any_value_empty = FALSE;
3552 value = modest_entry_get_text (fields->username);
3553 if ((value == NULL) || value[0] == '\0') {
3554 any_value_empty = TRUE;
3556 value = modest_entry_get_text (fields->password);
3557 if ((value == NULL) || value[0] == '\0') {
3558 any_value_empty = TRUE;
3560 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3564 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3565 const gchar* server_account_name,
3570 ModestWindow *window)
3572 g_return_if_fail(server_account_name);
3573 gboolean completed = FALSE;
3574 PasswordDialogFields *fields = NULL;
3576 /* Initalize output parameters: */
3583 #ifndef MODEST_TOOLKIT_GTK
3584 /* Maemo uses a different (awkward) button order,
3585 * It should probably just use gtk_alternative_dialog_button_order ().
3587 #ifdef MODEST_TOOLKIT_HILDON2
3589 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3593 GTK_RESPONSE_ACCEPT,
3595 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3596 HILDON_MARGIN_DOUBLE);
3599 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3602 _("mcen_bd_dialog_ok"),
3603 GTK_RESPONSE_ACCEPT,
3604 _("mcen_bd_dialog_cancel"),
3605 GTK_RESPONSE_REJECT,
3607 #endif /* MODEST_TOOLKIT_HILDON2 */
3610 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3614 GTK_RESPONSE_REJECT,
3616 GTK_RESPONSE_ACCEPT,
3618 #endif /* MODEST_TOOLKIT_GTK */
3620 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3622 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3623 modest_runtime_get_account_mgr(), server_account_name);
3624 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3625 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3628 gtk_widget_destroy (dialog);
3632 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3633 GtkWidget *label = gtk_label_new (txt);
3634 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3636 g_free (server_name);
3637 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3642 gchar *initial_username = modest_account_mgr_get_server_account_username (
3643 modest_runtime_get_account_mgr(), server_account_name);
3645 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3646 if (initial_username)
3647 modest_entry_set_text (entry_username, initial_username);
3649 /* Dim this if a connection has ever succeeded with this username,
3650 * as per the UI spec: */
3651 /* const gboolean username_known = */
3652 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3653 /* modest_runtime_get_account_mgr(), server_account_name); */
3654 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3656 /* We drop the username sensitive code and disallow changing it here
3657 * as tinymail does not support really changing the username in the callback
3659 gtk_widget_set_sensitive (entry_username, FALSE);
3661 /* Auto-capitalization is the default, so let's turn it off: */
3662 #ifdef MAEMO_CHANGES
3663 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3666 /* Create a size group to be used by all captions.
3667 * Note that HildonCaption does not create a default size group if we do not specify one.
3668 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3669 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3671 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3672 _("mail_fi_username"), FALSE,
3674 gtk_widget_show (entry_username);
3675 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3676 FALSE, FALSE, MODEST_MARGIN_HALF);
3677 gtk_widget_show (caption);
3680 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3681 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3682 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3684 /* Auto-capitalization is the default, so let's turn it off: */
3685 #ifdef MAEMO_CHANGES
3686 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3687 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3690 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3691 _("mail_fi_password"), FALSE,
3693 gtk_widget_show (entry_password);
3694 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3695 FALSE, FALSE, MODEST_MARGIN_HALF);
3696 gtk_widget_show (caption);
3697 g_object_unref (sizegroup);
3699 if (initial_username != NULL)
3700 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3702 /* This is not in the Maemo UI spec:
3703 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3704 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3708 fields = g_slice_new0 (PasswordDialogFields);
3709 fields->username = entry_username;
3710 fields->password = entry_password;
3711 fields->dialog = dialog;
3713 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3714 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3715 password_dialog_check_field (NULL, fields);
3717 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3719 while (!completed) {
3721 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3723 *username = g_strdup (modest_entry_get_text (entry_username));
3725 /* Note that an empty field becomes the "" string */
3726 if (*username && strlen (*username) > 0) {
3727 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3728 server_account_name,
3732 const gboolean username_was_changed =
3733 (strcmp (*username, initial_username) != 0);
3734 if (username_was_changed) {
3735 g_warning ("%s: tinymail does not yet support changing the "
3736 "username in the get_password() callback.\n", __FUNCTION__);
3742 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3743 _("mcen_ib_username_pw_incorrect"));
3749 *password = g_strdup (modest_entry_get_text (entry_password));
3751 /* We do not save the password in the configuration,
3752 * because this function is only called for passwords that should
3753 * not be remembered:
3754 modest_server_account_set_password (
3755 modest_runtime_get_account_mgr(), server_account_name,
3772 /* This is not in the Maemo UI spec:
3773 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3779 g_free (initial_username);
3780 gtk_widget_destroy (dialog);
3781 g_slice_free (PasswordDialogFields, fields);
3783 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3787 modest_ui_actions_on_cut (GtkAction *action,
3788 ModestWindow *window)
3790 GtkWidget *focused_widget;
3791 GtkClipboard *clipboard;
3793 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3794 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3795 if (GTK_IS_EDITABLE (focused_widget)) {
3796 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3797 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3798 gtk_clipboard_store (clipboard);
3799 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3800 GtkTextBuffer *buffer;
3802 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3803 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3804 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3805 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3806 gtk_clipboard_store (clipboard);
3808 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3809 TnyList *header_list = modest_header_view_get_selected_headers (
3810 MODEST_HEADER_VIEW (focused_widget));
3811 gboolean continue_download = FALSE;
3812 gint num_of_unc_msgs;
3814 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3816 if (num_of_unc_msgs) {
3817 TnyAccount *account = get_account_from_header_list (header_list);
3819 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3820 g_object_unref (account);
3824 if (num_of_unc_msgs == 0 || continue_download) {
3825 /* modest_platform_information_banner (
3826 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3827 modest_header_view_cut_selection (
3828 MODEST_HEADER_VIEW (focused_widget));
3831 g_object_unref (header_list);
3832 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3833 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3838 modest_ui_actions_on_copy (GtkAction *action,
3839 ModestWindow *window)
3841 GtkClipboard *clipboard;
3842 GtkWidget *focused_widget;
3843 gboolean copied = TRUE;
3845 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3846 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3848 if (GTK_IS_LABEL (focused_widget)) {
3850 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3851 gtk_clipboard_set_text (clipboard, selection, -1);
3853 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3854 gtk_clipboard_store (clipboard);
3855 } else if (GTK_IS_EDITABLE (focused_widget)) {
3856 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3857 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3858 gtk_clipboard_store (clipboard);
3859 } else if (GTK_IS_HTML (focused_widget)) {
3862 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3863 if ((sel == NULL) || (sel[0] == '\0')) {
3866 gtk_html_copy (GTK_HTML (focused_widget));
3867 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3868 gtk_clipboard_store (clipboard);
3870 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3871 GtkTextBuffer *buffer;
3872 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3873 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3874 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3875 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3876 gtk_clipboard_store (clipboard);
3878 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3879 TnyList *header_list = modest_header_view_get_selected_headers (
3880 MODEST_HEADER_VIEW (focused_widget));
3881 gboolean continue_download = FALSE;
3882 gint num_of_unc_msgs;
3884 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3886 if (num_of_unc_msgs) {
3887 TnyAccount *account = get_account_from_header_list (header_list);
3889 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3890 g_object_unref (account);
3894 if (num_of_unc_msgs == 0 || continue_download) {
3895 modest_platform_information_banner (
3896 NULL, NULL, _CS_GETTING_ITEMS);
3897 modest_header_view_copy_selection (
3898 MODEST_HEADER_VIEW (focused_widget));
3902 g_object_unref (header_list);
3904 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3905 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3908 /* Show information banner if there was a copy to clipboard */
3910 modest_platform_information_banner (
3911 NULL, NULL, _CS_COPIED);
3915 modest_ui_actions_on_undo (GtkAction *action,
3916 ModestWindow *window)
3918 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3919 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3921 g_return_if_reached ();
3926 modest_ui_actions_on_redo (GtkAction *action,
3927 ModestWindow *window)
3929 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3930 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3933 g_return_if_reached ();
3939 destroy_information_note (ModestMailOperation *mail_op,
3942 /* destroy information note */
3943 gtk_widget_destroy (GTK_WIDGET(user_data));
3947 destroy_folder_information_note (ModestMailOperation *mail_op,
3948 TnyFolder *new_folder,
3951 /* destroy information note */
3952 gtk_widget_destroy (GTK_WIDGET(user_data));
3957 paste_as_attachment_free (gpointer data)
3959 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3961 if (helper->banner) {
3962 gtk_widget_destroy (helper->banner);
3963 g_object_unref (helper->banner);
3969 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3974 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3980 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3985 modest_ui_actions_on_paste (GtkAction *action,
3986 ModestWindow *window)
3988 GtkWidget *focused_widget = NULL;
3989 GtkWidget *inf_note = NULL;
3990 ModestMailOperation *mail_op = NULL;
3992 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3993 if (GTK_IS_EDITABLE (focused_widget)) {
3994 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3995 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3996 ModestEmailClipboard *e_clipboard = NULL;
3997 e_clipboard = modest_runtime_get_email_clipboard ();
3998 if (modest_email_clipboard_cleared (e_clipboard)) {
3999 GtkTextBuffer *buffer;
4000 GtkClipboard *clipboard;
4002 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4003 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4004 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4005 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4006 ModestMailOperation *mail_op;
4007 TnyFolder *src_folder = NULL;
4008 TnyList *data = NULL;
4010 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4011 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4012 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4014 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4015 mail_op = modest_mail_operation_new (G_OBJECT (window));
4016 if (helper->banner != NULL) {
4017 g_object_ref (G_OBJECT (helper->banner));
4018 gtk_widget_show (GTK_WIDGET (helper->banner));
4022 modest_mail_operation_get_msgs_full (mail_op,
4024 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4026 paste_as_attachment_free);
4030 g_object_unref (data);
4032 g_object_unref (src_folder);
4035 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4036 ModestEmailClipboard *clipboard = NULL;
4037 TnyFolder *src_folder = NULL;
4038 TnyFolderStore *folder_store = NULL;
4039 TnyList *data = NULL;
4040 gboolean delete = FALSE;
4042 /* Check clipboard source */
4043 clipboard = modest_runtime_get_email_clipboard ();
4044 if (modest_email_clipboard_cleared (clipboard))
4047 /* Get elements to paste */
4048 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4050 /* Create a new mail operation */
4051 mail_op = modest_mail_operation_new (G_OBJECT(window));
4053 /* Get destination folder */
4054 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4056 /* transfer messages */
4060 /* Ask for user confirmation */
4062 modest_ui_actions_msgs_move_to_confirmation (window,
4063 TNY_FOLDER (folder_store),
4067 if (response == GTK_RESPONSE_OK) {
4068 /* Launch notification */
4069 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4071 if (inf_note != NULL) {
4072 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4073 gtk_widget_show (GTK_WIDGET(inf_note));
4076 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4077 modest_mail_operation_xfer_msgs (mail_op,
4079 TNY_FOLDER (folder_store),
4081 destroy_information_note,
4084 g_object_unref (mail_op);
4087 } else if (src_folder != NULL) {
4088 /* Launch notification */
4089 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4091 if (inf_note != NULL) {
4092 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4093 gtk_widget_show (GTK_WIDGET(inf_note));
4096 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4097 modest_mail_operation_xfer_folder (mail_op,
4101 destroy_folder_information_note,
4107 g_object_unref (data);
4108 if (src_folder != NULL)
4109 g_object_unref (src_folder);
4110 if (folder_store != NULL)
4111 g_object_unref (folder_store);
4117 modest_ui_actions_on_select_all (GtkAction *action,
4118 ModestWindow *window)
4120 GtkWidget *focused_widget;
4122 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4123 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4124 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4125 } else if (GTK_IS_LABEL (focused_widget)) {
4126 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4127 } else if (GTK_IS_EDITABLE (focused_widget)) {
4128 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4129 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4130 GtkTextBuffer *buffer;
4131 GtkTextIter start, end;
4133 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4134 gtk_text_buffer_get_start_iter (buffer, &start);
4135 gtk_text_buffer_get_end_iter (buffer, &end);
4136 gtk_text_buffer_select_range (buffer, &start, &end);
4137 } else if (GTK_IS_HTML (focused_widget)) {
4138 gtk_html_select_all (GTK_HTML (focused_widget));
4144 modest_ui_actions_on_mark_as_read (GtkAction *action,
4145 ModestWindow *window)
4147 g_return_if_fail (MODEST_IS_WINDOW(window));
4149 /* Mark each header as read */
4150 do_headers_action (window, headers_action_mark_as_read, NULL);
4154 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4155 ModestWindow *window)
4157 g_return_if_fail (MODEST_IS_WINDOW(window));
4159 /* Mark each header as read */
4160 do_headers_action (window, headers_action_mark_as_unread, NULL);
4164 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4165 GtkRadioAction *selected,
4166 ModestWindow *window)
4170 value = gtk_radio_action_get_current_value (selected);
4171 if (MODEST_IS_WINDOW (window)) {
4172 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4177 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4178 GtkRadioAction *selected,
4179 ModestWindow *window)
4181 TnyHeaderFlags flags;
4182 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4184 flags = gtk_radio_action_get_current_value (selected);
4185 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4189 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4190 GtkRadioAction *selected,
4191 ModestWindow *window)
4195 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4197 file_format = gtk_radio_action_get_current_value (selected);
4198 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4203 modest_ui_actions_on_zoom_plus (GtkAction *action,
4204 ModestWindow *window)
4206 g_return_if_fail (MODEST_IS_WINDOW (window));
4208 modest_window_zoom_plus (MODEST_WINDOW (window));
4212 modest_ui_actions_on_zoom_minus (GtkAction *action,
4213 ModestWindow *window)
4215 g_return_if_fail (MODEST_IS_WINDOW (window));
4217 modest_window_zoom_minus (MODEST_WINDOW (window));
4221 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4222 ModestWindow *window)
4224 ModestWindowMgr *mgr;
4225 gboolean fullscreen, active;
4226 g_return_if_fail (MODEST_IS_WINDOW (window));
4228 mgr = modest_runtime_get_window_mgr ();
4230 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4231 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4233 if (active != fullscreen) {
4234 modest_window_mgr_set_fullscreen_mode (mgr, active);
4235 #ifndef MODEST_TOOLKIT_HILDON2
4236 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4237 gtk_window_present (toplevel);
4243 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4244 ModestWindow *window)
4246 ModestWindowMgr *mgr;
4247 gboolean fullscreen;
4249 g_return_if_fail (MODEST_IS_WINDOW (window));
4251 mgr = modest_runtime_get_window_mgr ();
4252 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4253 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4258 * Used by modest_ui_actions_on_details to call do_headers_action
4261 headers_action_show_details (TnyHeader *header,
4262 ModestWindow *window,
4266 gboolean async_retrieval;
4267 GtkWindow *toplevel;
4270 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4271 async_retrieval = TRUE;
4272 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4273 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4275 async_retrieval = FALSE;
4277 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4278 modest_platform_run_header_details_dialog (toplevel, header, async_retrieval, msg);
4280 g_object_unref (msg);
4284 * Show the header details in a ModestDetailsDialog widget
4287 modest_ui_actions_on_details (GtkAction *action,
4290 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4294 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4298 header = tny_msg_get_header (msg);
4300 headers_action_show_details (header, win, NULL);
4301 g_object_unref (header);
4303 g_object_unref (msg);
4304 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4306 GtkWidget *header_view;
4308 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4309 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4311 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4313 modest_platform_run_folder_details_dialog (toplevel, folder);
4314 g_object_unref (folder);
4320 modest_ui_actions_on_limit_error (GtkAction *action,
4323 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4325 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS_MAXIMUM_CHARACTERS_REACHED);
4330 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4331 ModestMsgEditWindow *window)
4333 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4335 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4339 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4340 ModestMsgEditWindow *window)
4342 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4344 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4349 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4350 ModestWindow *window)
4352 gboolean active, fullscreen = FALSE;
4353 ModestWindowMgr *mgr;
4355 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4357 /* Check if we want to toggle the toolbar view in fullscreen
4359 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4360 "ViewShowToolbarFullScreen")) {
4364 /* Toggle toolbar */
4365 mgr = modest_runtime_get_window_mgr ();
4366 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4370 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4371 ModestMsgEditWindow *window)
4373 modest_msg_edit_window_select_font (window);
4378 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4379 const gchar *display_name,
4382 /* don't update the display name if it was already set;
4383 * updating the display name apparently is expensive */
4384 const gchar* old_name = gtk_window_get_title (window);
4386 if (display_name == NULL)
4389 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4390 return; /* don't do anything */
4392 /* This is usually used to change the title of the main window, which
4393 * is the one that holds the folder view. Note that this change can
4394 * happen even when the widget doesn't have the focus. */
4395 gtk_window_set_title (window, display_name);
4400 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4402 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4403 modest_msg_edit_window_select_contacts (window);
4407 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4410 modest_msg_edit_window_check_names (window, FALSE);
4415 on_move_to_dialog_response (GtkDialog *dialog,
4419 GtkWidget *parent_win;
4420 MoveToInfo *helper = NULL;
4421 ModestFolderView *folder_view;
4422 gboolean unset_edit_mode = FALSE;
4424 helper = (MoveToInfo *) user_data;
4426 parent_win = (GtkWidget *) helper->win;
4427 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4428 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4430 TnyFolderStore *dst_folder;
4431 TnyFolderStore *selected;
4433 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4434 selected = modest_folder_view_get_selected (folder_view);
4435 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4436 g_object_unref (selected);
4438 case GTK_RESPONSE_NONE:
4439 case GTK_RESPONSE_CANCEL:
4440 case GTK_RESPONSE_DELETE_EVENT:
4442 case GTK_RESPONSE_OK:
4443 dst_folder = modest_folder_view_get_selected (folder_view);
4445 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4446 /* Clean list to move used for filtering */
4447 modest_folder_view_set_list_to_move (folder_view, NULL);
4449 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4452 MODEST_WINDOW (parent_win));
4454 /* if the user selected a root folder
4455 (account) then do not perform any action */
4456 if (TNY_IS_ACCOUNT (dst_folder)) {
4457 g_signal_stop_emission_by_name (dialog, "response");
4461 /* Clean list to move used for filtering */
4462 modest_folder_view_set_list_to_move (folder_view, NULL);
4464 /* Moving from headers window in edit mode */
4465 modest_ui_actions_on_window_move_to (NULL, helper->list,
4467 MODEST_WINDOW (parent_win));
4471 g_object_unref (dst_folder);
4473 unset_edit_mode = TRUE;
4476 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4479 /* Free the helper and exit */
4481 g_object_unref (helper->list);
4482 if (unset_edit_mode) {
4483 #ifdef MODEST_TOOLKIT_HILDON2
4484 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4487 g_slice_free (MoveToInfo, helper);
4488 gtk_widget_destroy (GTK_WIDGET (dialog));
4492 create_move_to_dialog (GtkWindow *win,
4493 GtkWidget *folder_view,
4494 TnyList *list_to_move)
4496 GtkWidget *dialog, *tree_view = NULL;
4498 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4501 /* It could happen that we're trying to move a message from a
4502 window (msg window for example) after the main window was
4503 closed, so we can not just get the model of the folder
4505 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4506 const gchar *visible_id = NULL;
4508 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4509 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4510 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4511 MODEST_FOLDER_VIEW(tree_view));
4514 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4516 /* Show the same account than the one that is shown in the main window */
4517 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4520 const gchar *active_account_name = NULL;
4521 ModestAccountMgr *mgr = NULL;
4522 ModestAccountSettings *settings = NULL;
4523 ModestServerAccountSettings *store_settings = NULL;
4525 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4526 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4528 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4529 mgr = modest_runtime_get_account_mgr ();
4530 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4533 const gchar *store_account_name;
4534 store_settings = modest_account_settings_get_store_settings (settings);
4535 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4537 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4538 store_account_name);
4539 g_object_unref (store_settings);
4540 g_object_unref (settings);
4544 /* we keep a pointer to the embedded folder view, so we can
4545 * retrieve it with get_folder_view_from_move_to_dialog (see
4546 * above) later (needed for focus handling)
4548 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4550 /* Hide special folders */
4552 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4554 gtk_widget_show (GTK_WIDGET (tree_view));
4560 * Shows a confirmation dialog to the user when we're moving messages
4561 * from a remote server to the local storage. Returns the dialog
4562 * response. If it's other kind of movement then it always returns
4565 * This one is used by the next functions:
4566 * modest_ui_actions_on_paste - commented out
4567 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4570 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4571 TnyFolder *dest_folder,
4575 gint response = GTK_RESPONSE_OK;
4576 TnyAccount *account = NULL;
4577 TnyFolder *src_folder = NULL;
4578 TnyIterator *iter = NULL;
4579 TnyHeader *header = NULL;
4581 /* return with OK if the destination is a remote folder */
4582 if (modest_tny_folder_is_remote_folder (dest_folder))
4583 return GTK_RESPONSE_OK;
4585 /* Get source folder */
4586 iter = tny_list_create_iterator (headers);
4587 header = TNY_HEADER (tny_iterator_get_current (iter));
4589 src_folder = tny_header_get_folder (header);
4590 g_object_unref (header);
4592 g_object_unref (iter);
4594 /* if no src_folder, message may be an attahcment */
4595 if (src_folder == NULL)
4596 return GTK_RESPONSE_CANCEL;
4598 /* If the source is a local or MMC folder */
4599 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4600 g_object_unref (src_folder);
4601 return GTK_RESPONSE_OK;
4604 /* Get the account */
4605 account = tny_folder_get_account (src_folder);
4607 /* now if offline we ask the user */
4608 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4609 response = GTK_RESPONSE_OK;
4611 response = GTK_RESPONSE_CANCEL;
4614 g_object_unref (src_folder);
4615 g_object_unref (account);
4621 move_to_helper_destroyer (gpointer user_data)
4623 MoveToHelper *helper = (MoveToHelper *) user_data;
4625 /* Close the "Pasting" information banner */
4626 if (helper->banner) {
4627 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4628 g_object_unref (helper->banner);
4630 if (gtk_tree_row_reference_valid (helper->reference)) {
4631 gtk_tree_row_reference_free (helper->reference);
4632 helper->reference = NULL;
4638 move_to_cb (ModestMailOperation *mail_op,
4641 MoveToHelper *helper = (MoveToHelper *) user_data;
4642 GObject *object = modest_mail_operation_get_source (mail_op);
4644 /* Note that the operation could have failed, in that case do
4646 if (modest_mail_operation_get_status (mail_op) !=
4647 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4650 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4651 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4653 if (!modest_msg_view_window_select_next_message (self) &&
4654 !modest_msg_view_window_select_previous_message (self)) {
4655 /* No more messages to view, so close this window */
4656 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4659 g_object_unref (object);
4662 /* Destroy the helper */
4663 move_to_helper_destroyer (helper);
4667 folder_move_to_cb (ModestMailOperation *mail_op,
4668 TnyFolder *new_folder,
4673 object = modest_mail_operation_get_source (mail_op);
4675 move_to_cb (mail_op, user_data);
4680 msgs_move_to_cb (ModestMailOperation *mail_op,
4683 move_to_cb (mail_op, user_data);
4687 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4690 GObject *win = NULL;
4691 const GError *error;
4692 TnyAccount *account = NULL;
4694 win = modest_mail_operation_get_source (mail_op);
4695 error = modest_mail_operation_get_error (mail_op);
4697 if (TNY_IS_FOLDER (user_data))
4698 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4699 else if (TNY_IS_ACCOUNT (user_data))
4700 account = g_object_ref (user_data);
4702 /* If it's not a disk full error then show a generic error */
4703 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4704 (GtkWidget *) win, (GError *) error,
4706 modest_platform_run_information_dialog ((GtkWindow *) win,
4707 _("mail_in_ui_folder_move_target_error"),
4710 g_object_unref (account);
4712 g_object_unref (win);
4717 * Checks if we need a connection to do the transfer and if the user
4718 * wants to connect to complete it
4721 modest_ui_actions_xfer_messages_check (ModestWindow *parent_window,
4722 TnyFolderStore *src_folder,
4724 TnyFolder *dst_folder,
4725 gboolean delete_originals,
4726 gboolean *need_connection,
4729 TnyAccount *src_account;
4730 gint uncached_msgs = 0;
4732 /* We don't need any further check if
4734 * 1- the source folder is local OR
4735 * 2- the device is already online
4737 if (!modest_tny_folder_store_is_remote (src_folder) ||
4738 tny_device_is_online (modest_runtime_get_device())) {
4739 *need_connection = FALSE;
4744 /* We must ask for a connection when
4746 * - the message(s) is not already cached OR
4747 * - the message(s) is cached but the leave_on_server setting
4748 * is FALSE (because we need to sync the source folder to
4749 * delete the message from the server (for IMAP we could do it
4750 * offline, it'll take place the next time we get a
4753 uncached_msgs = header_list_count_uncached_msgs (headers);
4754 src_account = get_account_from_folder_store (src_folder);
4755 if (uncached_msgs > 0) {
4758 GtkWindow *toplevel;
4760 *need_connection = TRUE;
4761 num_headers = tny_list_get_length (headers);
4762 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4763 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
4765 if (modest_platform_run_confirmation_dialog (toplevel, msg) ==
4766 GTK_RESPONSE_CANCEL) {
4772 /* The transfer is possible and the user wants to */
4775 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4776 const gchar *account_name;
4777 gboolean leave_on_server;
4779 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4780 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4783 if (leave_on_server == TRUE) {
4784 *need_connection = FALSE;
4786 *need_connection = TRUE;
4789 *need_connection = FALSE;
4794 g_object_unref (src_account);
4798 xfer_messages_error_handler (ModestMailOperation *mail_op,
4802 const GError *error;
4803 TnyAccount *account;
4805 win = modest_mail_operation_get_source (mail_op);
4806 error = modest_mail_operation_get_error (mail_op);
4808 /* We cannot get the account from the mail op as that is the
4809 source account and for checking memory full conditions we
4810 need the destination one */
4811 account = TNY_ACCOUNT (user_data);
4814 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4815 (GtkWidget *) win, (GError*) error,
4816 account, _KR("cerm_memory_card_full"))) {
4817 modest_platform_run_information_dialog ((GtkWindow *) win,
4818 _("mail_in_ui_folder_move_target_error"),
4822 g_object_unref (win);
4826 TnyFolderStore *dst_folder;
4831 * Utility function that transfer messages from both the main window
4832 * and the msg view window when using the "Move to" dialog
4835 xfer_messages_performer (gboolean canceled,
4837 ModestWindow *parent_window,
4838 TnyAccount *account,
4841 TnyAccount *dst_account = NULL;
4842 gboolean dst_forbids_message_add = FALSE;
4843 XferMsgsHelper *helper;
4844 MoveToHelper *movehelper;
4845 ModestMailOperation *mail_op;
4847 helper = (XferMsgsHelper *) user_data;
4849 if (canceled || err) {
4850 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4851 (GtkWidget *) parent_window, err,
4853 /* Show the proper error message */
4854 modest_ui_actions_on_account_connection_error (parent_window, account);
4859 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4861 /* tinymail will return NULL for local folders it seems */
4862 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4863 modest_tny_account_get_protocol_type (dst_account),
4864 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4866 if (dst_forbids_message_add) {
4867 modest_platform_information_banner (GTK_WIDGET (parent_window),
4869 ngettext("mail_in_ui_folder_move_target_error",
4870 "mail_in_ui_folder_move_targets_error",
4871 tny_list_get_length (helper->headers)));
4875 movehelper = g_new0 (MoveToHelper, 1);
4878 /* Perform the mail operation */
4879 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4880 xfer_messages_error_handler,
4881 g_object_ref (dst_account),
4883 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4886 modest_mail_operation_xfer_msgs (mail_op,
4888 TNY_FOLDER (helper->dst_folder),
4893 g_object_unref (G_OBJECT (mail_op));
4896 g_object_unref (dst_account);
4897 g_object_unref (helper->dst_folder);
4898 g_object_unref (helper->headers);
4899 g_slice_free (XferMsgsHelper, helper);
4903 TnyFolder *src_folder;
4904 TnyFolderStore *dst_folder;
4905 gboolean delete_original;
4906 GtkWidget *folder_view;
4910 on_move_folder_cb (gboolean canceled,
4912 ModestWindow *parent_window,
4913 TnyAccount *account,
4916 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4917 GtkTreeSelection *sel;
4918 ModestMailOperation *mail_op = NULL;
4920 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4921 /* Note that the connection process can fail due to
4922 memory low conditions as it can not successfully
4923 store the summary */
4924 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4925 (GtkWidget*) parent_window, err,
4927 g_debug ("Error connecting when trying to move a folder");
4929 g_object_unref (G_OBJECT (info->src_folder));
4930 g_object_unref (G_OBJECT (info->dst_folder));
4935 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4936 #ifndef MODEST_TOOLKIT_HILDON2
4937 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4939 if (helper->banner != NULL) {
4940 g_object_ref (helper->banner);
4941 gtk_widget_show (GTK_WIDGET(helper->banner));
4944 /* Clean folder on header view before moving it */
4945 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4946 gtk_tree_selection_unselect_all (sel);
4948 /* Let gtk events run. We need that the folder
4949 view frees its reference to the source
4950 folder *before* issuing the mail operation
4951 so we need the signal handler of selection
4952 changed to happen before the mail
4954 while (gtk_events_pending ())
4955 gtk_main_iteration (); */
4958 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4959 modest_ui_actions_move_folder_error_handler,
4960 g_object_ref (info->dst_folder), g_object_unref);
4961 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4964 modest_mail_operation_xfer_folder (mail_op,
4965 TNY_FOLDER (info->src_folder),
4967 info->delete_original,
4970 g_object_unref (G_OBJECT (info->src_folder));
4972 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4975 /* Unref mail operation */
4976 g_object_unref (G_OBJECT (mail_op));
4977 g_object_unref (G_OBJECT (info->dst_folder));
4982 get_account_from_folder_store (TnyFolderStore *folder_store)
4984 if (TNY_IS_ACCOUNT (folder_store))
4985 return g_object_ref (folder_store);
4987 return tny_folder_get_account (TNY_FOLDER (folder_store));
4991 * UI handler for the "Move to" action when invoked from the
4992 * ModestFolderWindow
4995 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4996 TnyFolderStore *dst_folder,
5000 TnyFolderStore *src_folder = NULL;
5001 TnyIterator *iterator;
5003 if (tny_list_get_length (selection) != 1)
5006 iterator = tny_list_create_iterator (selection);
5007 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5008 g_object_unref (iterator);
5011 gboolean do_xfer = TRUE;
5013 /* Allow only to transfer folders to the local root folder */
5014 if (TNY_IS_ACCOUNT (dst_folder) &&
5015 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5016 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5017 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5021 modest_platform_run_information_dialog (toplevel,
5022 _("mail_in_ui_folder_move_target_error"),
5024 } else if (!TNY_IS_FOLDER (src_folder)) {
5025 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5030 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5031 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5033 info->src_folder = g_object_ref (src_folder);
5034 info->dst_folder = g_object_ref (dst_folder);
5035 info->delete_original = TRUE;
5036 info->folder_view = folder_view;
5038 connect_info->callback = on_move_folder_cb;
5039 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5040 connect_info->data = info;
5042 modest_platform_double_connect_and_perform(win, TRUE,
5043 TNY_FOLDER_STORE (src_folder),
5048 g_object_unref (src_folder);
5053 modest_ui_actions_transfer_messages_helper (ModestWindow *win,
5054 TnyFolder *src_folder,
5056 TnyFolder *dst_folder)
5058 gboolean need_connection = TRUE;
5059 gboolean do_xfer = TRUE;
5060 XferMsgsHelper *helper;
5062 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5063 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5064 g_return_if_fail (TNY_IS_LIST (headers));
5066 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5067 headers, TNY_FOLDER (dst_folder),
5068 TRUE, &need_connection,
5071 /* If we don't want to transfer just return */
5075 /* Create the helper */
5076 helper = g_slice_new (XferMsgsHelper);
5077 helper->dst_folder = g_object_ref (dst_folder);
5078 helper->headers = g_object_ref (headers);
5080 if (need_connection) {
5081 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5082 connect_info->callback = xfer_messages_performer;
5083 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5084 connect_info->data = helper;
5086 modest_platform_double_connect_and_perform(win, TRUE,
5087 TNY_FOLDER_STORE (src_folder),
5090 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5091 xfer_messages_performer (FALSE, NULL, win,
5092 src_account, helper);
5093 g_object_unref (src_account);
5098 * UI handler for the "Move to" action when invoked from the
5099 * ModestMsgViewWindow
5102 modest_ui_actions_on_window_move_to (GtkAction *action,
5104 TnyFolderStore *dst_folder,
5107 TnyFolder *src_folder = NULL;
5109 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5112 TnyHeader *header = NULL;
5115 iter = tny_list_create_iterator (headers);
5116 header = (TnyHeader *) tny_iterator_get_current (iter);
5117 src_folder = tny_header_get_folder (header);
5119 /* Transfer the messages */
5120 modest_ui_actions_transfer_messages_helper (win, src_folder,
5122 TNY_FOLDER (dst_folder));
5125 g_object_unref (header);
5126 g_object_unref (iter);
5127 g_object_unref (src_folder);
5132 modest_ui_actions_on_move_to (GtkAction *action,
5135 modest_ui_actions_on_edit_mode_move_to (win);
5139 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5141 GtkWidget *dialog = NULL;
5142 GtkWindow *toplevel = NULL;
5143 MoveToInfo *helper = NULL;
5144 TnyList *list_to_move;
5146 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5149 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5154 if (tny_list_get_length (list_to_move) < 1) {
5155 g_object_unref (list_to_move);
5159 /* Create and run the dialog */
5160 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5161 dialog = create_move_to_dialog (toplevel, NULL, list_to_move);
5162 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5163 GTK_WINDOW (dialog),
5167 helper = g_slice_new0 (MoveToInfo);
5168 helper->list = list_to_move;
5171 /* Listen to response signal */
5172 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5174 /* Show the dialog */
5175 gtk_widget_show (dialog);
5181 * Calls #HeadersFunc for each header already selected in the main
5182 * window or the message currently being shown in the msg view window
5185 do_headers_action (ModestWindow *win,
5189 TnyList *headers_list = NULL;
5190 TnyIterator *iter = NULL;
5191 TnyHeader *header = NULL;
5192 TnyFolder *folder = NULL;
5195 headers_list = get_selected_headers (win);
5199 /* Get the folder */
5200 iter = tny_list_create_iterator (headers_list);
5201 header = TNY_HEADER (tny_iterator_get_current (iter));
5203 folder = tny_header_get_folder (header);
5204 g_object_unref (header);
5207 /* Call the function for each header */
5208 while (!tny_iterator_is_done (iter)) {
5209 header = TNY_HEADER (tny_iterator_get_current (iter));
5210 func (header, win, user_data);
5211 g_object_unref (header);
5212 tny_iterator_next (iter);
5215 /* Trick: do a poke status in order to speed up the signaling
5218 tny_folder_poke_status (folder);
5219 g_object_unref (folder);
5223 g_object_unref (iter);
5224 g_object_unref (headers_list);
5228 modest_ui_actions_view_attachment (GtkAction *action,
5229 ModestWindow *window)
5231 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5232 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5234 /* not supported window for this action */
5235 g_return_if_reached ();
5240 modest_ui_actions_save_attachments (GtkAction *action,
5241 ModestWindow *window)
5243 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5245 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5248 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5250 /* not supported window for this action */
5251 g_return_if_reached ();
5256 modest_ui_actions_remove_attachments (GtkAction *action,
5257 ModestWindow *window)
5259 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5260 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5262 /* not supported window for this action */
5263 g_return_if_reached ();
5268 modest_ui_actions_on_settings (GtkAction *action,
5272 GtkWindow *toplevel;
5274 dialog = modest_platform_get_global_settings_dialog ();
5275 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5276 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5277 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5278 gtk_widget_show_all (dialog);
5280 gtk_dialog_run (GTK_DIALOG (dialog));
5282 gtk_widget_destroy (dialog);
5286 modest_ui_actions_on_help (GtkAction *action,
5289 /* Help app is not available at all in fremantle */
5290 #ifndef MODEST_TOOLKIT_HILDON2
5291 const gchar *help_id;
5293 g_return_if_fail (win && GTK_IS_WINDOW(win));
5295 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5298 modest_platform_show_help (win, help_id);
5303 modest_ui_actions_on_csm_help (GtkAction *action,
5306 /* Help app is not available at all in fremantle */
5310 retrieve_contents_cb (ModestMailOperation *mail_op,
5317 /* We only need this callback to show an error in case of
5318 memory low condition */
5319 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5320 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5325 retrieve_msg_contents_performer (gboolean canceled,
5327 ModestWindow *parent_window,
5328 TnyAccount *account,
5331 ModestMailOperation *mail_op;
5332 TnyList *headers = TNY_LIST (user_data);
5334 if (err || canceled) {
5335 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5336 (GtkWidget *) parent_window, err,
5341 /* Create mail operation */
5342 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5343 modest_ui_actions_disk_operations_error_handler,
5345 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5346 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5349 g_object_unref (mail_op);
5351 g_object_unref (headers);
5352 g_object_unref (account);
5356 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5357 ModestWindow *window)
5359 TnyList *headers = NULL;
5360 TnyAccount *account = NULL;
5361 TnyIterator *iter = NULL;
5362 TnyHeader *header = NULL;
5363 TnyFolder *folder = NULL;
5366 headers = get_selected_headers (window);
5370 /* Pick the account */
5371 iter = tny_list_create_iterator (headers);
5372 header = TNY_HEADER (tny_iterator_get_current (iter));
5373 folder = tny_header_get_folder (header);
5374 account = tny_folder_get_account (folder);
5375 g_object_unref (folder);
5376 g_object_unref (header);
5377 g_object_unref (iter);
5379 /* Connect and perform the message retrieval */
5380 modest_platform_connect_and_perform (window, TRUE,
5381 g_object_ref (account),
5382 retrieve_msg_contents_performer,
5383 g_object_ref (headers));
5386 g_object_unref (account);
5387 g_object_unref (headers);
5391 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5393 g_return_if_fail (MODEST_IS_WINDOW (window));
5396 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5400 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5402 g_return_if_fail (MODEST_IS_WINDOW (window));
5405 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5409 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5410 ModestWindow *window)
5412 g_return_if_fail (MODEST_IS_WINDOW (window));
5415 modest_ui_actions_check_menu_dimming_rules (window);
5419 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5420 ModestWindow *window)
5422 g_return_if_fail (MODEST_IS_WINDOW (window));
5425 modest_ui_actions_check_menu_dimming_rules (window);
5429 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5430 ModestWindow *window)
5432 g_return_if_fail (MODEST_IS_WINDOW (window));
5435 modest_ui_actions_check_menu_dimming_rules (window);
5439 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5440 ModestWindow *window)
5442 g_return_if_fail (MODEST_IS_WINDOW (window));
5445 modest_ui_actions_check_menu_dimming_rules (window);
5449 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5450 ModestWindow *window)
5452 g_return_if_fail (MODEST_IS_WINDOW (window));
5455 modest_ui_actions_check_menu_dimming_rules (window);
5459 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5460 ModestWindow *window)
5462 g_return_if_fail (MODEST_IS_WINDOW (window));
5465 modest_ui_actions_check_menu_dimming_rules (window);
5469 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5470 ModestWindow *window)
5472 g_return_if_fail (MODEST_IS_WINDOW (window));
5475 modest_ui_actions_check_menu_dimming_rules (window);
5479 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5480 ModestWindow *window)
5482 g_return_if_fail (MODEST_IS_WINDOW (window));
5485 modest_ui_actions_check_menu_dimming_rules (window);
5489 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5490 ModestWindow *window)
5492 g_return_if_fail (MODEST_IS_WINDOW (window));
5495 modest_ui_actions_check_menu_dimming_rules (window);
5499 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5501 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
5503 g_return_if_fail (MODEST_IS_WINDOW (window));
5505 /* we check for low-mem; in that case, show a warning, and don't allow
5508 if (modest_platform_check_memory_low (window, TRUE))
5511 modest_platform_show_search_messages (toplevel);
5515 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5517 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5519 g_return_if_fail (MODEST_IS_WINDOW (win));
5521 /* we check for low-mem; in that case, show a warning, and don't allow
5522 * for the addressbook
5524 if (modest_platform_check_memory_low (win, TRUE))
5527 modest_platform_show_addressbook (toplevel);
5532 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5533 ModestWindow *window)
5536 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5538 if (GTK_IS_TOGGLE_ACTION (action))
5539 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5543 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5549 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5555 const gchar* server_name = NULL;
5556 TnyTransportAccount *transport;
5557 gchar *message = NULL;
5558 ModestProtocol *protocol;
5560 /* Don't show anything if the user cancelled something or the
5561 * send receive request is not interactive. Authentication
5562 * errors are managed by the account store so no need to show
5563 * a dialog here again */
5564 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5565 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5566 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5570 /* Get the server name. Note that we could be using a
5571 connection specific transport account */
5572 transport = (TnyTransportAccount *)
5573 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5575 ModestTnyAccountStore *acc_store;
5576 const gchar *acc_name;
5577 TnyTransportAccount *conn_specific;
5579 acc_store = modest_runtime_get_account_store();
5580 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5581 conn_specific = (TnyTransportAccount *)
5582 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5583 if (conn_specific) {
5584 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5585 g_object_unref (conn_specific);
5587 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5589 g_object_unref (transport);
5593 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5594 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5595 tny_account_get_proto (TNY_ACCOUNT (transport)));
5597 g_warning ("%s: Account with no proto", __FUNCTION__);
5601 /* Show the appropriate message text for the GError: */
5602 switch (err->code) {
5603 case TNY_SERVICE_ERROR_CONNECT:
5604 message = modest_protocol_get_translation (protocol,
5605 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5608 case TNY_SERVICE_ERROR_SEND:
5609 message = g_strdup (_CS_UNABLE_TO_SEND);
5611 case TNY_SERVICE_ERROR_UNAVAILABLE:
5612 message = modest_protocol_get_translation (protocol,
5613 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5617 g_warning ("%s: unexpected ERROR %d",
5618 __FUNCTION__, err->code);
5619 message = g_strdup (_CS_UNABLE_TO_SEND);
5623 modest_platform_run_information_dialog (NULL, message, FALSE);
5628 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5633 ModestWindow *top_window = NULL;
5634 ModestWindowMgr *mgr = NULL;
5635 GtkWidget *header_view = NULL;
5636 TnyFolder *selected_folder = NULL;
5637 TnyFolderType folder_type;
5639 mgr = modest_runtime_get_window_mgr ();
5640 top_window = modest_window_mgr_get_current_top (mgr);
5645 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5646 header_view = (GtkWidget *)
5647 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5650 /* Get selected folder */
5652 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5653 if (!selected_folder)
5656 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5657 #if GTK_CHECK_VERSION(2, 8, 0)
5658 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5659 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5660 GtkTreeViewColumn *tree_column;
5662 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5663 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5665 gtk_tree_view_column_queue_resize (tree_column);
5667 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5668 gtk_widget_queue_draw (header_view);
5671 #ifndef MODEST_TOOLKIT_HILDON2
5672 /* Rerun dimming rules, because the message could become deletable for example */
5673 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5674 MODEST_DIMMING_RULES_TOOLBAR);
5675 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5676 MODEST_DIMMING_RULES_MENU);
5680 g_object_unref (selected_folder);
5684 modest_ui_actions_on_account_connection_error (ModestWindow *parent_window,
5685 TnyAccount *account)
5687 ModestProtocolType protocol_type;
5688 ModestProtocol *protocol;
5689 gchar *error_note = NULL;
5691 protocol_type = modest_tny_account_get_protocol_type (account);
5692 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5695 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5696 if (error_note == NULL) {
5697 g_warning ("%s: This should not be reached", __FUNCTION__);
5699 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
5700 modest_platform_run_information_dialog (toplevel, error_note, FALSE);
5701 g_free (error_note);
5706 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5710 TnyFolderStore *folder = NULL;
5711 TnyAccount *account = NULL;
5712 ModestProtocolType proto;
5713 ModestProtocol *protocol;
5714 TnyHeader *header = NULL;
5716 if (MODEST_IS_HEADER_WINDOW (win)) {
5717 GtkWidget *header_view;
5718 TnyList* headers = NULL;
5720 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5721 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5722 if (!headers || tny_list_get_length (headers) == 0) {
5724 g_object_unref (headers);
5727 iter = tny_list_create_iterator (headers);
5728 header = TNY_HEADER (tny_iterator_get_current (iter));
5730 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5732 g_warning ("List should contain headers");
5734 g_object_unref (iter);
5735 g_object_unref (headers);
5736 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5737 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5739 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5742 if (!header || !folder)
5745 /* Get the account type */
5746 account = tny_folder_get_account (TNY_FOLDER (folder));
5747 proto = modest_tny_account_get_protocol_type (account);
5748 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5751 subject = tny_header_dup_subject (header);
5752 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5756 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5762 g_object_unref (account);
5764 g_object_unref (folder);
5766 g_object_unref (header);
5772 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5773 const gchar *account_name,
5774 const gchar *account_title)
5776 ModestAccountMgr *account_mgr;
5779 ModestProtocol *protocol;
5780 gboolean removed = FALSE;
5782 g_return_val_if_fail (account_name, FALSE);
5783 g_return_val_if_fail (account_title, FALSE);
5785 account_mgr = modest_runtime_get_account_mgr();
5787 /* The warning text depends on the account type: */
5788 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5789 modest_account_mgr_get_store_protocol (account_mgr,
5791 txt = modest_protocol_get_translation (protocol,
5792 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5795 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5797 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5801 if (response == GTK_RESPONSE_OK) {
5802 /* Remove account. If it succeeds then it also removes
5803 the account from the ModestAccountView: */
5804 gboolean is_default = FALSE;
5805 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5806 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5808 g_free (default_account_name);
5810 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5812 #ifdef MODEST_TOOLKIT_HILDON2
5813 hildon_gtk_window_take_screenshot (parent_window, FALSE);
5815 /* Close all email notifications, we cannot
5816 distinguish if the notification belongs to
5817 this account or not, so for safety reasons
5818 we remove them all */
5819 modest_platform_remove_new_mail_notifications (FALSE);
5821 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5828 on_fetch_images_performer (gboolean canceled,
5830 ModestWindow *parent_window,
5831 TnyAccount *account,
5834 if (err || canceled) {
5835 /* Show an unable to retrieve images ??? */
5839 /* Note that the user could have closed the window while connecting */
5840 if (GTK_WIDGET_VISIBLE (parent_window))
5841 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5842 g_object_unref ((GObject *) user_data);
5846 modest_ui_actions_on_fetch_images (GtkAction *action,
5847 ModestWindow *window)
5849 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5851 modest_platform_connect_and_perform (window, TRUE,
5853 on_fetch_images_performer,
5854 g_object_ref (window));
5858 modest_ui_actions_on_reload_message (const gchar *msg_id)
5860 ModestWindow *window = NULL;
5862 g_return_if_fail (msg_id && msg_id[0] != '\0');
5863 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5869 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5872 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5875 /** Check whether any connections are active, and cancel them if
5877 * Returns TRUE is there was no problem,
5878 * or if an operation was cancelled so we can continue.
5879 * Returns FALSE if the user chose to cancel his request instead.
5883 modest_ui_actions_check_for_active_account (ModestWindow *self,
5884 const gchar* account_name)
5886 ModestTnySendQueue *send_queue;
5887 ModestTnyAccountStore *acc_store;
5888 ModestMailOperationQueue* queue;
5889 TnyConnectionStatus store_conn_status;
5890 TnyAccount *store_account = NULL, *transport_account = NULL;
5891 gboolean retval = TRUE, sending = FALSE;
5893 acc_store = modest_runtime_get_account_store ();
5894 queue = modest_runtime_get_mail_operation_queue ();
5897 modest_tny_account_store_get_server_account (acc_store,
5899 TNY_ACCOUNT_TYPE_STORE);
5901 /* This could happen if the account was deleted before the
5902 call to this function */
5907 modest_tny_account_store_get_server_account (acc_store,
5909 TNY_ACCOUNT_TYPE_TRANSPORT);
5911 /* This could happen if the account was deleted before the
5912 call to this function */
5913 if (!transport_account) {
5914 g_object_unref (store_account);
5918 /* If the transport account was not used yet, then the send
5919 queue could not exist (it's created on demand) */
5920 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5921 if (TNY_IS_SEND_QUEUE (send_queue))
5922 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5924 store_conn_status = tny_account_get_connection_status (store_account);
5925 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5928 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
5929 _("emev_nc_disconnect_account"));
5930 if (response == GTK_RESPONSE_OK) {
5939 /* FIXME: We should only cancel those of this account */
5940 modest_mail_operation_queue_cancel_all (queue);
5942 /* Also disconnect the account */
5943 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5944 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5945 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5949 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5955 g_object_unref (store_account);
5956 g_object_unref (transport_account);