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;
3408 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3409 /* Note that the connection process can fail due to
3410 memory low conditions as it can not successfully
3411 store the summary */
3412 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3413 (GtkWidget*) parent_window, err,
3415 g_debug ("Error connecting when trying to delete a folder");
3416 g_object_unref (G_OBJECT (info->folder));
3421 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3422 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3424 g_object_unref (G_OBJECT (info->folder));
3429 /* Unselect the folder before deleting it to free the headers */
3430 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3431 gtk_tree_selection_unselect_all (sel);
3433 /* Create the mail operation */
3435 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3436 modest_ui_actions_delete_folder_error_handler,
3439 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3441 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3443 g_object_unref (mail_op);
3444 g_object_unref (info->folder);
3449 delete_folder (ModestWindow *window, gboolean move_to_trash)
3451 TnyFolderStore *folder;
3452 GtkWidget *folder_view;
3455 GtkWindow *toplevel;
3457 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3459 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
3461 if (MODEST_IS_FOLDER_WINDOW (window)) {
3462 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3469 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3474 /* Show an error if it's an account */
3475 if (!TNY_IS_FOLDER (folder)) {
3476 modest_platform_run_information_dialog (toplevel,
3477 _("mail_in_ui_folder_delete_error"),
3479 g_object_unref (G_OBJECT (folder));
3484 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3485 tny_folder_get_name (TNY_FOLDER (folder)));
3486 response = modest_platform_run_confirmation_dialog (toplevel,
3487 (const gchar *) message);
3490 if (response == GTK_RESPONSE_OK) {
3491 TnyAccount *account = NULL;
3492 DeleteFolderInfo *info = NULL;
3493 info = g_new0(DeleteFolderInfo, 1);
3494 info->folder = g_object_ref (folder);
3495 info->move_to_trash = move_to_trash;
3497 account = tny_folder_get_account (TNY_FOLDER (folder));
3498 modest_platform_connect_if_remote_and_perform (window,
3500 TNY_FOLDER_STORE (account),
3501 on_delete_folder_cb, info);
3502 g_object_unref (account);
3503 g_object_unref (folder);
3511 modest_ui_actions_on_delete_folder (GtkAction *action,
3512 ModestWindow *window)
3514 modest_ui_actions_on_edit_mode_delete_folder (window);
3518 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3520 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3522 return delete_folder (window, FALSE);
3526 typedef struct _PasswordDialogFields {
3527 GtkWidget *username;
3528 GtkWidget *password;
3530 } PasswordDialogFields;
3533 password_dialog_check_field (GtkEditable *editable,
3534 PasswordDialogFields *fields)
3537 gboolean any_value_empty = FALSE;
3539 value = modest_entry_get_text (fields->username);
3540 if ((value == NULL) || value[0] == '\0') {
3541 any_value_empty = TRUE;
3543 value = modest_entry_get_text (fields->password);
3544 if ((value == NULL) || value[0] == '\0') {
3545 any_value_empty = TRUE;
3547 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3551 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3552 const gchar* server_account_name,
3557 ModestMainWindow *main_window)
3559 g_return_if_fail(server_account_name);
3560 gboolean completed = FALSE;
3561 PasswordDialogFields *fields = NULL;
3563 /* Initalize output parameters: */
3570 #ifndef MODEST_TOOLKIT_GTK
3571 /* Maemo uses a different (awkward) button order,
3572 * It should probably just use gtk_alternative_dialog_button_order ().
3574 #ifdef MODEST_TOOLKIT_HILDON2
3576 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3580 GTK_RESPONSE_ACCEPT,
3582 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3583 HILDON_MARGIN_DOUBLE);
3586 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3589 _("mcen_bd_dialog_ok"),
3590 GTK_RESPONSE_ACCEPT,
3591 _("mcen_bd_dialog_cancel"),
3592 GTK_RESPONSE_REJECT,
3594 #endif /* MODEST_TOOLKIT_HILDON2 */
3597 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3601 GTK_RESPONSE_REJECT,
3603 GTK_RESPONSE_ACCEPT,
3605 #endif /* MODEST_TOOLKIT_GTK */
3607 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3609 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3610 modest_runtime_get_account_mgr(), server_account_name);
3611 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3612 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3615 gtk_widget_destroy (dialog);
3619 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3620 GtkWidget *label = gtk_label_new (txt);
3621 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3623 g_free (server_name);
3624 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3629 gchar *initial_username = modest_account_mgr_get_server_account_username (
3630 modest_runtime_get_account_mgr(), server_account_name);
3632 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3633 if (initial_username)
3634 modest_entry_set_text (entry_username, initial_username);
3636 /* Dim this if a connection has ever succeeded with this username,
3637 * as per the UI spec: */
3638 /* const gboolean username_known = */
3639 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3640 /* modest_runtime_get_account_mgr(), server_account_name); */
3641 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3643 /* We drop the username sensitive code and disallow changing it here
3644 * as tinymail does not support really changing the username in the callback
3646 gtk_widget_set_sensitive (entry_username, FALSE);
3648 /* Auto-capitalization is the default, so let's turn it off: */
3649 #ifdef MAEMO_CHANGES
3650 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3653 /* Create a size group to be used by all captions.
3654 * Note that HildonCaption does not create a default size group if we do not specify one.
3655 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3656 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3658 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3659 _("mail_fi_username"), FALSE,
3661 gtk_widget_show (entry_username);
3662 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3663 FALSE, FALSE, MODEST_MARGIN_HALF);
3664 gtk_widget_show (caption);
3667 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3668 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3669 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3671 /* Auto-capitalization is the default, so let's turn it off: */
3672 #ifdef MAEMO_CHANGES
3673 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3674 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3677 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3678 _("mail_fi_password"), FALSE,
3680 gtk_widget_show (entry_password);
3681 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3682 FALSE, FALSE, MODEST_MARGIN_HALF);
3683 gtk_widget_show (caption);
3684 g_object_unref (sizegroup);
3686 if (initial_username != NULL)
3687 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3689 /* This is not in the Maemo UI spec:
3690 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3691 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3695 fields = g_slice_new0 (PasswordDialogFields);
3696 fields->username = entry_username;
3697 fields->password = entry_password;
3698 fields->dialog = dialog;
3700 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3701 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3702 password_dialog_check_field (NULL, fields);
3704 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3706 while (!completed) {
3708 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3710 *username = g_strdup (modest_entry_get_text (entry_username));
3712 /* Note that an empty field becomes the "" string */
3713 if (*username && strlen (*username) > 0) {
3714 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3715 server_account_name,
3719 const gboolean username_was_changed =
3720 (strcmp (*username, initial_username) != 0);
3721 if (username_was_changed) {
3722 g_warning ("%s: tinymail does not yet support changing the "
3723 "username in the get_password() callback.\n", __FUNCTION__);
3729 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3730 _("mcen_ib_username_pw_incorrect"));
3736 *password = g_strdup (modest_entry_get_text (entry_password));
3738 /* We do not save the password in the configuration,
3739 * because this function is only called for passwords that should
3740 * not be remembered:
3741 modest_server_account_set_password (
3742 modest_runtime_get_account_mgr(), server_account_name,
3759 /* This is not in the Maemo UI spec:
3760 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3766 g_free (initial_username);
3767 gtk_widget_destroy (dialog);
3768 g_slice_free (PasswordDialogFields, fields);
3770 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3774 modest_ui_actions_on_cut (GtkAction *action,
3775 ModestWindow *window)
3777 GtkWidget *focused_widget;
3778 GtkClipboard *clipboard;
3780 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3781 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3782 if (GTK_IS_EDITABLE (focused_widget)) {
3783 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3784 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3785 gtk_clipboard_store (clipboard);
3786 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3787 GtkTextBuffer *buffer;
3789 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3790 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3791 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3792 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3793 gtk_clipboard_store (clipboard);
3795 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3796 TnyList *header_list = modest_header_view_get_selected_headers (
3797 MODEST_HEADER_VIEW (focused_widget));
3798 gboolean continue_download = FALSE;
3799 gint num_of_unc_msgs;
3801 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3803 if (num_of_unc_msgs) {
3804 TnyAccount *account = get_account_from_header_list (header_list);
3806 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3807 g_object_unref (account);
3811 if (num_of_unc_msgs == 0 || continue_download) {
3812 /* modest_platform_information_banner (
3813 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3814 modest_header_view_cut_selection (
3815 MODEST_HEADER_VIEW (focused_widget));
3818 g_object_unref (header_list);
3819 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3820 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3825 modest_ui_actions_on_copy (GtkAction *action,
3826 ModestWindow *window)
3828 GtkClipboard *clipboard;
3829 GtkWidget *focused_widget;
3830 gboolean copied = TRUE;
3832 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3833 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3835 if (GTK_IS_LABEL (focused_widget)) {
3837 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3838 gtk_clipboard_set_text (clipboard, selection, -1);
3840 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3841 gtk_clipboard_store (clipboard);
3842 } else if (GTK_IS_EDITABLE (focused_widget)) {
3843 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3844 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3845 gtk_clipboard_store (clipboard);
3846 } else if (GTK_IS_HTML (focused_widget)) {
3849 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3850 if ((sel == NULL) || (sel[0] == '\0')) {
3853 gtk_html_copy (GTK_HTML (focused_widget));
3854 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3855 gtk_clipboard_store (clipboard);
3857 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3858 GtkTextBuffer *buffer;
3859 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3860 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3861 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3862 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3863 gtk_clipboard_store (clipboard);
3865 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3866 TnyList *header_list = modest_header_view_get_selected_headers (
3867 MODEST_HEADER_VIEW (focused_widget));
3868 gboolean continue_download = FALSE;
3869 gint num_of_unc_msgs;
3871 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3873 if (num_of_unc_msgs) {
3874 TnyAccount *account = get_account_from_header_list (header_list);
3876 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3877 g_object_unref (account);
3881 if (num_of_unc_msgs == 0 || continue_download) {
3882 modest_platform_information_banner (
3883 NULL, NULL, _CS_GETTING_ITEMS);
3884 modest_header_view_copy_selection (
3885 MODEST_HEADER_VIEW (focused_widget));
3889 g_object_unref (header_list);
3891 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3892 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3895 /* Show information banner if there was a copy to clipboard */
3897 modest_platform_information_banner (
3898 NULL, NULL, _CS_COPIED);
3902 modest_ui_actions_on_undo (GtkAction *action,
3903 ModestWindow *window)
3905 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3906 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3908 g_return_if_reached ();
3913 modest_ui_actions_on_redo (GtkAction *action,
3914 ModestWindow *window)
3916 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3917 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3920 g_return_if_reached ();
3926 destroy_information_note (ModestMailOperation *mail_op,
3929 /* destroy information note */
3930 gtk_widget_destroy (GTK_WIDGET(user_data));
3934 destroy_folder_information_note (ModestMailOperation *mail_op,
3935 TnyFolder *new_folder,
3938 /* destroy information note */
3939 gtk_widget_destroy (GTK_WIDGET(user_data));
3944 paste_as_attachment_free (gpointer data)
3946 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3948 if (helper->banner) {
3949 gtk_widget_destroy (helper->banner);
3950 g_object_unref (helper->banner);
3956 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3961 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3962 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3967 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3972 modest_ui_actions_on_paste (GtkAction *action,
3973 ModestWindow *window)
3975 GtkWidget *focused_widget = NULL;
3976 GtkWidget *inf_note = NULL;
3977 ModestMailOperation *mail_op = NULL;
3979 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3980 if (GTK_IS_EDITABLE (focused_widget)) {
3981 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3982 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3983 ModestEmailClipboard *e_clipboard = NULL;
3984 e_clipboard = modest_runtime_get_email_clipboard ();
3985 if (modest_email_clipboard_cleared (e_clipboard)) {
3986 GtkTextBuffer *buffer;
3987 GtkClipboard *clipboard;
3989 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3990 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3991 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3992 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3993 ModestMailOperation *mail_op;
3994 TnyFolder *src_folder = NULL;
3995 TnyList *data = NULL;
3997 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3998 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3999 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4001 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4002 mail_op = modest_mail_operation_new (G_OBJECT (window));
4003 if (helper->banner != NULL) {
4004 g_object_ref (G_OBJECT (helper->banner));
4005 gtk_widget_show (GTK_WIDGET (helper->banner));
4009 modest_mail_operation_get_msgs_full (mail_op,
4011 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4013 paste_as_attachment_free);
4017 g_object_unref (data);
4019 g_object_unref (src_folder);
4022 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4023 ModestEmailClipboard *clipboard = NULL;
4024 TnyFolder *src_folder = NULL;
4025 TnyFolderStore *folder_store = NULL;
4026 TnyList *data = NULL;
4027 gboolean delete = FALSE;
4029 /* Check clipboard source */
4030 clipboard = modest_runtime_get_email_clipboard ();
4031 if (modest_email_clipboard_cleared (clipboard))
4034 /* Get elements to paste */
4035 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4037 /* Create a new mail operation */
4038 mail_op = modest_mail_operation_new (G_OBJECT(window));
4040 /* Get destination folder */
4041 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4043 /* transfer messages */
4047 /* Ask for user confirmation */
4049 modest_ui_actions_msgs_move_to_confirmation (window,
4050 TNY_FOLDER (folder_store),
4054 if (response == GTK_RESPONSE_OK) {
4055 /* Launch notification */
4056 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4058 if (inf_note != NULL) {
4059 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4060 gtk_widget_show (GTK_WIDGET(inf_note));
4063 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4064 modest_mail_operation_xfer_msgs (mail_op,
4066 TNY_FOLDER (folder_store),
4068 destroy_information_note,
4071 g_object_unref (mail_op);
4074 } else if (src_folder != NULL) {
4075 /* Launch notification */
4076 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4078 if (inf_note != NULL) {
4079 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4080 gtk_widget_show (GTK_WIDGET(inf_note));
4083 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4084 modest_mail_operation_xfer_folder (mail_op,
4088 destroy_folder_information_note,
4094 g_object_unref (data);
4095 if (src_folder != NULL)
4096 g_object_unref (src_folder);
4097 if (folder_store != NULL)
4098 g_object_unref (folder_store);
4104 modest_ui_actions_on_select_all (GtkAction *action,
4105 ModestWindow *window)
4107 GtkWidget *focused_widget;
4109 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4110 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4111 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4112 } else if (GTK_IS_LABEL (focused_widget)) {
4113 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4114 } else if (GTK_IS_EDITABLE (focused_widget)) {
4115 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4116 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4117 GtkTextBuffer *buffer;
4118 GtkTextIter start, end;
4120 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4121 gtk_text_buffer_get_start_iter (buffer, &start);
4122 gtk_text_buffer_get_end_iter (buffer, &end);
4123 gtk_text_buffer_select_range (buffer, &start, &end);
4124 } else if (GTK_IS_HTML (focused_widget)) {
4125 gtk_html_select_all (GTK_HTML (focused_widget));
4131 modest_ui_actions_on_mark_as_read (GtkAction *action,
4132 ModestWindow *window)
4134 g_return_if_fail (MODEST_IS_WINDOW(window));
4136 /* Mark each header as read */
4137 do_headers_action (window, headers_action_mark_as_read, NULL);
4141 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4142 ModestWindow *window)
4144 g_return_if_fail (MODEST_IS_WINDOW(window));
4146 /* Mark each header as read */
4147 do_headers_action (window, headers_action_mark_as_unread, NULL);
4151 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4152 GtkRadioAction *selected,
4153 ModestWindow *window)
4157 value = gtk_radio_action_get_current_value (selected);
4158 if (MODEST_IS_WINDOW (window)) {
4159 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4164 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4165 GtkRadioAction *selected,
4166 ModestWindow *window)
4168 TnyHeaderFlags flags;
4169 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4171 flags = gtk_radio_action_get_current_value (selected);
4172 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4176 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4177 GtkRadioAction *selected,
4178 ModestWindow *window)
4182 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4184 file_format = gtk_radio_action_get_current_value (selected);
4185 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4190 modest_ui_actions_on_zoom_plus (GtkAction *action,
4191 ModestWindow *window)
4193 g_return_if_fail (MODEST_IS_WINDOW (window));
4195 modest_window_zoom_plus (MODEST_WINDOW (window));
4199 modest_ui_actions_on_zoom_minus (GtkAction *action,
4200 ModestWindow *window)
4202 g_return_if_fail (MODEST_IS_WINDOW (window));
4204 modest_window_zoom_minus (MODEST_WINDOW (window));
4208 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4209 ModestWindow *window)
4211 ModestWindowMgr *mgr;
4212 gboolean fullscreen, active;
4213 g_return_if_fail (MODEST_IS_WINDOW (window));
4215 mgr = modest_runtime_get_window_mgr ();
4217 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4218 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4220 if (active != fullscreen) {
4221 modest_window_mgr_set_fullscreen_mode (mgr, active);
4222 #ifndef MODEST_TOOLKIT_HILDON2
4223 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4224 gtk_window_present (toplevel);
4230 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4231 ModestWindow *window)
4233 ModestWindowMgr *mgr;
4234 gboolean fullscreen;
4236 g_return_if_fail (MODEST_IS_WINDOW (window));
4238 mgr = modest_runtime_get_window_mgr ();
4239 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4240 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4245 * Used by modest_ui_actions_on_details to call do_headers_action
4248 headers_action_show_details (TnyHeader *header,
4249 ModestWindow *window,
4253 gboolean async_retrieval;
4254 GtkWindow *toplevel;
4257 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4258 async_retrieval = TRUE;
4259 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4260 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4262 async_retrieval = FALSE;
4264 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4265 modest_platform_run_header_details_dialog (toplevel, header, async_retrieval, msg);
4267 g_object_unref (msg);
4271 * Show the header details in a ModestDetailsDialog widget
4274 modest_ui_actions_on_details (GtkAction *action,
4277 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4281 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4285 header = tny_msg_get_header (msg);
4287 headers_action_show_details (header, win, NULL);
4288 g_object_unref (header);
4290 g_object_unref (msg);
4291 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4293 GtkWidget *header_view;
4295 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4296 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4298 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4300 modest_platform_run_folder_details_dialog (toplevel, folder);
4301 g_object_unref (folder);
4307 modest_ui_actions_on_limit_error (GtkAction *action,
4310 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4312 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS_MAXIMUM_CHARACTERS_REACHED);
4317 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4318 ModestMsgEditWindow *window)
4320 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4322 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4326 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4327 ModestMsgEditWindow *window)
4329 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4331 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4336 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4337 ModestWindow *window)
4339 gboolean active, fullscreen = FALSE;
4340 ModestWindowMgr *mgr;
4342 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4344 /* Check if we want to toggle the toolbar view in fullscreen
4346 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4347 "ViewShowToolbarFullScreen")) {
4351 /* Toggle toolbar */
4352 mgr = modest_runtime_get_window_mgr ();
4353 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4357 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4358 ModestMsgEditWindow *window)
4360 modest_msg_edit_window_select_font (window);
4365 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4366 const gchar *display_name,
4369 /* don't update the display name if it was already set;
4370 * updating the display name apparently is expensive */
4371 const gchar* old_name = gtk_window_get_title (window);
4373 if (display_name == NULL)
4376 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4377 return; /* don't do anything */
4379 /* This is usually used to change the title of the main window, which
4380 * is the one that holds the folder view. Note that this change can
4381 * happen even when the widget doesn't have the focus. */
4382 gtk_window_set_title (window, display_name);
4387 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4389 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4390 modest_msg_edit_window_select_contacts (window);
4394 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4397 modest_msg_edit_window_check_names (window, FALSE);
4402 on_move_to_dialog_response (GtkDialog *dialog,
4406 GtkWidget *parent_win;
4407 MoveToInfo *helper = NULL;
4408 ModestFolderView *folder_view;
4409 gboolean unset_edit_mode = FALSE;
4411 helper = (MoveToInfo *) user_data;
4413 parent_win = (GtkWidget *) helper->win;
4414 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4415 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4417 TnyFolderStore *dst_folder;
4418 TnyFolderStore *selected;
4420 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4421 selected = modest_folder_view_get_selected (folder_view);
4422 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4423 g_object_unref (selected);
4425 case GTK_RESPONSE_NONE:
4426 case GTK_RESPONSE_CANCEL:
4427 case GTK_RESPONSE_DELETE_EVENT:
4429 case GTK_RESPONSE_OK:
4430 dst_folder = modest_folder_view_get_selected (folder_view);
4432 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4433 /* Clean list to move used for filtering */
4434 modest_folder_view_set_list_to_move (folder_view, NULL);
4436 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4439 MODEST_WINDOW (parent_win));
4441 /* if the user selected a root folder
4442 (account) then do not perform any action */
4443 if (TNY_IS_ACCOUNT (dst_folder)) {
4444 g_signal_stop_emission_by_name (dialog, "response");
4448 /* Clean list to move used for filtering */
4449 modest_folder_view_set_list_to_move (folder_view, NULL);
4451 /* Moving from headers window in edit mode */
4452 modest_ui_actions_on_window_move_to (NULL, helper->list,
4454 MODEST_WINDOW (parent_win));
4458 g_object_unref (dst_folder);
4460 unset_edit_mode = TRUE;
4463 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4466 /* Free the helper and exit */
4468 g_object_unref (helper->list);
4469 if (unset_edit_mode) {
4470 #ifdef MODEST_TOOLKIT_HILDON2
4471 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4474 g_slice_free (MoveToInfo, helper);
4475 gtk_widget_destroy (GTK_WIDGET (dialog));
4479 create_move_to_dialog (GtkWindow *win,
4480 GtkWidget *folder_view,
4481 TnyList *list_to_move)
4483 GtkWidget *dialog, *tree_view = NULL;
4485 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4488 /* It could happen that we're trying to move a message from a
4489 window (msg window for example) after the main window was
4490 closed, so we can not just get the model of the folder
4492 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4493 const gchar *visible_id = NULL;
4495 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4496 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4497 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4498 MODEST_FOLDER_VIEW(tree_view));
4501 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4503 /* Show the same account than the one that is shown in the main window */
4504 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4507 const gchar *active_account_name = NULL;
4508 ModestAccountMgr *mgr = NULL;
4509 ModestAccountSettings *settings = NULL;
4510 ModestServerAccountSettings *store_settings = NULL;
4512 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4513 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4514 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4515 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4517 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4518 mgr = modest_runtime_get_account_mgr ();
4519 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4522 const gchar *store_account_name;
4523 store_settings = modest_account_settings_get_store_settings (settings);
4524 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4526 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4527 store_account_name);
4528 g_object_unref (store_settings);
4529 g_object_unref (settings);
4533 /* we keep a pointer to the embedded folder view, so we can
4534 * retrieve it with get_folder_view_from_move_to_dialog (see
4535 * above) later (needed for focus handling)
4537 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4539 /* Hide special folders */
4541 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4543 gtk_widget_show (GTK_WIDGET (tree_view));
4549 * Shows a confirmation dialog to the user when we're moving messages
4550 * from a remote server to the local storage. Returns the dialog
4551 * response. If it's other kind of movement then it always returns
4554 * This one is used by the next functions:
4555 * modest_ui_actions_on_paste - commented out
4556 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4559 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4560 TnyFolder *dest_folder,
4564 gint response = GTK_RESPONSE_OK;
4565 TnyAccount *account = NULL;
4566 TnyFolder *src_folder = NULL;
4567 TnyIterator *iter = NULL;
4568 TnyHeader *header = NULL;
4570 /* return with OK if the destination is a remote folder */
4571 if (modest_tny_folder_is_remote_folder (dest_folder))
4572 return GTK_RESPONSE_OK;
4574 /* Get source folder */
4575 iter = tny_list_create_iterator (headers);
4576 header = TNY_HEADER (tny_iterator_get_current (iter));
4578 src_folder = tny_header_get_folder (header);
4579 g_object_unref (header);
4581 g_object_unref (iter);
4583 /* if no src_folder, message may be an attahcment */
4584 if (src_folder == NULL)
4585 return GTK_RESPONSE_CANCEL;
4587 /* If the source is a local or MMC folder */
4588 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4589 g_object_unref (src_folder);
4590 return GTK_RESPONSE_OK;
4593 /* Get the account */
4594 account = tny_folder_get_account (src_folder);
4596 /* now if offline we ask the user */
4597 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4598 response = GTK_RESPONSE_OK;
4600 response = GTK_RESPONSE_CANCEL;
4603 g_object_unref (src_folder);
4604 g_object_unref (account);
4610 move_to_helper_destroyer (gpointer user_data)
4612 MoveToHelper *helper = (MoveToHelper *) user_data;
4614 /* Close the "Pasting" information banner */
4615 if (helper->banner) {
4616 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4617 g_object_unref (helper->banner);
4619 if (gtk_tree_row_reference_valid (helper->reference)) {
4620 gtk_tree_row_reference_free (helper->reference);
4621 helper->reference = NULL;
4627 move_to_cb (ModestMailOperation *mail_op,
4630 MoveToHelper *helper = (MoveToHelper *) user_data;
4631 GObject *object = modest_mail_operation_get_source (mail_op);
4633 /* Note that the operation could have failed, in that case do
4635 if (modest_mail_operation_get_status (mail_op) !=
4636 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4639 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4640 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4642 if (!modest_msg_view_window_select_next_message (self) &&
4643 !modest_msg_view_window_select_previous_message (self)) {
4644 /* No more messages to view, so close this window */
4645 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4648 g_object_unref (object);
4651 /* Destroy the helper */
4652 move_to_helper_destroyer (helper);
4656 folder_move_to_cb (ModestMailOperation *mail_op,
4657 TnyFolder *new_folder,
4662 object = modest_mail_operation_get_source (mail_op);
4664 move_to_cb (mail_op, user_data);
4669 msgs_move_to_cb (ModestMailOperation *mail_op,
4672 move_to_cb (mail_op, user_data);
4676 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4679 GObject *win = NULL;
4680 const GError *error;
4681 TnyAccount *account = NULL;
4683 win = modest_mail_operation_get_source (mail_op);
4684 error = modest_mail_operation_get_error (mail_op);
4686 if (TNY_IS_FOLDER (user_data))
4687 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4688 else if (TNY_IS_ACCOUNT (user_data))
4689 account = g_object_ref (user_data);
4691 /* If it's not a disk full error then show a generic error */
4692 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4693 (GtkWidget *) win, (GError *) error,
4695 modest_platform_run_information_dialog ((GtkWindow *) win,
4696 _("mail_in_ui_folder_move_target_error"),
4699 g_object_unref (account);
4701 g_object_unref (win);
4706 * Checks if we need a connection to do the transfer and if the user
4707 * wants to connect to complete it
4710 modest_ui_actions_xfer_messages_check (ModestWindow *parent_window,
4711 TnyFolderStore *src_folder,
4713 TnyFolder *dst_folder,
4714 gboolean delete_originals,
4715 gboolean *need_connection,
4718 TnyAccount *src_account;
4719 gint uncached_msgs = 0;
4721 /* We don't need any further check if
4723 * 1- the source folder is local OR
4724 * 2- the device is already online
4726 if (!modest_tny_folder_store_is_remote (src_folder) ||
4727 tny_device_is_online (modest_runtime_get_device())) {
4728 *need_connection = FALSE;
4733 /* We must ask for a connection when
4735 * - the message(s) is not already cached OR
4736 * - the message(s) is cached but the leave_on_server setting
4737 * is FALSE (because we need to sync the source folder to
4738 * delete the message from the server (for IMAP we could do it
4739 * offline, it'll take place the next time we get a
4742 uncached_msgs = header_list_count_uncached_msgs (headers);
4743 src_account = get_account_from_folder_store (src_folder);
4744 if (uncached_msgs > 0) {
4747 GtkWindow *toplevel;
4749 *need_connection = TRUE;
4750 num_headers = tny_list_get_length (headers);
4751 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4752 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
4754 if (modest_platform_run_confirmation_dialog (toplevel, msg) ==
4755 GTK_RESPONSE_CANCEL) {
4761 /* The transfer is possible and the user wants to */
4764 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4765 const gchar *account_name;
4766 gboolean leave_on_server;
4768 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4769 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4772 if (leave_on_server == TRUE) {
4773 *need_connection = FALSE;
4775 *need_connection = TRUE;
4778 *need_connection = FALSE;
4783 g_object_unref (src_account);
4787 xfer_messages_error_handler (ModestMailOperation *mail_op,
4791 const GError *error;
4792 TnyAccount *account;
4794 win = modest_mail_operation_get_source (mail_op);
4795 error = modest_mail_operation_get_error (mail_op);
4797 /* We cannot get the account from the mail op as that is the
4798 source account and for checking memory full conditions we
4799 need the destination one */
4800 account = TNY_ACCOUNT (user_data);
4803 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4804 (GtkWidget *) win, (GError*) error,
4805 account, _KR("cerm_memory_card_full"))) {
4806 modest_platform_run_information_dialog ((GtkWindow *) win,
4807 _("mail_in_ui_folder_move_target_error"),
4811 g_object_unref (win);
4815 TnyFolderStore *dst_folder;
4820 * Utility function that transfer messages from both the main window
4821 * and the msg view window when using the "Move to" dialog
4824 xfer_messages_performer (gboolean canceled,
4826 ModestWindow *parent_window,
4827 TnyAccount *account,
4830 TnyAccount *dst_account = NULL;
4831 gboolean dst_forbids_message_add = FALSE;
4832 XferMsgsHelper *helper;
4833 MoveToHelper *movehelper;
4834 ModestMailOperation *mail_op;
4836 helper = (XferMsgsHelper *) user_data;
4838 if (canceled || err) {
4839 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4840 (GtkWidget *) parent_window, err,
4842 /* Show the proper error message */
4843 modest_ui_actions_on_account_connection_error (parent_window, account);
4848 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4850 /* tinymail will return NULL for local folders it seems */
4851 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4852 modest_tny_account_get_protocol_type (dst_account),
4853 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4855 if (dst_forbids_message_add) {
4856 modest_platform_information_banner (GTK_WIDGET (parent_window),
4858 ngettext("mail_in_ui_folder_move_target_error",
4859 "mail_in_ui_folder_move_targets_error",
4860 tny_list_get_length (helper->headers)));
4864 movehelper = g_new0 (MoveToHelper, 1);
4867 /* Perform the mail operation */
4868 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4869 xfer_messages_error_handler,
4870 g_object_ref (dst_account),
4872 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4875 modest_mail_operation_xfer_msgs (mail_op,
4877 TNY_FOLDER (helper->dst_folder),
4882 g_object_unref (G_OBJECT (mail_op));
4885 g_object_unref (dst_account);
4886 g_object_unref (helper->dst_folder);
4887 g_object_unref (helper->headers);
4888 g_slice_free (XferMsgsHelper, helper);
4892 TnyFolder *src_folder;
4893 TnyFolderStore *dst_folder;
4894 gboolean delete_original;
4895 GtkWidget *folder_view;
4899 on_move_folder_cb (gboolean canceled,
4901 ModestWindow *parent_window,
4902 TnyAccount *account,
4905 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4906 GtkTreeSelection *sel;
4907 ModestMailOperation *mail_op = NULL;
4909 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4910 /* Note that the connection process can fail due to
4911 memory low conditions as it can not successfully
4912 store the summary */
4913 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4914 (GtkWidget*) parent_window, err,
4916 g_debug ("Error connecting when trying to move a folder");
4918 g_object_unref (G_OBJECT (info->src_folder));
4919 g_object_unref (G_OBJECT (info->dst_folder));
4924 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4925 #ifndef MODEST_TOOLKIT_HILDON2
4926 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4928 if (helper->banner != NULL) {
4929 g_object_ref (helper->banner);
4930 gtk_widget_show (GTK_WIDGET(helper->banner));
4933 /* Clean folder on header view before moving it */
4934 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4935 gtk_tree_selection_unselect_all (sel);
4937 /* Let gtk events run. We need that the folder
4938 view frees its reference to the source
4939 folder *before* issuing the mail operation
4940 so we need the signal handler of selection
4941 changed to happen before the mail
4943 while (gtk_events_pending ())
4944 gtk_main_iteration (); */
4947 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4948 modest_ui_actions_move_folder_error_handler,
4949 g_object_ref (info->dst_folder), g_object_unref);
4950 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4953 modest_mail_operation_xfer_folder (mail_op,
4954 TNY_FOLDER (info->src_folder),
4956 info->delete_original,
4959 g_object_unref (G_OBJECT (info->src_folder));
4961 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4964 /* Unref mail operation */
4965 g_object_unref (G_OBJECT (mail_op));
4966 g_object_unref (G_OBJECT (info->dst_folder));
4971 get_account_from_folder_store (TnyFolderStore *folder_store)
4973 if (TNY_IS_ACCOUNT (folder_store))
4974 return g_object_ref (folder_store);
4976 return tny_folder_get_account (TNY_FOLDER (folder_store));
4980 * UI handler for the "Move to" action when invoked from the
4981 * ModestFolderWindow
4984 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4985 TnyFolderStore *dst_folder,
4989 TnyFolderStore *src_folder = NULL;
4990 TnyIterator *iterator;
4992 if (tny_list_get_length (selection) != 1)
4995 iterator = tny_list_create_iterator (selection);
4996 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
4997 g_object_unref (iterator);
5000 gboolean do_xfer = TRUE;
5002 /* Allow only to transfer folders to the local root folder */
5003 if (TNY_IS_ACCOUNT (dst_folder) &&
5004 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5005 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5006 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5010 modest_platform_run_information_dialog (toplevel,
5011 _("mail_in_ui_folder_move_target_error"),
5013 } else if (!TNY_IS_FOLDER (src_folder)) {
5014 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5019 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5020 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5022 info->src_folder = g_object_ref (src_folder);
5023 info->dst_folder = g_object_ref (dst_folder);
5024 info->delete_original = TRUE;
5025 info->folder_view = folder_view;
5027 connect_info->callback = on_move_folder_cb;
5028 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5029 connect_info->data = info;
5031 modest_platform_double_connect_and_perform(win, TRUE,
5032 TNY_FOLDER_STORE (src_folder),
5037 g_object_unref (src_folder);
5042 modest_ui_actions_transfer_messages_helper (ModestWindow *win,
5043 TnyFolder *src_folder,
5045 TnyFolder *dst_folder)
5047 gboolean need_connection = TRUE;
5048 gboolean do_xfer = TRUE;
5049 XferMsgsHelper *helper;
5051 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5052 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5053 g_return_if_fail (TNY_IS_LIST (headers));
5055 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5056 headers, TNY_FOLDER (dst_folder),
5057 TRUE, &need_connection,
5060 /* If we don't want to transfer just return */
5064 /* Create the helper */
5065 helper = g_slice_new (XferMsgsHelper);
5066 helper->dst_folder = g_object_ref (dst_folder);
5067 helper->headers = g_object_ref (headers);
5069 if (need_connection) {
5070 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5071 connect_info->callback = xfer_messages_performer;
5072 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5073 connect_info->data = helper;
5075 modest_platform_double_connect_and_perform(win, TRUE,
5076 TNY_FOLDER_STORE (src_folder),
5079 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5080 xfer_messages_performer (FALSE, NULL, win,
5081 src_account, helper);
5082 g_object_unref (src_account);
5087 * UI handler for the "Move to" action when invoked from the
5088 * ModestMsgViewWindow
5091 modest_ui_actions_on_window_move_to (GtkAction *action,
5093 TnyFolderStore *dst_folder,
5096 TnyFolder *src_folder = NULL;
5098 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5101 TnyHeader *header = NULL;
5104 iter = tny_list_create_iterator (headers);
5105 header = (TnyHeader *) tny_iterator_get_current (iter);
5106 src_folder = tny_header_get_folder (header);
5108 /* Transfer the messages */
5109 modest_ui_actions_transfer_messages_helper (win, src_folder,
5111 TNY_FOLDER (dst_folder));
5114 g_object_unref (header);
5115 g_object_unref (iter);
5116 g_object_unref (src_folder);
5121 modest_ui_actions_on_move_to (GtkAction *action,
5124 modest_ui_actions_on_edit_mode_move_to (win);
5128 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5130 GtkWidget *dialog = NULL;
5131 GtkWindow *toplevel = NULL;
5132 MoveToInfo *helper = NULL;
5133 TnyList *list_to_move;
5135 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5138 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5143 if (tny_list_get_length (list_to_move) < 1) {
5144 g_object_unref (list_to_move);
5148 /* Create and run the dialog */
5149 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5150 dialog = create_move_to_dialog (toplevel, NULL, list_to_move);
5151 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5152 GTK_WINDOW (dialog),
5156 helper = g_slice_new0 (MoveToInfo);
5157 helper->list = list_to_move;
5160 /* Listen to response signal */
5161 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5163 /* Show the dialog */
5164 gtk_widget_show (dialog);
5170 * Calls #HeadersFunc for each header already selected in the main
5171 * window or the message currently being shown in the msg view window
5174 do_headers_action (ModestWindow *win,
5178 TnyList *headers_list = NULL;
5179 TnyIterator *iter = NULL;
5180 TnyHeader *header = NULL;
5181 TnyFolder *folder = NULL;
5184 headers_list = get_selected_headers (win);
5188 /* Get the folder */
5189 iter = tny_list_create_iterator (headers_list);
5190 header = TNY_HEADER (tny_iterator_get_current (iter));
5192 folder = tny_header_get_folder (header);
5193 g_object_unref (header);
5196 /* Call the function for each header */
5197 while (!tny_iterator_is_done (iter)) {
5198 header = TNY_HEADER (tny_iterator_get_current (iter));
5199 func (header, win, user_data);
5200 g_object_unref (header);
5201 tny_iterator_next (iter);
5204 /* Trick: do a poke status in order to speed up the signaling
5207 tny_folder_poke_status (folder);
5208 g_object_unref (folder);
5212 g_object_unref (iter);
5213 g_object_unref (headers_list);
5217 modest_ui_actions_view_attachment (GtkAction *action,
5218 ModestWindow *window)
5220 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5221 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5223 /* not supported window for this action */
5224 g_return_if_reached ();
5229 modest_ui_actions_save_attachments (GtkAction *action,
5230 ModestWindow *window)
5232 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5234 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5237 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5239 /* not supported window for this action */
5240 g_return_if_reached ();
5245 modest_ui_actions_remove_attachments (GtkAction *action,
5246 ModestWindow *window)
5248 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5249 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5251 /* not supported window for this action */
5252 g_return_if_reached ();
5257 modest_ui_actions_on_settings (GtkAction *action,
5261 GtkWindow *toplevel;
5263 dialog = modest_platform_get_global_settings_dialog ();
5264 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5265 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5266 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5267 gtk_widget_show_all (dialog);
5269 gtk_dialog_run (GTK_DIALOG (dialog));
5271 gtk_widget_destroy (dialog);
5275 modest_ui_actions_on_help (GtkAction *action,
5278 /* Help app is not available at all in fremantle */
5279 #ifndef MODEST_TOOLKIT_HILDON2
5280 const gchar *help_id;
5282 g_return_if_fail (win && GTK_IS_WINDOW(win));
5284 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5287 modest_platform_show_help (win, help_id);
5292 modest_ui_actions_on_csm_help (GtkAction *action,
5295 /* Help app is not available at all in fremantle */
5299 retrieve_contents_cb (ModestMailOperation *mail_op,
5306 /* We only need this callback to show an error in case of
5307 memory low condition */
5308 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5309 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5314 retrieve_msg_contents_performer (gboolean canceled,
5316 ModestWindow *parent_window,
5317 TnyAccount *account,
5320 ModestMailOperation *mail_op;
5321 TnyList *headers = TNY_LIST (user_data);
5323 if (err || canceled) {
5324 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5325 (GtkWidget *) parent_window, err,
5330 /* Create mail operation */
5331 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5332 modest_ui_actions_disk_operations_error_handler,
5334 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5335 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5338 g_object_unref (mail_op);
5340 g_object_unref (headers);
5341 g_object_unref (account);
5345 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5346 ModestWindow *window)
5348 TnyList *headers = NULL;
5349 TnyAccount *account = NULL;
5350 TnyIterator *iter = NULL;
5351 TnyHeader *header = NULL;
5352 TnyFolder *folder = NULL;
5355 headers = get_selected_headers (window);
5359 /* Pick the account */
5360 iter = tny_list_create_iterator (headers);
5361 header = TNY_HEADER (tny_iterator_get_current (iter));
5362 folder = tny_header_get_folder (header);
5363 account = tny_folder_get_account (folder);
5364 g_object_unref (folder);
5365 g_object_unref (header);
5366 g_object_unref (iter);
5368 /* Connect and perform the message retrieval */
5369 modest_platform_connect_and_perform (window, TRUE,
5370 g_object_ref (account),
5371 retrieve_msg_contents_performer,
5372 g_object_ref (headers));
5375 g_object_unref (account);
5376 g_object_unref (headers);
5380 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5382 g_return_if_fail (MODEST_IS_WINDOW (window));
5385 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5389 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5391 g_return_if_fail (MODEST_IS_WINDOW (window));
5394 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5398 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5399 ModestWindow *window)
5401 g_return_if_fail (MODEST_IS_WINDOW (window));
5404 modest_ui_actions_check_menu_dimming_rules (window);
5408 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5409 ModestWindow *window)
5411 g_return_if_fail (MODEST_IS_WINDOW (window));
5414 modest_ui_actions_check_menu_dimming_rules (window);
5418 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5419 ModestWindow *window)
5421 g_return_if_fail (MODEST_IS_WINDOW (window));
5424 modest_ui_actions_check_menu_dimming_rules (window);
5428 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5429 ModestWindow *window)
5431 g_return_if_fail (MODEST_IS_WINDOW (window));
5434 modest_ui_actions_check_menu_dimming_rules (window);
5438 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5439 ModestWindow *window)
5441 g_return_if_fail (MODEST_IS_WINDOW (window));
5444 modest_ui_actions_check_menu_dimming_rules (window);
5448 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5449 ModestWindow *window)
5451 g_return_if_fail (MODEST_IS_WINDOW (window));
5454 modest_ui_actions_check_menu_dimming_rules (window);
5458 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5459 ModestWindow *window)
5461 g_return_if_fail (MODEST_IS_WINDOW (window));
5464 modest_ui_actions_check_menu_dimming_rules (window);
5468 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5469 ModestWindow *window)
5471 g_return_if_fail (MODEST_IS_WINDOW (window));
5474 modest_ui_actions_check_menu_dimming_rules (window);
5478 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5479 ModestWindow *window)
5481 g_return_if_fail (MODEST_IS_WINDOW (window));
5484 modest_ui_actions_check_menu_dimming_rules (window);
5488 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5490 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
5492 g_return_if_fail (MODEST_IS_WINDOW (window));
5494 /* we check for low-mem; in that case, show a warning, and don't allow
5497 if (modest_platform_check_memory_low (window, TRUE))
5500 modest_platform_show_search_messages (toplevel);
5504 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5506 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5508 g_return_if_fail (MODEST_IS_WINDOW (win));
5510 /* we check for low-mem; in that case, show a warning, and don't allow
5511 * for the addressbook
5513 if (modest_platform_check_memory_low (win, TRUE))
5516 modest_platform_show_addressbook (toplevel);
5521 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5522 ModestWindow *window)
5525 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5527 if (GTK_IS_TOGGLE_ACTION (action))
5528 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5532 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5538 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5544 const gchar* server_name = NULL;
5545 TnyTransportAccount *transport;
5546 gchar *message = NULL;
5547 ModestProtocol *protocol;
5549 /* Don't show anything if the user cancelled something or the
5550 * send receive request is not interactive. Authentication
5551 * errors are managed by the account store so no need to show
5552 * a dialog here again */
5553 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5554 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5555 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5559 /* Get the server name. Note that we could be using a
5560 connection specific transport account */
5561 transport = (TnyTransportAccount *)
5562 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5564 ModestTnyAccountStore *acc_store;
5565 const gchar *acc_name;
5566 TnyTransportAccount *conn_specific;
5568 acc_store = modest_runtime_get_account_store();
5569 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5570 conn_specific = (TnyTransportAccount *)
5571 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5572 if (conn_specific) {
5573 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5574 g_object_unref (conn_specific);
5576 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5578 g_object_unref (transport);
5582 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5583 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5584 tny_account_get_proto (TNY_ACCOUNT (transport)));
5586 g_warning ("%s: Account with no proto", __FUNCTION__);
5590 /* Show the appropriate message text for the GError: */
5591 switch (err->code) {
5592 case TNY_SERVICE_ERROR_CONNECT:
5593 message = modest_protocol_get_translation (protocol,
5594 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5597 case TNY_SERVICE_ERROR_SEND:
5598 message = g_strdup (_CS_UNABLE_TO_SEND);
5600 case TNY_SERVICE_ERROR_UNAVAILABLE:
5601 message = modest_protocol_get_translation (protocol,
5602 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5606 g_warning ("%s: unexpected ERROR %d",
5607 __FUNCTION__, err->code);
5608 message = g_strdup (_CS_UNABLE_TO_SEND);
5612 modest_platform_run_information_dialog (NULL, message, FALSE);
5617 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5622 ModestWindow *top_window = NULL;
5623 ModestWindowMgr *mgr = NULL;
5624 GtkWidget *header_view = NULL;
5625 TnyFolder *selected_folder = NULL;
5626 TnyFolderType folder_type;
5628 mgr = modest_runtime_get_window_mgr ();
5629 top_window = modest_window_mgr_get_current_top (mgr);
5634 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5635 header_view = (GtkWidget *)
5636 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5639 /* Get selected folder */
5641 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5642 if (!selected_folder)
5645 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5646 #if GTK_CHECK_VERSION(2, 8, 0)
5647 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5648 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5649 GtkTreeViewColumn *tree_column;
5651 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5652 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5654 gtk_tree_view_column_queue_resize (tree_column);
5656 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5657 gtk_widget_queue_draw (header_view);
5660 #ifndef MODEST_TOOLKIT_HILDON2
5661 /* Rerun dimming rules, because the message could become deletable for example */
5662 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5663 MODEST_DIMMING_RULES_TOOLBAR);
5664 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5665 MODEST_DIMMING_RULES_MENU);
5669 g_object_unref (selected_folder);
5673 modest_ui_actions_on_account_connection_error (ModestWindow *parent_window,
5674 TnyAccount *account)
5676 ModestProtocolType protocol_type;
5677 ModestProtocol *protocol;
5678 gchar *error_note = NULL;
5680 protocol_type = modest_tny_account_get_protocol_type (account);
5681 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5684 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5685 if (error_note == NULL) {
5686 g_warning ("%s: This should not be reached", __FUNCTION__);
5688 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
5689 modest_platform_run_information_dialog (toplevel, error_note, FALSE);
5690 g_free (error_note);
5695 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5699 TnyFolderStore *folder = NULL;
5700 TnyAccount *account = NULL;
5701 ModestProtocolType proto;
5702 ModestProtocol *protocol;
5703 TnyHeader *header = NULL;
5705 if (MODEST_IS_HEADER_WINDOW (win)) {
5706 GtkWidget *header_view;
5707 TnyList* headers = NULL;
5709 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5710 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5711 if (!headers || tny_list_get_length (headers) == 0) {
5713 g_object_unref (headers);
5716 iter = tny_list_create_iterator (headers);
5717 header = TNY_HEADER (tny_iterator_get_current (iter));
5719 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5721 g_warning ("List should contain headers");
5723 g_object_unref (iter);
5724 g_object_unref (headers);
5725 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5726 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5728 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5731 if (!header || !folder)
5734 /* Get the account type */
5735 account = tny_folder_get_account (TNY_FOLDER (folder));
5736 proto = modest_tny_account_get_protocol_type (account);
5737 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5740 subject = tny_header_dup_subject (header);
5741 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5745 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5751 g_object_unref (account);
5753 g_object_unref (folder);
5755 g_object_unref (header);
5761 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5762 const gchar *account_name,
5763 const gchar *account_title)
5765 ModestAccountMgr *account_mgr;
5768 ModestProtocol *protocol;
5769 gboolean removed = FALSE;
5771 g_return_val_if_fail (account_name, FALSE);
5772 g_return_val_if_fail (account_title, FALSE);
5774 account_mgr = modest_runtime_get_account_mgr();
5776 /* The warning text depends on the account type: */
5777 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5778 modest_account_mgr_get_store_protocol (account_mgr,
5780 txt = modest_protocol_get_translation (protocol,
5781 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5784 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5786 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5790 if (response == GTK_RESPONSE_OK) {
5791 /* Remove account. If it succeeds then it also removes
5792 the account from the ModestAccountView: */
5793 gboolean is_default = FALSE;
5794 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5795 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5797 g_free (default_account_name);
5799 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5801 #ifdef MODEST_TOOLKIT_HILDON2
5802 hildon_gtk_window_take_screenshot (parent_window, FALSE);
5804 /* Close all email notifications, we cannot
5805 distinguish if the notification belongs to
5806 this account or not, so for safety reasons
5807 we remove them all */
5808 modest_platform_remove_new_mail_notifications (FALSE);
5810 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5817 on_fetch_images_performer (gboolean canceled,
5819 ModestWindow *parent_window,
5820 TnyAccount *account,
5823 if (err || canceled) {
5824 /* Show an unable to retrieve images ??? */
5828 /* Note that the user could have closed the window while connecting */
5829 if (GTK_WIDGET_VISIBLE (parent_window))
5830 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5831 g_object_unref ((GObject *) user_data);
5835 modest_ui_actions_on_fetch_images (GtkAction *action,
5836 ModestWindow *window)
5838 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5840 modest_platform_connect_and_perform (window, TRUE,
5842 on_fetch_images_performer,
5843 g_object_ref (window));
5847 modest_ui_actions_on_reload_message (const gchar *msg_id)
5849 ModestWindow *window = NULL;
5851 g_return_if_fail (msg_id && msg_id[0] != '\0');
5852 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5858 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5861 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5864 /** Check whether any connections are active, and cancel them if
5866 * Returns TRUE is there was no problem,
5867 * or if an operation was cancelled so we can continue.
5868 * Returns FALSE if the user chose to cancel his request instead.
5872 modest_ui_actions_check_for_active_account (ModestWindow *self,
5873 const gchar* account_name)
5875 ModestTnySendQueue *send_queue;
5876 ModestTnyAccountStore *acc_store;
5877 ModestMailOperationQueue* queue;
5878 TnyConnectionStatus store_conn_status;
5879 TnyAccount *store_account = NULL, *transport_account = NULL;
5880 gboolean retval = TRUE, sending = FALSE;
5882 acc_store = modest_runtime_get_account_store ();
5883 queue = modest_runtime_get_mail_operation_queue ();
5886 modest_tny_account_store_get_server_account (acc_store,
5888 TNY_ACCOUNT_TYPE_STORE);
5890 /* This could happen if the account was deleted before the
5891 call to this function */
5896 modest_tny_account_store_get_server_account (acc_store,
5898 TNY_ACCOUNT_TYPE_TRANSPORT);
5900 /* This could happen if the account was deleted before the
5901 call to this function */
5902 if (!transport_account) {
5903 g_object_unref (store_account);
5907 /* If the transport account was not used yet, then the send
5908 queue could not exist (it's created on demand) */
5909 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5910 if (TNY_IS_SEND_QUEUE (send_queue))
5911 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5913 store_conn_status = tny_account_get_connection_status (store_account);
5914 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5916 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) self);
5918 response = modest_platform_run_confirmation_dialog (toplevel,
5919 _("emev_nc_disconnect_account"));
5920 if (response == GTK_RESPONSE_OK) {
5929 /* FIXME: We should only cancel those of this account */
5930 modest_mail_operation_queue_cancel_all (queue);
5932 /* Also disconnect the account */
5933 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5934 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5935 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5939 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5945 g_object_unref (store_account);
5946 g_object_unref (transport_account);