1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #include <widgets/modest-header-window.h>
54 #include <widgets/modest-folder-window.h>
55 #include <widgets/modest-accounts-window.h>
56 #ifdef MODEST_TOOLKIT_HILDON2
57 #include <hildon/hildon-gtk.h>
58 #include <modest-maemo-utils.h>
60 #include "modest-utils.h"
61 #include "widgets/modest-connection-specific-smtp-window.h"
62 #include "widgets/modest-ui-constants.h"
63 #include <widgets/modest-main-window.h>
64 #include <widgets/modest-msg-view-window.h>
65 #include <widgets/modest-account-view-window.h>
66 #include <widgets/modest-details-dialog.h>
67 #include <widgets/modest-attachments-view.h>
68 #include "widgets/modest-folder-view.h"
69 #include "widgets/modest-global-settings-dialog.h"
70 #include "modest-account-mgr-helpers.h"
71 #include "modest-mail-operation.h"
72 #include "modest-text-utils.h"
73 #include <modest-widget-memory.h>
74 #include <tny-error.h>
75 #include <tny-simple-list.h>
76 #include <tny-msg-view.h>
77 #include <tny-device.h>
78 #include <tny-merge-folder.h>
79 #include <widgets/modest-toolkit-utils.h>
80 #include <tny-camel-bs-msg.h>
81 #include <tny-camel-bs-mime-part.h>
84 #include <gtkhtml/gtkhtml.h>
86 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
88 typedef struct _GetMsgAsyncHelper {
90 ModestMailOperation *mail_op;
97 typedef enum _ReplyForwardAction {
101 } ReplyForwardAction;
103 typedef struct _ReplyForwardHelper {
104 guint reply_forward_type;
105 ReplyForwardAction action;
108 GtkWidget *parent_window;
111 } ReplyForwardHelper;
113 typedef struct _MoveToHelper {
114 GtkTreeRowReference *reference;
118 typedef struct _PasteAsAttachmentHelper {
119 ModestMsgEditWindow *window;
121 } PasteAsAttachmentHelper;
129 * The do_headers_action uses this kind of functions to perform some
130 * action to each member of a list of headers
132 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
134 static void do_headers_action (ModestWindow *win,
138 static void open_msg_cb (ModestMailOperation *mail_op,
145 static void reply_forward_cb (ModestMailOperation *mail_op,
152 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
154 static gint header_list_count_uncached_msgs (TnyList *header_list);
156 static gboolean connect_to_get_msg (ModestWindow *win,
157 gint num_of_uncached_msgs,
158 TnyAccount *account);
160 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
162 static void do_create_folder (ModestWindow *window,
163 TnyFolderStore *parent_folder,
164 const gchar *suggested_name);
166 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
168 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
169 TnyFolderStore *dst_folder,
173 static void modest_ui_actions_on_window_move_to (GtkAction *action,
174 TnyList *list_to_move,
175 TnyFolderStore *dst_folder,
179 * This function checks whether a TnyFolderStore is a pop account
182 remote_folder_has_leave_on_server (TnyFolderStore *folder)
187 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
189 account = get_account_from_folder_store (folder);
190 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
191 modest_tny_account_get_protocol_type (account)));
192 g_object_unref (account);
197 /* FIXME: this should be merged with the similar code in modest-account-view-window */
198 /* Show the account creation wizard dialog.
199 * returns: TRUE if an account was created. FALSE if the user cancelled.
202 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
204 gboolean result = FALSE;
206 gint dialog_response;
208 /* there is no such wizard yet */
209 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
210 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
214 ModestWindowMgr *mgr;
216 mgr = modest_runtime_get_window_mgr ();
218 window_list = modest_window_mgr_get_window_list (mgr);
219 if (window_list == NULL) {
220 win = MODEST_WINDOW (modest_accounts_window_new ());
221 if (modest_window_mgr_register_window (mgr, win, NULL)) {
222 gtk_widget_show_all (GTK_WIDGET (win));
224 gtk_widget_destroy (GTK_WIDGET (win));
229 g_list_free (window_list);
234 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
235 gtk_window_set_transient_for (GTK_WINDOW (wizard), toplevel);
238 /* make sure the mainwindow is visible. We need to present the
239 wizard again to give it the focus back. show_all are needed
240 in order to get the widgets properly drawn (MainWindow main
241 paned won't be in its right position and the dialog will be
244 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
245 gtk_widget_destroy (GTK_WIDGET (wizard));
246 if (gtk_events_pending ())
247 gtk_main_iteration ();
249 if (dialog_response == GTK_RESPONSE_CANCEL) {
252 /* Check whether an account was created: */
253 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
260 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
264 const gchar *authors[] = {
265 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
268 about = gtk_about_dialog_new ();
269 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
270 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
271 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
272 _("Copyright (c) 2006, Nokia Corporation\n"
273 "All rights reserved."));
274 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
275 _("a modest e-mail client\n\n"
276 "design and implementation: Dirk-Jan C. Binnema\n"
277 "contributions from the fine people at KC and Ig\n"
278 "uses the tinymail email framework written by Philip van Hoof"));
279 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
280 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
282 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
283 gtk_window_set_transient_for (GTK_WINDOW (about), toplevel);
284 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
286 gtk_dialog_run (GTK_DIALOG (about));
287 gtk_widget_destroy(about);
291 * Gets the list of currently selected messages. If the win is the
292 * main window, then it returns a newly allocated list of the headers
293 * selected in the header view. If win is the msg view window, then
294 * the value returned is a list with just a single header.
296 * The caller of this funcion must free the list.
299 get_selected_headers (ModestWindow *win)
301 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
302 /* for MsgViewWindows, we simply return a list with one element */
304 TnyList *list = NULL;
306 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
307 if (header != NULL) {
308 list = tny_simple_list_new ();
309 tny_list_prepend (list, G_OBJECT(header));
310 g_object_unref (G_OBJECT(header));
314 } else if (MODEST_IS_HEADER_WINDOW (win)) {
315 GtkWidget *header_view;
317 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
318 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
325 headers_action_mark_as_read (TnyHeader *header,
329 TnyHeaderFlags flags;
331 g_return_if_fail (TNY_IS_HEADER(header));
333 flags = tny_header_get_flags (header);
334 if (flags & TNY_HEADER_FLAG_SEEN) return;
335 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
339 headers_action_mark_as_unread (TnyHeader *header,
343 TnyHeaderFlags flags;
345 g_return_if_fail (TNY_IS_HEADER(header));
347 flags = tny_header_get_flags (header);
348 if (flags & TNY_HEADER_FLAG_SEEN) {
349 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
353 /** After deleing a message that is currently visible in a window,
354 * show the next message from the list, or close the window if there are no more messages.
357 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
359 /* Close msg view window or select next */
360 if (!modest_msg_view_window_select_next_message (win) &&
361 !modest_msg_view_window_select_previous_message (win)) {
363 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
369 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
371 modest_ui_actions_on_edit_mode_delete_message (win);
375 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
377 TnyList *header_list = NULL;
378 TnyIterator *iter = NULL;
379 TnyHeader *header = NULL;
380 gchar *message = NULL;
383 ModestWindowMgr *mgr;
384 gboolean retval = TRUE;
387 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
389 /* Get the headers, either from the header view (if win is the main window),
390 * or from the message view window: */
391 header_list = get_selected_headers (win);
392 if (!header_list) return FALSE;
394 /* Check if any of the headers are already opened, or in the process of being opened */
397 if (tny_list_get_length(header_list) == 1) {
398 iter = tny_list_create_iterator (header_list);
399 header = TNY_HEADER (tny_iterator_get_current (iter));
402 subject = tny_header_dup_subject (header);
404 subject = g_strdup (_("mail_va_no_subject"));
405 desc = g_strdup_printf ("%s", subject);
407 g_object_unref (header);
410 g_object_unref (iter);
412 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
413 tny_list_get_length(header_list)), desc);
415 /* Confirmation dialog */
416 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
417 response = modest_platform_run_confirmation_dialog (toplevel, message);
419 if (response == GTK_RESPONSE_OK) {
420 GtkTreeSelection *sel = NULL;
421 GList *sel_list = NULL;
422 ModestMailOperation *mail_op = NULL;
424 /* Find last selected row */
426 /* Disable window dimming management */
427 modest_window_disable_dimming (win);
429 /* Remove each header. If it's a view window header_view == NULL */
430 mail_op = modest_mail_operation_new ((GObject *) win);
431 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
433 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
434 g_object_unref (mail_op);
436 /* Enable window dimming management */
438 gtk_tree_selection_unselect_all (sel);
440 modest_window_enable_dimming (win);
442 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
443 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
445 /* Get main window */
446 mgr = modest_runtime_get_window_mgr ();
449 /* Update toolbar dimming state */
450 modest_ui_actions_check_menu_dimming_rules (win);
451 modest_ui_actions_check_toolbar_dimming_rules (win);
454 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
455 g_list_free (sel_list);
464 g_object_unref (header_list);
472 /* delete either message or folder, based on where we are */
474 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
476 g_return_if_fail (MODEST_IS_WINDOW(win));
478 /* Check first if the header view has the focus */
479 modest_ui_actions_on_delete_message (action, win);
483 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
485 ModestWindowMgr *mgr = NULL;
487 #ifdef MODEST_PLATFORM_MAEMO
488 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
489 #endif /* MODEST_PLATFORM_MAEMO */
491 g_debug ("closing down, clearing %d item(s) from operation queue",
492 modest_mail_operation_queue_num_elements
493 (modest_runtime_get_mail_operation_queue()));
495 /* cancel all outstanding operations */
496 modest_mail_operation_queue_cancel_all
497 (modest_runtime_get_mail_operation_queue());
499 g_debug ("queue has been cleared");
502 /* Check if there are opened editing windows */
503 mgr = modest_runtime_get_window_mgr ();
504 modest_window_mgr_close_all_windows (mgr);
506 /* note: when modest-tny-account-store is finalized,
507 it will automatically set all network connections
510 /* gtk_main_quit (); */
514 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
518 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
520 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
521 /* gtk_widget_destroy (GTK_WIDGET (win)); */
522 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
523 /* gboolean ret_value; */
524 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
525 /* } else if (MODEST_IS_WINDOW (win)) { */
526 /* gtk_widget_destroy (GTK_WIDGET (win)); */
528 /* g_return_if_reached (); */
533 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
535 if (MODEST_IS_MSG_VIEW_WINDOW (win))
536 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
537 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
538 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
542 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
544 GtkClipboard *clipboard = NULL;
545 gchar *selection = NULL;
547 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
548 selection = gtk_clipboard_wait_for_text (clipboard);
551 modest_address_book_add_address (selection, (GtkWindow *) win);
557 modest_ui_actions_on_new_account (GtkAction *action,
558 ModestWindow *window)
560 if (!modest_ui_actions_run_account_setup_wizard (window)) {
561 g_debug ("%s: wizard was already running", __FUNCTION__);
566 modest_ui_actions_on_accounts (GtkAction *action,
569 /* This is currently only implemented for Maemo */
570 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
571 if (!modest_ui_actions_run_account_setup_wizard (win))
572 g_debug ("%s: wizard was already running", __FUNCTION__);
576 /* Show the list of accounts */
577 GtkWindow *win_toplevel, *acc_toplevel;
578 GtkWidget *account_win;
580 account_win = modest_account_view_window_new ();
581 acc_toplevel = (GtkWindow *) gtk_widget_get_toplevel (account_win);
583 /* The accounts dialog must be modal */
584 win_toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
585 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), acc_toplevel, win_toplevel);
586 modest_utils_show_dialog_and_forget (win_toplevel, GTK_DIALOG (account_win));
591 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
593 /* Create the window if necessary: */
594 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
595 modest_connection_specific_smtp_window_fill_with_connections (
596 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
597 modest_runtime_get_account_mgr());
599 /* Show the window: */
600 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
601 GTK_WINDOW (specific_window), (GtkWindow *) win);
602 gtk_widget_show (specific_window);
606 count_part_size (const gchar *part)
608 GnomeVFSURI *vfs_uri;
609 gchar *escaped_filename;
611 GnomeVFSFileInfo *info;
614 /* Estimation of attachment size if we cannot get it from file info */
617 vfs_uri = gnome_vfs_uri_new (part);
619 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
620 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
621 g_free (escaped_filename);
622 gnome_vfs_uri_unref (vfs_uri);
624 info = gnome_vfs_file_info_new ();
626 if (gnome_vfs_get_file_info (part,
628 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
630 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
635 gnome_vfs_file_info_unref (info);
641 count_parts_size (GSList *parts)
646 for (node = parts; node != NULL; node = g_slist_next (node)) {
647 result += count_part_size ((const gchar *) node->data);
654 modest_ui_actions_compose_msg(ModestWindow *win,
657 const gchar *bcc_str,
658 const gchar *subject_str,
659 const gchar *body_str,
661 gboolean set_as_modified)
663 gchar *account_name = NULL;
664 const gchar *mailbox;
666 TnyAccount *account = NULL;
667 TnyFolder *folder = NULL;
668 gchar *from_str = NULL, *signature = NULL, *body = NULL;
669 gchar *recipient = NULL;
670 gboolean use_signature = FALSE;
671 ModestWindow *msg_win = NULL;
672 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
673 ModestTnyAccountStore *store = modest_runtime_get_account_store();
674 GnomeVFSFileSize total_size, allowed_size;
675 guint64 available_disk, expected_size, parts_size;
678 /* we check for low-mem */
679 if (modest_platform_check_memory_low (win, TRUE))
682 available_disk = modest_utils_get_available_space (NULL);
683 parts_count = g_slist_length (attachments);
684 parts_size = count_parts_size (attachments);
685 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
687 /* Double check: disk full condition or message too big */
688 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
689 expected_size > available_disk) {
690 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
691 modest_platform_system_banner (NULL, NULL, msg);
697 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
698 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
699 modest_platform_run_information_dialog (toplevel,
700 _("mail_ib_error_attachment_size"),
707 account_name = g_strdup (modest_window_get_active_account(win));
709 account_name = modest_account_mgr_get_default_account(mgr);
712 g_printerr ("modest: no account found\n");
717 mailbox = modest_window_get_active_mailbox (win);
720 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
722 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
725 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
727 g_printerr ("modest: failed to find Drafts folder\n");
730 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
732 g_printerr ("modest: failed get from string for '%s'\n", account_name);
736 recipient = modest_text_utils_get_email_address (from_str);
737 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
739 if (body_str != NULL) {
740 body = use_signature ? g_strconcat(body_str, "\n",
741 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
742 "\n", signature, NULL) : g_strdup(body_str);
745 gchar *gray_color_markup = NULL, *color_begin = NULL, *color_end = NULL;
748 if (gtk_style_lookup_color (GTK_WIDGET (win)->style, "SecondaryTextColor", &color))
749 gray_color_markup = modest_text_utils_get_color_string (&color);
750 if (!gray_color_markup)
751 gray_color_markup = g_strdup ("#999999");
753 color_begin = g_strdup_printf ("<font color=\"%s\">", gray_color_markup);
754 color_end = "</font>";
756 body = use_signature ? g_strconcat("<br/>\n", color_begin,
757 MODEST_TEXT_UTILS_SIGNATURE_MARKER, "<br/>\n",
758 signature, color_end, NULL) : g_strdup("");
760 g_free (gray_color_markup);
761 g_free (color_begin);
764 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
765 NULL, NULL, body, NULL, NULL, NULL, NULL, NULL);
767 g_printerr ("modest: failed to create new msg\n");
771 /* Create and register edit window */
772 /* This is destroyed by TODO. */
774 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
775 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
777 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
778 gtk_widget_destroy (GTK_WIDGET (msg_win));
781 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
782 gtk_widget_show_all (GTK_WIDGET (msg_win));
784 while (attachments) {
785 GnomeVFSFileSize att_size;
787 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
788 attachments->data, allowed_size);
789 total_size += att_size;
791 if (att_size > allowed_size) {
792 g_debug ("%s: total size: %u",
793 __FUNCTION__, (unsigned int)total_size);
796 allowed_size -= att_size;
798 attachments = g_slist_next(attachments);
805 g_free (account_name);
807 g_object_unref (G_OBJECT(account));
809 g_object_unref (G_OBJECT(folder));
811 g_object_unref (G_OBJECT(msg));
815 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
817 /* if there are no accounts yet, just show the wizard */
818 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
819 if (!modest_ui_actions_run_account_setup_wizard (win))
822 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
827 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
831 ModestMailOperationStatus status;
833 /* If there is no message or the operation was not successful */
834 status = modest_mail_operation_get_status (mail_op);
835 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
838 /* If it's a memory low issue, then show a banner */
839 error = modest_mail_operation_get_error (mail_op);
840 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
841 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
842 GtkWindow *toplevel = NULL;
843 GObject *source = modest_mail_operation_get_source (mail_op);
845 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (source));
846 modest_platform_run_information_dialog (toplevel,
847 _KR("memr_ib_operation_disabled"),
849 g_object_unref (source);
852 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
853 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
854 gchar *subject, *msg, *format = NULL;
857 subject = (header) ? tny_header_dup_subject (header) : NULL;
859 subject = g_strdup (_("mail_va_no_subject"));
861 account = modest_mail_operation_get_account (mail_op);
863 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
864 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
867 if (tny_account_get_connection_status (account) ==
868 TNY_CONNECTION_STATUS_CONNECTED) {
870 format = modest_protocol_get_translation (protocol,
871 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
874 format = modest_protocol_get_translation (protocol,
875 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
878 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
879 tny_account_get_hostname (account));
882 g_object_unref (account);
887 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
889 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
893 msg = g_strdup_printf (format, subject);
894 modest_platform_run_information_dialog (NULL, msg, FALSE);
900 /* Remove the header from the preregistered uids */
901 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
919 ModestWindow *caller_window;
920 OpenMsgBannerInfo *banner_info;
921 GtkTreeRowReference *rowref;
925 open_msg_banner_idle (gpointer userdata)
927 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
929 gdk_threads_enter ();
930 banner_info->idle_handler = 0;
931 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
932 if (banner_info->banner)
933 g_object_ref (banner_info->banner);
935 gdk_threads_leave ();
941 get_header_view_from_window (ModestWindow *window)
943 GtkWidget *header_view;
945 if (MODEST_IS_HEADER_WINDOW (window)){
946 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
955 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
958 gchar *account = NULL;
959 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
964 folder = tny_header_get_folder (header);
965 /* Gets folder type (OUTBOX headers will be opened in edit window */
966 if (modest_tny_folder_is_local_folder (folder)) {
967 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
968 if (folder_type == TNY_FOLDER_TYPE_INVALID)
969 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
972 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
973 TnyTransportAccount *traccount = NULL;
974 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
975 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
977 ModestTnySendQueue *send_queue = NULL;
978 ModestTnySendQueueStatus status;
980 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
981 TNY_ACCOUNT(traccount)));
982 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
983 if (TNY_IS_SEND_QUEUE (send_queue)) {
984 msg_id = modest_tny_send_queue_get_msg_id (header);
985 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
987 /* Only open messages in outbox with the editor if they are in Failed state */
988 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
992 /* In Fremantle we can not
993 open any message from
994 outbox which is not in
999 g_object_unref(traccount);
1001 g_warning("Cannot get transport account for message in outbox!!");
1003 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1004 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1008 TnyAccount *acc = tny_folder_get_account (folder);
1011 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1012 g_object_unref (acc);
1016 g_object_unref (folder);
1022 open_msg_cb (ModestMailOperation *mail_op,
1029 ModestWindowMgr *mgr = NULL;
1030 ModestWindow *parent_win = NULL;
1031 ModestWindow *win = NULL;
1032 gchar *account = NULL;
1033 gboolean open_in_editor = FALSE;
1035 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1037 /* Do nothing if there was any problem with the mail
1038 operation. The error will be shown by the error_handler of
1039 the mail operation */
1040 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1043 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1045 /* Mark header as read */
1046 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1048 account = get_info_from_header (header, &open_in_editor, &can_open);
1052 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1054 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1056 if (open_in_editor) {
1057 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1058 gchar *from_header = NULL, *acc_name;
1059 gchar *mailbox = NULL;
1061 from_header = tny_header_dup_from (header);
1063 /* we cannot edit without a valid account... */
1064 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1065 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1066 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1068 g_free (from_header);
1073 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1074 g_free (from_header);
1080 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1084 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1085 const gchar *mailbox = NULL;
1087 if (parent_win && MODEST_IS_WINDOW (parent_win))
1088 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1090 if (helper->rowref && helper->model) {
1091 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1092 helper->model, helper->rowref);
1094 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1099 /* Register and show new window */
1101 mgr = modest_runtime_get_window_mgr ();
1102 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1103 gtk_widget_destroy (GTK_WIDGET (win));
1106 gtk_widget_show_all (GTK_WIDGET(win));
1113 g_object_unref (parent_win);
1117 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1120 const GError *error;
1121 GObject *win = NULL;
1122 ModestMailOperationStatus status;
1124 win = modest_mail_operation_get_source (mail_op);
1125 error = modest_mail_operation_get_error (mail_op);
1126 status = modest_mail_operation_get_status (mail_op);
1128 /* If the mail op has been cancelled then it's not an error:
1129 don't show any message */
1130 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1131 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1132 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1133 (GError *) error, account)) {
1134 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1135 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1137 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1138 modest_platform_information_banner ((GtkWidget *) win,
1139 NULL, _("emev_ui_imap_inbox_select_error"));
1140 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1141 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1142 modest_platform_information_banner ((GtkWidget *) win,
1143 NULL, _CS_UNABLE_TO_OPEN_FILE_NOT_FOUND);
1144 } else if (user_data) {
1145 modest_platform_information_banner ((GtkWidget *) win,
1149 g_object_unref (account);
1153 g_object_unref (win);
1157 * Returns the account a list of headers belongs to. It returns a
1158 * *new* reference so don't forget to unref it
1161 get_account_from_header_list (TnyList *headers)
1163 TnyAccount *account = NULL;
1165 if (tny_list_get_length (headers) > 0) {
1166 TnyIterator *iter = tny_list_create_iterator (headers);
1167 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1168 TnyFolder *folder = tny_header_get_folder (header);
1171 g_object_unref (header);
1173 while (!tny_iterator_is_done (iter)) {
1174 header = TNY_HEADER (tny_iterator_get_current (iter));
1175 folder = tny_header_get_folder (header);
1178 g_object_unref (header);
1180 tny_iterator_next (iter);
1185 account = tny_folder_get_account (folder);
1186 g_object_unref (folder);
1190 g_object_unref (header);
1192 g_object_unref (iter);
1198 get_account_from_header (TnyHeader *header)
1200 TnyAccount *account = NULL;
1203 folder = tny_header_get_folder (header);
1206 account = tny_folder_get_account (folder);
1207 g_object_unref (folder);
1213 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1215 if (helper->caller_window)
1216 helper->caller_window = NULL;
1220 open_msg_helper_destroyer (gpointer user_data)
1222 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1224 if (helper->caller_window) {
1225 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1226 helper->caller_window = NULL;
1229 if (helper->banner_info) {
1230 g_free (helper->banner_info->message);
1231 if (helper->banner_info->idle_handler > 0) {
1232 g_source_remove (helper->banner_info->idle_handler);
1233 helper->banner_info->idle_handler = 0;
1235 if (helper->banner_info->banner != NULL) {
1236 gtk_widget_destroy (helper->banner_info->banner);
1237 g_object_unref (helper->banner_info->banner);
1238 helper->banner_info->banner = NULL;
1240 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1241 helper->banner_info = NULL;
1243 g_object_unref (helper->model);
1244 g_object_unref (helper->header);
1245 gtk_tree_row_reference_free (helper->rowref);
1246 g_slice_free (OpenMsgHelper, helper);
1250 open_msg_performer(gboolean canceled,
1252 ModestWindow *parent_window,
1253 TnyAccount *account,
1256 ModestMailOperation *mail_op = NULL;
1257 gchar *error_msg = NULL;
1258 ModestProtocolType proto;
1259 TnyConnectionStatus status;
1260 OpenMsgHelper *helper = NULL;
1261 ModestProtocol *protocol;
1262 ModestProtocolRegistry *protocol_registry;
1265 helper = (OpenMsgHelper *) user_data;
1267 status = tny_account_get_connection_status (account);
1268 if (err || canceled || helper->caller_window == NULL) {
1269 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1270 /* Free the helper */
1271 open_msg_helper_destroyer (helper);
1273 /* In disk full conditions we could get this error here */
1274 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1275 (GtkWidget *) parent_window, err,
1281 /* Get the error message depending on the protocol */
1282 proto = modest_tny_account_get_protocol_type (account);
1283 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1284 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1287 protocol_registry = modest_runtime_get_protocol_registry ();
1288 subject = tny_header_dup_subject (helper->header);
1290 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1291 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1295 if (error_msg == NULL) {
1296 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1301 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1304 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1305 g_free (account_name);
1306 open_msg_helper_destroyer (helper);
1311 ModestWindow *window;
1312 GtkWidget *header_view;
1315 header_view = get_header_view_from_window (parent_window);
1316 uid = modest_tny_folder_get_header_unique_id (helper->header);
1318 const gchar *mailbox = NULL;
1319 mailbox = modest_window_get_active_mailbox (parent_window);
1320 window = modest_msg_view_window_new_from_header_view
1321 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1322 if (window != NULL) {
1323 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1325 gtk_widget_destroy (GTK_WIDGET (window));
1327 gtk_widget_show_all (GTK_WIDGET(window));
1331 g_free (account_name);
1333 open_msg_helper_destroyer (helper);
1336 g_free (account_name);
1337 /* Create the mail operation */
1339 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1340 modest_ui_actions_disk_operations_error_handler,
1341 g_strdup (error_msg), g_free);
1342 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1348 headers = TNY_LIST (tny_simple_list_new ());
1349 tny_list_prepend (headers, G_OBJECT (helper->header));
1350 modest_mail_operation_get_msgs_full (mail_op,
1354 open_msg_helper_destroyer);
1355 g_object_unref (headers);
1362 g_object_unref (mail_op);
1363 g_object_unref (account);
1367 * This function is used by both modest_ui_actions_on_open and
1368 * modest_ui_actions_on_header_activated. This way we always do the
1369 * same when trying to open messages.
1372 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1374 ModestWindowMgr *mgr = NULL;
1375 TnyAccount *account;
1376 gboolean cached = FALSE;
1378 GtkWidget *header_view = NULL;
1379 OpenMsgHelper *helper;
1380 ModestWindow *window;
1382 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1384 mgr = modest_runtime_get_window_mgr ();
1387 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1388 if (header_view == NULL)
1391 /* Get the account */
1392 account = get_account_from_header (header);
1397 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1399 /* Do not open again the message and present the
1400 window to the user */
1403 #ifndef MODEST_TOOLKIT_HILDON2
1404 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
1405 gtk_window_present (toplevel);
1408 /* the header has been registered already, we don't do
1409 * anything but wait for the window to come up*/
1410 g_debug ("header %p already registered, waiting for window", header);
1415 /* Open each message */
1416 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1418 /* Allways download if we are online. */
1419 if (!tny_device_is_online (modest_runtime_get_device ())) {
1421 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1423 /* If ask for user permission to download the messages */
1424 response = modest_platform_run_confirmation_dialog (toplevel,
1425 _("mcen_nc_get_msg"));
1427 /* End if the user does not want to continue */
1428 if (response == GTK_RESPONSE_CANCEL) {
1434 /* We register the window for opening */
1435 modest_window_mgr_register_header (mgr, header, NULL);
1437 /* Create the helper. We need to get a reference to the model
1438 here because it could change while the message is readed
1439 (the user could switch between folders) */
1440 helper = g_slice_new (OpenMsgHelper);
1441 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1442 helper->caller_window = win;
1443 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1444 helper->header = g_object_ref (header);
1445 helper->rowref = gtk_tree_row_reference_copy (rowref);
1446 helper->banner_info = NULL;
1448 /* Connect to the account and perform */
1450 modest_platform_connect_and_perform (win, TRUE, g_object_ref (account),
1451 open_msg_performer, helper);
1453 /* Call directly the performer, do not need to connect */
1454 open_msg_performer (FALSE, NULL, win,
1455 g_object_ref (account), helper);
1460 g_object_unref (account);
1464 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1471 /* we check for low-mem; in that case, show a warning, and don't allow
1474 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1478 headers = get_selected_headers (win);
1482 headers_count = tny_list_get_length (headers);
1483 if (headers_count != 1) {
1484 if (headers_count > 1) {
1485 /* Don't allow activation if there are more than one message selected */
1486 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1489 g_object_unref (headers);
1493 iter = tny_list_create_iterator (headers);
1494 header = TNY_HEADER (tny_iterator_get_current (iter));
1495 g_object_unref (iter);
1499 open_msg_from_header (header, NULL, win);
1500 g_object_unref (header);
1503 g_object_unref(headers);
1507 rf_helper_window_closed (gpointer data,
1510 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1512 helper->parent_window = NULL;
1515 static ReplyForwardHelper*
1516 create_reply_forward_helper (ReplyForwardAction action,
1518 guint reply_forward_type,
1522 ReplyForwardHelper *rf_helper = NULL;
1523 const gchar *active_acc = modest_window_get_active_account (win);
1524 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1526 rf_helper = g_slice_new0 (ReplyForwardHelper);
1527 rf_helper->reply_forward_type = reply_forward_type;
1528 rf_helper->action = action;
1529 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1530 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1531 rf_helper->account_name = (active_acc) ?
1532 g_strdup (active_acc) :
1533 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1534 rf_helper->mailbox = g_strdup (active_mailbox);
1536 rf_helper->parts = g_object_ref (parts);
1538 rf_helper->parts = NULL;
1540 /* Note that window could be destroyed just AFTER calling
1541 register_window so we must ensure that this pointer does
1542 not hold invalid references */
1543 if (rf_helper->parent_window)
1544 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1545 rf_helper_window_closed, rf_helper);
1551 free_reply_forward_helper (gpointer data)
1553 ReplyForwardHelper *helper;
1555 helper = (ReplyForwardHelper *) data;
1556 g_free (helper->account_name);
1557 g_free (helper->mailbox);
1559 g_object_unref (helper->header);
1561 g_object_unref (helper->parts);
1562 if (helper->parent_window)
1563 g_object_weak_unref (G_OBJECT (helper->parent_window),
1564 rf_helper_window_closed, helper);
1565 g_slice_free (ReplyForwardHelper, helper);
1569 reply_forward_cb (ModestMailOperation *mail_op,
1576 TnyMsg *new_msg = NULL;
1577 ReplyForwardHelper *rf_helper;
1578 ModestWindow *msg_win = NULL;
1579 ModestEditType edit_type;
1581 TnyAccount *account = NULL;
1582 ModestWindowMgr *mgr = NULL;
1583 gchar *signature = NULL;
1584 gboolean use_signature;
1587 /* If there was any error. The mail operation could be NULL,
1588 this means that we already have the message downloaded and
1589 that we didn't do a mail operation to retrieve it */
1590 rf_helper = (ReplyForwardHelper *) user_data;
1591 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1594 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1595 rf_helper->account_name, rf_helper->mailbox);
1596 recipient = modest_text_utils_get_email_address (from);
1597 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1602 /* Create reply mail */
1603 switch (rf_helper->action) {
1604 /* Use the msg_header to ensure that we have all the
1605 information. The summary can lack some data */
1606 TnyHeader *msg_header;
1608 msg_header = tny_msg_get_header (msg);
1610 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1611 (use_signature) ? signature : NULL,
1612 rf_helper->reply_forward_type,
1613 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1614 g_object_unref (msg_header);
1616 case ACTION_REPLY_TO_ALL:
1617 msg_header = tny_msg_get_header (msg);
1619 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1620 (use_signature) ? signature : NULL,
1621 rf_helper->reply_forward_type,
1622 MODEST_TNY_MSG_REPLY_MODE_ALL);
1623 edit_type = MODEST_EDIT_TYPE_REPLY;
1624 g_object_unref (msg_header);
1626 case ACTION_FORWARD:
1628 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1629 rf_helper->reply_forward_type);
1630 edit_type = MODEST_EDIT_TYPE_FORWARD;
1633 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1635 g_return_if_reached ();
1643 g_warning ("%s: failed to create message\n", __FUNCTION__);
1647 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1648 rf_helper->account_name,
1649 TNY_ACCOUNT_TYPE_STORE);
1651 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1655 /* Create and register the windows */
1656 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1657 mgr = modest_runtime_get_window_mgr ();
1658 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1660 /* Note that register_window could have deleted the account */
1661 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1662 gdouble parent_zoom;
1664 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1665 modest_window_set_zoom (msg_win, parent_zoom);
1668 /* Show edit window */
1669 gtk_widget_show_all (GTK_WIDGET (msg_win));
1672 /* We always unregister the header because the message is
1673 forwarded or replied so the original one is no longer
1675 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1678 g_object_unref (G_OBJECT (new_msg));
1680 g_object_unref (G_OBJECT (account));
1681 free_reply_forward_helper (rf_helper);
1684 /* Checks a list of headers. If any of them are not currently
1685 * downloaded (CACHED) then returns TRUE else returns FALSE.
1688 header_list_count_uncached_msgs (TnyList *header_list)
1691 gint uncached_messages = 0;
1693 iter = tny_list_create_iterator (header_list);
1694 while (!tny_iterator_is_done (iter)) {
1697 header = TNY_HEADER (tny_iterator_get_current (iter));
1699 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1700 uncached_messages ++;
1701 g_object_unref (header);
1704 tny_iterator_next (iter);
1706 g_object_unref (iter);
1708 return uncached_messages;
1711 /* Returns FALSE if the user does not want to download the
1712 * messages. Returns TRUE if the user allowed the download.
1715 connect_to_get_msg (ModestWindow *win,
1716 gint num_of_uncached_msgs,
1717 TnyAccount *account)
1719 GtkResponseType response;
1720 GtkWindow *toplevel;
1722 /* Allways download if we are online. */
1723 if (tny_device_is_online (modest_runtime_get_device ()))
1726 /* If offline, then ask for user permission to download the messages */
1727 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1728 response = modest_platform_run_confirmation_dialog (toplevel,
1729 ngettext("mcen_nc_get_msg",
1731 num_of_uncached_msgs));
1733 if (response == GTK_RESPONSE_CANCEL)
1736 return modest_platform_connect_and_wait(toplevel, account);
1740 reply_forward_performer (gboolean canceled,
1742 ModestWindow *parent_window,
1743 TnyAccount *account,
1746 ReplyForwardHelper *rf_helper = NULL;
1747 ModestMailOperation *mail_op;
1749 rf_helper = (ReplyForwardHelper *) user_data;
1751 if (canceled || err) {
1752 free_reply_forward_helper (rf_helper);
1756 /* Retrieve the message */
1757 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1758 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1759 modest_ui_actions_disk_operations_error_handler,
1761 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1762 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1765 g_object_unref(mail_op);
1769 all_parts_retrieved (TnyMimePart *part)
1771 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1774 TnyList *pending_parts;
1775 TnyIterator *iterator;
1776 gboolean all_retrieved = TRUE;
1778 pending_parts = TNY_LIST (tny_simple_list_new ());
1779 tny_mime_part_get_parts (part, pending_parts);
1780 iterator = tny_list_create_iterator (pending_parts);
1781 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1784 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1786 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1787 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1789 all_retrieved = FALSE;
1792 g_object_unref (child);
1793 tny_iterator_next (iterator);
1795 g_object_unref (iterator);
1796 g_object_unref (pending_parts);
1797 return all_retrieved;
1802 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1805 TnyIterator *iterator;
1807 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
1808 tny_list_append (list, G_OBJECT (part));
1810 parts = TNY_LIST (tny_simple_list_new ());
1811 tny_mime_part_get_parts (part, parts);
1812 for (iterator = tny_list_create_iterator (parts);
1813 !tny_iterator_is_done (iterator);
1814 tny_iterator_next (iterator)) {
1817 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1818 forward_pending_parts_helper (child, list);
1819 g_object_unref (child);
1821 g_object_unref (iterator);
1822 g_object_unref (parts);
1826 forward_pending_parts (TnyMsg *msg)
1828 TnyList *result = TNY_LIST (tny_simple_list_new ());
1829 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
1830 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
1837 * Common code for the reply and forward actions
1840 reply_forward (ReplyForwardAction action, ModestWindow *win)
1842 ReplyForwardHelper *rf_helper = NULL;
1843 guint reply_forward_type;
1845 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1847 /* we check for low-mem; in that case, show a warning, and don't allow
1848 * reply/forward (because it could potentially require a lot of memory */
1849 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1853 /* we need an account when editing */
1854 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1855 if (!modest_ui_actions_run_account_setup_wizard (win))
1859 reply_forward_type =
1860 modest_conf_get_int (modest_runtime_get_conf (),
1861 (action == ACTION_FORWARD) ?
1862 MODEST_CONF_FORWARD_TYPE :
1863 MODEST_CONF_REPLY_TYPE,
1866 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1868 TnyHeader *header = NULL;
1869 /* Get header and message. Do not free them here, the
1870 reply_forward_cb must do it */
1871 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1872 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1874 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
1876 rf_helper = create_reply_forward_helper (action, win,
1877 reply_forward_type, header, NULL);
1878 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1880 gboolean do_download = TRUE;
1882 if (msg && header && action == ACTION_FORWARD) {
1883 /* Not all parts retrieved. Then we have to retrieve them all before
1884 * creating the forward message */
1885 if (!tny_device_is_online (modest_runtime_get_device ())) {
1887 GtkWindow *toplevel;
1889 /* If ask for user permission to download the messages */
1890 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1891 response = modest_platform_run_confirmation_dialog (toplevel,
1892 ngettext("mcen_nc_get_msg",
1896 /* End if the user does not want to continue */
1897 if (response == GTK_RESPONSE_CANCEL)
1898 do_download = FALSE;
1902 TnyList *pending_parts;
1904 TnyAccount *account;
1907 pending_parts = forward_pending_parts (msg);
1908 rf_helper = create_reply_forward_helper (action, win,
1909 reply_forward_type, header, pending_parts);
1910 g_object_unref (pending_parts);
1912 folder = tny_header_get_folder (header);
1913 account = tny_folder_get_account (folder);
1914 modest_platform_connect_and_perform (win,
1916 reply_forward_performer,
1918 g_object_unref (folder);
1919 g_object_unref (account);
1923 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1928 g_object_unref (msg);
1930 g_object_unref (header);
1932 TnyHeader *header = NULL;
1934 gboolean do_retrieve = TRUE;
1935 TnyList *header_list = NULL;
1937 header_list = get_selected_headers (win);
1940 /* Check that only one message is selected for replying */
1941 if (tny_list_get_length (header_list) != 1) {
1942 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1943 NULL, _("mcen_ib_select_one_message"));
1944 g_object_unref (header_list);
1948 /* Only reply/forward to one message */
1949 iter = tny_list_create_iterator (header_list);
1950 header = TNY_HEADER (tny_iterator_get_current (iter));
1951 g_object_unref (iter);
1953 /* Retrieve messages */
1954 do_retrieve = (action == ACTION_FORWARD) ||
1955 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1958 TnyAccount *account = NULL;
1959 TnyFolder *folder = NULL;
1960 gdouble download = TRUE;
1961 guint uncached_msgs = 0;
1963 folder = tny_header_get_folder (header);
1965 goto do_retrieve_frees;
1966 account = tny_folder_get_account (folder);
1968 goto do_retrieve_frees;
1970 uncached_msgs = header_list_count_uncached_msgs (header_list);
1972 if (uncached_msgs > 0) {
1973 /* Allways download if we are online. */
1974 if (!tny_device_is_online (modest_runtime_get_device ())) {
1976 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1978 /* If ask for user permission to download the messages */
1979 response = modest_platform_run_confirmation_dialog (toplevel,
1980 ngettext("mcen_nc_get_msg",
1984 /* End if the user does not want to continue */
1985 if (response == GTK_RESPONSE_CANCEL)
1992 rf_helper = create_reply_forward_helper (action, win,
1993 reply_forward_type, header, NULL);
1994 if (uncached_msgs > 0) {
1995 modest_platform_connect_and_perform (win,
1997 reply_forward_performer,
2000 reply_forward_performer (FALSE, NULL, win,
2001 account, rf_helper);
2006 g_object_unref (account);
2008 g_object_unref (folder);
2010 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2013 g_object_unref (header_list);
2014 g_object_unref (header);
2019 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2021 g_return_if_fail (MODEST_IS_WINDOW(win));
2023 reply_forward (ACTION_REPLY, win);
2027 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2029 g_return_if_fail (MODEST_IS_WINDOW(win));
2031 reply_forward (ACTION_FORWARD, win);
2035 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2037 g_return_if_fail (MODEST_IS_WINDOW(win));
2039 reply_forward (ACTION_REPLY_TO_ALL, win);
2043 modest_ui_actions_on_next (GtkAction *action,
2044 ModestWindow *window)
2046 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2047 modest_msg_view_window_select_next_message (
2048 MODEST_MSG_VIEW_WINDOW (window));
2050 g_return_if_reached ();
2055 modest_ui_actions_on_prev (GtkAction *action,
2056 ModestWindow *window)
2058 g_return_if_fail (MODEST_IS_WINDOW(window));
2060 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2061 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2063 g_return_if_reached ();
2068 modest_ui_actions_on_sort (GtkAction *action,
2069 ModestWindow *window)
2071 GtkWidget *header_view = NULL;
2073 g_return_if_fail (MODEST_IS_WINDOW(window));
2075 if (MODEST_IS_HEADER_WINDOW (window)) {
2076 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2080 modest_platform_information_banner (NULL, NULL, _CS_NOTHING_TO_SORT);
2085 /* Show sorting dialog */
2086 modest_utils_run_sort_dialog (MODEST_WINDOW (window), MODEST_SORT_HEADERS);
2090 sync_folder_cb (ModestMailOperation *mail_op,
2094 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2096 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2097 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2099 /* We must clear first, because otherwise set_folder will ignore */
2100 /* the change as the folders are the same */
2101 modest_header_view_clear (header_view);
2102 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2104 g_object_unref (parent);
2107 g_object_unref (header_view);
2111 idle_refresh_folder (gpointer source)
2113 ModestHeaderView *header_view = NULL;
2115 /* If the window still exists */
2116 if (!GTK_IS_WIDGET (source) ||
2117 !GTK_WIDGET_VISIBLE (source))
2120 /* Refresh the current view */
2121 if (MODEST_IS_HEADER_WINDOW (source))
2122 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2124 TnyFolder *folder = modest_header_view_get_folder (header_view);
2126 /* Sync the folder status */
2127 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2128 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2129 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2130 g_object_unref (folder);
2131 g_object_unref (mail_op);
2139 update_account_cb (ModestMailOperation *self,
2140 TnyList *new_headers,
2144 gboolean show_visual_notifications;
2146 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2147 show_visual_notifications = (top) ? FALSE : TRUE;
2149 /* Notify new messages have been downloaded. If the
2150 send&receive was invoked by the user then do not show any
2151 visual notification, only play a sound and activate the LED
2152 (for the Maemo version) */
2153 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2155 /* We only notify about really new messages (not seen) we get */
2156 TnyList *actually_new_list;
2157 TnyIterator *iterator;
2158 actually_new_list = TNY_LIST (tny_simple_list_new ());
2159 for (iterator = tny_list_create_iterator (new_headers);
2160 !tny_iterator_is_done (iterator);
2161 tny_iterator_next (iterator)) {
2163 TnyHeaderFlags flags;
2164 header = TNY_HEADER (tny_iterator_get_current (iterator));
2165 flags = tny_header_get_flags (header);
2167 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2168 /* Messages are ordered from most
2169 recent to oldest. But we want to
2170 show notifications starting from
2171 the oldest message. That's why we
2173 tny_list_prepend (actually_new_list, G_OBJECT (header));
2175 g_object_unref (header);
2177 g_object_unref (iterator);
2179 if (tny_list_get_length (actually_new_list) > 0) {
2180 GList *new_headers_list = NULL;
2182 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2184 /* Send notifications */
2185 if (new_headers_list) {
2186 modest_platform_on_new_headers_received (new_headers_list,
2187 show_visual_notifications);
2189 modest_utils_free_notification_list (new_headers_list);
2192 g_object_unref (actually_new_list);
2196 /* Refresh the current folder in an idle. We do this
2197 in order to avoid refresh cancelations if the
2198 currently viewed folder is the inbox */
2199 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2200 idle_refresh_folder,
2207 TnyAccount *account;
2209 gchar *account_name;
2210 gboolean poke_status;
2211 gboolean interactive;
2212 ModestMailOperation *mail_op;
2216 do_send_receive_performer (gboolean canceled,
2218 ModestWindow *parent_window,
2219 TnyAccount *account,
2222 SendReceiveInfo *info;
2224 info = (SendReceiveInfo *) user_data;
2226 if (err || canceled) {
2227 /* In disk full conditions we could get this error here */
2228 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2229 (GtkWidget *) parent_window, err,
2232 if (info->mail_op) {
2233 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2240 /* Send & receive. */
2241 modest_mail_operation_update_account (info->mail_op, info->account_name,
2242 info->poke_status, info->interactive,
2243 update_account_cb, info->win);
2248 g_object_unref (G_OBJECT (info->mail_op));
2249 if (info->account_name)
2250 g_free (info->account_name);
2252 g_object_unref (info->win);
2254 g_object_unref (info->account);
2255 g_slice_free (SendReceiveInfo, info);
2259 * This function performs the send & receive required actions. The
2260 * window is used to create the mail operation. Typically it should
2261 * always be the main window, but we pass it as argument in order to
2265 modest_ui_actions_do_send_receive (const gchar *account_name,
2266 gboolean force_connection,
2267 gboolean poke_status,
2268 gboolean interactive,
2271 gchar *acc_name = NULL;
2272 SendReceiveInfo *info;
2273 ModestTnyAccountStore *acc_store;
2274 TnyAccount *account;
2276 /* If no account name was provided then get the current account, and if
2277 there is no current account then pick the default one: */
2278 if (!account_name) {
2280 acc_name = g_strdup (modest_window_get_active_account (win));
2282 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2284 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2288 acc_name = g_strdup (account_name);
2291 acc_store = modest_runtime_get_account_store ();
2292 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2296 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2300 /* Do not automatically refresh accounts that are flagged as
2301 NO_AUTO_UPDATE. This could be useful for accounts that
2302 handle their own update times */
2304 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2305 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2306 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2307 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2309 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2310 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2311 g_object_unref (account);
2318 /* Create the info for the connect and perform */
2319 info = g_slice_new (SendReceiveInfo);
2320 info->account_name = acc_name;
2321 info->win = (win) ? g_object_ref (win) : NULL;
2322 info->poke_status = poke_status;
2323 info->interactive = interactive;
2324 info->account = account;
2325 /* We need to create the operation here, because otherwise it
2326 could happen that the queue emits the queue-empty signal
2327 while we're trying to connect the account */
2328 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2329 modest_ui_actions_disk_operations_error_handler,
2331 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2333 /* Invoke the connect and perform */
2334 modest_platform_connect_and_perform (win, force_connection, info->account,
2335 do_send_receive_performer, info);
2340 modest_ui_actions_do_cancel_send (const gchar *account_name,
2343 TnyTransportAccount *transport_account;
2344 TnySendQueue *send_queue = NULL;
2345 GError *error = NULL;
2347 /* Get transport account */
2349 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2350 (modest_runtime_get_account_store(),
2352 TNY_ACCOUNT_TYPE_TRANSPORT));
2353 if (!transport_account) {
2354 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2359 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2360 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2361 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2362 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2363 "modest: could not find send queue for account\n");
2365 /* Cancel the current send */
2366 tny_account_cancel (TNY_ACCOUNT (transport_account));
2368 /* Suspend all pending messages */
2369 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2373 if (transport_account != NULL)
2374 g_object_unref (G_OBJECT (transport_account));
2378 modest_ui_actions_cancel_send_all (ModestWindow *win)
2380 GSList *account_names, *iter;
2382 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2385 iter = account_names;
2387 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2388 iter = g_slist_next (iter);
2391 modest_account_mgr_free_account_names (account_names);
2392 account_names = NULL;
2396 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2399 /* Check if accounts exist */
2400 gboolean accounts_exist =
2401 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2403 /* If not, allow the user to create an account before trying to send/receive. */
2404 if (!accounts_exist)
2405 modest_ui_actions_on_accounts (NULL, win);
2407 /* Cancel all sending operaitons */
2408 modest_ui_actions_cancel_send_all (win);
2412 * Refreshes all accounts. This function will be used by automatic
2416 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2417 gboolean force_connection,
2418 gboolean poke_status,
2419 gboolean interactive)
2421 GSList *account_names, *iter;
2423 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2426 iter = account_names;
2428 modest_ui_actions_do_send_receive ((const char*) iter->data,
2430 poke_status, interactive, win);
2431 iter = g_slist_next (iter);
2434 modest_account_mgr_free_account_names (account_names);
2435 account_names = NULL;
2439 * Handler of the click on Send&Receive button in the main toolbar
2442 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2444 /* Check if accounts exist */
2445 gboolean accounts_exist;
2448 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2450 /* If not, allow the user to create an account before trying to send/receive. */
2451 if (!accounts_exist)
2452 modest_ui_actions_on_accounts (NULL, win);
2454 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2455 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2456 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2458 const gchar *active_account;
2459 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2461 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2468 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2471 ModestWindow *window)
2473 GtkTreeRowReference *rowref;
2475 g_return_if_fail (MODEST_IS_WINDOW(window));
2476 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2477 g_return_if_fail (TNY_IS_HEADER (header));
2479 if (modest_header_view_count_selected_headers (header_view) > 1) {
2480 /* Don't allow activation if there are more than one message selected */
2481 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2485 /* we check for low-mem; in that case, show a warning, and don't allow
2486 * activating headers
2488 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2492 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2493 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2494 gtk_tree_row_reference_free (rowref);
2498 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2504 GtkWindow *toplevel;
2506 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
2507 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2509 online = tny_device_is_online (modest_runtime_get_device());
2512 /* already online -- the item is simply not there... */
2513 dialog = gtk_message_dialog_new (toplevel,
2515 GTK_MESSAGE_WARNING,
2517 _("The %s you selected cannot be found"),
2519 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2520 gtk_dialog_run (GTK_DIALOG(dialog));
2522 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2525 _("mcen_bd_dialog_cancel"),
2526 GTK_RESPONSE_REJECT,
2527 _("mcen_bd_dialog_ok"),
2528 GTK_RESPONSE_ACCEPT,
2530 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2531 "Do you want to get online?"), item);
2532 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2533 gtk_label_new (txt), FALSE, FALSE, 0);
2534 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2537 gtk_window_set_default_size ((GtkWindow *) dialog, 300, 300);
2538 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2539 /* TODO: Comment about why is this commented out: */
2540 /* modest_platform_connect_and_wait (); */
2543 gtk_widget_destroy (dialog);
2547 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2550 /* g_debug ("%s %s", __FUNCTION__, link); */
2555 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2558 modest_platform_activate_uri (link);
2562 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2565 modest_platform_show_uri_popup (link);
2569 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2572 /* we check for low-mem; in that case, show a warning, and don't allow
2573 * viewing attachments
2575 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2578 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2582 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2583 const gchar *address,
2586 /* g_debug ("%s %s", __FUNCTION__, address); */
2590 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2591 TnyMsg *saved_draft,
2594 ModestMsgEditWindow *edit_window;
2596 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2598 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2600 /* Set draft is there was no error */
2601 if (!modest_mail_operation_get_error (mail_op))
2602 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2604 g_object_unref(edit_window);
2608 enough_space_for_message (ModestMsgEditWindow *edit_window,
2611 guint64 available_disk, expected_size;
2616 available_disk = modest_utils_get_available_space (NULL);
2617 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2618 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2623 /* Double check: disk full condition or message too big */
2624 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2625 expected_size > available_disk) {
2626 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2627 modest_platform_information_banner (NULL, NULL, msg);
2634 * djcb: if we're in low-memory state, we only allow for
2635 * saving messages smaller than
2636 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2637 * should still allow for sending anything critical...
2639 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2640 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2644 * djcb: we also make sure that the attachments are smaller than the max size
2645 * this is for the case where we'd try to forward a message with attachments
2646 * bigger than our max allowed size, or sending an message from drafts which
2647 * somehow got past our checks when attaching.
2649 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2650 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) edit_window);
2651 modest_platform_run_information_dialog (toplevel,
2652 _("mail_ib_error_attachment_size"),
2661 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2663 TnyTransportAccount *transport_account;
2664 ModestMailOperation *mail_operation;
2666 gchar *account_name;
2667 ModestAccountMgr *account_mgr;
2668 gboolean had_error = FALSE;
2670 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2672 data = modest_msg_edit_window_get_msg_data (edit_window);
2675 if (!enough_space_for_message (edit_window, data)) {
2676 modest_msg_edit_window_free_msg_data (edit_window, data);
2680 account_name = g_strdup (data->account_name);
2681 account_mgr = modest_runtime_get_account_mgr();
2683 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2685 account_name = modest_account_mgr_get_default_account (account_mgr);
2686 if (!account_name) {
2687 g_printerr ("modest: no account found\n");
2688 modest_msg_edit_window_free_msg_data (edit_window, data);
2692 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2693 account_name = g_strdup (data->account_name);
2697 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2698 (modest_runtime_get_account_store (),
2700 TNY_ACCOUNT_TYPE_TRANSPORT));
2701 if (!transport_account) {
2702 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2703 g_free (account_name);
2704 modest_msg_edit_window_free_msg_data (edit_window, data);
2708 /* Create the mail operation */
2709 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2711 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2713 modest_mail_operation_save_to_drafts (mail_operation,
2725 data->priority_flags,
2728 on_save_to_drafts_cb,
2729 g_object_ref(edit_window));
2731 /* In hildon2 we always show the information banner on saving to drafts.
2732 * It will be a system information banner in this case.
2734 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2735 modest_platform_information_banner (NULL, NULL, text);
2737 modest_msg_edit_window_set_modified (edit_window, FALSE);
2740 g_free (account_name);
2741 g_object_unref (G_OBJECT (transport_account));
2742 g_object_unref (G_OBJECT (mail_operation));
2744 modest_msg_edit_window_free_msg_data (edit_window, data);
2750 /* For instance, when clicking the Send toolbar button when editing a message: */
2752 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2754 TnyTransportAccount *transport_account = NULL;
2755 gboolean had_error = FALSE, add_to_contacts;
2757 ModestAccountMgr *account_mgr;
2758 gchar *account_name;
2759 ModestMailOperation *mail_operation;
2762 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2764 /* Check whether to automatically add new contacts to addressbook or not */
2765 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
2766 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
2767 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
2770 data = modest_msg_edit_window_get_msg_data (edit_window);
2772 recipients = g_strconcat (data->to?data->to:"",
2773 data->cc?data->cc:"",
2774 data->bcc?data->bcc:"",
2776 if (recipients == NULL || recipients[0] == '\0') {
2777 /* Empty subject -> no send */
2778 g_free (recipients);
2779 modest_msg_edit_window_free_msg_data (edit_window, data);
2782 g_free (recipients);
2785 if (!enough_space_for_message (edit_window, data)) {
2786 modest_msg_edit_window_free_msg_data (edit_window, data);
2790 account_mgr = modest_runtime_get_account_mgr();
2791 account_name = g_strdup (data->account_name);
2793 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2796 account_name = modest_account_mgr_get_default_account (account_mgr);
2798 if (!account_name) {
2799 modest_msg_edit_window_free_msg_data (edit_window, data);
2800 /* Run account setup wizard */
2801 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2806 /* Get the currently-active transport account for this modest account: */
2807 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2809 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2810 (modest_runtime_get_account_store (),
2811 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2814 if (!transport_account) {
2815 modest_msg_edit_window_free_msg_data (edit_window, data);
2816 /* Run account setup wizard */
2817 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2822 /* Create the mail operation */
2823 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2824 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2826 modest_mail_operation_send_new_mail (mail_operation,
2840 data->priority_flags);
2842 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2843 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2845 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2846 const GError *error = modest_mail_operation_get_error (mail_operation);
2847 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2848 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2849 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2850 modest_platform_information_banner (NULL, NULL, _CS_NOT_ENOUGH_MEMORY);
2856 g_free (account_name);
2857 g_object_unref (G_OBJECT (transport_account));
2858 g_object_unref (G_OBJECT (mail_operation));
2860 modest_msg_edit_window_free_msg_data (edit_window, data);
2863 modest_msg_edit_window_set_sent (edit_window, TRUE);
2865 /* Save settings and close the window: */
2866 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2873 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2874 ModestMsgEditWindow *window)
2876 ModestMsgEditFormatState *format_state = NULL;
2878 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2879 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2881 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2884 format_state = modest_msg_edit_window_get_format_state (window);
2885 g_return_if_fail (format_state != NULL);
2887 format_state->bold = gtk_toggle_action_get_active (action);
2888 modest_msg_edit_window_set_format_state (window, format_state);
2889 g_free (format_state);
2894 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2895 ModestMsgEditWindow *window)
2897 ModestMsgEditFormatState *format_state = NULL;
2899 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2900 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2902 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2905 format_state = modest_msg_edit_window_get_format_state (window);
2906 g_return_if_fail (format_state != NULL);
2908 format_state->italics = gtk_toggle_action_get_active (action);
2909 modest_msg_edit_window_set_format_state (window, format_state);
2910 g_free (format_state);
2915 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2916 ModestMsgEditWindow *window)
2918 ModestMsgEditFormatState *format_state = NULL;
2920 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2921 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2923 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2926 format_state = modest_msg_edit_window_get_format_state (window);
2927 g_return_if_fail (format_state != NULL);
2929 format_state->bullet = gtk_toggle_action_get_active (action);
2930 modest_msg_edit_window_set_format_state (window, format_state);
2931 g_free (format_state);
2936 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2937 GtkRadioAction *selected,
2938 ModestMsgEditWindow *window)
2940 ModestMsgEditFormatState *format_state = NULL;
2941 GtkJustification value;
2943 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2945 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2948 value = gtk_radio_action_get_current_value (selected);
2950 format_state = modest_msg_edit_window_get_format_state (window);
2951 g_return_if_fail (format_state != NULL);
2953 format_state->justification = value;
2954 modest_msg_edit_window_set_format_state (window, format_state);
2955 g_free (format_state);
2959 modest_ui_actions_on_select_editor_color (GtkAction *action,
2960 ModestMsgEditWindow *window)
2962 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2963 g_return_if_fail (GTK_IS_ACTION (action));
2965 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2968 modest_msg_edit_window_select_color (window);
2972 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2973 ModestMsgEditWindow *window)
2975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2976 g_return_if_fail (GTK_IS_ACTION (action));
2978 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2984 modest_ui_actions_on_insert_image (GObject *object,
2985 ModestMsgEditWindow *window)
2987 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2990 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2993 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2996 modest_msg_edit_window_insert_image (window);
3000 modest_ui_actions_on_attach_file (GtkAction *action,
3001 ModestMsgEditWindow *window)
3003 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3004 g_return_if_fail (GTK_IS_ACTION (action));
3006 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3009 modest_msg_edit_window_offer_attach_file (window);
3013 modest_ui_actions_on_remove_attachments (GtkAction *action,
3014 ModestMsgEditWindow *window)
3016 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3018 modest_msg_edit_window_remove_attachments (window, NULL);
3022 do_create_folder_cb (ModestMailOperation *mail_op,
3023 TnyFolderStore *parent_folder,
3024 TnyFolder *new_folder,
3027 gchar *suggested_name = (gchar *) user_data;
3028 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3029 const GError *error;
3031 error = modest_mail_operation_get_error (mail_op);
3033 gboolean disk_full = FALSE;
3034 TnyAccount *account;
3035 /* Show an error. If there was some problem writing to
3036 disk, show it, otherwise show the generic folder
3037 create error. We do it here and not in an error
3038 handler because the call to do_create_folder will
3039 stop the main loop in a gtk_dialog_run and then,
3040 the message won't be shown until that dialog is
3042 account = modest_mail_operation_get_account (mail_op);
3045 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3046 (GtkWidget *) source_win,
3049 _("mail_in_ui_folder_create_error_memory"));
3050 g_object_unref (account);
3053 /* Show an error and try again if there is no
3054 full memory condition */
3055 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3056 _("mail_in_ui_folder_create_error"));
3057 do_create_folder ((ModestWindow *) source_win,
3058 parent_folder, (const gchar *) suggested_name);
3062 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3063 * FIXME: any other? */
3064 GtkWidget *folder_view;
3066 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3067 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3069 /* Select the newly created folder. It could happen
3070 that the widget is no longer there (i.e. the window
3071 has been destroyed, so we need to check this */
3073 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3075 g_object_unref (new_folder);
3077 /* Free. Note that the first time it'll be NULL so noop */
3078 g_free (suggested_name);
3079 g_object_unref (source_win);
3084 TnyFolderStore *parent;
3085 } CreateFolderConnect;
3088 do_create_folder_performer (gboolean canceled,
3090 ModestWindow *parent_window,
3091 TnyAccount *account,
3094 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3095 ModestMailOperation *mail_op;
3097 if (canceled || err) {
3098 /* In disk full conditions we could get this error here */
3099 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3100 (GtkWidget *) parent_window, err,
3101 NULL, _("mail_in_ui_folder_create_error_memory"));
3103 /* This happens if we have selected the outbox folder
3105 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3106 TNY_IS_MERGE_FOLDER (helper->parent)) {
3107 /* Show an error and retry */
3108 modest_platform_information_banner ((GtkWidget *) parent_window,
3110 _("mail_in_ui_folder_create_error"));
3112 do_create_folder (parent_window, helper->parent, helper->folder_name);
3118 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3119 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3121 modest_mail_operation_create_folder (mail_op,
3123 (const gchar *) helper->folder_name,
3124 do_create_folder_cb,
3125 g_strdup (helper->folder_name));
3126 g_object_unref (mail_op);
3130 g_object_unref (helper->parent);
3131 if (helper->folder_name)
3132 g_free (helper->folder_name);
3133 g_slice_free (CreateFolderConnect, helper);
3138 do_create_folder (ModestWindow *parent_window,
3139 TnyFolderStore *suggested_parent,
3140 const gchar *suggested_name)
3143 gchar *folder_name = NULL;
3144 TnyFolderStore *parent_folder = NULL;
3145 GtkWindow *toplevel;
3147 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
3148 result = modest_platform_run_new_folder_dialog (toplevel,
3150 (gchar *) suggested_name,
3154 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3155 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3156 helper->folder_name = g_strdup (folder_name);
3157 helper->parent = g_object_ref (parent_folder);
3159 modest_platform_connect_if_remote_and_perform (parent_window,
3162 do_create_folder_performer,
3167 g_free (folder_name);
3169 g_object_unref (parent_folder);
3173 modest_ui_actions_create_folder(GtkWindow *parent_window,
3174 GtkWidget *folder_view,
3175 TnyFolderStore *parent_folder)
3177 if (!parent_folder) {
3178 ModestTnyAccountStore *acc_store;
3180 acc_store = modest_runtime_get_account_store ();
3182 parent_folder = (TnyFolderStore *)
3183 modest_tny_account_store_get_local_folders_account (acc_store);
3186 if (parent_folder) {
3187 do_create_folder (MODEST_WINDOW (parent_window), parent_folder, NULL);
3188 g_object_unref (parent_folder);
3193 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3196 g_return_if_fail (MODEST_IS_WINDOW(window));
3198 if (MODEST_IS_FOLDER_WINDOW (window)) {
3199 GtkWidget *folder_view;
3200 GtkWindow *toplevel;
3202 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3203 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
3204 modest_ui_actions_create_folder (toplevel, folder_view, NULL);
3206 g_assert_not_reached ();
3211 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3214 const GError *error = NULL;
3215 gchar *message = NULL;
3217 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3219 /* Get error message */
3220 error = modest_mail_operation_get_error (mail_op);
3222 g_return_if_reached ();
3224 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3225 (GError *) error, account);
3227 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3228 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3229 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3230 message = _CS_FOLDER_ALREADY_EXISTS;
3231 } else if (error->domain == TNY_ERROR_DOMAIN &&
3232 error->code == TNY_SERVICE_ERROR_STATE) {
3233 /* This means that the folder is already in use (a
3234 message is opened for example */
3235 message = _("emev_ni_internal_error");
3237 message = _CS_UNABLE_TO_RENAME;
3240 /* We don't set a parent for the dialog because the dialog
3241 will be destroyed so the banner won't appear */
3242 modest_platform_information_banner (NULL, NULL, message);
3245 g_object_unref (account);
3251 TnyFolderStore *folder;
3256 on_rename_folder_cb (ModestMailOperation *mail_op,
3257 TnyFolder *new_folder,
3260 ModestFolderView *folder_view;
3262 /* If the window was closed when renaming a folder, or if
3263 * it's not a main window this will happen */
3264 if (!MODEST_IS_FOLDER_VIEW (user_data))
3267 folder_view = MODEST_FOLDER_VIEW (user_data);
3268 /* Note that if the rename fails new_folder will be NULL */
3270 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3272 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3276 on_rename_folder_performer (gboolean canceled,
3278 ModestWindow *parent_window,
3279 TnyAccount *account,
3282 ModestMailOperation *mail_op = NULL;
3283 GtkTreeSelection *sel = NULL;
3284 GtkWidget *folder_view = NULL;
3285 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3287 if (canceled || err) {
3288 /* In disk full conditions we could get this error here */
3289 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3290 (GtkWidget *) parent_window, err,
3295 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3296 modest_ui_actions_rename_folder_error_handler,
3297 parent_window, NULL);
3299 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3301 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3302 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3303 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3306 /* Clear the folders view */
3307 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3308 gtk_tree_selection_unselect_all (sel);
3310 /* Actually rename the folder */
3311 modest_mail_operation_rename_folder (mail_op,
3312 TNY_FOLDER (data->folder),
3313 (const gchar *) (data->new_name),
3314 on_rename_folder_cb,
3316 g_object_unref (mail_op);
3319 g_object_unref (data->folder);
3320 g_free (data->new_name);
3325 modest_ui_actions_on_rename_folder (GtkAction *action,
3326 ModestWindow *window)
3328 modest_ui_actions_on_edit_mode_rename_folder (window);
3332 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3334 TnyFolderStore *folder;
3335 GtkWidget *folder_view;
3336 gboolean do_rename = TRUE;
3338 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3340 if (MODEST_IS_FOLDER_WINDOW (window)) {
3341 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3346 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3351 if (TNY_IS_FOLDER (folder)) {
3352 gchar *folder_name = NULL;
3354 const gchar *current_name;
3355 TnyFolderStore *parent;
3357 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3358 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3359 response = modest_platform_run_rename_folder_dialog (MODEST_WINDOW (window),
3360 parent, current_name,
3362 g_object_unref (parent);
3364 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3367 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3368 rename_folder_data->folder = g_object_ref (folder);
3369 rename_folder_data->new_name = folder_name;
3370 modest_platform_connect_if_remote_and_perform (window, TRUE,
3371 folder, on_rename_folder_performer, rename_folder_data);
3374 g_object_unref (folder);
3379 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3382 GObject *win = modest_mail_operation_get_source (mail_op);
3383 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
3385 modest_platform_run_information_dialog (toplevel,
3386 _("mail_in_ui_folder_delete_error"),
3388 g_object_unref (win);
3392 TnyFolderStore *folder;
3393 gboolean move_to_trash;
3397 on_delete_folder_cb (gboolean canceled,
3399 ModestWindow *parent_window,
3400 TnyAccount *account,
3403 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3404 GtkWidget *folder_view;
3405 ModestMailOperation *mail_op;
3406 GtkTreeSelection *sel;
3407 ModestWindow *modest_window;
3409 #ifdef MODEST_TOOLKIT_HILDON2
3410 modest_window = (ModestWindow*) parent_window;
3412 if (MODEST_IS_SHELL (parent_window)) {
3413 modest_window = modest_shell_peek_window (MODEST_SHELL (parent_window));
3415 modest_window = NULL;
3419 if (!MODEST_IS_WINDOW(modest_window) || canceled || (err!=NULL)) {
3420 /* Note that the connection process can fail due to
3421 memory low conditions as it can not successfully
3422 store the summary */
3423 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3424 (GtkWidget*) parent_window, err,
3426 g_debug ("Error connecting when trying to delete a folder");
3427 g_object_unref (G_OBJECT (info->folder));
3432 if (MODEST_IS_FOLDER_WINDOW (modest_window)) {
3433 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (modest_window)));
3435 g_object_unref (G_OBJECT (info->folder));
3440 /* Unselect the folder before deleting it to free the headers */
3441 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3442 gtk_tree_selection_unselect_all (sel);
3444 /* Create the mail operation */
3446 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3447 modest_ui_actions_delete_folder_error_handler,
3450 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3452 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3454 g_object_unref (mail_op);
3455 g_object_unref (info->folder);
3460 delete_folder (ModestWindow *window, gboolean move_to_trash)
3462 TnyFolderStore *folder;
3463 GtkWidget *folder_view;
3467 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3469 if (MODEST_IS_FOLDER_WINDOW (window)) {
3470 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3477 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3482 /* Show an error if it's an account */
3483 if (!TNY_IS_FOLDER (folder)) {
3484 modest_platform_run_information_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3485 _("mail_in_ui_folder_delete_error"),
3487 g_object_unref (G_OBJECT (folder));
3492 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3493 tny_folder_get_name (TNY_FOLDER (folder)));
3494 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3495 (const gchar *) message);
3498 if (response == GTK_RESPONSE_OK) {
3499 TnyAccount *account = NULL;
3500 DeleteFolderInfo *info = NULL;
3501 info = g_new0(DeleteFolderInfo, 1);
3502 info->folder = g_object_ref (folder);
3503 info->move_to_trash = move_to_trash;
3505 account = tny_folder_get_account (TNY_FOLDER (folder));
3506 modest_platform_connect_if_remote_and_perform (window,
3508 TNY_FOLDER_STORE (account),
3509 on_delete_folder_cb, info);
3510 g_object_unref (account);
3511 g_object_unref (folder);
3519 modest_ui_actions_on_delete_folder (GtkAction *action,
3520 ModestWindow *window)
3522 modest_ui_actions_on_edit_mode_delete_folder (window);
3526 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3528 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3530 return delete_folder (window, FALSE);
3534 typedef struct _PasswordDialogFields {
3535 GtkWidget *username;
3536 GtkWidget *password;
3538 } PasswordDialogFields;
3541 password_dialog_check_field (GtkEditable *editable,
3542 PasswordDialogFields *fields)
3545 gboolean any_value_empty = FALSE;
3547 value = modest_entry_get_text (fields->username);
3548 if ((value == NULL) || value[0] == '\0') {
3549 any_value_empty = TRUE;
3551 value = modest_entry_get_text (fields->password);
3552 if ((value == NULL) || value[0] == '\0') {
3553 any_value_empty = TRUE;
3555 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3559 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3560 const gchar* server_account_name,
3565 ModestMainWindow *main_window)
3567 g_return_if_fail(server_account_name);
3568 gboolean completed = FALSE;
3569 PasswordDialogFields *fields = NULL;
3571 /* Initalize output parameters: */
3578 #ifndef MODEST_TOOLKIT_GTK
3579 /* Maemo uses a different (awkward) button order,
3580 * It should probably just use gtk_alternative_dialog_button_order ().
3582 #ifdef MODEST_TOOLKIT_HILDON2
3584 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3588 GTK_RESPONSE_ACCEPT,
3590 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3591 HILDON_MARGIN_DOUBLE);
3594 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3597 _("mcen_bd_dialog_ok"),
3598 GTK_RESPONSE_ACCEPT,
3599 _("mcen_bd_dialog_cancel"),
3600 GTK_RESPONSE_REJECT,
3602 #endif /* MODEST_TOOLKIT_HILDON2 */
3605 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3609 GTK_RESPONSE_REJECT,
3611 GTK_RESPONSE_ACCEPT,
3613 #endif /* MODEST_TOOLKIT_GTK */
3615 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3617 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3618 modest_runtime_get_account_mgr(), server_account_name);
3619 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3620 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3623 gtk_widget_destroy (dialog);
3627 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3628 GtkWidget *label = gtk_label_new (txt);
3629 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3631 g_free (server_name);
3632 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3637 gchar *initial_username = modest_account_mgr_get_server_account_username (
3638 modest_runtime_get_account_mgr(), server_account_name);
3640 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3641 if (initial_username)
3642 modest_entry_set_text (entry_username, initial_username);
3644 /* Dim this if a connection has ever succeeded with this username,
3645 * as per the UI spec: */
3646 /* const gboolean username_known = */
3647 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3648 /* modest_runtime_get_account_mgr(), server_account_name); */
3649 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3651 /* We drop the username sensitive code and disallow changing it here
3652 * as tinymail does not support really changing the username in the callback
3654 gtk_widget_set_sensitive (entry_username, FALSE);
3656 /* Auto-capitalization is the default, so let's turn it off: */
3657 #ifdef MAEMO_CHANGES
3658 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3661 /* Create a size group to be used by all captions.
3662 * Note that HildonCaption does not create a default size group if we do not specify one.
3663 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3664 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3666 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3667 _("mail_fi_username"), FALSE,
3669 gtk_widget_show (entry_username);
3670 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3671 FALSE, FALSE, MODEST_MARGIN_HALF);
3672 gtk_widget_show (caption);
3675 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3676 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3677 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3679 /* Auto-capitalization is the default, so let's turn it off: */
3680 #ifdef MAEMO_CHANGES
3681 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3682 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3685 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3686 _("mail_fi_password"), FALSE,
3688 gtk_widget_show (entry_password);
3689 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3690 FALSE, FALSE, MODEST_MARGIN_HALF);
3691 gtk_widget_show (caption);
3692 g_object_unref (sizegroup);
3694 if (initial_username != NULL)
3695 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3697 /* This is not in the Maemo UI spec:
3698 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3699 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3703 fields = g_slice_new0 (PasswordDialogFields);
3704 fields->username = entry_username;
3705 fields->password = entry_password;
3706 fields->dialog = dialog;
3708 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3709 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3710 password_dialog_check_field (NULL, fields);
3712 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3714 while (!completed) {
3716 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3718 *username = g_strdup (modest_entry_get_text (entry_username));
3720 /* Note that an empty field becomes the "" string */
3721 if (*username && strlen (*username) > 0) {
3722 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3723 server_account_name,
3727 const gboolean username_was_changed =
3728 (strcmp (*username, initial_username) != 0);
3729 if (username_was_changed) {
3730 g_warning ("%s: tinymail does not yet support changing the "
3731 "username in the get_password() callback.\n", __FUNCTION__);
3737 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3738 _("mcen_ib_username_pw_incorrect"));
3744 *password = g_strdup (modest_entry_get_text (entry_password));
3746 /* We do not save the password in the configuration,
3747 * because this function is only called for passwords that should
3748 * not be remembered:
3749 modest_server_account_set_password (
3750 modest_runtime_get_account_mgr(), server_account_name,
3767 /* This is not in the Maemo UI spec:
3768 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3774 g_free (initial_username);
3775 gtk_widget_destroy (dialog);
3776 g_slice_free (PasswordDialogFields, fields);
3778 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3782 modest_ui_actions_on_cut (GtkAction *action,
3783 ModestWindow *window)
3785 GtkWidget *focused_widget;
3786 GtkClipboard *clipboard;
3788 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3789 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3790 if (GTK_IS_EDITABLE (focused_widget)) {
3791 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3792 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3793 gtk_clipboard_store (clipboard);
3794 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3795 GtkTextBuffer *buffer;
3797 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3798 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3799 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3800 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3801 gtk_clipboard_store (clipboard);
3803 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3804 TnyList *header_list = modest_header_view_get_selected_headers (
3805 MODEST_HEADER_VIEW (focused_widget));
3806 gboolean continue_download = FALSE;
3807 gint num_of_unc_msgs;
3809 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3811 if (num_of_unc_msgs) {
3812 TnyAccount *account = get_account_from_header_list (header_list);
3814 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3815 g_object_unref (account);
3819 if (num_of_unc_msgs == 0 || continue_download) {
3820 /* modest_platform_information_banner (
3821 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3822 modest_header_view_cut_selection (
3823 MODEST_HEADER_VIEW (focused_widget));
3826 g_object_unref (header_list);
3827 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3828 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3833 modest_ui_actions_on_copy (GtkAction *action,
3834 ModestWindow *window)
3836 GtkClipboard *clipboard;
3837 GtkWidget *focused_widget;
3838 gboolean copied = TRUE;
3840 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3841 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3843 if (GTK_IS_LABEL (focused_widget)) {
3845 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3846 gtk_clipboard_set_text (clipboard, selection, -1);
3848 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3849 gtk_clipboard_store (clipboard);
3850 } else if (GTK_IS_EDITABLE (focused_widget)) {
3851 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3852 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3853 gtk_clipboard_store (clipboard);
3854 } else if (GTK_IS_HTML (focused_widget)) {
3857 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3858 if ((sel == NULL) || (sel[0] == '\0')) {
3861 gtk_html_copy (GTK_HTML (focused_widget));
3862 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3863 gtk_clipboard_store (clipboard);
3865 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3866 GtkTextBuffer *buffer;
3867 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3868 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3869 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3870 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3871 gtk_clipboard_store (clipboard);
3873 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3874 TnyList *header_list = modest_header_view_get_selected_headers (
3875 MODEST_HEADER_VIEW (focused_widget));
3876 gboolean continue_download = FALSE;
3877 gint num_of_unc_msgs;
3879 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3881 if (num_of_unc_msgs) {
3882 TnyAccount *account = get_account_from_header_list (header_list);
3884 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3885 g_object_unref (account);
3889 if (num_of_unc_msgs == 0 || continue_download) {
3890 modest_platform_information_banner (
3891 NULL, NULL, _CS_GETTING_ITEMS);
3892 modest_header_view_copy_selection (
3893 MODEST_HEADER_VIEW (focused_widget));
3897 g_object_unref (header_list);
3899 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3900 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3903 /* Show information banner if there was a copy to clipboard */
3905 modest_platform_information_banner (
3906 NULL, NULL, _CS_COPIED);
3910 modest_ui_actions_on_undo (GtkAction *action,
3911 ModestWindow *window)
3913 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3914 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3916 g_return_if_reached ();
3921 modest_ui_actions_on_redo (GtkAction *action,
3922 ModestWindow *window)
3924 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3925 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3928 g_return_if_reached ();
3934 destroy_information_note (ModestMailOperation *mail_op,
3937 /* destroy information note */
3938 gtk_widget_destroy (GTK_WIDGET(user_data));
3942 destroy_folder_information_note (ModestMailOperation *mail_op,
3943 TnyFolder *new_folder,
3946 /* destroy information note */
3947 gtk_widget_destroy (GTK_WIDGET(user_data));
3952 paste_as_attachment_free (gpointer data)
3954 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3956 if (helper->banner) {
3957 gtk_widget_destroy (helper->banner);
3958 g_object_unref (helper->banner);
3964 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3969 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3970 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3975 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3980 modest_ui_actions_on_paste (GtkAction *action,
3981 ModestWindow *window)
3983 GtkWidget *focused_widget = NULL;
3984 GtkWidget *inf_note = NULL;
3985 ModestMailOperation *mail_op = NULL;
3987 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3988 if (GTK_IS_EDITABLE (focused_widget)) {
3989 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3990 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3991 ModestEmailClipboard *e_clipboard = NULL;
3992 e_clipboard = modest_runtime_get_email_clipboard ();
3993 if (modest_email_clipboard_cleared (e_clipboard)) {
3994 GtkTextBuffer *buffer;
3995 GtkClipboard *clipboard;
3997 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3998 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3999 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4000 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4001 ModestMailOperation *mail_op;
4002 TnyFolder *src_folder = NULL;
4003 TnyList *data = NULL;
4005 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4006 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4007 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4009 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4010 mail_op = modest_mail_operation_new (G_OBJECT (window));
4011 if (helper->banner != NULL) {
4012 g_object_ref (G_OBJECT (helper->banner));
4013 gtk_widget_show (GTK_WIDGET (helper->banner));
4017 modest_mail_operation_get_msgs_full (mail_op,
4019 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4021 paste_as_attachment_free);
4025 g_object_unref (data);
4027 g_object_unref (src_folder);
4030 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4031 ModestEmailClipboard *clipboard = NULL;
4032 TnyFolder *src_folder = NULL;
4033 TnyFolderStore *folder_store = NULL;
4034 TnyList *data = NULL;
4035 gboolean delete = FALSE;
4037 /* Check clipboard source */
4038 clipboard = modest_runtime_get_email_clipboard ();
4039 if (modest_email_clipboard_cleared (clipboard))
4042 /* Get elements to paste */
4043 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4045 /* Create a new mail operation */
4046 mail_op = modest_mail_operation_new (G_OBJECT(window));
4048 /* Get destination folder */
4049 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4051 /* transfer messages */
4055 /* Ask for user confirmation */
4057 modest_ui_actions_msgs_move_to_confirmation (window,
4058 TNY_FOLDER (folder_store),
4062 if (response == GTK_RESPONSE_OK) {
4063 /* Launch notification */
4064 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4066 if (inf_note != NULL) {
4067 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4068 gtk_widget_show (GTK_WIDGET(inf_note));
4071 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4072 modest_mail_operation_xfer_msgs (mail_op,
4074 TNY_FOLDER (folder_store),
4076 destroy_information_note,
4079 g_object_unref (mail_op);
4082 } else if (src_folder != NULL) {
4083 /* Launch notification */
4084 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4086 if (inf_note != NULL) {
4087 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4088 gtk_widget_show (GTK_WIDGET(inf_note));
4091 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4092 modest_mail_operation_xfer_folder (mail_op,
4096 destroy_folder_information_note,
4102 g_object_unref (data);
4103 if (src_folder != NULL)
4104 g_object_unref (src_folder);
4105 if (folder_store != NULL)
4106 g_object_unref (folder_store);
4112 modest_ui_actions_on_select_all (GtkAction *action,
4113 ModestWindow *window)
4115 GtkWidget *focused_widget;
4117 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4118 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4119 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4120 } else if (GTK_IS_LABEL (focused_widget)) {
4121 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4122 } else if (GTK_IS_EDITABLE (focused_widget)) {
4123 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4124 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4125 GtkTextBuffer *buffer;
4126 GtkTextIter start, end;
4128 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4129 gtk_text_buffer_get_start_iter (buffer, &start);
4130 gtk_text_buffer_get_end_iter (buffer, &end);
4131 gtk_text_buffer_select_range (buffer, &start, &end);
4132 } else if (GTK_IS_HTML (focused_widget)) {
4133 gtk_html_select_all (GTK_HTML (focused_widget));
4139 modest_ui_actions_on_mark_as_read (GtkAction *action,
4140 ModestWindow *window)
4142 g_return_if_fail (MODEST_IS_WINDOW(window));
4144 /* Mark each header as read */
4145 do_headers_action (window, headers_action_mark_as_read, NULL);
4149 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4150 ModestWindow *window)
4152 g_return_if_fail (MODEST_IS_WINDOW(window));
4154 /* Mark each header as read */
4155 do_headers_action (window, headers_action_mark_as_unread, NULL);
4159 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4160 GtkRadioAction *selected,
4161 ModestWindow *window)
4165 value = gtk_radio_action_get_current_value (selected);
4166 if (MODEST_IS_WINDOW (window)) {
4167 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4172 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4173 GtkRadioAction *selected,
4174 ModestWindow *window)
4176 TnyHeaderFlags flags;
4177 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4179 flags = gtk_radio_action_get_current_value (selected);
4180 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4184 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4185 GtkRadioAction *selected,
4186 ModestWindow *window)
4190 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4192 file_format = gtk_radio_action_get_current_value (selected);
4193 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4198 modest_ui_actions_on_zoom_plus (GtkAction *action,
4199 ModestWindow *window)
4201 g_return_if_fail (MODEST_IS_WINDOW (window));
4203 modest_window_zoom_plus (MODEST_WINDOW (window));
4207 modest_ui_actions_on_zoom_minus (GtkAction *action,
4208 ModestWindow *window)
4210 g_return_if_fail (MODEST_IS_WINDOW (window));
4212 modest_window_zoom_minus (MODEST_WINDOW (window));
4216 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4217 ModestWindow *window)
4219 ModestWindowMgr *mgr;
4220 gboolean fullscreen, active;
4221 g_return_if_fail (MODEST_IS_WINDOW (window));
4223 mgr = modest_runtime_get_window_mgr ();
4225 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4226 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4228 if (active != fullscreen) {
4229 modest_window_mgr_set_fullscreen_mode (mgr, active);
4230 #ifndef MODEST_TOOLKIT_HILDON2
4231 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4232 gtk_window_present (toplevel);
4238 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4239 ModestWindow *window)
4241 ModestWindowMgr *mgr;
4242 gboolean fullscreen;
4244 g_return_if_fail (MODEST_IS_WINDOW (window));
4246 mgr = modest_runtime_get_window_mgr ();
4247 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4248 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4253 * Used by modest_ui_actions_on_details to call do_headers_action
4256 headers_action_show_details (TnyHeader *header,
4257 ModestWindow *window,
4261 gboolean async_retrieval;
4262 GtkWindow *toplevel;
4265 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4266 async_retrieval = TRUE;
4267 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4268 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4270 async_retrieval = FALSE;
4272 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4273 modest_platform_run_header_details_dialog (toplevel, header, async_retrieval, msg);
4275 g_object_unref (msg);
4279 * Show the header details in a ModestDetailsDialog widget
4282 modest_ui_actions_on_details (GtkAction *action,
4285 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4289 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4293 header = tny_msg_get_header (msg);
4295 headers_action_show_details (header, win, NULL);
4296 g_object_unref (header);
4298 g_object_unref (msg);
4299 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4301 GtkWidget *header_view;
4303 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4304 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4306 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4308 modest_platform_run_folder_details_dialog (toplevel, folder);
4309 g_object_unref (folder);
4315 modest_ui_actions_on_limit_error (GtkAction *action,
4318 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4320 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS_MAXIMUM_CHARACTERS_REACHED);
4325 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4326 ModestMsgEditWindow *window)
4328 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4330 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4334 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4335 ModestMsgEditWindow *window)
4337 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4339 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4344 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4345 ModestWindow *window)
4347 gboolean active, fullscreen = FALSE;
4348 ModestWindowMgr *mgr;
4350 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4352 /* Check if we want to toggle the toolbar view in fullscreen
4354 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4355 "ViewShowToolbarFullScreen")) {
4359 /* Toggle toolbar */
4360 mgr = modest_runtime_get_window_mgr ();
4361 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4365 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4366 ModestMsgEditWindow *window)
4368 modest_msg_edit_window_select_font (window);
4373 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4374 const gchar *display_name,
4377 /* don't update the display name if it was already set;
4378 * updating the display name apparently is expensive */
4379 const gchar* old_name = gtk_window_get_title (window);
4381 if (display_name == NULL)
4384 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4385 return; /* don't do anything */
4387 /* This is usually used to change the title of the main window, which
4388 * is the one that holds the folder view. Note that this change can
4389 * happen even when the widget doesn't have the focus. */
4390 gtk_window_set_title (window, display_name);
4395 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4397 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4398 modest_msg_edit_window_select_contacts (window);
4402 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4404 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4405 modest_msg_edit_window_check_names (window, FALSE);
4410 on_move_to_dialog_response (GtkDialog *dialog,
4414 GtkWidget *parent_win;
4415 MoveToInfo *helper = NULL;
4416 ModestFolderView *folder_view;
4417 gboolean unset_edit_mode = FALSE;
4419 helper = (MoveToInfo *) user_data;
4421 parent_win = (GtkWidget *) helper->win;
4422 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4423 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4425 TnyFolderStore *dst_folder;
4426 TnyFolderStore *selected;
4428 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4429 selected = modest_folder_view_get_selected (folder_view);
4430 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4431 g_object_unref (selected);
4433 case GTK_RESPONSE_NONE:
4434 case GTK_RESPONSE_CANCEL:
4435 case GTK_RESPONSE_DELETE_EVENT:
4437 case GTK_RESPONSE_OK:
4438 dst_folder = modest_folder_view_get_selected (folder_view);
4440 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4441 /* Clean list to move used for filtering */
4442 modest_folder_view_set_list_to_move (folder_view, NULL);
4444 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4447 MODEST_WINDOW (parent_win));
4449 /* if the user selected a root folder
4450 (account) then do not perform any action */
4451 if (TNY_IS_ACCOUNT (dst_folder)) {
4452 g_signal_stop_emission_by_name (dialog, "response");
4456 /* Clean list to move used for filtering */
4457 modest_folder_view_set_list_to_move (folder_view, NULL);
4459 /* Moving from headers window in edit mode */
4460 modest_ui_actions_on_window_move_to (NULL, helper->list,
4462 MODEST_WINDOW (parent_win));
4466 g_object_unref (dst_folder);
4468 unset_edit_mode = TRUE;
4471 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4474 /* Free the helper and exit */
4476 g_object_unref (helper->list);
4477 if (unset_edit_mode) {
4478 #ifdef MODEST_TOOLKIT_HILDON2
4479 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4482 g_slice_free (MoveToInfo, helper);
4483 gtk_widget_destroy (GTK_WIDGET (dialog));
4487 create_move_to_dialog (GtkWindow *win,
4488 GtkWidget *folder_view,
4489 TnyList *list_to_move)
4491 GtkWidget *dialog, *tree_view = NULL;
4493 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4496 /* It could happen that we're trying to move a message from a
4497 window (msg window for example) after the main window was
4498 closed, so we can not just get the model of the folder
4500 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4501 const gchar *visible_id = NULL;
4503 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4504 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4505 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4506 MODEST_FOLDER_VIEW(tree_view));
4509 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4511 /* Show the same account than the one that is shown in the main window */
4512 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4515 const gchar *active_account_name = NULL;
4516 ModestAccountMgr *mgr = NULL;
4517 ModestAccountSettings *settings = NULL;
4518 ModestServerAccountSettings *store_settings = NULL;
4520 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4521 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4522 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4523 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4525 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4526 mgr = modest_runtime_get_account_mgr ();
4527 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4530 const gchar *store_account_name;
4531 store_settings = modest_account_settings_get_store_settings (settings);
4532 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4534 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4535 store_account_name);
4536 g_object_unref (store_settings);
4537 g_object_unref (settings);
4541 /* we keep a pointer to the embedded folder view, so we can
4542 * retrieve it with get_folder_view_from_move_to_dialog (see
4543 * above) later (needed for focus handling)
4545 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4547 /* Hide special folders */
4549 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4551 gtk_widget_show (GTK_WIDGET (tree_view));
4557 * Shows a confirmation dialog to the user when we're moving messages
4558 * from a remote server to the local storage. Returns the dialog
4559 * response. If it's other kind of movement then it always returns
4562 * This one is used by the next functions:
4563 * modest_ui_actions_on_paste - commented out
4564 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4567 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4568 TnyFolder *dest_folder,
4572 gint response = GTK_RESPONSE_OK;
4573 TnyAccount *account = NULL;
4574 TnyFolder *src_folder = NULL;
4575 TnyIterator *iter = NULL;
4576 TnyHeader *header = NULL;
4578 /* return with OK if the destination is a remote folder */
4579 if (modest_tny_folder_is_remote_folder (dest_folder))
4580 return GTK_RESPONSE_OK;
4582 /* Get source folder */
4583 iter = tny_list_create_iterator (headers);
4584 header = TNY_HEADER (tny_iterator_get_current (iter));
4586 src_folder = tny_header_get_folder (header);
4587 g_object_unref (header);
4589 g_object_unref (iter);
4591 /* if no src_folder, message may be an attahcment */
4592 if (src_folder == NULL)
4593 return GTK_RESPONSE_CANCEL;
4595 /* If the source is a local or MMC folder */
4596 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4597 g_object_unref (src_folder);
4598 return GTK_RESPONSE_OK;
4601 /* Get the account */
4602 account = tny_folder_get_account (src_folder);
4604 /* now if offline we ask the user */
4605 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4606 response = GTK_RESPONSE_OK;
4608 response = GTK_RESPONSE_CANCEL;
4611 g_object_unref (src_folder);
4612 g_object_unref (account);
4618 move_to_helper_destroyer (gpointer user_data)
4620 MoveToHelper *helper = (MoveToHelper *) user_data;
4622 /* Close the "Pasting" information banner */
4623 if (helper->banner) {
4624 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4625 g_object_unref (helper->banner);
4627 if (gtk_tree_row_reference_valid (helper->reference)) {
4628 gtk_tree_row_reference_free (helper->reference);
4629 helper->reference = NULL;
4635 move_to_cb (ModestMailOperation *mail_op,
4638 MoveToHelper *helper = (MoveToHelper *) user_data;
4639 GObject *object = modest_mail_operation_get_source (mail_op);
4641 /* Note that the operation could have failed, in that case do
4643 if (modest_mail_operation_get_status (mail_op) !=
4644 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4647 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4648 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4650 if (!modest_msg_view_window_select_next_message (self) &&
4651 !modest_msg_view_window_select_previous_message (self)) {
4652 /* No more messages to view, so close this window */
4653 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4656 g_object_unref (object);
4659 /* Destroy the helper */
4660 move_to_helper_destroyer (helper);
4664 folder_move_to_cb (ModestMailOperation *mail_op,
4665 TnyFolder *new_folder,
4670 object = modest_mail_operation_get_source (mail_op);
4672 move_to_cb (mail_op, user_data);
4677 msgs_move_to_cb (ModestMailOperation *mail_op,
4680 move_to_cb (mail_op, user_data);
4684 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4687 GObject *win = NULL;
4688 const GError *error;
4689 TnyAccount *account = NULL;
4691 win = modest_mail_operation_get_source (mail_op);
4692 error = modest_mail_operation_get_error (mail_op);
4694 if (TNY_IS_FOLDER (user_data))
4695 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4696 else if (TNY_IS_ACCOUNT (user_data))
4697 account = g_object_ref (user_data);
4699 /* If it's not a disk full error then show a generic error */
4700 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4701 (GtkWidget *) win, (GError *) error,
4703 modest_platform_run_information_dialog ((GtkWindow *) win,
4704 _("mail_in_ui_folder_move_target_error"),
4707 g_object_unref (account);
4709 g_object_unref (win);
4714 * Checks if we need a connection to do the transfer and if the user
4715 * wants to connect to complete it
4718 modest_ui_actions_xfer_messages_check (ModestWindow *parent_window,
4719 TnyFolderStore *src_folder,
4721 TnyFolder *dst_folder,
4722 gboolean delete_originals,
4723 gboolean *need_connection,
4726 TnyAccount *src_account;
4727 gint uncached_msgs = 0;
4729 /* We don't need any further check if
4731 * 1- the source folder is local OR
4732 * 2- the device is already online
4734 if (!modest_tny_folder_store_is_remote (src_folder) ||
4735 tny_device_is_online (modest_runtime_get_device())) {
4736 *need_connection = FALSE;
4741 /* We must ask for a connection when
4743 * - the message(s) is not already cached OR
4744 * - the message(s) is cached but the leave_on_server setting
4745 * is FALSE (because we need to sync the source folder to
4746 * delete the message from the server (for IMAP we could do it
4747 * offline, it'll take place the next time we get a
4750 uncached_msgs = header_list_count_uncached_msgs (headers);
4751 src_account = get_account_from_folder_store (src_folder);
4752 if (uncached_msgs > 0) {
4755 GtkWindow *toplevel;
4757 *need_connection = TRUE;
4758 num_headers = tny_list_get_length (headers);
4759 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4760 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
4762 if (modest_platform_run_confirmation_dialog (toplevel, msg) ==
4763 GTK_RESPONSE_CANCEL) {
4769 /* The transfer is possible and the user wants to */
4772 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4773 const gchar *account_name;
4774 gboolean leave_on_server;
4776 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4777 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4780 if (leave_on_server == TRUE) {
4781 *need_connection = FALSE;
4783 *need_connection = TRUE;
4786 *need_connection = FALSE;
4791 g_object_unref (src_account);
4795 xfer_messages_error_handler (ModestMailOperation *mail_op,
4799 const GError *error;
4800 TnyAccount *account;
4802 win = modest_mail_operation_get_source (mail_op);
4803 error = modest_mail_operation_get_error (mail_op);
4805 /* We cannot get the account from the mail op as that is the
4806 source account and for checking memory full conditions we
4807 need the destination one */
4808 account = TNY_ACCOUNT (user_data);
4811 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4812 (GtkWidget *) win, (GError*) error,
4813 account, _KR("cerm_memory_card_full"))) {
4814 modest_platform_run_information_dialog ((GtkWindow *) win,
4815 _("mail_in_ui_folder_move_target_error"),
4819 g_object_unref (win);
4823 TnyFolderStore *dst_folder;
4828 * Utility function that transfer messages from both the main window
4829 * and the msg view window when using the "Move to" dialog
4832 xfer_messages_performer (gboolean canceled,
4834 ModestWindow *parent_window,
4835 TnyAccount *account,
4838 TnyAccount *dst_account = NULL;
4839 gboolean dst_forbids_message_add = FALSE;
4840 XferMsgsHelper *helper;
4841 MoveToHelper *movehelper;
4842 ModestMailOperation *mail_op;
4844 helper = (XferMsgsHelper *) user_data;
4846 if (canceled || err) {
4847 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4848 (GtkWidget *) parent_window, err,
4850 /* Show the proper error message */
4851 modest_ui_actions_on_account_connection_error (parent_window, account);
4856 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4858 /* tinymail will return NULL for local folders it seems */
4859 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4860 modest_tny_account_get_protocol_type (dst_account),
4861 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4863 if (dst_forbids_message_add) {
4864 modest_platform_information_banner (GTK_WIDGET (parent_window),
4866 ngettext("mail_in_ui_folder_move_target_error",
4867 "mail_in_ui_folder_move_targets_error",
4868 tny_list_get_length (helper->headers)));
4872 movehelper = g_new0 (MoveToHelper, 1);
4875 /* Perform the mail operation */
4876 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4877 xfer_messages_error_handler,
4878 g_object_ref (dst_account),
4880 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4883 modest_mail_operation_xfer_msgs (mail_op,
4885 TNY_FOLDER (helper->dst_folder),
4890 g_object_unref (G_OBJECT (mail_op));
4893 g_object_unref (dst_account);
4894 g_object_unref (helper->dst_folder);
4895 g_object_unref (helper->headers);
4896 g_slice_free (XferMsgsHelper, helper);
4900 TnyFolder *src_folder;
4901 TnyFolderStore *dst_folder;
4902 gboolean delete_original;
4903 GtkWidget *folder_view;
4907 on_move_folder_cb (gboolean canceled,
4909 ModestWindow *parent_window,
4910 TnyAccount *account,
4913 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4914 GtkTreeSelection *sel;
4915 ModestMailOperation *mail_op = NULL;
4917 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4918 /* Note that the connection process can fail due to
4919 memory low conditions as it can not successfully
4920 store the summary */
4921 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4922 (GtkWidget*) parent_window, err,
4924 g_debug ("Error connecting when trying to move a folder");
4926 g_object_unref (G_OBJECT (info->src_folder));
4927 g_object_unref (G_OBJECT (info->dst_folder));
4932 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4933 #ifndef MODEST_TOOLKIT_HILDON2
4934 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4936 if (helper->banner != NULL) {
4937 g_object_ref (helper->banner);
4938 gtk_widget_show (GTK_WIDGET(helper->banner));
4941 /* Clean folder on header view before moving it */
4942 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4943 gtk_tree_selection_unselect_all (sel);
4945 /* Let gtk events run. We need that the folder
4946 view frees its reference to the source
4947 folder *before* issuing the mail operation
4948 so we need the signal handler of selection
4949 changed to happen before the mail
4951 while (gtk_events_pending ())
4952 gtk_main_iteration (); */
4955 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4956 modest_ui_actions_move_folder_error_handler,
4957 g_object_ref (info->dst_folder), g_object_unref);
4958 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4961 modest_mail_operation_xfer_folder (mail_op,
4962 TNY_FOLDER (info->src_folder),
4964 info->delete_original,
4967 g_object_unref (G_OBJECT (info->src_folder));
4969 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4972 /* Unref mail operation */
4973 g_object_unref (G_OBJECT (mail_op));
4974 g_object_unref (G_OBJECT (info->dst_folder));
4979 get_account_from_folder_store (TnyFolderStore *folder_store)
4981 if (TNY_IS_ACCOUNT (folder_store))
4982 return g_object_ref (folder_store);
4984 return tny_folder_get_account (TNY_FOLDER (folder_store));
4988 * UI handler for the "Move to" action when invoked from the
4989 * ModestFolderWindow
4992 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4993 TnyFolderStore *dst_folder,
4997 TnyFolderStore *src_folder = NULL;
4998 TnyIterator *iterator;
5000 if (tny_list_get_length (selection) != 1)
5003 iterator = tny_list_create_iterator (selection);
5004 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5005 g_object_unref (iterator);
5008 gboolean do_xfer = TRUE;
5010 /* Allow only to transfer folders to the local root folder */
5011 if (TNY_IS_ACCOUNT (dst_folder) &&
5012 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5013 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5014 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5018 modest_platform_run_information_dialog (toplevel,
5019 _("mail_in_ui_folder_move_target_error"),
5021 } else if (!TNY_IS_FOLDER (src_folder)) {
5022 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5027 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5028 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5030 info->src_folder = g_object_ref (src_folder);
5031 info->dst_folder = g_object_ref (dst_folder);
5032 info->delete_original = TRUE;
5033 info->folder_view = folder_view;
5035 connect_info->callback = on_move_folder_cb;
5036 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5037 connect_info->data = info;
5039 modest_platform_double_connect_and_perform(win, TRUE,
5040 TNY_FOLDER_STORE (src_folder),
5045 g_object_unref (src_folder);
5050 modest_ui_actions_transfer_messages_helper (ModestWindow *win,
5051 TnyFolder *src_folder,
5053 TnyFolder *dst_folder)
5055 gboolean need_connection = TRUE;
5056 gboolean do_xfer = TRUE;
5057 XferMsgsHelper *helper;
5059 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5060 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5061 g_return_if_fail (TNY_IS_LIST (headers));
5063 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5064 headers, TNY_FOLDER (dst_folder),
5065 TRUE, &need_connection,
5068 /* If we don't want to transfer just return */
5072 /* Create the helper */
5073 helper = g_slice_new (XferMsgsHelper);
5074 helper->dst_folder = g_object_ref (dst_folder);
5075 helper->headers = g_object_ref (headers);
5077 if (need_connection) {
5078 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5079 connect_info->callback = xfer_messages_performer;
5080 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5081 connect_info->data = helper;
5083 modest_platform_double_connect_and_perform(win, TRUE,
5084 TNY_FOLDER_STORE (src_folder),
5087 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5088 xfer_messages_performer (FALSE, NULL, win,
5089 src_account, helper);
5090 g_object_unref (src_account);
5095 * UI handler for the "Move to" action when invoked from the
5096 * ModestMsgViewWindow
5099 modest_ui_actions_on_window_move_to (GtkAction *action,
5101 TnyFolderStore *dst_folder,
5104 TnyFolder *src_folder = NULL;
5106 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5109 TnyHeader *header = NULL;
5112 iter = tny_list_create_iterator (headers);
5113 header = (TnyHeader *) tny_iterator_get_current (iter);
5114 src_folder = tny_header_get_folder (header);
5116 /* Transfer the messages */
5117 modest_ui_actions_transfer_messages_helper (win, src_folder,
5119 TNY_FOLDER (dst_folder));
5122 g_object_unref (header);
5123 g_object_unref (iter);
5124 g_object_unref (src_folder);
5129 modest_ui_actions_on_move_to (GtkAction *action,
5132 modest_ui_actions_on_edit_mode_move_to (win);
5136 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5138 GtkWidget *dialog = NULL;
5139 GtkWindow *toplevel = NULL;
5140 MoveToInfo *helper = NULL;
5141 TnyList *list_to_move;
5143 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5146 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5151 if (tny_list_get_length (list_to_move) < 1) {
5152 g_object_unref (list_to_move);
5156 /* Create and run the dialog */
5157 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5158 dialog = create_move_to_dialog (toplevel, NULL, list_to_move);
5159 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5160 GTK_WINDOW (dialog),
5164 helper = g_slice_new0 (MoveToInfo);
5165 helper->list = list_to_move;
5168 /* Listen to response signal */
5169 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5171 /* Show the dialog */
5172 gtk_widget_show (dialog);
5178 * Calls #HeadersFunc for each header already selected in the main
5179 * window or the message currently being shown in the msg view window
5182 do_headers_action (ModestWindow *win,
5186 TnyList *headers_list = NULL;
5187 TnyIterator *iter = NULL;
5188 TnyHeader *header = NULL;
5189 TnyFolder *folder = NULL;
5192 headers_list = get_selected_headers (win);
5196 /* Get the folder */
5197 iter = tny_list_create_iterator (headers_list);
5198 header = TNY_HEADER (tny_iterator_get_current (iter));
5200 folder = tny_header_get_folder (header);
5201 g_object_unref (header);
5204 /* Call the function for each header */
5205 while (!tny_iterator_is_done (iter)) {
5206 header = TNY_HEADER (tny_iterator_get_current (iter));
5207 func (header, win, user_data);
5208 g_object_unref (header);
5209 tny_iterator_next (iter);
5212 /* Trick: do a poke status in order to speed up the signaling
5215 tny_folder_poke_status (folder);
5216 g_object_unref (folder);
5220 g_object_unref (iter);
5221 g_object_unref (headers_list);
5225 modest_ui_actions_view_attachment (GtkAction *action,
5226 ModestWindow *window)
5228 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5229 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5231 /* not supported window for this action */
5232 g_return_if_reached ();
5237 modest_ui_actions_save_attachments (GtkAction *action,
5238 ModestWindow *window)
5240 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5242 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5245 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5247 /* not supported window for this action */
5248 g_return_if_reached ();
5253 modest_ui_actions_remove_attachments (GtkAction *action,
5254 ModestWindow *window)
5256 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5257 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5259 /* not supported window for this action */
5260 g_return_if_reached ();
5265 modest_ui_actions_on_settings (GtkAction *action,
5269 GtkWindow *toplevel;
5271 dialog = modest_platform_get_global_settings_dialog ();
5272 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5273 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5274 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5275 gtk_widget_show_all (dialog);
5277 gtk_dialog_run (GTK_DIALOG (dialog));
5279 gtk_widget_destroy (dialog);
5283 modest_ui_actions_on_help (GtkAction *action,
5286 /* Help app is not available at all in fremantle */
5287 #ifndef MODEST_TOOLKIT_HILDON2
5288 const gchar *help_id;
5290 g_return_if_fail (win && GTK_IS_WINDOW(win));
5292 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5295 modest_platform_show_help (win, help_id);
5300 modest_ui_actions_on_csm_help (GtkAction *action,
5303 /* Help app is not available at all in fremantle */
5307 retrieve_contents_cb (ModestMailOperation *mail_op,
5314 /* We only need this callback to show an error in case of
5315 memory low condition */
5316 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5317 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5322 retrieve_msg_contents_performer (gboolean canceled,
5324 ModestWindow *parent_window,
5325 TnyAccount *account,
5328 ModestMailOperation *mail_op;
5329 TnyList *headers = TNY_LIST (user_data);
5331 if (err || canceled) {
5332 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5333 (GtkWidget *) parent_window, err,
5338 /* Create mail operation */
5339 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5340 modest_ui_actions_disk_operations_error_handler,
5342 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5343 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5346 g_object_unref (mail_op);
5348 g_object_unref (headers);
5349 g_object_unref (account);
5353 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5354 ModestWindow *window)
5356 TnyList *headers = NULL;
5357 TnyAccount *account = NULL;
5358 TnyIterator *iter = NULL;
5359 TnyHeader *header = NULL;
5360 TnyFolder *folder = NULL;
5363 headers = get_selected_headers (window);
5367 /* Pick the account */
5368 iter = tny_list_create_iterator (headers);
5369 header = TNY_HEADER (tny_iterator_get_current (iter));
5370 folder = tny_header_get_folder (header);
5371 account = tny_folder_get_account (folder);
5372 g_object_unref (folder);
5373 g_object_unref (header);
5374 g_object_unref (iter);
5376 /* Connect and perform the message retrieval */
5377 modest_platform_connect_and_perform (window, TRUE,
5378 g_object_ref (account),
5379 retrieve_msg_contents_performer,
5380 g_object_ref (headers));
5383 g_object_unref (account);
5384 g_object_unref (headers);
5388 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5390 g_return_if_fail (MODEST_IS_WINDOW (window));
5393 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5397 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5399 g_return_if_fail (MODEST_IS_WINDOW (window));
5402 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5406 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5407 ModestWindow *window)
5409 g_return_if_fail (MODEST_IS_WINDOW (window));
5412 modest_ui_actions_check_menu_dimming_rules (window);
5416 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5417 ModestWindow *window)
5419 g_return_if_fail (MODEST_IS_WINDOW (window));
5422 modest_ui_actions_check_menu_dimming_rules (window);
5426 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5427 ModestWindow *window)
5429 g_return_if_fail (MODEST_IS_WINDOW (window));
5432 modest_ui_actions_check_menu_dimming_rules (window);
5436 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5437 ModestWindow *window)
5439 g_return_if_fail (MODEST_IS_WINDOW (window));
5442 modest_ui_actions_check_menu_dimming_rules (window);
5446 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5447 ModestWindow *window)
5449 g_return_if_fail (MODEST_IS_WINDOW (window));
5452 modest_ui_actions_check_menu_dimming_rules (window);
5456 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5457 ModestWindow *window)
5459 g_return_if_fail (MODEST_IS_WINDOW (window));
5462 modest_ui_actions_check_menu_dimming_rules (window);
5466 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5467 ModestWindow *window)
5469 g_return_if_fail (MODEST_IS_WINDOW (window));
5472 modest_ui_actions_check_menu_dimming_rules (window);
5476 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5477 ModestWindow *window)
5479 g_return_if_fail (MODEST_IS_WINDOW (window));
5482 modest_ui_actions_check_menu_dimming_rules (window);
5486 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5487 ModestWindow *window)
5489 g_return_if_fail (MODEST_IS_WINDOW (window));
5492 modest_ui_actions_check_menu_dimming_rules (window);
5496 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5498 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
5500 g_return_if_fail (MODEST_IS_WINDOW (window));
5502 /* we check for low-mem; in that case, show a warning, and don't allow
5505 if (modest_platform_check_memory_low (window, TRUE))
5508 modest_platform_show_search_messages (toplevel);
5512 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5514 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5516 g_return_if_fail (MODEST_IS_WINDOW (win));
5518 /* we check for low-mem; in that case, show a warning, and don't allow
5519 * for the addressbook
5521 if (modest_platform_check_memory_low (win, TRUE))
5524 modest_platform_show_addressbook (toplevel);
5529 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5530 ModestWindow *window)
5533 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5535 if (GTK_IS_TOGGLE_ACTION (action))
5536 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5540 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5546 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5552 const gchar* server_name = NULL;
5553 TnyTransportAccount *transport;
5554 gchar *message = NULL;
5555 ModestProtocol *protocol;
5557 /* Don't show anything if the user cancelled something or the
5558 * send receive request is not interactive. Authentication
5559 * errors are managed by the account store so no need to show
5560 * a dialog here again */
5561 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5562 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5563 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5567 /* Get the server name. Note that we could be using a
5568 connection specific transport account */
5569 transport = (TnyTransportAccount *)
5570 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5572 ModestTnyAccountStore *acc_store;
5573 const gchar *acc_name;
5574 TnyTransportAccount *conn_specific;
5576 acc_store = modest_runtime_get_account_store();
5577 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5578 conn_specific = (TnyTransportAccount *)
5579 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5580 if (conn_specific) {
5581 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5582 g_object_unref (conn_specific);
5584 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5586 g_object_unref (transport);
5590 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5591 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5592 tny_account_get_proto (TNY_ACCOUNT (transport)));
5594 g_warning ("%s: Account with no proto", __FUNCTION__);
5598 /* Show the appropriate message text for the GError: */
5599 switch (err->code) {
5600 case TNY_SERVICE_ERROR_CONNECT:
5601 message = modest_protocol_get_translation (protocol,
5602 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5605 case TNY_SERVICE_ERROR_SEND:
5606 message = g_strdup (_CS_UNABLE_TO_SEND);
5608 case TNY_SERVICE_ERROR_UNAVAILABLE:
5609 message = modest_protocol_get_translation (protocol,
5610 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5614 g_warning ("%s: unexpected ERROR %d",
5615 __FUNCTION__, err->code);
5616 message = g_strdup (_CS_UNABLE_TO_SEND);
5620 modest_platform_run_information_dialog (NULL, message, FALSE);
5625 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5630 ModestWindow *top_window = NULL;
5631 ModestWindowMgr *mgr = NULL;
5632 GtkWidget *header_view = NULL;
5633 TnyFolder *selected_folder = NULL;
5634 TnyFolderType folder_type;
5636 mgr = modest_runtime_get_window_mgr ();
5637 top_window = modest_window_mgr_get_current_top (mgr);
5642 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5643 header_view = (GtkWidget *)
5644 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5647 /* Get selected folder */
5649 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5650 if (!selected_folder)
5653 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5654 #if GTK_CHECK_VERSION(2, 8, 0)
5655 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5656 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5657 GtkTreeViewColumn *tree_column;
5659 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5660 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5662 gtk_tree_view_column_queue_resize (tree_column);
5664 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5665 gtk_widget_queue_draw (header_view);
5668 #ifndef MODEST_TOOLKIT_HILDON2
5669 /* Rerun dimming rules, because the message could become deletable for example */
5670 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5671 MODEST_DIMMING_RULES_TOOLBAR);
5672 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5673 MODEST_DIMMING_RULES_MENU);
5677 g_object_unref (selected_folder);
5681 modest_ui_actions_on_account_connection_error (ModestWindow *parent_window,
5682 TnyAccount *account)
5684 ModestProtocolType protocol_type;
5685 ModestProtocol *protocol;
5686 gchar *error_note = NULL;
5688 protocol_type = modest_tny_account_get_protocol_type (account);
5689 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5692 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5693 if (error_note == NULL) {
5694 g_warning ("%s: This should not be reached", __FUNCTION__);
5696 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
5697 modest_platform_run_information_dialog (toplevel, error_note, FALSE);
5698 g_free (error_note);
5703 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5707 TnyFolderStore *folder = NULL;
5708 TnyAccount *account = NULL;
5709 ModestProtocolType proto;
5710 ModestProtocol *protocol;
5711 TnyHeader *header = NULL;
5713 if (MODEST_IS_HEADER_WINDOW (win)) {
5714 GtkWidget *header_view;
5715 TnyList* headers = NULL;
5717 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5718 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5719 if (!headers || tny_list_get_length (headers) == 0) {
5721 g_object_unref (headers);
5724 iter = tny_list_create_iterator (headers);
5725 header = TNY_HEADER (tny_iterator_get_current (iter));
5727 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5729 g_warning ("List should contain headers");
5731 g_object_unref (iter);
5732 g_object_unref (headers);
5733 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5734 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5736 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5739 if (!header || !folder)
5742 /* Get the account type */
5743 account = tny_folder_get_account (TNY_FOLDER (folder));
5744 proto = modest_tny_account_get_protocol_type (account);
5745 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5748 subject = tny_header_dup_subject (header);
5749 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5753 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5759 g_object_unref (account);
5761 g_object_unref (folder);
5763 g_object_unref (header);
5769 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5770 const gchar *account_name,
5771 const gchar *account_title)
5773 ModestAccountMgr *account_mgr;
5776 ModestProtocol *protocol;
5777 gboolean removed = FALSE;
5779 g_return_val_if_fail (account_name, FALSE);
5780 g_return_val_if_fail (account_title, FALSE);
5782 account_mgr = modest_runtime_get_account_mgr();
5784 /* The warning text depends on the account type: */
5785 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5786 modest_account_mgr_get_store_protocol (account_mgr,
5788 txt = modest_protocol_get_translation (protocol,
5789 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5792 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5794 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5798 if (response == GTK_RESPONSE_OK) {
5799 /* Remove account. If it succeeds then it also removes
5800 the account from the ModestAccountView: */
5801 gboolean is_default = FALSE;
5802 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5803 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5805 g_free (default_account_name);
5807 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5809 #ifdef MODEST_TOOLKIT_HILDON2
5810 hildon_gtk_window_take_screenshot (parent_window, FALSE);
5812 /* Close all email notifications, we cannot
5813 distinguish if the notification belongs to
5814 this account or not, so for safety reasons
5815 we remove them all */
5816 modest_platform_remove_new_mail_notifications (FALSE);
5818 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5825 on_fetch_images_performer (gboolean canceled,
5827 ModestWindow *parent_window,
5828 TnyAccount *account,
5831 if (err || canceled) {
5832 /* Show an unable to retrieve images ??? */
5836 /* Note that the user could have closed the window while connecting */
5837 if (GTK_WIDGET_VISIBLE (parent_window))
5838 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5839 g_object_unref ((GObject *) user_data);
5843 modest_ui_actions_on_fetch_images (GtkAction *action,
5844 ModestWindow *window)
5846 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5848 modest_platform_connect_and_perform (window, TRUE,
5850 on_fetch_images_performer,
5851 g_object_ref (window));
5855 modest_ui_actions_on_reload_message (const gchar *msg_id)
5857 ModestWindow *window = NULL;
5859 g_return_if_fail (msg_id && msg_id[0] != '\0');
5860 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5866 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5869 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5872 /** Check whether any connections are active, and cancel them if
5874 * Returns TRUE is there was no problem,
5875 * or if an operation was cancelled so we can continue.
5876 * Returns FALSE if the user chose to cancel his request instead.
5880 modest_ui_actions_check_for_active_account (ModestWindow *self,
5881 const gchar* account_name)
5883 ModestTnySendQueue *send_queue;
5884 ModestTnyAccountStore *acc_store;
5885 ModestMailOperationQueue* queue;
5886 TnyConnectionStatus store_conn_status;
5887 TnyAccount *store_account = NULL, *transport_account = NULL;
5888 gboolean retval = TRUE, sending = FALSE;
5890 acc_store = modest_runtime_get_account_store ();
5891 queue = modest_runtime_get_mail_operation_queue ();
5894 modest_tny_account_store_get_server_account (acc_store,
5896 TNY_ACCOUNT_TYPE_STORE);
5898 /* This could happen if the account was deleted before the
5899 call to this function */
5904 modest_tny_account_store_get_server_account (acc_store,
5906 TNY_ACCOUNT_TYPE_TRANSPORT);
5908 /* This could happen if the account was deleted before the
5909 call to this function */
5910 if (!transport_account) {
5911 g_object_unref (store_account);
5915 /* If the transport account was not used yet, then the send
5916 queue could not exist (it's created on demand) */
5917 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5918 if (TNY_IS_SEND_QUEUE (send_queue))
5919 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5921 store_conn_status = tny_account_get_connection_status (store_account);
5922 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5925 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (self)),
5926 _("emev_nc_disconnect_account"));
5927 if (response == GTK_RESPONSE_OK) {
5936 /* FIXME: We should only cancel those of this account */
5937 modest_mail_operation_queue_cancel_all (queue);
5939 /* Also disconnect the account */
5940 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5941 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5942 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5946 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5952 g_object_unref (store_account);
5953 g_object_unref (transport_account);