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>
81 #include <gtkhtml/gtkhtml.h>
83 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
85 typedef struct _GetMsgAsyncHelper {
87 ModestMailOperation *mail_op;
94 typedef enum _ReplyForwardAction {
100 typedef struct _ReplyForwardHelper {
101 guint reply_forward_type;
102 ReplyForwardAction action;
105 GtkWidget *parent_window;
107 } ReplyForwardHelper;
109 typedef struct _MoveToHelper {
110 GtkTreeRowReference *reference;
114 typedef struct _PasteAsAttachmentHelper {
115 ModestMsgEditWindow *window;
117 } PasteAsAttachmentHelper;
125 * The do_headers_action uses this kind of functions to perform some
126 * action to each member of a list of headers
128 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
130 static void do_headers_action (ModestWindow *win,
134 static void open_msg_cb (ModestMailOperation *mail_op,
141 static void reply_forward_cb (ModestMailOperation *mail_op,
148 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
150 static gint header_list_count_uncached_msgs (TnyList *header_list);
152 static gboolean connect_to_get_msg (ModestWindow *win,
153 gint num_of_uncached_msgs,
154 TnyAccount *account);
156 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
158 static void do_create_folder (GtkWindow *window,
159 TnyFolderStore *parent_folder,
160 const gchar *suggested_name);
162 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
164 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
165 TnyFolderStore *dst_folder,
169 static void modest_ui_actions_on_window_move_to (GtkAction *action,
170 TnyList *list_to_move,
171 TnyFolderStore *dst_folder,
175 * This function checks whether a TnyFolderStore is a pop account
178 remote_folder_has_leave_on_server (TnyFolderStore *folder)
183 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
185 account = get_account_from_folder_store (folder);
186 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
187 modest_tny_account_get_protocol_type (account)));
188 g_object_unref (account);
193 /* FIXME: this should be merged with the similar code in modest-account-view-window */
194 /* Show the account creation wizard dialog.
195 * returns: TRUE if an account was created. FALSE if the user cancelled.
198 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
200 gboolean result = FALSE;
202 gint dialog_response;
204 /* there is no such wizard yet */
205 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
206 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
210 ModestWindowMgr *mgr;
212 mgr = modest_runtime_get_window_mgr ();
214 window_list = modest_window_mgr_get_window_list (mgr);
215 if (window_list == NULL) {
216 win = MODEST_WINDOW (modest_accounts_window_new ());
217 if (modest_window_mgr_register_window (mgr, win, NULL)) {
218 gtk_widget_show_all (GTK_WIDGET (win));
220 gtk_widget_destroy (GTK_WIDGET (win));
225 g_list_free (window_list);
230 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
232 /* make sure the mainwindow is visible. We need to present the
233 wizard again to give it the focus back. show_all are needed
234 in order to get the widgets properly drawn (MainWindow main
235 paned won't be in its right position and the dialog will be
238 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
239 gtk_widget_destroy (GTK_WIDGET (wizard));
240 if (gtk_events_pending ())
241 gtk_main_iteration ();
243 if (dialog_response == GTK_RESPONSE_CANCEL) {
246 /* Check whether an account was created: */
247 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
254 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
257 const gchar *authors[] = {
258 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
261 about = gtk_about_dialog_new ();
262 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
263 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
264 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
265 _("Copyright (c) 2006, Nokia Corporation\n"
266 "All rights reserved."));
267 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
268 _("a modest e-mail client\n\n"
269 "design and implementation: Dirk-Jan C. Binnema\n"
270 "contributions from the fine people at KC and Ig\n"
271 "uses the tinymail email framework written by Philip van Hoof"));
272 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
273 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
274 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
275 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
277 gtk_dialog_run (GTK_DIALOG (about));
278 gtk_widget_destroy(about);
282 * Gets the list of currently selected messages. If the win is the
283 * main window, then it returns a newly allocated list of the headers
284 * selected in the header view. If win is the msg view window, then
285 * the value returned is a list with just a single header.
287 * The caller of this funcion must free the list.
290 get_selected_headers (ModestWindow *win)
292 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
293 /* for MsgViewWindows, we simply return a list with one element */
295 TnyList *list = NULL;
297 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
298 if (header != NULL) {
299 list = tny_simple_list_new ();
300 tny_list_prepend (list, G_OBJECT(header));
301 g_object_unref (G_OBJECT(header));
305 } else if (MODEST_IS_HEADER_WINDOW (win)) {
306 GtkWidget *header_view;
308 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
309 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
316 headers_action_mark_as_read (TnyHeader *header,
320 TnyHeaderFlags flags;
322 g_return_if_fail (TNY_IS_HEADER(header));
324 flags = tny_header_get_flags (header);
325 if (flags & TNY_HEADER_FLAG_SEEN) return;
326 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
330 headers_action_mark_as_unread (TnyHeader *header,
334 TnyHeaderFlags flags;
336 g_return_if_fail (TNY_IS_HEADER(header));
338 flags = tny_header_get_flags (header);
339 if (flags & TNY_HEADER_FLAG_SEEN) {
340 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
344 /** After deleing a message that is currently visible in a window,
345 * show the next message from the list, or close the window if there are no more messages.
348 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
350 /* Close msg view window or select next */
351 if (!modest_msg_view_window_select_next_message (win) &&
352 !modest_msg_view_window_select_previous_message (win)) {
354 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
360 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
362 modest_ui_actions_on_edit_mode_delete_message (win);
366 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
368 TnyList *header_list = NULL;
369 TnyIterator *iter = NULL;
370 TnyHeader *header = NULL;
371 gchar *message = NULL;
374 ModestWindowMgr *mgr;
375 gboolean retval = TRUE;
377 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
379 /* Get the headers, either from the header view (if win is the main window),
380 * or from the message view window: */
381 header_list = get_selected_headers (win);
382 if (!header_list) return FALSE;
384 /* Check if any of the headers are already opened, or in the process of being opened */
387 if (tny_list_get_length(header_list) == 1) {
388 iter = tny_list_create_iterator (header_list);
389 header = TNY_HEADER (tny_iterator_get_current (iter));
392 subject = tny_header_dup_subject (header);
394 subject = g_strdup (_("mail_va_no_subject"));
395 desc = g_strdup_printf ("%s", subject);
397 g_object_unref (header);
400 g_object_unref (iter);
402 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
403 tny_list_get_length(header_list)), desc);
405 /* Confirmation dialog */
406 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
409 if (response == GTK_RESPONSE_OK) {
410 GtkTreeSelection *sel = NULL;
411 GList *sel_list = NULL;
412 ModestMailOperation *mail_op = NULL;
414 /* Find last selected row */
416 /* Disable window dimming management */
417 modest_window_disable_dimming (win);
419 /* Remove each header. If it's a view window header_view == NULL */
420 mail_op = modest_mail_operation_new ((GObject *) win);
421 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
423 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
424 g_object_unref (mail_op);
426 /* Enable window dimming management */
428 gtk_tree_selection_unselect_all (sel);
430 modest_window_enable_dimming (win);
432 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
433 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
435 /* Get main window */
436 mgr = modest_runtime_get_window_mgr ();
439 /* Update toolbar dimming state */
440 modest_ui_actions_check_menu_dimming_rules (win);
441 modest_ui_actions_check_toolbar_dimming_rules (win);
444 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
445 g_list_free (sel_list);
454 g_object_unref (header_list);
462 /* delete either message or folder, based on where we are */
464 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
466 g_return_if_fail (MODEST_IS_WINDOW(win));
468 /* Check first if the header view has the focus */
469 modest_ui_actions_on_delete_message (action, win);
473 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
475 ModestWindowMgr *mgr = NULL;
477 #ifdef MODEST_PLATFORM_MAEMO
478 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
479 #endif /* MODEST_PLATFORM_MAEMO */
481 g_debug ("closing down, clearing %d item(s) from operation queue",
482 modest_mail_operation_queue_num_elements
483 (modest_runtime_get_mail_operation_queue()));
485 /* cancel all outstanding operations */
486 modest_mail_operation_queue_cancel_all
487 (modest_runtime_get_mail_operation_queue());
489 g_debug ("queue has been cleared");
492 /* Check if there are opened editing windows */
493 mgr = modest_runtime_get_window_mgr ();
494 modest_window_mgr_close_all_windows (mgr);
496 /* note: when modest-tny-account-store is finalized,
497 it will automatically set all network connections
500 /* gtk_main_quit (); */
504 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
508 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
510 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
511 /* gtk_widget_destroy (GTK_WIDGET (win)); */
512 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
513 /* gboolean ret_value; */
514 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
515 /* } else if (MODEST_IS_WINDOW (win)) { */
516 /* gtk_widget_destroy (GTK_WIDGET (win)); */
518 /* g_return_if_reached (); */
523 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
525 if (MODEST_IS_MSG_VIEW_WINDOW (win))
526 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
527 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
528 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
532 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
534 GtkClipboard *clipboard = NULL;
535 gchar *selection = NULL;
537 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
538 selection = gtk_clipboard_wait_for_text (clipboard);
541 modest_address_book_add_address (selection, (GtkWindow *) win);
547 modest_ui_actions_on_new_account (GtkAction *action,
548 ModestWindow *window)
550 if (!modest_ui_actions_run_account_setup_wizard (window)) {
551 g_debug ("%s: wizard was already running", __FUNCTION__);
556 modest_ui_actions_on_accounts (GtkAction *action,
559 /* This is currently only implemented for Maemo */
560 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
561 if (!modest_ui_actions_run_account_setup_wizard (win))
562 g_debug ("%s: wizard was already running", __FUNCTION__);
566 /* Show the list of accounts */
567 GtkWindow *toplevel, *account_win;
569 account_win = GTK_WINDOW (modest_account_view_window_new ());
570 toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (win)));
572 /* The accounts dialog must be modal */
573 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
574 modest_utils_show_dialog_and_forget (toplevel, GTK_DIALOG (account_win));
579 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
581 /* This is currently only implemented for Maemo,
582 * because it requires an API (libconic) to detect different connection
585 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
587 /* Create the window if necessary: */
588 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
589 modest_connection_specific_smtp_window_fill_with_connections (
590 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
591 modest_runtime_get_account_mgr());
593 /* Show the window: */
594 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
595 GTK_WINDOW (specific_window), (GtkWindow *) win);
596 gtk_widget_show (specific_window);
597 #endif /* !MODEST_TOOLKIT_GTK */
601 count_part_size (const gchar *part)
603 GnomeVFSURI *vfs_uri;
604 gchar *escaped_filename;
606 GnomeVFSFileInfo *info;
609 /* Estimation of attachment size if we cannot get it from file info */
612 vfs_uri = gnome_vfs_uri_new (part);
614 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
615 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
616 g_free (escaped_filename);
617 gnome_vfs_uri_unref (vfs_uri);
619 info = gnome_vfs_file_info_new ();
621 if (gnome_vfs_get_file_info (part,
623 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
625 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
630 gnome_vfs_file_info_unref (info);
636 count_parts_size (GSList *parts)
641 for (node = parts; node != NULL; node = g_slist_next (node)) {
642 result += count_part_size ((const gchar *) node->data);
649 modest_ui_actions_compose_msg(ModestWindow *win,
652 const gchar *bcc_str,
653 const gchar *subject_str,
654 const gchar *body_str,
656 gboolean set_as_modified)
658 gchar *account_name = NULL;
659 const gchar *mailbox;
661 TnyAccount *account = NULL;
662 TnyFolder *folder = NULL;
663 gchar *from_str = NULL, *signature = NULL, *body = NULL;
664 gchar *recipient = NULL;
665 gboolean use_signature = FALSE;
666 ModestWindow *msg_win = NULL;
667 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
668 ModestTnyAccountStore *store = modest_runtime_get_account_store();
669 GnomeVFSFileSize total_size, allowed_size;
670 guint64 available_disk, expected_size, parts_size;
673 /* we check for low-mem */
674 if (modest_platform_check_memory_low (win, TRUE))
677 available_disk = modest_utils_get_available_space (NULL);
678 parts_count = g_slist_length (attachments);
679 parts_size = count_parts_size (attachments);
680 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
682 /* Double check: disk full condition or message too big */
683 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
684 expected_size > available_disk) {
685 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
686 modest_platform_system_banner (NULL, NULL, msg);
692 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
693 modest_platform_run_information_dialog (
695 _("mail_ib_error_attachment_size"),
702 account_name = g_strdup (modest_window_get_active_account(win));
704 account_name = modest_account_mgr_get_default_account(mgr);
707 g_printerr ("modest: no account found\n");
712 mailbox = modest_window_get_active_mailbox (win);
715 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
717 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
720 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
722 g_printerr ("modest: failed to find Drafts folder\n");
725 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
727 g_printerr ("modest: failed get from string for '%s'\n", account_name);
731 recipient = modest_text_utils_get_email_address (from_str);
732 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
734 if (body_str != NULL) {
735 body = use_signature ? g_strconcat(body_str, "\n",
736 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
737 "\n", signature, NULL) : g_strdup(body_str);
739 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
740 "\n", signature, NULL) : g_strdup("");
743 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
745 g_printerr ("modest: failed to create new msg\n");
749 /* Create and register edit window */
750 /* This is destroyed by TODO. */
752 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
753 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
755 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
756 gtk_widget_destroy (GTK_WIDGET (msg_win));
759 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
760 gtk_widget_show_all (GTK_WIDGET (msg_win));
762 while (attachments) {
763 GnomeVFSFileSize att_size;
765 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
766 attachments->data, allowed_size);
767 total_size += att_size;
769 if (att_size > allowed_size) {
770 g_debug ("%s: total size: %u",
771 __FUNCTION__, (unsigned int)total_size);
774 allowed_size -= att_size;
776 attachments = g_slist_next(attachments);
783 g_free (account_name);
785 g_object_unref (G_OBJECT(account));
787 g_object_unref (G_OBJECT(folder));
789 g_object_unref (G_OBJECT(msg));
793 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
795 /* if there are no accounts yet, just show the wizard */
796 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
797 if (!modest_ui_actions_run_account_setup_wizard (win))
800 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
805 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
809 ModestMailOperationStatus status;
811 /* If there is no message or the operation was not successful */
812 status = modest_mail_operation_get_status (mail_op);
813 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
816 /* If it's a memory low issue, then show a banner */
817 error = modest_mail_operation_get_error (mail_op);
818 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
819 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
820 GObject *source = modest_mail_operation_get_source (mail_op);
821 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
822 _KR("memr_ib_operation_disabled"),
824 g_object_unref (source);
827 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
828 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
829 gchar *subject, *msg, *format = NULL;
832 subject = (header) ? tny_header_dup_subject (header) : NULL;
834 subject = g_strdup (_("mail_va_no_subject"));
836 account = modest_mail_operation_get_account (mail_op);
838 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
839 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
842 if (tny_account_get_connection_status (account) ==
843 TNY_CONNECTION_STATUS_CONNECTED) {
845 format = modest_protocol_get_translation (protocol,
846 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
849 format = modest_protocol_get_translation (protocol,
850 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
853 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
854 tny_account_get_hostname (account));
857 g_object_unref (account);
862 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
864 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
868 msg = g_strdup_printf (format, subject);
869 modest_platform_run_information_dialog (NULL, msg, FALSE);
875 /* Remove the header from the preregistered uids */
876 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
894 ModestWindow *caller_window;
895 OpenMsgBannerInfo *banner_info;
896 GtkTreeRowReference *rowref;
900 open_msg_banner_idle (gpointer userdata)
902 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
904 gdk_threads_enter ();
905 banner_info->idle_handler = 0;
906 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
907 if (banner_info->banner)
908 g_object_ref (banner_info->banner);
910 gdk_threads_leave ();
916 get_header_view_from_window (ModestWindow *window)
918 GtkWidget *header_view;
920 if (MODEST_IS_HEADER_WINDOW (window)){
921 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
930 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
933 gchar *account = NULL;
934 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
939 folder = tny_header_get_folder (header);
940 /* Gets folder type (OUTBOX headers will be opened in edit window */
941 if (modest_tny_folder_is_local_folder (folder)) {
942 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
943 if (folder_type == TNY_FOLDER_TYPE_INVALID)
944 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
947 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
948 TnyTransportAccount *traccount = NULL;
949 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
950 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
952 ModestTnySendQueue *send_queue = NULL;
953 ModestTnySendQueueStatus status;
955 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
956 TNY_ACCOUNT(traccount)));
957 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
958 if (TNY_IS_SEND_QUEUE (send_queue)) {
959 msg_id = modest_tny_send_queue_get_msg_id (header);
960 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
962 /* Only open messages in outbox with the editor if they are in Failed state */
963 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
967 /* In Fremantle we can not
968 open any message from
969 outbox which is not in
974 g_object_unref(traccount);
976 g_warning("Cannot get transport account for message in outbox!!");
978 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
979 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
983 TnyAccount *acc = tny_folder_get_account (folder);
986 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
987 g_object_unref (acc);
991 g_object_unref (folder);
997 open_msg_cb (ModestMailOperation *mail_op,
1004 ModestWindowMgr *mgr = NULL;
1005 ModestWindow *parent_win = NULL;
1006 ModestWindow *win = NULL;
1007 gchar *account = NULL;
1008 gboolean open_in_editor = FALSE;
1010 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1012 /* Do nothing if there was any problem with the mail
1013 operation. The error will be shown by the error_handler of
1014 the mail operation */
1015 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1018 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1020 /* Mark header as read */
1021 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1023 account = get_info_from_header (header, &open_in_editor, &can_open);
1027 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1029 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1031 if (open_in_editor) {
1032 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1033 gchar *from_header = NULL, *acc_name;
1034 gchar *mailbox = NULL;
1036 from_header = tny_header_dup_from (header);
1038 /* we cannot edit without a valid account... */
1039 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1040 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1041 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1043 g_free (from_header);
1048 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1049 g_free (from_header);
1055 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1059 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1060 const gchar *mailbox = NULL;
1062 if (parent_win && MODEST_IS_WINDOW (parent_win))
1063 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1065 if (helper->rowref && helper->model) {
1066 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1067 helper->model, helper->rowref);
1069 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1074 /* Register and show new window */
1076 mgr = modest_runtime_get_window_mgr ();
1077 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1078 gtk_widget_destroy (GTK_WIDGET (win));
1081 gtk_widget_show_all (GTK_WIDGET(win));
1088 g_object_unref (parent_win);
1092 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1095 const GError *error;
1096 GObject *win = NULL;
1097 ModestMailOperationStatus status;
1099 win = modest_mail_operation_get_source (mail_op);
1100 error = modest_mail_operation_get_error (mail_op);
1101 status = modest_mail_operation_get_status (mail_op);
1103 /* If the mail op has been cancelled then it's not an error:
1104 don't show any message */
1105 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1106 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1107 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1108 (GError *) error, account)) {
1109 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1110 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1112 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1113 modest_platform_information_banner ((GtkWidget *) win,
1114 NULL, _("emev_ui_imap_inbox_select_error"));
1115 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1116 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1117 modest_platform_information_banner ((GtkWidget *) win,
1118 NULL, _CS_UNABLE_TO_OPEN_FILE_NOT_FOUND);
1119 } else if (user_data) {
1120 modest_platform_information_banner ((GtkWidget *) win,
1124 g_object_unref (account);
1128 g_object_unref (win);
1132 * Returns the account a list of headers belongs to. It returns a
1133 * *new* reference so don't forget to unref it
1136 get_account_from_header_list (TnyList *headers)
1138 TnyAccount *account = NULL;
1140 if (tny_list_get_length (headers) > 0) {
1141 TnyIterator *iter = tny_list_create_iterator (headers);
1142 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1143 TnyFolder *folder = tny_header_get_folder (header);
1146 g_object_unref (header);
1148 while (!tny_iterator_is_done (iter)) {
1149 header = TNY_HEADER (tny_iterator_get_current (iter));
1150 folder = tny_header_get_folder (header);
1153 g_object_unref (header);
1155 tny_iterator_next (iter);
1160 account = tny_folder_get_account (folder);
1161 g_object_unref (folder);
1165 g_object_unref (header);
1167 g_object_unref (iter);
1173 get_account_from_header (TnyHeader *header)
1175 TnyAccount *account = NULL;
1178 folder = tny_header_get_folder (header);
1181 account = tny_folder_get_account (folder);
1182 g_object_unref (folder);
1188 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1190 if (helper->caller_window)
1191 helper->caller_window = NULL;
1195 open_msg_helper_destroyer (gpointer user_data)
1197 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1199 if (helper->caller_window) {
1200 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1201 helper->caller_window = NULL;
1204 if (helper->banner_info) {
1205 g_free (helper->banner_info->message);
1206 if (helper->banner_info->idle_handler > 0) {
1207 g_source_remove (helper->banner_info->idle_handler);
1208 helper->banner_info->idle_handler = 0;
1210 if (helper->banner_info->banner != NULL) {
1211 gtk_widget_destroy (helper->banner_info->banner);
1212 g_object_unref (helper->banner_info->banner);
1213 helper->banner_info->banner = NULL;
1215 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1216 helper->banner_info = NULL;
1218 g_object_unref (helper->model);
1219 g_object_unref (helper->header);
1220 gtk_tree_row_reference_free (helper->rowref);
1221 g_slice_free (OpenMsgHelper, helper);
1225 open_msg_performer(gboolean canceled,
1227 GtkWindow *parent_window,
1228 TnyAccount *account,
1231 ModestMailOperation *mail_op = NULL;
1232 gchar *error_msg = NULL;
1233 ModestProtocolType proto;
1234 TnyConnectionStatus status;
1235 OpenMsgHelper *helper = NULL;
1236 ModestProtocol *protocol;
1237 ModestProtocolRegistry *protocol_registry;
1240 helper = (OpenMsgHelper *) user_data;
1242 status = tny_account_get_connection_status (account);
1243 if (err || canceled || helper->caller_window == NULL) {
1244 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1245 /* Free the helper */
1246 open_msg_helper_destroyer (helper);
1248 /* In disk full conditions we could get this error here */
1249 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1250 (GtkWidget *) parent_window, err,
1256 /* Get the error message depending on the protocol */
1257 proto = modest_tny_account_get_protocol_type (account);
1258 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1259 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1262 protocol_registry = modest_runtime_get_protocol_registry ();
1263 subject = tny_header_dup_subject (helper->header);
1265 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1266 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1270 if (error_msg == NULL) {
1271 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1276 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1279 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1280 g_free (account_name);
1281 open_msg_helper_destroyer (helper);
1286 ModestWindow *window;
1287 GtkWidget *header_view;
1290 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1291 uid = modest_tny_folder_get_header_unique_id (helper->header);
1293 const gchar *mailbox = NULL;
1294 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1295 window = modest_msg_view_window_new_from_header_view
1296 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1297 if (window != NULL) {
1298 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1300 gtk_widget_destroy (GTK_WIDGET (window));
1302 gtk_widget_show_all (GTK_WIDGET(window));
1306 g_free (account_name);
1308 open_msg_helper_destroyer (helper);
1311 g_free (account_name);
1312 /* Create the mail operation */
1314 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1315 modest_ui_actions_disk_operations_error_handler,
1316 g_strdup (error_msg), g_free);
1317 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1323 headers = TNY_LIST (tny_simple_list_new ());
1324 tny_list_prepend (headers, G_OBJECT (helper->header));
1325 modest_mail_operation_get_msgs_full (mail_op,
1329 open_msg_helper_destroyer);
1330 g_object_unref (headers);
1337 g_object_unref (mail_op);
1338 g_object_unref (account);
1342 * This function is used by both modest_ui_actions_on_open and
1343 * modest_ui_actions_on_header_activated. This way we always do the
1344 * same when trying to open messages.
1347 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1349 ModestWindowMgr *mgr = NULL;
1350 TnyAccount *account;
1351 gboolean cached = FALSE;
1353 GtkWidget *header_view = NULL;
1354 OpenMsgHelper *helper;
1355 ModestWindow *window;
1357 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1359 mgr = modest_runtime_get_window_mgr ();
1362 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1363 if (header_view == NULL)
1366 /* Get the account */
1367 account = get_account_from_header (header);
1372 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1374 /* Do not open again the message and present the
1375 window to the user */
1378 #ifndef MODEST_TOOLKIT_HILDON2
1379 gtk_window_present (GTK_WINDOW (window));
1382 /* the header has been registered already, we don't do
1383 * anything but wait for the window to come up*/
1384 g_debug ("header %p already registered, waiting for window", header);
1389 /* Open each message */
1390 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1392 /* Allways download if we are online. */
1393 if (!tny_device_is_online (modest_runtime_get_device ())) {
1396 /* If ask for user permission to download the messages */
1397 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1398 _("mcen_nc_get_msg"));
1400 /* End if the user does not want to continue */
1401 if (response == GTK_RESPONSE_CANCEL) {
1407 /* We register the window for opening */
1408 modest_window_mgr_register_header (mgr, header, NULL);
1410 /* Create the helper. We need to get a reference to the model
1411 here because it could change while the message is readed
1412 (the user could switch between folders) */
1413 helper = g_slice_new (OpenMsgHelper);
1414 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1415 helper->caller_window = win;
1416 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1417 helper->header = g_object_ref (header);
1418 helper->rowref = gtk_tree_row_reference_copy (rowref);
1419 helper->banner_info = NULL;
1421 /* Connect to the account and perform */
1423 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1424 open_msg_performer, helper);
1426 /* Call directly the performer, do not need to connect */
1427 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1428 g_object_ref (account), helper);
1433 g_object_unref (account);
1437 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1444 /* we check for low-mem; in that case, show a warning, and don't allow
1447 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1451 headers = get_selected_headers (win);
1455 headers_count = tny_list_get_length (headers);
1456 if (headers_count != 1) {
1457 if (headers_count > 1) {
1458 /* Don't allow activation if there are more than one message selected */
1459 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1462 g_object_unref (headers);
1466 iter = tny_list_create_iterator (headers);
1467 header = TNY_HEADER (tny_iterator_get_current (iter));
1468 g_object_unref (iter);
1472 open_msg_from_header (header, NULL, win);
1473 g_object_unref (header);
1476 g_object_unref(headers);
1480 rf_helper_window_closed (gpointer data,
1483 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1485 helper->parent_window = NULL;
1488 static ReplyForwardHelper*
1489 create_reply_forward_helper (ReplyForwardAction action,
1491 guint reply_forward_type,
1494 ReplyForwardHelper *rf_helper = NULL;
1495 const gchar *active_acc = modest_window_get_active_account (win);
1496 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1498 rf_helper = g_slice_new0 (ReplyForwardHelper);
1499 rf_helper->reply_forward_type = reply_forward_type;
1500 rf_helper->action = action;
1501 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1502 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1503 rf_helper->account_name = (active_acc) ?
1504 g_strdup (active_acc) :
1505 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1506 rf_helper->mailbox = g_strdup (active_mailbox);
1508 /* Note that window could be destroyed just AFTER calling
1509 register_window so we must ensure that this pointer does
1510 not hold invalid references */
1511 if (rf_helper->parent_window)
1512 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1513 rf_helper_window_closed, rf_helper);
1519 free_reply_forward_helper (gpointer data)
1521 ReplyForwardHelper *helper;
1523 helper = (ReplyForwardHelper *) data;
1524 g_free (helper->account_name);
1525 g_free (helper->mailbox);
1527 g_object_unref (helper->header);
1528 if (helper->parent_window)
1529 g_object_weak_unref (G_OBJECT (helper->parent_window),
1530 rf_helper_window_closed, helper);
1531 g_slice_free (ReplyForwardHelper, helper);
1535 reply_forward_cb (ModestMailOperation *mail_op,
1542 TnyMsg *new_msg = NULL;
1543 ReplyForwardHelper *rf_helper;
1544 ModestWindow *msg_win = NULL;
1545 ModestEditType edit_type;
1547 TnyAccount *account = NULL;
1548 ModestWindowMgr *mgr = NULL;
1549 gchar *signature = NULL;
1550 gboolean use_signature;
1553 /* If there was any error. The mail operation could be NULL,
1554 this means that we already have the message downloaded and
1555 that we didn't do a mail operation to retrieve it */
1556 rf_helper = (ReplyForwardHelper *) user_data;
1557 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1560 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1561 rf_helper->account_name, rf_helper->mailbox);
1562 recipient = modest_text_utils_get_email_address (from);
1563 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1568 /* Create reply mail */
1569 switch (rf_helper->action) {
1570 /* Use the msg_header to ensure that we have all the
1571 information. The summary can lack some data */
1572 TnyHeader *msg_header;
1574 msg_header = tny_msg_get_header (msg);
1576 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1577 (use_signature) ? signature : NULL,
1578 rf_helper->reply_forward_type,
1579 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1580 g_object_unref (msg_header);
1582 case ACTION_REPLY_TO_ALL:
1583 msg_header = tny_msg_get_header (msg);
1585 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1586 (use_signature) ? signature : NULL,
1587 rf_helper->reply_forward_type,
1588 MODEST_TNY_MSG_REPLY_MODE_ALL);
1589 edit_type = MODEST_EDIT_TYPE_REPLY;
1590 g_object_unref (msg_header);
1592 case ACTION_FORWARD:
1594 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1595 rf_helper->reply_forward_type);
1596 edit_type = MODEST_EDIT_TYPE_FORWARD;
1599 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1601 g_return_if_reached ();
1609 g_warning ("%s: failed to create message\n", __FUNCTION__);
1613 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1614 rf_helper->account_name,
1615 TNY_ACCOUNT_TYPE_STORE);
1617 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1621 /* Create and register the windows */
1622 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1623 mgr = modest_runtime_get_window_mgr ();
1624 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1626 /* Note that register_window could have deleted the account */
1627 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1628 gdouble parent_zoom;
1630 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1631 modest_window_set_zoom (msg_win, parent_zoom);
1634 /* Show edit window */
1635 gtk_widget_show_all (GTK_WIDGET (msg_win));
1638 /* We always unregister the header because the message is
1639 forwarded or replied so the original one is no longer
1641 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1644 g_object_unref (G_OBJECT (new_msg));
1646 g_object_unref (G_OBJECT (account));
1647 free_reply_forward_helper (rf_helper);
1650 /* Checks a list of headers. If any of them are not currently
1651 * downloaded (CACHED) then returns TRUE else returns FALSE.
1654 header_list_count_uncached_msgs (TnyList *header_list)
1657 gint uncached_messages = 0;
1659 iter = tny_list_create_iterator (header_list);
1660 while (!tny_iterator_is_done (iter)) {
1663 header = TNY_HEADER (tny_iterator_get_current (iter));
1665 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1666 uncached_messages ++;
1667 g_object_unref (header);
1670 tny_iterator_next (iter);
1672 g_object_unref (iter);
1674 return uncached_messages;
1677 /* Returns FALSE if the user does not want to download the
1678 * messages. Returns TRUE if the user allowed the download.
1681 connect_to_get_msg (ModestWindow *win,
1682 gint num_of_uncached_msgs,
1683 TnyAccount *account)
1685 GtkResponseType response;
1687 /* Allways download if we are online. */
1688 if (tny_device_is_online (modest_runtime_get_device ()))
1691 /* If offline, then ask for user permission to download the messages */
1692 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1693 ngettext("mcen_nc_get_msg",
1695 num_of_uncached_msgs));
1697 if (response == GTK_RESPONSE_CANCEL)
1700 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1704 reply_forward_performer (gboolean canceled,
1706 GtkWindow *parent_window,
1707 TnyAccount *account,
1710 ReplyForwardHelper *rf_helper = NULL;
1711 ModestMailOperation *mail_op;
1713 rf_helper = (ReplyForwardHelper *) user_data;
1715 if (canceled || err) {
1716 free_reply_forward_helper (rf_helper);
1720 /* Retrieve the message */
1721 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1722 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1723 modest_ui_actions_disk_operations_error_handler,
1725 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1726 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1729 g_object_unref(mail_op);
1733 * Common code for the reply and forward actions
1736 reply_forward (ReplyForwardAction action, ModestWindow *win)
1738 ReplyForwardHelper *rf_helper = NULL;
1739 guint reply_forward_type;
1741 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1743 /* we check for low-mem; in that case, show a warning, and don't allow
1744 * reply/forward (because it could potentially require a lot of memory */
1745 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1749 /* we need an account when editing */
1750 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1751 if (!modest_ui_actions_run_account_setup_wizard (win))
1755 reply_forward_type =
1756 modest_conf_get_int (modest_runtime_get_conf (),
1757 (action == ACTION_FORWARD) ?
1758 MODEST_CONF_FORWARD_TYPE :
1759 MODEST_CONF_REPLY_TYPE,
1762 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1764 TnyHeader *header = NULL;
1765 /* Get header and message. Do not free them here, the
1766 reply_forward_cb must do it */
1767 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1768 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1770 if (msg && header) {
1772 rf_helper = create_reply_forward_helper (action, win,
1773 reply_forward_type, header);
1774 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1776 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1780 g_object_unref (msg);
1782 g_object_unref (header);
1784 TnyHeader *header = NULL;
1786 gboolean do_retrieve = TRUE;
1787 TnyList *header_list = NULL;
1789 header_list = get_selected_headers (win);
1792 /* Check that only one message is selected for replying */
1793 if (tny_list_get_length (header_list) != 1) {
1794 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1795 NULL, _("mcen_ib_select_one_message"));
1796 g_object_unref (header_list);
1800 /* Only reply/forward to one message */
1801 iter = tny_list_create_iterator (header_list);
1802 header = TNY_HEADER (tny_iterator_get_current (iter));
1803 g_object_unref (iter);
1805 /* Retrieve messages */
1806 do_retrieve = (action == ACTION_FORWARD) ||
1807 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1810 TnyAccount *account = NULL;
1811 TnyFolder *folder = NULL;
1812 gdouble download = TRUE;
1813 guint uncached_msgs = 0;
1815 folder = tny_header_get_folder (header);
1817 goto do_retrieve_frees;
1818 account = tny_folder_get_account (folder);
1820 goto do_retrieve_frees;
1822 uncached_msgs = header_list_count_uncached_msgs (header_list);
1824 if (uncached_msgs > 0) {
1825 /* Allways download if we are online. */
1826 if (!tny_device_is_online (modest_runtime_get_device ())) {
1829 /* If ask for user permission to download the messages */
1830 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1831 ngettext("mcen_nc_get_msg",
1835 /* End if the user does not want to continue */
1836 if (response == GTK_RESPONSE_CANCEL)
1843 rf_helper = create_reply_forward_helper (action, win,
1844 reply_forward_type, header);
1845 if (uncached_msgs > 0) {
1846 modest_platform_connect_and_perform (GTK_WINDOW (win),
1848 reply_forward_performer,
1851 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1852 account, rf_helper);
1857 g_object_unref (account);
1859 g_object_unref (folder);
1861 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
1864 g_object_unref (header_list);
1865 g_object_unref (header);
1870 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1872 g_return_if_fail (MODEST_IS_WINDOW(win));
1874 reply_forward (ACTION_REPLY, win);
1878 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1880 g_return_if_fail (MODEST_IS_WINDOW(win));
1882 reply_forward (ACTION_FORWARD, win);
1886 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1888 g_return_if_fail (MODEST_IS_WINDOW(win));
1890 reply_forward (ACTION_REPLY_TO_ALL, win);
1894 modest_ui_actions_on_next (GtkAction *action,
1895 ModestWindow *window)
1897 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1898 modest_msg_view_window_select_next_message (
1899 MODEST_MSG_VIEW_WINDOW (window));
1901 g_return_if_reached ();
1906 modest_ui_actions_on_prev (GtkAction *action,
1907 ModestWindow *window)
1909 g_return_if_fail (MODEST_IS_WINDOW(window));
1911 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1912 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1914 g_return_if_reached ();
1919 modest_ui_actions_on_sort (GtkAction *action,
1920 ModestWindow *window)
1922 GtkWidget *header_view = NULL;
1924 g_return_if_fail (MODEST_IS_WINDOW(window));
1926 if (MODEST_IS_HEADER_WINDOW (window)) {
1927 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1931 modest_platform_information_banner (NULL, NULL, _CS_NOTHING_TO_SORT);
1936 /* Show sorting dialog */
1937 modest_utils_run_sort_dialog (MODEST_WINDOW (window), MODEST_SORT_HEADERS);
1941 sync_folder_cb (ModestMailOperation *mail_op,
1945 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
1947 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
1948 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1950 /* We must clear first, because otherwise set_folder will ignore */
1951 /* the change as the folders are the same */
1952 modest_header_view_clear (header_view);
1953 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
1955 g_object_unref (parent);
1958 g_object_unref (header_view);
1962 idle_refresh_folder (gpointer source)
1964 ModestHeaderView *header_view = NULL;
1966 /* If the window still exists */
1967 if (!GTK_IS_WIDGET (source) ||
1968 !GTK_WIDGET_VISIBLE (source))
1971 /* Refresh the current view */
1972 if (MODEST_IS_HEADER_WINDOW (source))
1973 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
1975 TnyFolder *folder = modest_header_view_get_folder (header_view);
1977 /* Sync the folder status */
1978 ModestMailOperation *mail_op = modest_mail_operation_new (source);
1979 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1980 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
1981 g_object_unref (folder);
1982 g_object_unref (mail_op);
1990 update_account_cb (ModestMailOperation *self,
1991 TnyList *new_headers,
1995 gboolean show_visual_notifications;
1997 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
1998 show_visual_notifications = (top) ? FALSE : TRUE;
2000 /* Notify new messages have been downloaded. If the
2001 send&receive was invoked by the user then do not show any
2002 visual notification, only play a sound and activate the LED
2003 (for the Maemo version) */
2004 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2006 /* We only notify about really new messages (not seen) we get */
2007 TnyList *actually_new_list;
2008 TnyIterator *iterator;
2009 actually_new_list = TNY_LIST (tny_simple_list_new ());
2010 for (iterator = tny_list_create_iterator (new_headers);
2011 !tny_iterator_is_done (iterator);
2012 tny_iterator_next (iterator)) {
2014 TnyHeaderFlags flags;
2015 header = TNY_HEADER (tny_iterator_get_current (iterator));
2016 flags = tny_header_get_flags (header);
2018 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2019 /* Messages are ordered from most
2020 recent to oldest. But we want to
2021 show notifications starting from
2022 the oldest message. That's why we
2024 tny_list_prepend (actually_new_list, G_OBJECT (header));
2026 g_object_unref (header);
2028 g_object_unref (iterator);
2030 if (tny_list_get_length (actually_new_list) > 0) {
2031 GList *new_headers_list = NULL;
2033 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2035 /* Send notifications */
2036 if (new_headers_list) {
2037 modest_platform_on_new_headers_received (new_headers_list,
2038 show_visual_notifications);
2040 modest_utils_free_notification_list (new_headers_list);
2043 g_object_unref (actually_new_list);
2047 /* Refresh the current folder in an idle. We do this
2048 in order to avoid refresh cancelations if the
2049 currently viewed folder is the inbox */
2050 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2051 idle_refresh_folder,
2058 TnyAccount *account;
2060 gchar *account_name;
2061 gboolean poke_status;
2062 gboolean interactive;
2063 ModestMailOperation *mail_op;
2067 do_send_receive_performer (gboolean canceled,
2069 GtkWindow *parent_window,
2070 TnyAccount *account,
2073 SendReceiveInfo *info;
2075 info = (SendReceiveInfo *) user_data;
2077 if (err || canceled) {
2078 /* In disk full conditions we could get this error here */
2079 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2080 (GtkWidget *) parent_window, err,
2083 if (info->mail_op) {
2084 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2091 /* Send & receive. */
2092 modest_mail_operation_update_account (info->mail_op, info->account_name,
2093 info->poke_status, info->interactive,
2094 update_account_cb, info->win);
2099 g_object_unref (G_OBJECT (info->mail_op));
2100 if (info->account_name)
2101 g_free (info->account_name);
2103 g_object_unref (info->win);
2105 g_object_unref (info->account);
2106 g_slice_free (SendReceiveInfo, info);
2110 * This function performs the send & receive required actions. The
2111 * window is used to create the mail operation. Typically it should
2112 * always be the main window, but we pass it as argument in order to
2116 modest_ui_actions_do_send_receive (const gchar *account_name,
2117 gboolean force_connection,
2118 gboolean poke_status,
2119 gboolean interactive,
2122 gchar *acc_name = NULL;
2123 SendReceiveInfo *info;
2124 ModestTnyAccountStore *acc_store;
2125 TnyAccount *account;
2127 /* If no account name was provided then get the current account, and if
2128 there is no current account then pick the default one: */
2129 if (!account_name) {
2131 acc_name = g_strdup (modest_window_get_active_account (win));
2133 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2135 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2139 acc_name = g_strdup (account_name);
2142 acc_store = modest_runtime_get_account_store ();
2143 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2147 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2151 /* Do not automatically refresh accounts that are flagged as
2152 NO_AUTO_UPDATE. This could be useful for accounts that
2153 handle their own update times */
2155 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2156 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2157 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2158 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2160 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2161 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2162 g_object_unref (account);
2169 /* Create the info for the connect and perform */
2170 info = g_slice_new (SendReceiveInfo);
2171 info->account_name = acc_name;
2172 info->win = (win) ? g_object_ref (win) : NULL;
2173 info->poke_status = poke_status;
2174 info->interactive = interactive;
2175 info->account = account;
2176 /* We need to create the operation here, because otherwise it
2177 could happen that the queue emits the queue-empty signal
2178 while we're trying to connect the account */
2179 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2180 modest_ui_actions_disk_operations_error_handler,
2182 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2184 /* Invoke the connect and perform */
2185 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2186 force_connection, info->account,
2187 do_send_receive_performer, info);
2192 modest_ui_actions_do_cancel_send (const gchar *account_name,
2195 TnyTransportAccount *transport_account;
2196 TnySendQueue *send_queue = NULL;
2197 GError *error = NULL;
2199 /* Get transport account */
2201 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2202 (modest_runtime_get_account_store(),
2204 TNY_ACCOUNT_TYPE_TRANSPORT));
2205 if (!transport_account) {
2206 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2211 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2212 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2213 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2214 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2215 "modest: could not find send queue for account\n");
2217 /* Cancel the current send */
2218 tny_account_cancel (TNY_ACCOUNT (transport_account));
2220 /* Suspend all pending messages */
2221 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2225 if (transport_account != NULL)
2226 g_object_unref (G_OBJECT (transport_account));
2230 modest_ui_actions_cancel_send_all (ModestWindow *win)
2232 GSList *account_names, *iter;
2234 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2237 iter = account_names;
2239 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2240 iter = g_slist_next (iter);
2243 modest_account_mgr_free_account_names (account_names);
2244 account_names = NULL;
2248 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2251 /* Check if accounts exist */
2252 gboolean accounts_exist =
2253 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2255 /* If not, allow the user to create an account before trying to send/receive. */
2256 if (!accounts_exist)
2257 modest_ui_actions_on_accounts (NULL, win);
2259 /* Cancel all sending operaitons */
2260 modest_ui_actions_cancel_send_all (win);
2264 * Refreshes all accounts. This function will be used by automatic
2268 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2269 gboolean force_connection,
2270 gboolean poke_status,
2271 gboolean interactive)
2273 GSList *account_names, *iter;
2275 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2278 iter = account_names;
2280 modest_ui_actions_do_send_receive ((const char*) iter->data,
2282 poke_status, interactive, win);
2283 iter = g_slist_next (iter);
2286 modest_account_mgr_free_account_names (account_names);
2287 account_names = NULL;
2291 * Handler of the click on Send&Receive button in the main toolbar
2294 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2296 /* Check if accounts exist */
2297 gboolean accounts_exist;
2300 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2302 /* If not, allow the user to create an account before trying to send/receive. */
2303 if (!accounts_exist)
2304 modest_ui_actions_on_accounts (NULL, win);
2306 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2307 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2308 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2310 const gchar *active_account;
2311 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2313 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2320 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2323 ModestWindow *window)
2325 GtkTreeRowReference *rowref;
2327 g_return_if_fail (MODEST_IS_WINDOW(window));
2328 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2329 g_return_if_fail (TNY_IS_HEADER (header));
2331 if (modest_header_view_count_selected_headers (header_view) > 1) {
2332 /* Don't allow activation if there are more than one message selected */
2333 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2337 /* we check for low-mem; in that case, show a warning, and don't allow
2338 * activating headers
2340 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2344 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2345 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2346 gtk_tree_row_reference_free (rowref);
2350 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2357 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2359 online = tny_device_is_online (modest_runtime_get_device());
2362 /* already online -- the item is simply not there... */
2363 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2365 GTK_MESSAGE_WARNING,
2367 _("The %s you selected cannot be found"),
2369 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2370 gtk_dialog_run (GTK_DIALOG(dialog));
2372 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2375 _("mcen_bd_dialog_cancel"),
2376 GTK_RESPONSE_REJECT,
2377 _("mcen_bd_dialog_ok"),
2378 GTK_RESPONSE_ACCEPT,
2380 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2381 "Do you want to get online?"), item);
2382 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2383 gtk_label_new (txt), FALSE, FALSE, 0);
2384 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2387 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2388 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2389 /* TODO: Comment about why is this commented out: */
2390 /* modest_platform_connect_and_wait (); */
2393 gtk_widget_destroy (dialog);
2397 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2400 /* g_debug ("%s %s", __FUNCTION__, link); */
2405 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2408 modest_platform_activate_uri (link);
2412 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2415 modest_platform_show_uri_popup (link);
2419 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2422 /* we check for low-mem; in that case, show a warning, and don't allow
2423 * viewing attachments
2425 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2428 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2432 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2433 const gchar *address,
2436 /* g_debug ("%s %s", __FUNCTION__, address); */
2440 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2441 TnyMsg *saved_draft,
2444 ModestMsgEditWindow *edit_window;
2446 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2448 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2450 /* Set draft is there was no error */
2451 if (!modest_mail_operation_get_error (mail_op))
2452 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2454 g_object_unref(edit_window);
2458 enough_space_for_message (ModestMsgEditWindow *edit_window,
2461 guint64 available_disk, expected_size;
2466 available_disk = modest_utils_get_available_space (NULL);
2467 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2468 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2473 /* Double check: disk full condition or message too big */
2474 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2475 expected_size > available_disk) {
2476 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2477 modest_platform_information_banner (NULL, NULL, msg);
2484 * djcb: if we're in low-memory state, we only allow for
2485 * saving messages smaller than
2486 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2487 * should still allow for sending anything critical...
2489 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2490 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2494 * djcb: we also make sure that the attachments are smaller than the max size
2495 * this is for the case where we'd try to forward a message with attachments
2496 * bigger than our max allowed size, or sending an message from drafts which
2497 * somehow got past our checks when attaching.
2499 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2500 modest_platform_run_information_dialog (
2501 GTK_WINDOW(edit_window),
2502 _("mail_ib_error_attachment_size"),
2511 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2513 TnyTransportAccount *transport_account;
2514 ModestMailOperation *mail_operation;
2516 gchar *account_name;
2517 ModestAccountMgr *account_mgr;
2518 gboolean had_error = FALSE;
2520 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2522 data = modest_msg_edit_window_get_msg_data (edit_window);
2525 if (!enough_space_for_message (edit_window, data)) {
2526 modest_msg_edit_window_free_msg_data (edit_window, data);
2530 account_name = g_strdup (data->account_name);
2531 account_mgr = modest_runtime_get_account_mgr();
2533 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2535 account_name = modest_account_mgr_get_default_account (account_mgr);
2536 if (!account_name) {
2537 g_printerr ("modest: no account found\n");
2538 modest_msg_edit_window_free_msg_data (edit_window, data);
2542 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2543 account_name = g_strdup (data->account_name);
2547 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2548 (modest_runtime_get_account_store (),
2550 TNY_ACCOUNT_TYPE_TRANSPORT));
2551 if (!transport_account) {
2552 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2553 g_free (account_name);
2554 modest_msg_edit_window_free_msg_data (edit_window, data);
2558 /* Create the mail operation */
2559 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2561 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2563 modest_mail_operation_save_to_drafts (mail_operation,
2575 data->priority_flags,
2578 on_save_to_drafts_cb,
2579 g_object_ref(edit_window));
2581 /* In hildon2 we always show the information banner on saving to drafts.
2582 * It will be a system information banner in this case.
2584 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2585 modest_platform_information_banner (NULL, NULL, text);
2587 modest_msg_edit_window_set_modified (edit_window, FALSE);
2590 g_free (account_name);
2591 g_object_unref (G_OBJECT (transport_account));
2592 g_object_unref (G_OBJECT (mail_operation));
2594 modest_msg_edit_window_free_msg_data (edit_window, data);
2600 /* For instance, when clicking the Send toolbar button when editing a message: */
2602 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2604 TnyTransportAccount *transport_account = NULL;
2605 gboolean had_error = FALSE, add_to_contacts;
2607 ModestAccountMgr *account_mgr;
2608 gchar *account_name;
2609 ModestMailOperation *mail_operation;
2612 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2614 /* Check whether to automatically add new contacts to addressbook or not */
2615 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
2616 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
2617 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
2620 data = modest_msg_edit_window_get_msg_data (edit_window);
2622 recipients = g_strconcat (data->to?data->to:"",
2623 data->cc?data->cc:"",
2624 data->bcc?data->bcc:"",
2626 if (recipients == NULL || recipients[0] == '\0') {
2627 /* Empty subject -> no send */
2628 g_free (recipients);
2629 modest_msg_edit_window_free_msg_data (edit_window, data);
2632 g_free (recipients);
2635 if (!enough_space_for_message (edit_window, data)) {
2636 modest_msg_edit_window_free_msg_data (edit_window, data);
2640 account_mgr = modest_runtime_get_account_mgr();
2641 account_name = g_strdup (data->account_name);
2643 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2646 account_name = modest_account_mgr_get_default_account (account_mgr);
2648 if (!account_name) {
2649 modest_msg_edit_window_free_msg_data (edit_window, data);
2650 /* Run account setup wizard */
2651 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2656 /* Get the currently-active transport account for this modest account: */
2657 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2659 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2660 (modest_runtime_get_account_store (),
2661 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2664 if (!transport_account) {
2665 modest_msg_edit_window_free_msg_data (edit_window, data);
2666 /* Run account setup wizard */
2667 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2672 /* Create the mail operation */
2673 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2674 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2676 modest_mail_operation_send_new_mail (mail_operation,
2690 data->priority_flags);
2692 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2693 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2695 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2696 const GError *error = modest_mail_operation_get_error (mail_operation);
2697 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2698 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2699 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2700 modest_platform_information_banner (NULL, NULL, _CS_NOT_ENOUGH_MEMORY);
2706 g_free (account_name);
2707 g_object_unref (G_OBJECT (transport_account));
2708 g_object_unref (G_OBJECT (mail_operation));
2710 modest_msg_edit_window_free_msg_data (edit_window, data);
2713 modest_msg_edit_window_set_sent (edit_window, TRUE);
2715 /* Save settings and close the window: */
2716 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2723 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2724 ModestMsgEditWindow *window)
2726 ModestMsgEditFormatState *format_state = NULL;
2728 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2729 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2731 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2734 format_state = modest_msg_edit_window_get_format_state (window);
2735 g_return_if_fail (format_state != NULL);
2737 format_state->bold = gtk_toggle_action_get_active (action);
2738 modest_msg_edit_window_set_format_state (window, format_state);
2739 g_free (format_state);
2744 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2745 ModestMsgEditWindow *window)
2747 ModestMsgEditFormatState *format_state = NULL;
2749 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2750 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2752 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2755 format_state = modest_msg_edit_window_get_format_state (window);
2756 g_return_if_fail (format_state != NULL);
2758 format_state->italics = gtk_toggle_action_get_active (action);
2759 modest_msg_edit_window_set_format_state (window, format_state);
2760 g_free (format_state);
2765 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2766 ModestMsgEditWindow *window)
2768 ModestMsgEditFormatState *format_state = NULL;
2770 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2771 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2773 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2776 format_state = modest_msg_edit_window_get_format_state (window);
2777 g_return_if_fail (format_state != NULL);
2779 format_state->bullet = gtk_toggle_action_get_active (action);
2780 modest_msg_edit_window_set_format_state (window, format_state);
2781 g_free (format_state);
2786 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2787 GtkRadioAction *selected,
2788 ModestMsgEditWindow *window)
2790 ModestMsgEditFormatState *format_state = NULL;
2791 GtkJustification value;
2793 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2795 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2798 value = gtk_radio_action_get_current_value (selected);
2800 format_state = modest_msg_edit_window_get_format_state (window);
2801 g_return_if_fail (format_state != NULL);
2803 format_state->justification = value;
2804 modest_msg_edit_window_set_format_state (window, format_state);
2805 g_free (format_state);
2809 modest_ui_actions_on_select_editor_color (GtkAction *action,
2810 ModestMsgEditWindow *window)
2812 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2813 g_return_if_fail (GTK_IS_ACTION (action));
2815 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2818 modest_msg_edit_window_select_color (window);
2822 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2823 ModestMsgEditWindow *window)
2825 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2826 g_return_if_fail (GTK_IS_ACTION (action));
2828 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2834 modest_ui_actions_on_insert_image (GObject *object,
2835 ModestMsgEditWindow *window)
2837 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2840 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2843 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2846 modest_msg_edit_window_insert_image (window);
2850 modest_ui_actions_on_attach_file (GtkAction *action,
2851 ModestMsgEditWindow *window)
2853 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2854 g_return_if_fail (GTK_IS_ACTION (action));
2856 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2859 modest_msg_edit_window_offer_attach_file (window);
2863 modest_ui_actions_on_remove_attachments (GtkAction *action,
2864 ModestMsgEditWindow *window)
2866 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2868 modest_msg_edit_window_remove_attachments (window, NULL);
2872 do_create_folder_cb (ModestMailOperation *mail_op,
2873 TnyFolderStore *parent_folder,
2874 TnyFolder *new_folder,
2877 gchar *suggested_name = (gchar *) user_data;
2878 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
2879 const GError *error;
2881 error = modest_mail_operation_get_error (mail_op);
2883 gboolean disk_full = FALSE;
2884 TnyAccount *account;
2885 /* Show an error. If there was some problem writing to
2886 disk, show it, otherwise show the generic folder
2887 create error. We do it here and not in an error
2888 handler because the call to do_create_folder will
2889 stop the main loop in a gtk_dialog_run and then,
2890 the message won't be shown until that dialog is
2892 account = modest_mail_operation_get_account (mail_op);
2895 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2896 (GtkWidget *) source_win,
2899 _("mail_in_ui_folder_create_error_memory"));
2900 g_object_unref (account);
2903 /* Show an error and try again if there is no
2904 full memory condition */
2905 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
2906 _("mail_in_ui_folder_create_error"));
2907 do_create_folder ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (source_win)),
2908 parent_folder, (const gchar *) suggested_name);
2912 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
2913 * FIXME: any other? */
2914 GtkWidget *folder_view;
2916 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
2917 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
2919 /* Select the newly created folder. It could happen
2920 that the widget is no longer there (i.e. the window
2921 has been destroyed, so we need to check this */
2923 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
2925 g_object_unref (new_folder);
2927 /* Free. Note that the first time it'll be NULL so noop */
2928 g_free (suggested_name);
2929 g_object_unref (source_win);
2934 TnyFolderStore *parent;
2935 } CreateFolderConnect;
2938 do_create_folder_performer (gboolean canceled,
2940 GtkWindow *parent_window,
2941 TnyAccount *account,
2944 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
2945 ModestMailOperation *mail_op;
2947 if (canceled || err) {
2948 /* In disk full conditions we could get this error here */
2949 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2950 (GtkWidget *) parent_window, err,
2951 NULL, _("mail_in_ui_folder_create_error_memory"));
2953 /* This happens if we have selected the outbox folder
2955 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
2956 TNY_IS_MERGE_FOLDER (helper->parent)) {
2957 /* Show an error and retry */
2958 modest_platform_information_banner ((GtkWidget *) parent_window,
2960 _("mail_in_ui_folder_create_error"));
2962 do_create_folder (parent_window, helper->parent, helper->folder_name);
2968 mail_op = modest_mail_operation_new ((GObject *) parent_window);
2969 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2971 modest_mail_operation_create_folder (mail_op,
2973 (const gchar *) helper->folder_name,
2974 do_create_folder_cb,
2975 g_strdup (helper->folder_name));
2976 g_object_unref (mail_op);
2980 g_object_unref (helper->parent);
2981 if (helper->folder_name)
2982 g_free (helper->folder_name);
2983 g_slice_free (CreateFolderConnect, helper);
2988 do_create_folder (GtkWindow *parent_window,
2989 TnyFolderStore *suggested_parent,
2990 const gchar *suggested_name)
2993 gchar *folder_name = NULL;
2994 TnyFolderStore *parent_folder = NULL;
2996 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2998 (gchar *) suggested_name,
3002 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3003 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3004 helper->folder_name = g_strdup (folder_name);
3005 helper->parent = g_object_ref (parent_folder);
3007 modest_platform_connect_if_remote_and_perform (parent_window,
3010 do_create_folder_performer,
3015 g_free (folder_name);
3017 g_object_unref (parent_folder);
3021 modest_ui_actions_create_folder(GtkWindow *parent_window,
3022 GtkWidget *folder_view,
3023 TnyFolderStore *parent_folder)
3025 if (!parent_folder) {
3026 ModestTnyAccountStore *acc_store;
3028 acc_store = modest_runtime_get_account_store ();
3030 parent_folder = (TnyFolderStore *)
3031 modest_tny_account_store_get_local_folders_account (acc_store);
3034 if (parent_folder) {
3035 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3036 g_object_unref (parent_folder);
3041 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3044 g_return_if_fail (MODEST_IS_WINDOW(window));
3046 if (MODEST_IS_FOLDER_WINDOW (window)) {
3047 GtkWidget *folder_view;
3048 GtkWindow *toplevel;
3050 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3051 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
3052 modest_ui_actions_create_folder (toplevel, folder_view, NULL);
3054 g_assert_not_reached ();
3059 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3062 const GError *error = NULL;
3063 gchar *message = NULL;
3065 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3067 /* Get error message */
3068 error = modest_mail_operation_get_error (mail_op);
3070 g_return_if_reached ();
3072 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3073 (GError *) error, account);
3075 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3076 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3077 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3078 message = _CS_FOLDER_ALREADY_EXISTS;
3079 } else if (error->domain == TNY_ERROR_DOMAIN &&
3080 error->code == TNY_SERVICE_ERROR_STATE) {
3081 /* This means that the folder is already in use (a
3082 message is opened for example */
3083 message = _("emev_ni_internal_error");
3085 message = _CS_UNABLE_TO_RENAME;
3088 /* We don't set a parent for the dialog because the dialog
3089 will be destroyed so the banner won't appear */
3090 modest_platform_information_banner (NULL, NULL, message);
3093 g_object_unref (account);
3099 TnyFolderStore *folder;
3104 on_rename_folder_cb (ModestMailOperation *mail_op,
3105 TnyFolder *new_folder,
3108 ModestFolderView *folder_view;
3110 /* If the window was closed when renaming a folder, or if
3111 * it's not a main window this will happen */
3112 if (!MODEST_IS_FOLDER_VIEW (user_data))
3115 folder_view = MODEST_FOLDER_VIEW (user_data);
3116 /* Note that if the rename fails new_folder will be NULL */
3118 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3120 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3124 on_rename_folder_performer (gboolean canceled,
3126 GtkWindow *parent_window,
3127 TnyAccount *account,
3130 ModestMailOperation *mail_op = NULL;
3131 GtkTreeSelection *sel = NULL;
3132 GtkWidget *folder_view = NULL;
3133 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3135 if (canceled || err) {
3136 /* In disk full conditions we could get this error here */
3137 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3138 (GtkWidget *) parent_window, err,
3143 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3144 modest_ui_actions_rename_folder_error_handler,
3145 parent_window, NULL);
3147 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3149 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3150 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3151 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3154 /* Clear the folders view */
3155 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3156 gtk_tree_selection_unselect_all (sel);
3158 /* Actually rename the folder */
3159 modest_mail_operation_rename_folder (mail_op,
3160 TNY_FOLDER (data->folder),
3161 (const gchar *) (data->new_name),
3162 on_rename_folder_cb,
3164 g_object_unref (mail_op);
3167 g_object_unref (data->folder);
3168 g_free (data->new_name);
3173 modest_ui_actions_on_rename_folder (GtkAction *action,
3174 ModestWindow *window)
3176 modest_ui_actions_on_edit_mode_rename_folder (window);
3180 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3182 TnyFolderStore *folder;
3183 GtkWidget *folder_view;
3184 gboolean do_rename = TRUE;
3186 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3188 if (MODEST_IS_FOLDER_WINDOW (window)) {
3189 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3194 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3199 if (TNY_IS_FOLDER (folder)) {
3200 gchar *folder_name = NULL;
3202 const gchar *current_name;
3203 TnyFolderStore *parent;
3205 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3206 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3207 response = modest_platform_run_rename_folder_dialog (MODEST_WINDOW (window),
3208 parent, current_name,
3210 g_object_unref (parent);
3212 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3215 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3216 rename_folder_data->folder = g_object_ref (folder);
3217 rename_folder_data->new_name = folder_name;
3218 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3219 folder, on_rename_folder_performer, rename_folder_data);
3222 g_object_unref (folder);
3227 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3230 GObject *win = modest_mail_operation_get_source (mail_op);
3232 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3233 _("mail_in_ui_folder_delete_error"),
3235 g_object_unref (win);
3239 TnyFolderStore *folder;
3240 gboolean move_to_trash;
3244 on_delete_folder_cb (gboolean canceled,
3246 GtkWindow *parent_window,
3247 TnyAccount *account,
3250 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3251 GtkWidget *folder_view;
3252 ModestMailOperation *mail_op;
3253 GtkTreeSelection *sel;
3255 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3256 /* Note that the connection process can fail due to
3257 memory low conditions as it can not successfully
3258 store the summary */
3259 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3260 (GtkWidget*) parent_window, err,
3262 g_debug ("Error connecting when trying to delete a folder");
3263 g_object_unref (G_OBJECT (info->folder));
3268 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3269 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3271 g_object_unref (G_OBJECT (info->folder));
3276 /* Unselect the folder before deleting it to free the headers */
3277 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3278 gtk_tree_selection_unselect_all (sel);
3280 /* Create the mail operation */
3282 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3283 modest_ui_actions_delete_folder_error_handler,
3286 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3288 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3290 g_object_unref (mail_op);
3291 g_object_unref (info->folder);
3296 delete_folder (ModestWindow *window, gboolean move_to_trash)
3298 TnyFolderStore *folder;
3299 GtkWidget *folder_view;
3303 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3305 if (MODEST_IS_FOLDER_WINDOW (window)) {
3306 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3313 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3318 /* Show an error if it's an account */
3319 if (!TNY_IS_FOLDER (folder)) {
3320 modest_platform_run_information_dialog (GTK_WINDOW (window),
3321 _("mail_in_ui_folder_delete_error"),
3323 g_object_unref (G_OBJECT (folder));
3328 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3329 tny_folder_get_name (TNY_FOLDER (folder)));
3330 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3331 (const gchar *) message);
3334 if (response == GTK_RESPONSE_OK) {
3335 TnyAccount *account = NULL;
3336 DeleteFolderInfo *info = NULL;
3337 info = g_new0(DeleteFolderInfo, 1);
3338 info->folder = g_object_ref (folder);
3339 info->move_to_trash = move_to_trash;
3341 account = tny_folder_get_account (TNY_FOLDER (folder));
3342 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3344 TNY_FOLDER_STORE (account),
3345 on_delete_folder_cb, info);
3346 g_object_unref (account);
3347 g_object_unref (folder);
3355 modest_ui_actions_on_delete_folder (GtkAction *action,
3356 ModestWindow *window)
3358 modest_ui_actions_on_edit_mode_delete_folder (window);
3362 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3364 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3366 return delete_folder (window, FALSE);
3370 typedef struct _PasswordDialogFields {
3371 GtkWidget *username;
3372 GtkWidget *password;
3374 } PasswordDialogFields;
3377 password_dialog_check_field (GtkEditable *editable,
3378 PasswordDialogFields *fields)
3381 gboolean any_value_empty = FALSE;
3383 value = modest_entry_get_text (fields->username);
3384 if ((value == NULL) || value[0] == '\0') {
3385 any_value_empty = TRUE;
3387 value = modest_entry_get_text (fields->password);
3388 if ((value == NULL) || value[0] == '\0') {
3389 any_value_empty = TRUE;
3391 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3395 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3396 const gchar* server_account_name,
3401 ModestMainWindow *main_window)
3403 g_return_if_fail(server_account_name);
3404 gboolean completed = FALSE;
3405 PasswordDialogFields *fields = NULL;
3407 /* Initalize output parameters: */
3414 #ifndef MODEST_TOOLKIT_GTK
3415 /* Maemo uses a different (awkward) button order,
3416 * It should probably just use gtk_alternative_dialog_button_order ().
3418 #ifdef MODEST_TOOLKIT_HILDON2
3420 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3424 GTK_RESPONSE_ACCEPT,
3426 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3427 HILDON_MARGIN_DOUBLE);
3430 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3433 _("mcen_bd_dialog_ok"),
3434 GTK_RESPONSE_ACCEPT,
3435 _("mcen_bd_dialog_cancel"),
3436 GTK_RESPONSE_REJECT,
3438 #endif /* MODEST_TOOLKIT_HILDON2 */
3441 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3445 GTK_RESPONSE_REJECT,
3447 GTK_RESPONSE_ACCEPT,
3449 #endif /* MODEST_TOOLKIT_GTK */
3451 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3453 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3454 modest_runtime_get_account_mgr(), server_account_name);
3455 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3456 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3459 gtk_widget_destroy (dialog);
3463 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3464 GtkWidget *label = gtk_label_new (txt);
3465 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3467 g_free (server_name);
3468 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3473 gchar *initial_username = modest_account_mgr_get_server_account_username (
3474 modest_runtime_get_account_mgr(), server_account_name);
3476 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3477 if (initial_username)
3478 modest_entry_set_text (entry_username, initial_username);
3480 /* Dim this if a connection has ever succeeded with this username,
3481 * as per the UI spec: */
3482 /* const gboolean username_known = */
3483 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3484 /* modest_runtime_get_account_mgr(), server_account_name); */
3485 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3487 /* We drop the username sensitive code and disallow changing it here
3488 * as tinymail does not support really changing the username in the callback
3490 gtk_widget_set_sensitive (entry_username, FALSE);
3492 /* Auto-capitalization is the default, so let's turn it off: */
3493 #ifdef MAEMO_CHANGES
3494 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3497 /* Create a size group to be used by all captions.
3498 * Note that HildonCaption does not create a default size group if we do not specify one.
3499 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3500 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3502 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3503 _("mail_fi_username"), FALSE,
3505 gtk_widget_show (entry_username);
3506 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3507 FALSE, FALSE, MODEST_MARGIN_HALF);
3508 gtk_widget_show (caption);
3511 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3512 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3513 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3515 /* Auto-capitalization is the default, so let's turn it off: */
3516 #ifdef MAEMO_CHANGES
3517 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3518 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3521 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3522 _("mail_fi_password"), FALSE,
3524 gtk_widget_show (entry_password);
3525 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3526 FALSE, FALSE, MODEST_MARGIN_HALF);
3527 gtk_widget_show (caption);
3528 g_object_unref (sizegroup);
3530 if (initial_username != NULL)
3531 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3533 /* This is not in the Maemo UI spec:
3534 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3535 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3539 fields = g_slice_new0 (PasswordDialogFields);
3540 fields->username = entry_username;
3541 fields->password = entry_password;
3542 fields->dialog = dialog;
3544 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3545 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3546 password_dialog_check_field (NULL, fields);
3548 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3550 while (!completed) {
3552 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3554 *username = g_strdup (modest_entry_get_text (entry_username));
3556 /* Note that an empty field becomes the "" string */
3557 if (*username && strlen (*username) > 0) {
3558 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3559 server_account_name,
3563 const gboolean username_was_changed =
3564 (strcmp (*username, initial_username) != 0);
3565 if (username_was_changed) {
3566 g_warning ("%s: tinymail does not yet support changing the "
3567 "username in the get_password() callback.\n", __FUNCTION__);
3573 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3574 _("mcen_ib_username_pw_incorrect"));
3580 *password = g_strdup (modest_entry_get_text (entry_password));
3582 /* We do not save the password in the configuration,
3583 * because this function is only called for passwords that should
3584 * not be remembered:
3585 modest_server_account_set_password (
3586 modest_runtime_get_account_mgr(), server_account_name,
3603 /* This is not in the Maemo UI spec:
3604 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3610 g_free (initial_username);
3611 gtk_widget_destroy (dialog);
3612 g_slice_free (PasswordDialogFields, fields);
3614 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3618 modest_ui_actions_on_cut (GtkAction *action,
3619 ModestWindow *window)
3621 GtkWidget *focused_widget;
3622 GtkClipboard *clipboard;
3624 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3625 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3626 if (GTK_IS_EDITABLE (focused_widget)) {
3627 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3628 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3629 gtk_clipboard_store (clipboard);
3630 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3631 GtkTextBuffer *buffer;
3633 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3634 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3635 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3636 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3637 gtk_clipboard_store (clipboard);
3639 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3640 TnyList *header_list = modest_header_view_get_selected_headers (
3641 MODEST_HEADER_VIEW (focused_widget));
3642 gboolean continue_download = FALSE;
3643 gint num_of_unc_msgs;
3645 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3647 if (num_of_unc_msgs) {
3648 TnyAccount *account = get_account_from_header_list (header_list);
3650 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3651 g_object_unref (account);
3655 if (num_of_unc_msgs == 0 || continue_download) {
3656 /* modest_platform_information_banner (
3657 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3658 modest_header_view_cut_selection (
3659 MODEST_HEADER_VIEW (focused_widget));
3662 g_object_unref (header_list);
3663 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3664 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3669 modest_ui_actions_on_copy (GtkAction *action,
3670 ModestWindow *window)
3672 GtkClipboard *clipboard;
3673 GtkWidget *focused_widget;
3674 gboolean copied = TRUE;
3676 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3677 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3679 if (GTK_IS_LABEL (focused_widget)) {
3681 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3682 gtk_clipboard_set_text (clipboard, selection, -1);
3684 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3685 gtk_clipboard_store (clipboard);
3686 } else if (GTK_IS_EDITABLE (focused_widget)) {
3687 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3688 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3689 gtk_clipboard_store (clipboard);
3690 } else if (GTK_IS_HTML (focused_widget)) {
3693 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3694 if ((sel == NULL) || (sel[0] == '\0')) {
3697 gtk_html_copy (GTK_HTML (focused_widget));
3698 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3699 gtk_clipboard_store (clipboard);
3701 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3702 GtkTextBuffer *buffer;
3703 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3704 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3705 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3706 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3707 gtk_clipboard_store (clipboard);
3709 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3710 TnyList *header_list = modest_header_view_get_selected_headers (
3711 MODEST_HEADER_VIEW (focused_widget));
3712 gboolean continue_download = FALSE;
3713 gint num_of_unc_msgs;
3715 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3717 if (num_of_unc_msgs) {
3718 TnyAccount *account = get_account_from_header_list (header_list);
3720 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3721 g_object_unref (account);
3725 if (num_of_unc_msgs == 0 || continue_download) {
3726 modest_platform_information_banner (
3727 NULL, NULL, _CS_GETTING_ITEMS);
3728 modest_header_view_copy_selection (
3729 MODEST_HEADER_VIEW (focused_widget));
3733 g_object_unref (header_list);
3735 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3736 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3739 /* Show information banner if there was a copy to clipboard */
3741 modest_platform_information_banner (
3742 NULL, NULL, _CS_COPIED);
3746 modest_ui_actions_on_undo (GtkAction *action,
3747 ModestWindow *window)
3749 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3750 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3752 g_return_if_reached ();
3757 modest_ui_actions_on_redo (GtkAction *action,
3758 ModestWindow *window)
3760 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3761 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3764 g_return_if_reached ();
3770 destroy_information_note (ModestMailOperation *mail_op,
3773 /* destroy information note */
3774 gtk_widget_destroy (GTK_WIDGET(user_data));
3778 destroy_folder_information_note (ModestMailOperation *mail_op,
3779 TnyFolder *new_folder,
3782 /* destroy information note */
3783 gtk_widget_destroy (GTK_WIDGET(user_data));
3788 paste_as_attachment_free (gpointer data)
3790 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3792 if (helper->banner) {
3793 gtk_widget_destroy (helper->banner);
3794 g_object_unref (helper->banner);
3800 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3805 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3806 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3811 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3816 modest_ui_actions_on_paste (GtkAction *action,
3817 ModestWindow *window)
3819 GtkWidget *focused_widget = NULL;
3820 GtkWidget *inf_note = NULL;
3821 ModestMailOperation *mail_op = NULL;
3823 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3824 if (GTK_IS_EDITABLE (focused_widget)) {
3825 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3826 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3827 ModestEmailClipboard *e_clipboard = NULL;
3828 e_clipboard = modest_runtime_get_email_clipboard ();
3829 if (modest_email_clipboard_cleared (e_clipboard)) {
3830 GtkTextBuffer *buffer;
3831 GtkClipboard *clipboard;
3833 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3834 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3835 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3836 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3837 ModestMailOperation *mail_op;
3838 TnyFolder *src_folder = NULL;
3839 TnyList *data = NULL;
3841 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3842 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3843 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3845 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3846 mail_op = modest_mail_operation_new (G_OBJECT (window));
3847 if (helper->banner != NULL) {
3848 g_object_ref (G_OBJECT (helper->banner));
3849 gtk_widget_show (GTK_WIDGET (helper->banner));
3853 modest_mail_operation_get_msgs_full (mail_op,
3855 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3857 paste_as_attachment_free);
3861 g_object_unref (data);
3863 g_object_unref (src_folder);
3866 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3867 ModestEmailClipboard *clipboard = NULL;
3868 TnyFolder *src_folder = NULL;
3869 TnyFolderStore *folder_store = NULL;
3870 TnyList *data = NULL;
3871 gboolean delete = FALSE;
3873 /* Check clipboard source */
3874 clipboard = modest_runtime_get_email_clipboard ();
3875 if (modest_email_clipboard_cleared (clipboard))
3878 /* Get elements to paste */
3879 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3881 /* Create a new mail operation */
3882 mail_op = modest_mail_operation_new (G_OBJECT(window));
3884 /* Get destination folder */
3885 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3887 /* transfer messages */
3891 /* Ask for user confirmation */
3893 modest_ui_actions_msgs_move_to_confirmation (window,
3894 TNY_FOLDER (folder_store),
3898 if (response == GTK_RESPONSE_OK) {
3899 /* Launch notification */
3900 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3902 if (inf_note != NULL) {
3903 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3904 gtk_widget_show (GTK_WIDGET(inf_note));
3907 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3908 modest_mail_operation_xfer_msgs (mail_op,
3910 TNY_FOLDER (folder_store),
3912 destroy_information_note,
3915 g_object_unref (mail_op);
3918 } else if (src_folder != NULL) {
3919 /* Launch notification */
3920 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3922 if (inf_note != NULL) {
3923 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3924 gtk_widget_show (GTK_WIDGET(inf_note));
3927 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3928 modest_mail_operation_xfer_folder (mail_op,
3932 destroy_folder_information_note,
3938 g_object_unref (data);
3939 if (src_folder != NULL)
3940 g_object_unref (src_folder);
3941 if (folder_store != NULL)
3942 g_object_unref (folder_store);
3948 modest_ui_actions_on_select_all (GtkAction *action,
3949 ModestWindow *window)
3951 GtkWidget *focused_widget;
3953 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3954 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3955 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3956 } else if (GTK_IS_LABEL (focused_widget)) {
3957 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3958 } else if (GTK_IS_EDITABLE (focused_widget)) {
3959 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3960 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3961 GtkTextBuffer *buffer;
3962 GtkTextIter start, end;
3964 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3965 gtk_text_buffer_get_start_iter (buffer, &start);
3966 gtk_text_buffer_get_end_iter (buffer, &end);
3967 gtk_text_buffer_select_range (buffer, &start, &end);
3968 } else if (GTK_IS_HTML (focused_widget)) {
3969 gtk_html_select_all (GTK_HTML (focused_widget));
3975 modest_ui_actions_on_mark_as_read (GtkAction *action,
3976 ModestWindow *window)
3978 g_return_if_fail (MODEST_IS_WINDOW(window));
3980 /* Mark each header as read */
3981 do_headers_action (window, headers_action_mark_as_read, NULL);
3985 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3986 ModestWindow *window)
3988 g_return_if_fail (MODEST_IS_WINDOW(window));
3990 /* Mark each header as read */
3991 do_headers_action (window, headers_action_mark_as_unread, NULL);
3995 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3996 GtkRadioAction *selected,
3997 ModestWindow *window)
4001 value = gtk_radio_action_get_current_value (selected);
4002 if (MODEST_IS_WINDOW (window)) {
4003 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4008 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4009 GtkRadioAction *selected,
4010 ModestWindow *window)
4012 TnyHeaderFlags flags;
4013 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4015 flags = gtk_radio_action_get_current_value (selected);
4016 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4020 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4021 GtkRadioAction *selected,
4022 ModestWindow *window)
4026 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4028 file_format = gtk_radio_action_get_current_value (selected);
4029 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4034 modest_ui_actions_on_zoom_plus (GtkAction *action,
4035 ModestWindow *window)
4037 g_return_if_fail (MODEST_IS_WINDOW (window));
4039 modest_window_zoom_plus (MODEST_WINDOW (window));
4043 modest_ui_actions_on_zoom_minus (GtkAction *action,
4044 ModestWindow *window)
4046 g_return_if_fail (MODEST_IS_WINDOW (window));
4048 modest_window_zoom_minus (MODEST_WINDOW (window));
4052 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4053 ModestWindow *window)
4055 ModestWindowMgr *mgr;
4056 gboolean fullscreen, active;
4057 g_return_if_fail (MODEST_IS_WINDOW (window));
4059 mgr = modest_runtime_get_window_mgr ();
4061 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4062 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4064 if (active != fullscreen) {
4065 modest_window_mgr_set_fullscreen_mode (mgr, active);
4066 #ifndef MODEST_TOOLKIT_HILDON2
4067 gtk_window_present (GTK_WINDOW (window));
4073 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4074 ModestWindow *window)
4076 ModestWindowMgr *mgr;
4077 gboolean fullscreen;
4079 g_return_if_fail (MODEST_IS_WINDOW (window));
4081 mgr = modest_runtime_get_window_mgr ();
4082 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4083 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4088 * Used by modest_ui_actions_on_details to call do_headers_action
4091 headers_action_show_details (TnyHeader *header,
4092 ModestWindow *window,
4096 gboolean async_retrieval;
4097 GtkWindow *toplevel;
4100 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4101 async_retrieval = TRUE;
4102 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4104 async_retrieval = FALSE;
4106 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4107 modest_platform_run_header_details_dialog (toplevel, header, async_retrieval, msg);
4109 g_object_unref (msg);
4113 * Show the header details in a ModestDetailsDialog widget
4116 modest_ui_actions_on_details (GtkAction *action,
4119 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4123 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4127 header = tny_msg_get_header (msg);
4129 headers_action_show_details (header, win, NULL);
4130 g_object_unref (header);
4132 g_object_unref (msg);
4133 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4135 GtkWidget *header_view;
4137 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4138 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4140 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4142 modest_platform_run_folder_details_dialog (toplevel, folder);
4143 g_object_unref (folder);
4149 modest_ui_actions_on_limit_error (GtkAction *action,
4152 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4154 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS_MAXIMUM_CHARACTERS_REACHED);
4159 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4160 ModestMsgEditWindow *window)
4162 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4164 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4168 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4169 ModestMsgEditWindow *window)
4171 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4173 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4178 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4179 ModestWindow *window)
4181 gboolean active, fullscreen = FALSE;
4182 ModestWindowMgr *mgr;
4184 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4186 /* Check if we want to toggle the toolbar view in fullscreen
4188 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4189 "ViewShowToolbarFullScreen")) {
4193 /* Toggle toolbar */
4194 mgr = modest_runtime_get_window_mgr ();
4195 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4199 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4200 ModestMsgEditWindow *window)
4202 modest_msg_edit_window_select_font (window);
4207 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4208 const gchar *display_name,
4211 /* don't update the display name if it was already set;
4212 * updating the display name apparently is expensive */
4213 const gchar* old_name = gtk_window_get_title (window);
4215 if (display_name == NULL)
4218 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4219 return; /* don't do anything */
4221 /* This is usually used to change the title of the main window, which
4222 * is the one that holds the folder view. Note that this change can
4223 * happen even when the widget doesn't have the focus. */
4224 gtk_window_set_title (window, display_name);
4229 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4231 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4232 modest_msg_edit_window_select_contacts (window);
4236 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4238 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4239 modest_msg_edit_window_check_names (window, FALSE);
4244 on_move_to_dialog_response (GtkDialog *dialog,
4248 GtkWidget *parent_win;
4249 MoveToInfo *helper = NULL;
4250 ModestFolderView *folder_view;
4251 gboolean unset_edit_mode = FALSE;
4253 helper = (MoveToInfo *) user_data;
4255 parent_win = (GtkWidget *) helper->win;
4256 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4257 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4259 TnyFolderStore *dst_folder;
4260 TnyFolderStore *selected;
4262 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4263 selected = modest_folder_view_get_selected (folder_view);
4264 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4265 g_object_unref (selected);
4267 case GTK_RESPONSE_NONE:
4268 case GTK_RESPONSE_CANCEL:
4269 case GTK_RESPONSE_DELETE_EVENT:
4271 case GTK_RESPONSE_OK:
4272 dst_folder = modest_folder_view_get_selected (folder_view);
4274 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4275 /* Clean list to move used for filtering */
4276 modest_folder_view_set_list_to_move (folder_view, NULL);
4278 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4281 GTK_WINDOW (parent_win));
4283 /* if the user selected a root folder
4284 (account) then do not perform any action */
4285 if (TNY_IS_ACCOUNT (dst_folder)) {
4286 g_signal_stop_emission_by_name (dialog, "response");
4290 /* Clean list to move used for filtering */
4291 modest_folder_view_set_list_to_move (folder_view, NULL);
4293 /* Moving from headers window in edit mode */
4294 modest_ui_actions_on_window_move_to (NULL, helper->list,
4296 MODEST_WINDOW (parent_win));
4300 g_object_unref (dst_folder);
4302 unset_edit_mode = TRUE;
4305 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4308 /* Free the helper and exit */
4310 g_object_unref (helper->list);
4311 if (unset_edit_mode) {
4312 #ifdef MODEST_TOOLKIT_HILDON2
4313 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4316 g_slice_free (MoveToInfo, helper);
4317 gtk_widget_destroy (GTK_WIDGET (dialog));
4321 create_move_to_dialog (GtkWindow *win,
4322 GtkWidget *folder_view,
4323 TnyList *list_to_move)
4325 GtkWidget *dialog, *tree_view = NULL;
4327 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4330 /* It could happen that we're trying to move a message from a
4331 window (msg window for example) after the main window was
4332 closed, so we can not just get the model of the folder
4334 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4335 const gchar *visible_id = NULL;
4337 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4338 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4339 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4340 MODEST_FOLDER_VIEW(tree_view));
4343 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4345 /* Show the same account than the one that is shown in the main window */
4346 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4349 const gchar *active_account_name = NULL;
4350 ModestAccountMgr *mgr = NULL;
4351 ModestAccountSettings *settings = NULL;
4352 ModestServerAccountSettings *store_settings = NULL;
4354 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4355 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4356 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4357 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4359 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4360 mgr = modest_runtime_get_account_mgr ();
4361 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4364 const gchar *store_account_name;
4365 store_settings = modest_account_settings_get_store_settings (settings);
4366 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4368 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4369 store_account_name);
4370 g_object_unref (store_settings);
4371 g_object_unref (settings);
4375 /* we keep a pointer to the embedded folder view, so we can
4376 * retrieve it with get_folder_view_from_move_to_dialog (see
4377 * above) later (needed for focus handling)
4379 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4381 /* Hide special folders */
4383 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4385 gtk_widget_show (GTK_WIDGET (tree_view));
4391 * Shows a confirmation dialog to the user when we're moving messages
4392 * from a remote server to the local storage. Returns the dialog
4393 * response. If it's other kind of movement then it always returns
4396 * This one is used by the next functions:
4397 * modest_ui_actions_on_paste - commented out
4398 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4401 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4402 TnyFolder *dest_folder,
4406 gint response = GTK_RESPONSE_OK;
4407 TnyAccount *account = NULL;
4408 TnyFolder *src_folder = NULL;
4409 TnyIterator *iter = NULL;
4410 TnyHeader *header = NULL;
4412 /* return with OK if the destination is a remote folder */
4413 if (modest_tny_folder_is_remote_folder (dest_folder))
4414 return GTK_RESPONSE_OK;
4416 /* Get source folder */
4417 iter = tny_list_create_iterator (headers);
4418 header = TNY_HEADER (tny_iterator_get_current (iter));
4420 src_folder = tny_header_get_folder (header);
4421 g_object_unref (header);
4423 g_object_unref (iter);
4425 /* if no src_folder, message may be an attahcment */
4426 if (src_folder == NULL)
4427 return GTK_RESPONSE_CANCEL;
4429 /* If the source is a local or MMC folder */
4430 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4431 g_object_unref (src_folder);
4432 return GTK_RESPONSE_OK;
4435 /* Get the account */
4436 account = tny_folder_get_account (src_folder);
4438 /* now if offline we ask the user */
4439 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4440 response = GTK_RESPONSE_OK;
4442 response = GTK_RESPONSE_CANCEL;
4445 g_object_unref (src_folder);
4446 g_object_unref (account);
4452 move_to_helper_destroyer (gpointer user_data)
4454 MoveToHelper *helper = (MoveToHelper *) user_data;
4456 /* Close the "Pasting" information banner */
4457 if (helper->banner) {
4458 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4459 g_object_unref (helper->banner);
4461 if (gtk_tree_row_reference_valid (helper->reference)) {
4462 gtk_tree_row_reference_free (helper->reference);
4463 helper->reference = NULL;
4469 move_to_cb (ModestMailOperation *mail_op,
4472 MoveToHelper *helper = (MoveToHelper *) user_data;
4473 GObject *object = modest_mail_operation_get_source (mail_op);
4475 /* Note that the operation could have failed, in that case do
4477 if (modest_mail_operation_get_status (mail_op) !=
4478 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4481 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4482 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4484 if (!modest_msg_view_window_select_next_message (self) &&
4485 !modest_msg_view_window_select_previous_message (self)) {
4486 /* No more messages to view, so close this window */
4487 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4490 g_object_unref (object);
4493 /* Destroy the helper */
4494 move_to_helper_destroyer (helper);
4498 folder_move_to_cb (ModestMailOperation *mail_op,
4499 TnyFolder *new_folder,
4504 object = modest_mail_operation_get_source (mail_op);
4506 move_to_cb (mail_op, user_data);
4511 msgs_move_to_cb (ModestMailOperation *mail_op,
4514 move_to_cb (mail_op, user_data);
4518 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4521 GObject *win = NULL;
4522 const GError *error;
4523 TnyAccount *account = NULL;
4525 win = modest_mail_operation_get_source (mail_op);
4526 error = modest_mail_operation_get_error (mail_op);
4528 if (TNY_IS_FOLDER (user_data))
4529 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4530 else if (TNY_IS_ACCOUNT (user_data))
4531 account = g_object_ref (user_data);
4533 /* If it's not a disk full error then show a generic error */
4534 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4535 (GtkWidget *) win, (GError *) error,
4537 modest_platform_run_information_dialog ((GtkWindow *) win,
4538 _("mail_in_ui_folder_move_target_error"),
4541 g_object_unref (account);
4543 g_object_unref (win);
4548 * Checks if we need a connection to do the transfer and if the user
4549 * wants to connect to complete it
4552 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
4553 TnyFolderStore *src_folder,
4555 TnyFolder *dst_folder,
4556 gboolean delete_originals,
4557 gboolean *need_connection,
4560 TnyAccount *src_account;
4561 gint uncached_msgs = 0;
4563 /* We don't need any further check if
4565 * 1- the source folder is local OR
4566 * 2- the device is already online
4568 if (!modest_tny_folder_store_is_remote (src_folder) ||
4569 tny_device_is_online (modest_runtime_get_device())) {
4570 *need_connection = FALSE;
4575 /* We must ask for a connection when
4577 * - the message(s) is not already cached OR
4578 * - the message(s) is cached but the leave_on_server setting
4579 * is FALSE (because we need to sync the source folder to
4580 * delete the message from the server (for IMAP we could do it
4581 * offline, it'll take place the next time we get a
4584 uncached_msgs = header_list_count_uncached_msgs (headers);
4585 src_account = get_account_from_folder_store (src_folder);
4586 if (uncached_msgs > 0) {
4590 *need_connection = TRUE;
4591 num_headers = tny_list_get_length (headers);
4592 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4594 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
4595 GTK_RESPONSE_CANCEL) {
4601 /* The transfer is possible and the user wants to */
4604 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4605 const gchar *account_name;
4606 gboolean leave_on_server;
4608 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4609 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4612 if (leave_on_server == TRUE) {
4613 *need_connection = FALSE;
4615 *need_connection = TRUE;
4618 *need_connection = FALSE;
4623 g_object_unref (src_account);
4627 xfer_messages_error_handler (ModestMailOperation *mail_op,
4631 const GError *error;
4632 TnyAccount *account;
4634 win = modest_mail_operation_get_source (mail_op);
4635 error = modest_mail_operation_get_error (mail_op);
4637 /* We cannot get the account from the mail op as that is the
4638 source account and for checking memory full conditions we
4639 need the destination one */
4640 account = TNY_ACCOUNT (user_data);
4643 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4644 (GtkWidget *) win, (GError*) error,
4645 account, _KR("cerm_memory_card_full"))) {
4646 modest_platform_run_information_dialog ((GtkWindow *) win,
4647 _("mail_in_ui_folder_move_target_error"),
4651 g_object_unref (win);
4655 TnyFolderStore *dst_folder;
4660 * Utility function that transfer messages from both the main window
4661 * and the msg view window when using the "Move to" dialog
4664 xfer_messages_performer (gboolean canceled,
4666 GtkWindow *parent_window,
4667 TnyAccount *account,
4670 ModestWindow *win = MODEST_WINDOW (parent_window);
4671 TnyAccount *dst_account = NULL;
4672 gboolean dst_forbids_message_add = FALSE;
4673 XferMsgsHelper *helper;
4674 MoveToHelper *movehelper;
4675 ModestMailOperation *mail_op;
4677 helper = (XferMsgsHelper *) user_data;
4679 if (canceled || err) {
4680 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4681 (GtkWidget *) parent_window, err,
4683 /* Show the proper error message */
4684 modest_ui_actions_on_account_connection_error (parent_window, account);
4689 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4691 /* tinymail will return NULL for local folders it seems */
4692 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4693 modest_tny_account_get_protocol_type (dst_account),
4694 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4696 if (dst_forbids_message_add) {
4697 modest_platform_information_banner (GTK_WIDGET (win),
4699 ngettext("mail_in_ui_folder_move_target_error",
4700 "mail_in_ui_folder_move_targets_error",
4701 tny_list_get_length (helper->headers)));
4705 movehelper = g_new0 (MoveToHelper, 1);
4708 /* Perform the mail operation */
4709 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4710 xfer_messages_error_handler,
4711 g_object_ref (dst_account),
4713 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4716 modest_mail_operation_xfer_msgs (mail_op,
4718 TNY_FOLDER (helper->dst_folder),
4723 g_object_unref (G_OBJECT (mail_op));
4726 g_object_unref (dst_account);
4727 g_object_unref (helper->dst_folder);
4728 g_object_unref (helper->headers);
4729 g_slice_free (XferMsgsHelper, helper);
4733 TnyFolder *src_folder;
4734 TnyFolderStore *dst_folder;
4735 gboolean delete_original;
4736 GtkWidget *folder_view;
4740 on_move_folder_cb (gboolean canceled,
4742 GtkWindow *parent_window,
4743 TnyAccount *account,
4746 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4747 GtkTreeSelection *sel;
4748 ModestMailOperation *mail_op = NULL;
4750 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4751 /* Note that the connection process can fail due to
4752 memory low conditions as it can not successfully
4753 store the summary */
4754 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4755 (GtkWidget*) parent_window, err,
4757 g_debug ("Error connecting when trying to move a folder");
4759 g_object_unref (G_OBJECT (info->src_folder));
4760 g_object_unref (G_OBJECT (info->dst_folder));
4765 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4766 #ifndef MODEST_TOOLKIT_HILDON2
4767 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4769 if (helper->banner != NULL) {
4770 g_object_ref (helper->banner);
4771 gtk_widget_show (GTK_WIDGET(helper->banner));
4774 /* Clean folder on header view before moving it */
4775 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4776 gtk_tree_selection_unselect_all (sel);
4778 /* Let gtk events run. We need that the folder
4779 view frees its reference to the source
4780 folder *before* issuing the mail operation
4781 so we need the signal handler of selection
4782 changed to happen before the mail
4784 while (gtk_events_pending ())
4785 gtk_main_iteration (); */
4788 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4789 modest_ui_actions_move_folder_error_handler,
4790 g_object_ref (info->dst_folder), g_object_unref);
4791 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4794 modest_mail_operation_xfer_folder (mail_op,
4795 TNY_FOLDER (info->src_folder),
4797 info->delete_original,
4800 g_object_unref (G_OBJECT (info->src_folder));
4802 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4805 /* Unref mail operation */
4806 g_object_unref (G_OBJECT (mail_op));
4807 g_object_unref (G_OBJECT (info->dst_folder));
4812 get_account_from_folder_store (TnyFolderStore *folder_store)
4814 if (TNY_IS_ACCOUNT (folder_store))
4815 return g_object_ref (folder_store);
4817 return tny_folder_get_account (TNY_FOLDER (folder_store));
4821 * UI handler for the "Move to" action when invoked from the
4822 * ModestFolderWindow
4825 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4826 TnyFolderStore *dst_folder,
4830 TnyFolderStore *src_folder = NULL;
4831 TnyIterator *iterator;
4833 if (tny_list_get_length (selection) != 1)
4836 iterator = tny_list_create_iterator (selection);
4837 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
4838 g_object_unref (iterator);
4841 gboolean do_xfer = TRUE;
4843 /* Allow only to transfer folders to the local root folder */
4844 if (TNY_IS_ACCOUNT (dst_folder) &&
4845 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
4846 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
4849 modest_platform_run_information_dialog (win,
4850 _("mail_in_ui_folder_move_target_error"),
4852 } else if (!TNY_IS_FOLDER (src_folder)) {
4853 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4858 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4859 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4861 info->src_folder = g_object_ref (src_folder);
4862 info->dst_folder = g_object_ref (dst_folder);
4863 info->delete_original = TRUE;
4864 info->folder_view = folder_view;
4866 connect_info->callback = on_move_folder_cb;
4867 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
4868 connect_info->data = info;
4870 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4871 TNY_FOLDER_STORE (src_folder),
4876 g_object_unref (src_folder);
4881 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
4882 TnyFolder *src_folder,
4884 TnyFolder *dst_folder)
4886 gboolean need_connection = TRUE;
4887 gboolean do_xfer = TRUE;
4888 XferMsgsHelper *helper;
4890 g_return_if_fail (TNY_IS_FOLDER (src_folder));
4891 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4892 g_return_if_fail (TNY_IS_LIST (headers));
4894 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
4895 headers, TNY_FOLDER (dst_folder),
4896 TRUE, &need_connection,
4899 /* If we don't want to transfer just return */
4903 /* Create the helper */
4904 helper = g_slice_new (XferMsgsHelper);
4905 helper->dst_folder = g_object_ref (dst_folder);
4906 helper->headers = g_object_ref (headers);
4908 if (need_connection) {
4909 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4910 connect_info->callback = xfer_messages_performer;
4911 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4912 connect_info->data = helper;
4914 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4915 TNY_FOLDER_STORE (src_folder),
4918 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
4919 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
4920 src_account, helper);
4921 g_object_unref (src_account);
4926 * UI handler for the "Move to" action when invoked from the
4927 * ModestMsgViewWindow
4930 modest_ui_actions_on_window_move_to (GtkAction *action,
4932 TnyFolderStore *dst_folder,
4935 TnyFolder *src_folder = NULL;
4937 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4940 TnyHeader *header = NULL;
4943 iter = tny_list_create_iterator (headers);
4944 header = (TnyHeader *) tny_iterator_get_current (iter);
4945 src_folder = tny_header_get_folder (header);
4947 /* Transfer the messages */
4948 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
4950 TNY_FOLDER (dst_folder));
4953 g_object_unref (header);
4954 g_object_unref (iter);
4955 g_object_unref (src_folder);
4960 modest_ui_actions_on_move_to (GtkAction *action,
4963 modest_ui_actions_on_edit_mode_move_to (win);
4967 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
4969 GtkWidget *dialog = NULL;
4970 MoveToInfo *helper = NULL;
4971 TnyList *list_to_move;
4973 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
4976 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
4981 if (tny_list_get_length (list_to_move) < 1) {
4982 g_object_unref (list_to_move);
4986 /* Create and run the dialog */
4987 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
4988 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
4989 GTK_WINDOW (dialog),
4993 helper = g_slice_new0 (MoveToInfo);
4994 helper->list = list_to_move;
4997 /* Listen to response signal */
4998 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5000 /* Show the dialog */
5001 gtk_widget_show (dialog);
5007 * Calls #HeadersFunc for each header already selected in the main
5008 * window or the message currently being shown in the msg view window
5011 do_headers_action (ModestWindow *win,
5015 TnyList *headers_list = NULL;
5016 TnyIterator *iter = NULL;
5017 TnyHeader *header = NULL;
5018 TnyFolder *folder = NULL;
5021 headers_list = get_selected_headers (win);
5025 /* Get the folder */
5026 iter = tny_list_create_iterator (headers_list);
5027 header = TNY_HEADER (tny_iterator_get_current (iter));
5029 folder = tny_header_get_folder (header);
5030 g_object_unref (header);
5033 /* Call the function for each header */
5034 while (!tny_iterator_is_done (iter)) {
5035 header = TNY_HEADER (tny_iterator_get_current (iter));
5036 func (header, win, user_data);
5037 g_object_unref (header);
5038 tny_iterator_next (iter);
5041 /* Trick: do a poke status in order to speed up the signaling
5044 tny_folder_poke_status (folder);
5045 g_object_unref (folder);
5049 g_object_unref (iter);
5050 g_object_unref (headers_list);
5054 modest_ui_actions_view_attachment (GtkAction *action,
5055 ModestWindow *window)
5057 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5058 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5060 /* not supported window for this action */
5061 g_return_if_reached ();
5066 modest_ui_actions_save_attachments (GtkAction *action,
5067 ModestWindow *window)
5069 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5071 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5074 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5076 /* not supported window for this action */
5077 g_return_if_reached ();
5082 modest_ui_actions_remove_attachments (GtkAction *action,
5083 ModestWindow *window)
5085 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5086 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5088 /* not supported window for this action */
5089 g_return_if_reached ();
5094 modest_ui_actions_on_settings (GtkAction *action,
5098 GtkWindow *toplevel;
5100 dialog = modest_platform_get_global_settings_dialog ();
5101 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5102 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5103 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5104 gtk_widget_show_all (dialog);
5106 gtk_dialog_run (GTK_DIALOG (dialog));
5108 gtk_widget_destroy (dialog);
5112 modest_ui_actions_on_help (GtkAction *action,
5115 /* Help app is not available at all in fremantle */
5116 #ifndef MODEST_TOOLKIT_HILDON2
5117 const gchar *help_id;
5119 g_return_if_fail (win && GTK_IS_WINDOW(win));
5121 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5124 modest_platform_show_help (GTK_WINDOW (win), help_id);
5129 modest_ui_actions_on_csm_help (GtkAction *action,
5132 /* Help app is not available at all in fremantle */
5136 retrieve_contents_cb (ModestMailOperation *mail_op,
5143 /* We only need this callback to show an error in case of
5144 memory low condition */
5145 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5146 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5151 retrieve_msg_contents_performer (gboolean canceled,
5153 GtkWindow *parent_window,
5154 TnyAccount *account,
5157 ModestMailOperation *mail_op;
5158 TnyList *headers = TNY_LIST (user_data);
5160 if (err || canceled) {
5161 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5162 (GtkWidget *) parent_window, err,
5167 /* Create mail operation */
5168 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5169 modest_ui_actions_disk_operations_error_handler,
5171 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5172 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5175 g_object_unref (mail_op);
5177 g_object_unref (headers);
5178 g_object_unref (account);
5182 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5183 ModestWindow *window)
5185 TnyList *headers = NULL;
5186 TnyAccount *account = NULL;
5187 TnyIterator *iter = NULL;
5188 TnyHeader *header = NULL;
5189 TnyFolder *folder = NULL;
5192 headers = get_selected_headers (window);
5196 /* Pick the account */
5197 iter = tny_list_create_iterator (headers);
5198 header = TNY_HEADER (tny_iterator_get_current (iter));
5199 folder = tny_header_get_folder (header);
5200 account = tny_folder_get_account (folder);
5201 g_object_unref (folder);
5202 g_object_unref (header);
5203 g_object_unref (iter);
5205 /* Connect and perform the message retrieval */
5206 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5207 g_object_ref (account),
5208 retrieve_msg_contents_performer,
5209 g_object_ref (headers));
5212 g_object_unref (account);
5213 g_object_unref (headers);
5217 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5219 g_return_if_fail (MODEST_IS_WINDOW (window));
5222 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5226 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5228 g_return_if_fail (MODEST_IS_WINDOW (window));
5231 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5235 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5236 ModestWindow *window)
5238 g_return_if_fail (MODEST_IS_WINDOW (window));
5241 modest_ui_actions_check_menu_dimming_rules (window);
5245 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5246 ModestWindow *window)
5248 g_return_if_fail (MODEST_IS_WINDOW (window));
5251 modest_ui_actions_check_menu_dimming_rules (window);
5255 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5256 ModestWindow *window)
5258 g_return_if_fail (MODEST_IS_WINDOW (window));
5261 modest_ui_actions_check_menu_dimming_rules (window);
5265 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5266 ModestWindow *window)
5268 g_return_if_fail (MODEST_IS_WINDOW (window));
5271 modest_ui_actions_check_menu_dimming_rules (window);
5275 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5276 ModestWindow *window)
5278 g_return_if_fail (MODEST_IS_WINDOW (window));
5281 modest_ui_actions_check_menu_dimming_rules (window);
5285 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5286 ModestWindow *window)
5288 g_return_if_fail (MODEST_IS_WINDOW (window));
5291 modest_ui_actions_check_menu_dimming_rules (window);
5295 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5296 ModestWindow *window)
5298 g_return_if_fail (MODEST_IS_WINDOW (window));
5301 modest_ui_actions_check_menu_dimming_rules (window);
5305 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5306 ModestWindow *window)
5308 g_return_if_fail (MODEST_IS_WINDOW (window));
5311 modest_ui_actions_check_menu_dimming_rules (window);
5315 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5316 ModestWindow *window)
5318 g_return_if_fail (MODEST_IS_WINDOW (window));
5321 modest_ui_actions_check_menu_dimming_rules (window);
5325 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5327 g_return_if_fail (MODEST_IS_WINDOW (window));
5329 /* we check for low-mem; in that case, show a warning, and don't allow
5332 if (modest_platform_check_memory_low (window, TRUE))
5335 modest_platform_show_search_messages (GTK_WINDOW (window));
5339 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5341 g_return_if_fail (MODEST_IS_WINDOW (win));
5344 /* we check for low-mem; in that case, show a warning, and don't allow
5345 * for the addressbook
5347 if (modest_platform_check_memory_low (win, TRUE))
5351 modest_platform_show_addressbook (GTK_WINDOW (win));
5356 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5357 ModestWindow *window)
5360 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5362 if (GTK_IS_TOGGLE_ACTION (action))
5363 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5367 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5373 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5379 const gchar* server_name = NULL;
5380 TnyTransportAccount *transport;
5381 gchar *message = NULL;
5382 ModestProtocol *protocol;
5384 /* Don't show anything if the user cancelled something or the
5385 * send receive request is not interactive. Authentication
5386 * errors are managed by the account store so no need to show
5387 * a dialog here again */
5388 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5389 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5390 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5394 /* Get the server name. Note that we could be using a
5395 connection specific transport account */
5396 transport = (TnyTransportAccount *)
5397 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5399 ModestTnyAccountStore *acc_store;
5400 const gchar *acc_name;
5401 TnyTransportAccount *conn_specific;
5403 acc_store = modest_runtime_get_account_store();
5404 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5405 conn_specific = (TnyTransportAccount *)
5406 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5407 if (conn_specific) {
5408 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5409 g_object_unref (conn_specific);
5411 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5413 g_object_unref (transport);
5417 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5418 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5419 tny_account_get_proto (TNY_ACCOUNT (transport)));
5421 g_warning ("%s: Account with no proto", __FUNCTION__);
5425 /* Show the appropriate message text for the GError: */
5426 switch (err->code) {
5427 case TNY_SERVICE_ERROR_CONNECT:
5428 message = modest_protocol_get_translation (protocol,
5429 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5432 case TNY_SERVICE_ERROR_SEND:
5433 message = g_strdup (_CS_UNABLE_TO_SEND);
5435 case TNY_SERVICE_ERROR_UNAVAILABLE:
5436 message = modest_protocol_get_translation (protocol,
5437 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5441 g_warning ("%s: unexpected ERROR %d",
5442 __FUNCTION__, err->code);
5443 message = g_strdup (_CS_UNABLE_TO_SEND);
5447 modest_platform_run_information_dialog (NULL, message, FALSE);
5452 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5457 ModestWindow *top_window = NULL;
5458 ModestWindowMgr *mgr = NULL;
5459 GtkWidget *header_view = NULL;
5460 TnyFolder *selected_folder = NULL;
5461 TnyFolderType folder_type;
5463 mgr = modest_runtime_get_window_mgr ();
5464 top_window = modest_window_mgr_get_current_top (mgr);
5469 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5470 header_view = (GtkWidget *)
5471 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5474 /* Get selected folder */
5476 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5477 if (!selected_folder)
5480 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5481 #if GTK_CHECK_VERSION(2, 8, 0)
5482 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5483 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5484 GtkTreeViewColumn *tree_column;
5486 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5487 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5489 gtk_tree_view_column_queue_resize (tree_column);
5491 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5492 gtk_widget_queue_draw (header_view);
5495 #ifndef MODEST_TOOLKIT_HILDON2
5496 /* Rerun dimming rules, because the message could become deletable for example */
5497 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5498 MODEST_DIMMING_RULES_TOOLBAR);
5499 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5500 MODEST_DIMMING_RULES_MENU);
5504 g_object_unref (selected_folder);
5508 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5509 TnyAccount *account)
5511 ModestProtocolType protocol_type;
5512 ModestProtocol *protocol;
5513 gchar *error_note = NULL;
5515 protocol_type = modest_tny_account_get_protocol_type (account);
5516 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5519 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5520 if (error_note == NULL) {
5521 g_warning ("%s: This should not be reached", __FUNCTION__);
5523 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
5524 g_free (error_note);
5529 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5533 TnyFolderStore *folder = NULL;
5534 TnyAccount *account = NULL;
5535 ModestProtocolType proto;
5536 ModestProtocol *protocol;
5537 TnyHeader *header = NULL;
5539 if (MODEST_IS_HEADER_WINDOW (win)) {
5540 GtkWidget *header_view;
5541 TnyList* headers = NULL;
5543 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5544 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5545 if (!headers || tny_list_get_length (headers) == 0) {
5547 g_object_unref (headers);
5550 iter = tny_list_create_iterator (headers);
5551 header = TNY_HEADER (tny_iterator_get_current (iter));
5553 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5555 g_warning ("List should contain headers");
5557 g_object_unref (iter);
5558 g_object_unref (headers);
5559 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5560 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5562 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5565 if (!header || !folder)
5568 /* Get the account type */
5569 account = tny_folder_get_account (TNY_FOLDER (folder));
5570 proto = modest_tny_account_get_protocol_type (account);
5571 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5574 subject = tny_header_dup_subject (header);
5575 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5579 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5585 g_object_unref (account);
5587 g_object_unref (folder);
5589 g_object_unref (header);
5595 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5596 const gchar *account_name,
5597 const gchar *account_title)
5599 ModestAccountMgr *account_mgr;
5602 ModestProtocol *protocol;
5603 gboolean removed = FALSE;
5605 g_return_val_if_fail (account_name, FALSE);
5606 g_return_val_if_fail (account_title, FALSE);
5608 account_mgr = modest_runtime_get_account_mgr();
5610 /* The warning text depends on the account type: */
5611 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5612 modest_account_mgr_get_store_protocol (account_mgr,
5614 txt = modest_protocol_get_translation (protocol,
5615 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5618 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5620 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5624 if (response == GTK_RESPONSE_OK) {
5625 /* Remove account. If it succeeds then it also removes
5626 the account from the ModestAccountView: */
5627 gboolean is_default = FALSE;
5628 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5629 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5631 g_free (default_account_name);
5633 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5635 /* Close all email notifications, we cannot
5636 distinguish if the notification belongs to
5637 this account or not, so for safety reasons
5638 we remove them all */
5639 modest_platform_remove_new_mail_notifications (FALSE);
5641 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5648 on_fetch_images_performer (gboolean canceled,
5650 GtkWindow *parent_window,
5651 TnyAccount *account,
5654 if (err || canceled) {
5655 /* Show an unable to retrieve images ??? */
5659 /* Note that the user could have closed the window while connecting */
5660 if (GTK_WIDGET_VISIBLE (parent_window))
5661 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5662 g_object_unref ((GObject *) user_data);
5666 modest_ui_actions_on_fetch_images (GtkAction *action,
5667 ModestWindow *window)
5669 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5671 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5673 on_fetch_images_performer,
5674 g_object_ref (window));
5678 modest_ui_actions_on_reload_message (const gchar *msg_id)
5680 ModestWindow *window = NULL;
5682 g_return_if_fail (msg_id && msg_id[0] != '\0');
5683 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5689 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5692 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5695 /** Check whether any connections are active, and cancel them if
5697 * Returns TRUE is there was no problem,
5698 * or if an operation was cancelled so we can continue.
5699 * Returns FALSE if the user chose to cancel his request instead.
5703 modest_ui_actions_check_for_active_account (ModestWindow *self,
5704 const gchar* account_name)
5706 ModestTnySendQueue *send_queue;
5707 ModestTnyAccountStore *acc_store;
5708 ModestMailOperationQueue* queue;
5709 TnyConnectionStatus store_conn_status;
5710 TnyAccount *store_account = NULL, *transport_account = NULL;
5711 gboolean retval = TRUE, sending = FALSE;
5713 acc_store = modest_runtime_get_account_store ();
5714 queue = modest_runtime_get_mail_operation_queue ();
5717 modest_tny_account_store_get_server_account (acc_store,
5719 TNY_ACCOUNT_TYPE_STORE);
5721 /* This could happen if the account was deleted before the
5722 call to this function */
5727 modest_tny_account_store_get_server_account (acc_store,
5729 TNY_ACCOUNT_TYPE_TRANSPORT);
5731 /* This could happen if the account was deleted before the
5732 call to this function */
5733 if (!transport_account) {
5734 g_object_unref (store_account);
5738 /* If the transport account was not used yet, then the send
5739 queue could not exist (it's created on demand) */
5740 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5741 if (TNY_IS_SEND_QUEUE (send_queue))
5742 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5744 store_conn_status = tny_account_get_connection_status (store_account);
5745 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5748 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
5749 _("emev_nc_disconnect_account"));
5750 if (response == GTK_RESPONSE_OK) {
5759 /* FIXME: We should only cancel those of this account */
5760 modest_mail_operation_queue_cancel_all (queue);
5762 /* Also disconnect the account */
5763 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5764 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5765 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5769 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5775 g_object_unref (store_account);
5776 g_object_unref (transport_account);