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;
3456 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3458 if (MODEST_IS_FOLDER_WINDOW (window)) {
3459 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3466 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3471 /* Show an error if it's an account */
3472 if (!TNY_IS_FOLDER (folder)) {
3473 modest_platform_run_information_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3474 _("mail_in_ui_folder_delete_error"),
3476 g_object_unref (G_OBJECT (folder));
3481 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3482 tny_folder_get_name (TNY_FOLDER (folder)));
3483 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3484 (const gchar *) message);
3487 if (response == GTK_RESPONSE_OK) {
3488 TnyAccount *account = NULL;
3489 DeleteFolderInfo *info = NULL;
3490 info = g_new0(DeleteFolderInfo, 1);
3491 info->folder = g_object_ref (folder);
3492 info->move_to_trash = move_to_trash;
3494 account = tny_folder_get_account (TNY_FOLDER (folder));
3495 modest_platform_connect_if_remote_and_perform (window,
3497 TNY_FOLDER_STORE (account),
3498 on_delete_folder_cb, info);
3499 g_object_unref (account);
3500 g_object_unref (folder);
3508 modest_ui_actions_on_delete_folder (GtkAction *action,
3509 ModestWindow *window)
3511 modest_ui_actions_on_edit_mode_delete_folder (window);
3515 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3517 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3519 return delete_folder (window, FALSE);
3523 typedef struct _PasswordDialogFields {
3524 GtkWidget *username;
3525 GtkWidget *password;
3527 } PasswordDialogFields;
3530 password_dialog_check_field (GtkEditable *editable,
3531 PasswordDialogFields *fields)
3534 gboolean any_value_empty = FALSE;
3536 value = modest_entry_get_text (fields->username);
3537 if ((value == NULL) || value[0] == '\0') {
3538 any_value_empty = TRUE;
3540 value = modest_entry_get_text (fields->password);
3541 if ((value == NULL) || value[0] == '\0') {
3542 any_value_empty = TRUE;
3544 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3548 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3549 const gchar* server_account_name,
3554 ModestMainWindow *main_window)
3556 g_return_if_fail(server_account_name);
3557 gboolean completed = FALSE;
3558 PasswordDialogFields *fields = NULL;
3560 /* Initalize output parameters: */
3567 #ifndef MODEST_TOOLKIT_GTK
3568 /* Maemo uses a different (awkward) button order,
3569 * It should probably just use gtk_alternative_dialog_button_order ().
3571 #ifdef MODEST_TOOLKIT_HILDON2
3573 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3577 GTK_RESPONSE_ACCEPT,
3579 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3580 HILDON_MARGIN_DOUBLE);
3583 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3586 _("mcen_bd_dialog_ok"),
3587 GTK_RESPONSE_ACCEPT,
3588 _("mcen_bd_dialog_cancel"),
3589 GTK_RESPONSE_REJECT,
3591 #endif /* MODEST_TOOLKIT_HILDON2 */
3594 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3598 GTK_RESPONSE_REJECT,
3600 GTK_RESPONSE_ACCEPT,
3602 #endif /* MODEST_TOOLKIT_GTK */
3604 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3606 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3607 modest_runtime_get_account_mgr(), server_account_name);
3608 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3609 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3612 gtk_widget_destroy (dialog);
3616 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3617 GtkWidget *label = gtk_label_new (txt);
3618 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3620 g_free (server_name);
3621 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3626 gchar *initial_username = modest_account_mgr_get_server_account_username (
3627 modest_runtime_get_account_mgr(), server_account_name);
3629 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3630 if (initial_username)
3631 modest_entry_set_text (entry_username, initial_username);
3633 /* Dim this if a connection has ever succeeded with this username,
3634 * as per the UI spec: */
3635 /* const gboolean username_known = */
3636 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3637 /* modest_runtime_get_account_mgr(), server_account_name); */
3638 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3640 /* We drop the username sensitive code and disallow changing it here
3641 * as tinymail does not support really changing the username in the callback
3643 gtk_widget_set_sensitive (entry_username, FALSE);
3645 /* Auto-capitalization is the default, so let's turn it off: */
3646 #ifdef MAEMO_CHANGES
3647 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3650 /* Create a size group to be used by all captions.
3651 * Note that HildonCaption does not create a default size group if we do not specify one.
3652 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3653 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3655 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3656 _("mail_fi_username"), FALSE,
3658 gtk_widget_show (entry_username);
3659 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3660 FALSE, FALSE, MODEST_MARGIN_HALF);
3661 gtk_widget_show (caption);
3664 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3665 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3666 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3668 /* Auto-capitalization is the default, so let's turn it off: */
3669 #ifdef MAEMO_CHANGES
3670 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3671 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3674 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3675 _("mail_fi_password"), FALSE,
3677 gtk_widget_show (entry_password);
3678 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3679 FALSE, FALSE, MODEST_MARGIN_HALF);
3680 gtk_widget_show (caption);
3681 g_object_unref (sizegroup);
3683 if (initial_username != NULL)
3684 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3686 /* This is not in the Maemo UI spec:
3687 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3688 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3692 fields = g_slice_new0 (PasswordDialogFields);
3693 fields->username = entry_username;
3694 fields->password = entry_password;
3695 fields->dialog = dialog;
3697 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3698 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3699 password_dialog_check_field (NULL, fields);
3701 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3703 while (!completed) {
3705 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3707 *username = g_strdup (modest_entry_get_text (entry_username));
3709 /* Note that an empty field becomes the "" string */
3710 if (*username && strlen (*username) > 0) {
3711 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3712 server_account_name,
3716 const gboolean username_was_changed =
3717 (strcmp (*username, initial_username) != 0);
3718 if (username_was_changed) {
3719 g_warning ("%s: tinymail does not yet support changing the "
3720 "username in the get_password() callback.\n", __FUNCTION__);
3726 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3727 _("mcen_ib_username_pw_incorrect"));
3733 *password = g_strdup (modest_entry_get_text (entry_password));
3735 /* We do not save the password in the configuration,
3736 * because this function is only called for passwords that should
3737 * not be remembered:
3738 modest_server_account_set_password (
3739 modest_runtime_get_account_mgr(), server_account_name,
3756 /* This is not in the Maemo UI spec:
3757 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3763 g_free (initial_username);
3764 gtk_widget_destroy (dialog);
3765 g_slice_free (PasswordDialogFields, fields);
3767 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3771 modest_ui_actions_on_cut (GtkAction *action,
3772 ModestWindow *window)
3774 GtkWidget *focused_widget;
3775 GtkClipboard *clipboard;
3777 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3778 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3779 if (GTK_IS_EDITABLE (focused_widget)) {
3780 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3781 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3782 gtk_clipboard_store (clipboard);
3783 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3784 GtkTextBuffer *buffer;
3786 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3787 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3788 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3789 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3790 gtk_clipboard_store (clipboard);
3792 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3793 TnyList *header_list = modest_header_view_get_selected_headers (
3794 MODEST_HEADER_VIEW (focused_widget));
3795 gboolean continue_download = FALSE;
3796 gint num_of_unc_msgs;
3798 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3800 if (num_of_unc_msgs) {
3801 TnyAccount *account = get_account_from_header_list (header_list);
3803 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3804 g_object_unref (account);
3808 if (num_of_unc_msgs == 0 || continue_download) {
3809 /* modest_platform_information_banner (
3810 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3811 modest_header_view_cut_selection (
3812 MODEST_HEADER_VIEW (focused_widget));
3815 g_object_unref (header_list);
3816 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3817 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3822 modest_ui_actions_on_copy (GtkAction *action,
3823 ModestWindow *window)
3825 GtkClipboard *clipboard;
3826 GtkWidget *focused_widget;
3827 gboolean copied = TRUE;
3829 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3830 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3832 if (GTK_IS_LABEL (focused_widget)) {
3834 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3835 gtk_clipboard_set_text (clipboard, selection, -1);
3837 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3838 gtk_clipboard_store (clipboard);
3839 } else if (GTK_IS_EDITABLE (focused_widget)) {
3840 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3841 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3842 gtk_clipboard_store (clipboard);
3843 } else if (GTK_IS_HTML (focused_widget)) {
3846 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3847 if ((sel == NULL) || (sel[0] == '\0')) {
3850 gtk_html_copy (GTK_HTML (focused_widget));
3851 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3852 gtk_clipboard_store (clipboard);
3854 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3855 GtkTextBuffer *buffer;
3856 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3857 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3858 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3859 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3860 gtk_clipboard_store (clipboard);
3862 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3863 TnyList *header_list = modest_header_view_get_selected_headers (
3864 MODEST_HEADER_VIEW (focused_widget));
3865 gboolean continue_download = FALSE;
3866 gint num_of_unc_msgs;
3868 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3870 if (num_of_unc_msgs) {
3871 TnyAccount *account = get_account_from_header_list (header_list);
3873 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3874 g_object_unref (account);
3878 if (num_of_unc_msgs == 0 || continue_download) {
3879 modest_platform_information_banner (
3880 NULL, NULL, _CS_GETTING_ITEMS);
3881 modest_header_view_copy_selection (
3882 MODEST_HEADER_VIEW (focused_widget));
3886 g_object_unref (header_list);
3888 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3889 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3892 /* Show information banner if there was a copy to clipboard */
3894 modest_platform_information_banner (
3895 NULL, NULL, _CS_COPIED);
3899 modest_ui_actions_on_undo (GtkAction *action,
3900 ModestWindow *window)
3902 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3903 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3905 g_return_if_reached ();
3910 modest_ui_actions_on_redo (GtkAction *action,
3911 ModestWindow *window)
3913 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3914 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3917 g_return_if_reached ();
3923 destroy_information_note (ModestMailOperation *mail_op,
3926 /* destroy information note */
3927 gtk_widget_destroy (GTK_WIDGET(user_data));
3931 destroy_folder_information_note (ModestMailOperation *mail_op,
3932 TnyFolder *new_folder,
3935 /* destroy information note */
3936 gtk_widget_destroy (GTK_WIDGET(user_data));
3941 paste_as_attachment_free (gpointer data)
3943 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3945 if (helper->banner) {
3946 gtk_widget_destroy (helper->banner);
3947 g_object_unref (helper->banner);
3953 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3958 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3959 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3964 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3969 modest_ui_actions_on_paste (GtkAction *action,
3970 ModestWindow *window)
3972 GtkWidget *focused_widget = NULL;
3973 GtkWidget *inf_note = NULL;
3974 ModestMailOperation *mail_op = NULL;
3976 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
3977 if (GTK_IS_EDITABLE (focused_widget)) {
3978 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3979 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3980 ModestEmailClipboard *e_clipboard = NULL;
3981 e_clipboard = modest_runtime_get_email_clipboard ();
3982 if (modest_email_clipboard_cleared (e_clipboard)) {
3983 GtkTextBuffer *buffer;
3984 GtkClipboard *clipboard;
3986 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3987 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3988 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3989 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3990 ModestMailOperation *mail_op;
3991 TnyFolder *src_folder = NULL;
3992 TnyList *data = NULL;
3994 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3995 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3996 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3998 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3999 mail_op = modest_mail_operation_new (G_OBJECT (window));
4000 if (helper->banner != NULL) {
4001 g_object_ref (G_OBJECT (helper->banner));
4002 gtk_widget_show (GTK_WIDGET (helper->banner));
4006 modest_mail_operation_get_msgs_full (mail_op,
4008 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4010 paste_as_attachment_free);
4014 g_object_unref (data);
4016 g_object_unref (src_folder);
4019 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4020 ModestEmailClipboard *clipboard = NULL;
4021 TnyFolder *src_folder = NULL;
4022 TnyFolderStore *folder_store = NULL;
4023 TnyList *data = NULL;
4024 gboolean delete = FALSE;
4026 /* Check clipboard source */
4027 clipboard = modest_runtime_get_email_clipboard ();
4028 if (modest_email_clipboard_cleared (clipboard))
4031 /* Get elements to paste */
4032 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4034 /* Create a new mail operation */
4035 mail_op = modest_mail_operation_new (G_OBJECT(window));
4037 /* Get destination folder */
4038 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4040 /* transfer messages */
4044 /* Ask for user confirmation */
4046 modest_ui_actions_msgs_move_to_confirmation (window,
4047 TNY_FOLDER (folder_store),
4051 if (response == GTK_RESPONSE_OK) {
4052 /* Launch notification */
4053 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4055 if (inf_note != NULL) {
4056 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4057 gtk_widget_show (GTK_WIDGET(inf_note));
4060 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4061 modest_mail_operation_xfer_msgs (mail_op,
4063 TNY_FOLDER (folder_store),
4065 destroy_information_note,
4068 g_object_unref (mail_op);
4071 } else if (src_folder != NULL) {
4072 /* Launch notification */
4073 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4075 if (inf_note != NULL) {
4076 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4077 gtk_widget_show (GTK_WIDGET(inf_note));
4080 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4081 modest_mail_operation_xfer_folder (mail_op,
4085 destroy_folder_information_note,
4091 g_object_unref (data);
4092 if (src_folder != NULL)
4093 g_object_unref (src_folder);
4094 if (folder_store != NULL)
4095 g_object_unref (folder_store);
4101 modest_ui_actions_on_select_all (GtkAction *action,
4102 ModestWindow *window)
4104 GtkWidget *focused_widget;
4106 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4107 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4108 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4109 } else if (GTK_IS_LABEL (focused_widget)) {
4110 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4111 } else if (GTK_IS_EDITABLE (focused_widget)) {
4112 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4113 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4114 GtkTextBuffer *buffer;
4115 GtkTextIter start, end;
4117 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4118 gtk_text_buffer_get_start_iter (buffer, &start);
4119 gtk_text_buffer_get_end_iter (buffer, &end);
4120 gtk_text_buffer_select_range (buffer, &start, &end);
4121 } else if (GTK_IS_HTML (focused_widget)) {
4122 gtk_html_select_all (GTK_HTML (focused_widget));
4128 modest_ui_actions_on_mark_as_read (GtkAction *action,
4129 ModestWindow *window)
4131 g_return_if_fail (MODEST_IS_WINDOW(window));
4133 /* Mark each header as read */
4134 do_headers_action (window, headers_action_mark_as_read, NULL);
4138 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4139 ModestWindow *window)
4141 g_return_if_fail (MODEST_IS_WINDOW(window));
4143 /* Mark each header as read */
4144 do_headers_action (window, headers_action_mark_as_unread, NULL);
4148 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4149 GtkRadioAction *selected,
4150 ModestWindow *window)
4154 value = gtk_radio_action_get_current_value (selected);
4155 if (MODEST_IS_WINDOW (window)) {
4156 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4161 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4162 GtkRadioAction *selected,
4163 ModestWindow *window)
4165 TnyHeaderFlags flags;
4166 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4168 flags = gtk_radio_action_get_current_value (selected);
4169 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4173 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4174 GtkRadioAction *selected,
4175 ModestWindow *window)
4179 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4181 file_format = gtk_radio_action_get_current_value (selected);
4182 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4187 modest_ui_actions_on_zoom_plus (GtkAction *action,
4188 ModestWindow *window)
4190 g_return_if_fail (MODEST_IS_WINDOW (window));
4192 modest_window_zoom_plus (MODEST_WINDOW (window));
4196 modest_ui_actions_on_zoom_minus (GtkAction *action,
4197 ModestWindow *window)
4199 g_return_if_fail (MODEST_IS_WINDOW (window));
4201 modest_window_zoom_minus (MODEST_WINDOW (window));
4205 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4206 ModestWindow *window)
4208 ModestWindowMgr *mgr;
4209 gboolean fullscreen, active;
4210 g_return_if_fail (MODEST_IS_WINDOW (window));
4212 mgr = modest_runtime_get_window_mgr ();
4214 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4215 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4217 if (active != fullscreen) {
4218 modest_window_mgr_set_fullscreen_mode (mgr, active);
4219 #ifndef MODEST_TOOLKIT_HILDON2
4220 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4221 gtk_window_present (toplevel);
4227 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4228 ModestWindow *window)
4230 ModestWindowMgr *mgr;
4231 gboolean fullscreen;
4233 g_return_if_fail (MODEST_IS_WINDOW (window));
4235 mgr = modest_runtime_get_window_mgr ();
4236 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4237 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4242 * Used by modest_ui_actions_on_details to call do_headers_action
4245 headers_action_show_details (TnyHeader *header,
4246 ModestWindow *window,
4250 gboolean async_retrieval;
4251 GtkWindow *toplevel;
4254 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4255 async_retrieval = TRUE;
4256 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4257 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4259 async_retrieval = FALSE;
4261 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4262 modest_platform_run_header_details_dialog (toplevel, header, async_retrieval, msg);
4264 g_object_unref (msg);
4268 * Show the header details in a ModestDetailsDialog widget
4271 modest_ui_actions_on_details (GtkAction *action,
4274 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4278 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4282 header = tny_msg_get_header (msg);
4284 headers_action_show_details (header, win, NULL);
4285 g_object_unref (header);
4287 g_object_unref (msg);
4288 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4290 GtkWidget *header_view;
4292 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4293 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4295 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4297 modest_platform_run_folder_details_dialog (toplevel, folder);
4298 g_object_unref (folder);
4304 modest_ui_actions_on_limit_error (GtkAction *action,
4307 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4309 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS_MAXIMUM_CHARACTERS_REACHED);
4314 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4315 ModestMsgEditWindow *window)
4317 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4319 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4323 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4324 ModestMsgEditWindow *window)
4326 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4328 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4333 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4334 ModestWindow *window)
4336 gboolean active, fullscreen = FALSE;
4337 ModestWindowMgr *mgr;
4339 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4341 /* Check if we want to toggle the toolbar view in fullscreen
4343 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4344 "ViewShowToolbarFullScreen")) {
4348 /* Toggle toolbar */
4349 mgr = modest_runtime_get_window_mgr ();
4350 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4354 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4355 ModestMsgEditWindow *window)
4357 modest_msg_edit_window_select_font (window);
4362 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4363 const gchar *display_name,
4366 /* don't update the display name if it was already set;
4367 * updating the display name apparently is expensive */
4368 const gchar* old_name = gtk_window_get_title (window);
4370 if (display_name == NULL)
4373 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4374 return; /* don't do anything */
4376 /* This is usually used to change the title of the main window, which
4377 * is the one that holds the folder view. Note that this change can
4378 * happen even when the widget doesn't have the focus. */
4379 gtk_window_set_title (window, display_name);
4384 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4387 modest_msg_edit_window_select_contacts (window);
4391 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4393 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4394 modest_msg_edit_window_check_names (window, FALSE);
4399 on_move_to_dialog_response (GtkDialog *dialog,
4403 GtkWidget *parent_win;
4404 MoveToInfo *helper = NULL;
4405 ModestFolderView *folder_view;
4406 gboolean unset_edit_mode = FALSE;
4408 helper = (MoveToInfo *) user_data;
4410 parent_win = (GtkWidget *) helper->win;
4411 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4412 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4414 TnyFolderStore *dst_folder;
4415 TnyFolderStore *selected;
4417 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4418 selected = modest_folder_view_get_selected (folder_view);
4419 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4420 g_object_unref (selected);
4422 case GTK_RESPONSE_NONE:
4423 case GTK_RESPONSE_CANCEL:
4424 case GTK_RESPONSE_DELETE_EVENT:
4426 case GTK_RESPONSE_OK:
4427 dst_folder = modest_folder_view_get_selected (folder_view);
4429 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4430 /* Clean list to move used for filtering */
4431 modest_folder_view_set_list_to_move (folder_view, NULL);
4433 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4436 MODEST_WINDOW (parent_win));
4438 /* if the user selected a root folder
4439 (account) then do not perform any action */
4440 if (TNY_IS_ACCOUNT (dst_folder)) {
4441 g_signal_stop_emission_by_name (dialog, "response");
4445 /* Clean list to move used for filtering */
4446 modest_folder_view_set_list_to_move (folder_view, NULL);
4448 /* Moving from headers window in edit mode */
4449 modest_ui_actions_on_window_move_to (NULL, helper->list,
4451 MODEST_WINDOW (parent_win));
4455 g_object_unref (dst_folder);
4457 unset_edit_mode = TRUE;
4460 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4463 /* Free the helper and exit */
4465 g_object_unref (helper->list);
4466 if (unset_edit_mode) {
4467 #ifdef MODEST_TOOLKIT_HILDON2
4468 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4471 g_slice_free (MoveToInfo, helper);
4472 gtk_widget_destroy (GTK_WIDGET (dialog));
4476 create_move_to_dialog (GtkWindow *win,
4477 GtkWidget *folder_view,
4478 TnyList *list_to_move)
4480 GtkWidget *dialog, *tree_view = NULL;
4482 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4485 /* It could happen that we're trying to move a message from a
4486 window (msg window for example) after the main window was
4487 closed, so we can not just get the model of the folder
4489 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4490 const gchar *visible_id = NULL;
4492 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4493 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4494 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4495 MODEST_FOLDER_VIEW(tree_view));
4498 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4500 /* Show the same account than the one that is shown in the main window */
4501 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4504 const gchar *active_account_name = NULL;
4505 ModestAccountMgr *mgr = NULL;
4506 ModestAccountSettings *settings = NULL;
4507 ModestServerAccountSettings *store_settings = NULL;
4509 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4510 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4511 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4512 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4514 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4515 mgr = modest_runtime_get_account_mgr ();
4516 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4519 const gchar *store_account_name;
4520 store_settings = modest_account_settings_get_store_settings (settings);
4521 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4523 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4524 store_account_name);
4525 g_object_unref (store_settings);
4526 g_object_unref (settings);
4530 /* we keep a pointer to the embedded folder view, so we can
4531 * retrieve it with get_folder_view_from_move_to_dialog (see
4532 * above) later (needed for focus handling)
4534 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4536 /* Hide special folders */
4538 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4540 gtk_widget_show (GTK_WIDGET (tree_view));
4546 * Shows a confirmation dialog to the user when we're moving messages
4547 * from a remote server to the local storage. Returns the dialog
4548 * response. If it's other kind of movement then it always returns
4551 * This one is used by the next functions:
4552 * modest_ui_actions_on_paste - commented out
4553 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4556 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4557 TnyFolder *dest_folder,
4561 gint response = GTK_RESPONSE_OK;
4562 TnyAccount *account = NULL;
4563 TnyFolder *src_folder = NULL;
4564 TnyIterator *iter = NULL;
4565 TnyHeader *header = NULL;
4567 /* return with OK if the destination is a remote folder */
4568 if (modest_tny_folder_is_remote_folder (dest_folder))
4569 return GTK_RESPONSE_OK;
4571 /* Get source folder */
4572 iter = tny_list_create_iterator (headers);
4573 header = TNY_HEADER (tny_iterator_get_current (iter));
4575 src_folder = tny_header_get_folder (header);
4576 g_object_unref (header);
4578 g_object_unref (iter);
4580 /* if no src_folder, message may be an attahcment */
4581 if (src_folder == NULL)
4582 return GTK_RESPONSE_CANCEL;
4584 /* If the source is a local or MMC folder */
4585 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4586 g_object_unref (src_folder);
4587 return GTK_RESPONSE_OK;
4590 /* Get the account */
4591 account = tny_folder_get_account (src_folder);
4593 /* now if offline we ask the user */
4594 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4595 response = GTK_RESPONSE_OK;
4597 response = GTK_RESPONSE_CANCEL;
4600 g_object_unref (src_folder);
4601 g_object_unref (account);
4607 move_to_helper_destroyer (gpointer user_data)
4609 MoveToHelper *helper = (MoveToHelper *) user_data;
4611 /* Close the "Pasting" information banner */
4612 if (helper->banner) {
4613 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4614 g_object_unref (helper->banner);
4616 if (gtk_tree_row_reference_valid (helper->reference)) {
4617 gtk_tree_row_reference_free (helper->reference);
4618 helper->reference = NULL;
4624 move_to_cb (ModestMailOperation *mail_op,
4627 MoveToHelper *helper = (MoveToHelper *) user_data;
4628 GObject *object = modest_mail_operation_get_source (mail_op);
4630 /* Note that the operation could have failed, in that case do
4632 if (modest_mail_operation_get_status (mail_op) !=
4633 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4636 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4637 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4639 if (!modest_msg_view_window_select_next_message (self) &&
4640 !modest_msg_view_window_select_previous_message (self)) {
4641 /* No more messages to view, so close this window */
4642 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4645 g_object_unref (object);
4648 /* Destroy the helper */
4649 move_to_helper_destroyer (helper);
4653 folder_move_to_cb (ModestMailOperation *mail_op,
4654 TnyFolder *new_folder,
4659 object = modest_mail_operation_get_source (mail_op);
4661 move_to_cb (mail_op, user_data);
4666 msgs_move_to_cb (ModestMailOperation *mail_op,
4669 move_to_cb (mail_op, user_data);
4673 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4676 GObject *win = NULL;
4677 const GError *error;
4678 TnyAccount *account = NULL;
4680 win = modest_mail_operation_get_source (mail_op);
4681 error = modest_mail_operation_get_error (mail_op);
4683 if (TNY_IS_FOLDER (user_data))
4684 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4685 else if (TNY_IS_ACCOUNT (user_data))
4686 account = g_object_ref (user_data);
4688 /* If it's not a disk full error then show a generic error */
4689 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4690 (GtkWidget *) win, (GError *) error,
4692 modest_platform_run_information_dialog ((GtkWindow *) win,
4693 _("mail_in_ui_folder_move_target_error"),
4696 g_object_unref (account);
4698 g_object_unref (win);
4703 * Checks if we need a connection to do the transfer and if the user
4704 * wants to connect to complete it
4707 modest_ui_actions_xfer_messages_check (ModestWindow *parent_window,
4708 TnyFolderStore *src_folder,
4710 TnyFolder *dst_folder,
4711 gboolean delete_originals,
4712 gboolean *need_connection,
4715 TnyAccount *src_account;
4716 gint uncached_msgs = 0;
4718 /* We don't need any further check if
4720 * 1- the source folder is local OR
4721 * 2- the device is already online
4723 if (!modest_tny_folder_store_is_remote (src_folder) ||
4724 tny_device_is_online (modest_runtime_get_device())) {
4725 *need_connection = FALSE;
4730 /* We must ask for a connection when
4732 * - the message(s) is not already cached OR
4733 * - the message(s) is cached but the leave_on_server setting
4734 * is FALSE (because we need to sync the source folder to
4735 * delete the message from the server (for IMAP we could do it
4736 * offline, it'll take place the next time we get a
4739 uncached_msgs = header_list_count_uncached_msgs (headers);
4740 src_account = get_account_from_folder_store (src_folder);
4741 if (uncached_msgs > 0) {
4744 GtkWindow *toplevel;
4746 *need_connection = TRUE;
4747 num_headers = tny_list_get_length (headers);
4748 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4749 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
4751 if (modest_platform_run_confirmation_dialog (toplevel, msg) ==
4752 GTK_RESPONSE_CANCEL) {
4758 /* The transfer is possible and the user wants to */
4761 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4762 const gchar *account_name;
4763 gboolean leave_on_server;
4765 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4766 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4769 if (leave_on_server == TRUE) {
4770 *need_connection = FALSE;
4772 *need_connection = TRUE;
4775 *need_connection = FALSE;
4780 g_object_unref (src_account);
4784 xfer_messages_error_handler (ModestMailOperation *mail_op,
4788 const GError *error;
4789 TnyAccount *account;
4791 win = modest_mail_operation_get_source (mail_op);
4792 error = modest_mail_operation_get_error (mail_op);
4794 /* We cannot get the account from the mail op as that is the
4795 source account and for checking memory full conditions we
4796 need the destination one */
4797 account = TNY_ACCOUNT (user_data);
4800 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4801 (GtkWidget *) win, (GError*) error,
4802 account, _KR("cerm_memory_card_full"))) {
4803 modest_platform_run_information_dialog ((GtkWindow *) win,
4804 _("mail_in_ui_folder_move_target_error"),
4808 g_object_unref (win);
4812 TnyFolderStore *dst_folder;
4817 * Utility function that transfer messages from both the main window
4818 * and the msg view window when using the "Move to" dialog
4821 xfer_messages_performer (gboolean canceled,
4823 ModestWindow *parent_window,
4824 TnyAccount *account,
4827 TnyAccount *dst_account = NULL;
4828 gboolean dst_forbids_message_add = FALSE;
4829 XferMsgsHelper *helper;
4830 MoveToHelper *movehelper;
4831 ModestMailOperation *mail_op;
4833 helper = (XferMsgsHelper *) user_data;
4835 if (canceled || err) {
4836 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4837 (GtkWidget *) parent_window, err,
4839 /* Show the proper error message */
4840 modest_ui_actions_on_account_connection_error (parent_window, account);
4845 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4847 /* tinymail will return NULL for local folders it seems */
4848 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4849 modest_tny_account_get_protocol_type (dst_account),
4850 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4852 if (dst_forbids_message_add) {
4853 modest_platform_information_banner (GTK_WIDGET (parent_window),
4855 ngettext("mail_in_ui_folder_move_target_error",
4856 "mail_in_ui_folder_move_targets_error",
4857 tny_list_get_length (helper->headers)));
4861 movehelper = g_new0 (MoveToHelper, 1);
4864 /* Perform the mail operation */
4865 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4866 xfer_messages_error_handler,
4867 g_object_ref (dst_account),
4869 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4872 modest_mail_operation_xfer_msgs (mail_op,
4874 TNY_FOLDER (helper->dst_folder),
4879 g_object_unref (G_OBJECT (mail_op));
4882 g_object_unref (dst_account);
4883 g_object_unref (helper->dst_folder);
4884 g_object_unref (helper->headers);
4885 g_slice_free (XferMsgsHelper, helper);
4889 TnyFolder *src_folder;
4890 TnyFolderStore *dst_folder;
4891 gboolean delete_original;
4892 GtkWidget *folder_view;
4896 on_move_folder_cb (gboolean canceled,
4898 ModestWindow *parent_window,
4899 TnyAccount *account,
4902 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4903 GtkTreeSelection *sel;
4904 ModestMailOperation *mail_op = NULL;
4906 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4907 /* Note that the connection process can fail due to
4908 memory low conditions as it can not successfully
4909 store the summary */
4910 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4911 (GtkWidget*) parent_window, err,
4913 g_debug ("Error connecting when trying to move a folder");
4915 g_object_unref (G_OBJECT (info->src_folder));
4916 g_object_unref (G_OBJECT (info->dst_folder));
4921 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4922 #ifndef MODEST_TOOLKIT_HILDON2
4923 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4925 if (helper->banner != NULL) {
4926 g_object_ref (helper->banner);
4927 gtk_widget_show (GTK_WIDGET(helper->banner));
4930 /* Clean folder on header view before moving it */
4931 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4932 gtk_tree_selection_unselect_all (sel);
4934 /* Let gtk events run. We need that the folder
4935 view frees its reference to the source
4936 folder *before* issuing the mail operation
4937 so we need the signal handler of selection
4938 changed to happen before the mail
4940 while (gtk_events_pending ())
4941 gtk_main_iteration (); */
4944 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4945 modest_ui_actions_move_folder_error_handler,
4946 g_object_ref (info->dst_folder), g_object_unref);
4947 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4950 modest_mail_operation_xfer_folder (mail_op,
4951 TNY_FOLDER (info->src_folder),
4953 info->delete_original,
4956 g_object_unref (G_OBJECT (info->src_folder));
4958 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4961 /* Unref mail operation */
4962 g_object_unref (G_OBJECT (mail_op));
4963 g_object_unref (G_OBJECT (info->dst_folder));
4968 get_account_from_folder_store (TnyFolderStore *folder_store)
4970 if (TNY_IS_ACCOUNT (folder_store))
4971 return g_object_ref (folder_store);
4973 return tny_folder_get_account (TNY_FOLDER (folder_store));
4977 * UI handler for the "Move to" action when invoked from the
4978 * ModestFolderWindow
4981 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4982 TnyFolderStore *dst_folder,
4986 TnyFolderStore *src_folder = NULL;
4987 TnyIterator *iterator;
4989 if (tny_list_get_length (selection) != 1)
4992 iterator = tny_list_create_iterator (selection);
4993 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
4994 g_object_unref (iterator);
4997 gboolean do_xfer = TRUE;
4999 /* Allow only to transfer folders to the local root folder */
5000 if (TNY_IS_ACCOUNT (dst_folder) &&
5001 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5002 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5003 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5007 modest_platform_run_information_dialog (toplevel,
5008 _("mail_in_ui_folder_move_target_error"),
5010 } else if (!TNY_IS_FOLDER (src_folder)) {
5011 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5016 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5017 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5019 info->src_folder = g_object_ref (src_folder);
5020 info->dst_folder = g_object_ref (dst_folder);
5021 info->delete_original = TRUE;
5022 info->folder_view = folder_view;
5024 connect_info->callback = on_move_folder_cb;
5025 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5026 connect_info->data = info;
5028 modest_platform_double_connect_and_perform(win, TRUE,
5029 TNY_FOLDER_STORE (src_folder),
5034 g_object_unref (src_folder);
5039 modest_ui_actions_transfer_messages_helper (ModestWindow *win,
5040 TnyFolder *src_folder,
5042 TnyFolder *dst_folder)
5044 gboolean need_connection = TRUE;
5045 gboolean do_xfer = TRUE;
5046 XferMsgsHelper *helper;
5048 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5049 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5050 g_return_if_fail (TNY_IS_LIST (headers));
5052 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5053 headers, TNY_FOLDER (dst_folder),
5054 TRUE, &need_connection,
5057 /* If we don't want to transfer just return */
5061 /* Create the helper */
5062 helper = g_slice_new (XferMsgsHelper);
5063 helper->dst_folder = g_object_ref (dst_folder);
5064 helper->headers = g_object_ref (headers);
5066 if (need_connection) {
5067 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5068 connect_info->callback = xfer_messages_performer;
5069 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5070 connect_info->data = helper;
5072 modest_platform_double_connect_and_perform(win, TRUE,
5073 TNY_FOLDER_STORE (src_folder),
5076 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5077 xfer_messages_performer (FALSE, NULL, win,
5078 src_account, helper);
5079 g_object_unref (src_account);
5084 * UI handler for the "Move to" action when invoked from the
5085 * ModestMsgViewWindow
5088 modest_ui_actions_on_window_move_to (GtkAction *action,
5090 TnyFolderStore *dst_folder,
5093 TnyFolder *src_folder = NULL;
5095 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5098 TnyHeader *header = NULL;
5101 iter = tny_list_create_iterator (headers);
5102 header = (TnyHeader *) tny_iterator_get_current (iter);
5103 src_folder = tny_header_get_folder (header);
5105 /* Transfer the messages */
5106 modest_ui_actions_transfer_messages_helper (win, src_folder,
5108 TNY_FOLDER (dst_folder));
5111 g_object_unref (header);
5112 g_object_unref (iter);
5113 g_object_unref (src_folder);
5118 modest_ui_actions_on_move_to (GtkAction *action,
5121 modest_ui_actions_on_edit_mode_move_to (win);
5125 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5127 GtkWidget *dialog = NULL;
5128 GtkWindow *toplevel = NULL;
5129 MoveToInfo *helper = NULL;
5130 TnyList *list_to_move;
5132 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5135 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5140 if (tny_list_get_length (list_to_move) < 1) {
5141 g_object_unref (list_to_move);
5145 /* Create and run the dialog */
5146 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5147 dialog = create_move_to_dialog (toplevel, NULL, list_to_move);
5148 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5149 GTK_WINDOW (dialog),
5153 helper = g_slice_new0 (MoveToInfo);
5154 helper->list = list_to_move;
5157 /* Listen to response signal */
5158 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5160 /* Show the dialog */
5161 gtk_widget_show (dialog);
5167 * Calls #HeadersFunc for each header already selected in the main
5168 * window or the message currently being shown in the msg view window
5171 do_headers_action (ModestWindow *win,
5175 TnyList *headers_list = NULL;
5176 TnyIterator *iter = NULL;
5177 TnyHeader *header = NULL;
5178 TnyFolder *folder = NULL;
5181 headers_list = get_selected_headers (win);
5185 /* Get the folder */
5186 iter = tny_list_create_iterator (headers_list);
5187 header = TNY_HEADER (tny_iterator_get_current (iter));
5189 folder = tny_header_get_folder (header);
5190 g_object_unref (header);
5193 /* Call the function for each header */
5194 while (!tny_iterator_is_done (iter)) {
5195 header = TNY_HEADER (tny_iterator_get_current (iter));
5196 func (header, win, user_data);
5197 g_object_unref (header);
5198 tny_iterator_next (iter);
5201 /* Trick: do a poke status in order to speed up the signaling
5204 tny_folder_poke_status (folder);
5205 g_object_unref (folder);
5209 g_object_unref (iter);
5210 g_object_unref (headers_list);
5214 modest_ui_actions_view_attachment (GtkAction *action,
5215 ModestWindow *window)
5217 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5218 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5220 /* not supported window for this action */
5221 g_return_if_reached ();
5226 modest_ui_actions_save_attachments (GtkAction *action,
5227 ModestWindow *window)
5229 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5231 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5234 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5236 /* not supported window for this action */
5237 g_return_if_reached ();
5242 modest_ui_actions_remove_attachments (GtkAction *action,
5243 ModestWindow *window)
5245 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5246 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5248 /* not supported window for this action */
5249 g_return_if_reached ();
5254 modest_ui_actions_on_settings (GtkAction *action,
5258 GtkWindow *toplevel;
5260 dialog = modest_platform_get_global_settings_dialog ();
5261 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5262 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5263 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5264 gtk_widget_show_all (dialog);
5266 gtk_dialog_run (GTK_DIALOG (dialog));
5268 gtk_widget_destroy (dialog);
5272 modest_ui_actions_on_help (GtkAction *action,
5275 /* Help app is not available at all in fremantle */
5276 #ifndef MODEST_TOOLKIT_HILDON2
5277 const gchar *help_id;
5279 g_return_if_fail (win && GTK_IS_WINDOW(win));
5281 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5284 modest_platform_show_help (win, help_id);
5289 modest_ui_actions_on_csm_help (GtkAction *action,
5292 /* Help app is not available at all in fremantle */
5296 retrieve_contents_cb (ModestMailOperation *mail_op,
5303 /* We only need this callback to show an error in case of
5304 memory low condition */
5305 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5306 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5311 retrieve_msg_contents_performer (gboolean canceled,
5313 ModestWindow *parent_window,
5314 TnyAccount *account,
5317 ModestMailOperation *mail_op;
5318 TnyList *headers = TNY_LIST (user_data);
5320 if (err || canceled) {
5321 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5322 (GtkWidget *) parent_window, err,
5327 /* Create mail operation */
5328 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5329 modest_ui_actions_disk_operations_error_handler,
5331 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5332 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5335 g_object_unref (mail_op);
5337 g_object_unref (headers);
5338 g_object_unref (account);
5342 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5343 ModestWindow *window)
5345 TnyList *headers = NULL;
5346 TnyAccount *account = NULL;
5347 TnyIterator *iter = NULL;
5348 TnyHeader *header = NULL;
5349 TnyFolder *folder = NULL;
5352 headers = get_selected_headers (window);
5356 /* Pick the account */
5357 iter = tny_list_create_iterator (headers);
5358 header = TNY_HEADER (tny_iterator_get_current (iter));
5359 folder = tny_header_get_folder (header);
5360 account = tny_folder_get_account (folder);
5361 g_object_unref (folder);
5362 g_object_unref (header);
5363 g_object_unref (iter);
5365 /* Connect and perform the message retrieval */
5366 modest_platform_connect_and_perform (window, TRUE,
5367 g_object_ref (account),
5368 retrieve_msg_contents_performer,
5369 g_object_ref (headers));
5372 g_object_unref (account);
5373 g_object_unref (headers);
5377 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5379 g_return_if_fail (MODEST_IS_WINDOW (window));
5382 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5386 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5388 g_return_if_fail (MODEST_IS_WINDOW (window));
5391 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5395 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5396 ModestWindow *window)
5398 g_return_if_fail (MODEST_IS_WINDOW (window));
5401 modest_ui_actions_check_menu_dimming_rules (window);
5405 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5406 ModestWindow *window)
5408 g_return_if_fail (MODEST_IS_WINDOW (window));
5411 modest_ui_actions_check_menu_dimming_rules (window);
5415 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5416 ModestWindow *window)
5418 g_return_if_fail (MODEST_IS_WINDOW (window));
5421 modest_ui_actions_check_menu_dimming_rules (window);
5425 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5426 ModestWindow *window)
5428 g_return_if_fail (MODEST_IS_WINDOW (window));
5431 modest_ui_actions_check_menu_dimming_rules (window);
5435 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5436 ModestWindow *window)
5438 g_return_if_fail (MODEST_IS_WINDOW (window));
5441 modest_ui_actions_check_menu_dimming_rules (window);
5445 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5446 ModestWindow *window)
5448 g_return_if_fail (MODEST_IS_WINDOW (window));
5451 modest_ui_actions_check_menu_dimming_rules (window);
5455 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5456 ModestWindow *window)
5458 g_return_if_fail (MODEST_IS_WINDOW (window));
5461 modest_ui_actions_check_menu_dimming_rules (window);
5465 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5466 ModestWindow *window)
5468 g_return_if_fail (MODEST_IS_WINDOW (window));
5471 modest_ui_actions_check_menu_dimming_rules (window);
5475 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5476 ModestWindow *window)
5478 g_return_if_fail (MODEST_IS_WINDOW (window));
5481 modest_ui_actions_check_menu_dimming_rules (window);
5485 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5487 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
5489 g_return_if_fail (MODEST_IS_WINDOW (window));
5491 /* we check for low-mem; in that case, show a warning, and don't allow
5494 if (modest_platform_check_memory_low (window, TRUE))
5497 modest_platform_show_search_messages (toplevel);
5501 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5503 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5505 g_return_if_fail (MODEST_IS_WINDOW (win));
5507 /* we check for low-mem; in that case, show a warning, and don't allow
5508 * for the addressbook
5510 if (modest_platform_check_memory_low (win, TRUE))
5513 modest_platform_show_addressbook (toplevel);
5518 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5519 ModestWindow *window)
5522 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5524 if (GTK_IS_TOGGLE_ACTION (action))
5525 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5529 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5535 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5541 const gchar* server_name = NULL;
5542 TnyTransportAccount *transport;
5543 gchar *message = NULL;
5544 ModestProtocol *protocol;
5546 /* Don't show anything if the user cancelled something or the
5547 * send receive request is not interactive. Authentication
5548 * errors are managed by the account store so no need to show
5549 * a dialog here again */
5550 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5551 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5552 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5556 /* Get the server name. Note that we could be using a
5557 connection specific transport account */
5558 transport = (TnyTransportAccount *)
5559 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5561 ModestTnyAccountStore *acc_store;
5562 const gchar *acc_name;
5563 TnyTransportAccount *conn_specific;
5565 acc_store = modest_runtime_get_account_store();
5566 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5567 conn_specific = (TnyTransportAccount *)
5568 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5569 if (conn_specific) {
5570 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5571 g_object_unref (conn_specific);
5573 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5575 g_object_unref (transport);
5579 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5580 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5581 tny_account_get_proto (TNY_ACCOUNT (transport)));
5583 g_warning ("%s: Account with no proto", __FUNCTION__);
5587 /* Show the appropriate message text for the GError: */
5588 switch (err->code) {
5589 case TNY_SERVICE_ERROR_CONNECT:
5590 message = modest_protocol_get_translation (protocol,
5591 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5594 case TNY_SERVICE_ERROR_SEND:
5595 message = g_strdup (_CS_UNABLE_TO_SEND);
5597 case TNY_SERVICE_ERROR_UNAVAILABLE:
5598 message = modest_protocol_get_translation (protocol,
5599 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5603 g_warning ("%s: unexpected ERROR %d",
5604 __FUNCTION__, err->code);
5605 message = g_strdup (_CS_UNABLE_TO_SEND);
5609 modest_platform_run_information_dialog (NULL, message, FALSE);
5614 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5619 ModestWindow *top_window = NULL;
5620 ModestWindowMgr *mgr = NULL;
5621 GtkWidget *header_view = NULL;
5622 TnyFolder *selected_folder = NULL;
5623 TnyFolderType folder_type;
5625 mgr = modest_runtime_get_window_mgr ();
5626 top_window = modest_window_mgr_get_current_top (mgr);
5631 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5632 header_view = (GtkWidget *)
5633 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5636 /* Get selected folder */
5638 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5639 if (!selected_folder)
5642 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5643 #if GTK_CHECK_VERSION(2, 8, 0)
5644 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5645 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5646 GtkTreeViewColumn *tree_column;
5648 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5649 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5651 gtk_tree_view_column_queue_resize (tree_column);
5653 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5654 gtk_widget_queue_draw (header_view);
5657 #ifndef MODEST_TOOLKIT_HILDON2
5658 /* Rerun dimming rules, because the message could become deletable for example */
5659 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5660 MODEST_DIMMING_RULES_TOOLBAR);
5661 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5662 MODEST_DIMMING_RULES_MENU);
5666 g_object_unref (selected_folder);
5670 modest_ui_actions_on_account_connection_error (ModestWindow *parent_window,
5671 TnyAccount *account)
5673 ModestProtocolType protocol_type;
5674 ModestProtocol *protocol;
5675 gchar *error_note = NULL;
5677 protocol_type = modest_tny_account_get_protocol_type (account);
5678 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5681 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5682 if (error_note == NULL) {
5683 g_warning ("%s: This should not be reached", __FUNCTION__);
5685 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
5686 modest_platform_run_information_dialog (toplevel, error_note, FALSE);
5687 g_free (error_note);
5692 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5696 TnyFolderStore *folder = NULL;
5697 TnyAccount *account = NULL;
5698 ModestProtocolType proto;
5699 ModestProtocol *protocol;
5700 TnyHeader *header = NULL;
5702 if (MODEST_IS_HEADER_WINDOW (win)) {
5703 GtkWidget *header_view;
5704 TnyList* headers = NULL;
5706 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5707 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5708 if (!headers || tny_list_get_length (headers) == 0) {
5710 g_object_unref (headers);
5713 iter = tny_list_create_iterator (headers);
5714 header = TNY_HEADER (tny_iterator_get_current (iter));
5716 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5718 g_warning ("List should contain headers");
5720 g_object_unref (iter);
5721 g_object_unref (headers);
5722 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5723 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5725 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5728 if (!header || !folder)
5731 /* Get the account type */
5732 account = tny_folder_get_account (TNY_FOLDER (folder));
5733 proto = modest_tny_account_get_protocol_type (account);
5734 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5737 subject = tny_header_dup_subject (header);
5738 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5742 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5748 g_object_unref (account);
5750 g_object_unref (folder);
5752 g_object_unref (header);
5758 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5759 const gchar *account_name,
5760 const gchar *account_title)
5762 ModestAccountMgr *account_mgr;
5765 ModestProtocol *protocol;
5766 gboolean removed = FALSE;
5768 g_return_val_if_fail (account_name, FALSE);
5769 g_return_val_if_fail (account_title, FALSE);
5771 account_mgr = modest_runtime_get_account_mgr();
5773 /* The warning text depends on the account type: */
5774 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5775 modest_account_mgr_get_store_protocol (account_mgr,
5777 txt = modest_protocol_get_translation (protocol,
5778 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5781 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5783 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5787 if (response == GTK_RESPONSE_OK) {
5788 /* Remove account. If it succeeds then it also removes
5789 the account from the ModestAccountView: */
5790 gboolean is_default = FALSE;
5791 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5792 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5794 g_free (default_account_name);
5796 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5798 #ifdef MODEST_TOOLKIT_HILDON2
5799 hildon_gtk_window_take_screenshot (parent_window, FALSE);
5801 /* Close all email notifications, we cannot
5802 distinguish if the notification belongs to
5803 this account or not, so for safety reasons
5804 we remove them all */
5805 modest_platform_remove_new_mail_notifications (FALSE);
5807 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5814 on_fetch_images_performer (gboolean canceled,
5816 ModestWindow *parent_window,
5817 TnyAccount *account,
5820 if (err || canceled) {
5821 /* Show an unable to retrieve images ??? */
5825 /* Note that the user could have closed the window while connecting */
5826 if (GTK_WIDGET_VISIBLE (parent_window))
5827 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5828 g_object_unref ((GObject *) user_data);
5832 modest_ui_actions_on_fetch_images (GtkAction *action,
5833 ModestWindow *window)
5835 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5837 modest_platform_connect_and_perform (window, TRUE,
5839 on_fetch_images_performer,
5840 g_object_ref (window));
5844 modest_ui_actions_on_reload_message (const gchar *msg_id)
5846 ModestWindow *window = NULL;
5848 g_return_if_fail (msg_id && msg_id[0] != '\0');
5849 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5855 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5858 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5861 /** Check whether any connections are active, and cancel them if
5863 * Returns TRUE is there was no problem,
5864 * or if an operation was cancelled so we can continue.
5865 * Returns FALSE if the user chose to cancel his request instead.
5869 modest_ui_actions_check_for_active_account (ModestWindow *self,
5870 const gchar* account_name)
5872 ModestTnySendQueue *send_queue;
5873 ModestTnyAccountStore *acc_store;
5874 ModestMailOperationQueue* queue;
5875 TnyConnectionStatus store_conn_status;
5876 TnyAccount *store_account = NULL, *transport_account = NULL;
5877 gboolean retval = TRUE, sending = FALSE;
5879 acc_store = modest_runtime_get_account_store ();
5880 queue = modest_runtime_get_mail_operation_queue ();
5883 modest_tny_account_store_get_server_account (acc_store,
5885 TNY_ACCOUNT_TYPE_STORE);
5887 /* This could happen if the account was deleted before the
5888 call to this function */
5893 modest_tny_account_store_get_server_account (acc_store,
5895 TNY_ACCOUNT_TYPE_TRANSPORT);
5897 /* This could happen if the account was deleted before the
5898 call to this function */
5899 if (!transport_account) {
5900 g_object_unref (store_account);
5904 /* If the transport account was not used yet, then the send
5905 queue could not exist (it's created on demand) */
5906 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5907 if (TNY_IS_SEND_QUEUE (send_queue))
5908 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5910 store_conn_status = tny_account_get_connection_status (store_account);
5911 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5914 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (self)),
5915 _("emev_nc_disconnect_account"));
5916 if (response == GTK_RESPONSE_OK) {
5925 /* FIXME: We should only cancel those of this account */
5926 modest_mail_operation_queue_cancel_all (queue);
5928 /* Also disconnect the account */
5929 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5930 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5931 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5935 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5941 g_object_unref (store_account);
5942 g_object_unref (transport_account);