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 ("sfil_ni_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("ckdg_ib_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("sfil_ni_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("ckdg_ib_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("ckdg_ib_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("mcen_ib_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("ecoc_ib_edwin_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,
3844 _CS("ckct_nw_pasting"));
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,
3901 _CS("ckct_nw_pasting"));
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,
3921 _CS("ckct_nw_pasting"));
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);
4085 #ifndef MODEST_TOOLKIT_HILDON2
4086 gtk_window_present (GTK_WINDOW (window));
4091 * Used by modest_ui_actions_on_details to call do_headers_action
4094 headers_action_show_details (TnyHeader *header,
4095 ModestWindow *window,
4099 gboolean async_retrieval;
4102 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4103 async_retrieval = TRUE;
4104 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4106 async_retrieval = FALSE;
4108 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4110 g_object_unref (msg);
4114 * Show the header details in a ModestDetailsDialog widget
4117 modest_ui_actions_on_details (GtkAction *action,
4120 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4124 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4128 header = tny_msg_get_header (msg);
4130 headers_action_show_details (header, win, NULL);
4131 g_object_unref (header);
4133 g_object_unref (msg);
4134 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4136 GtkWidget *header_view;
4138 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4139 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4141 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4143 modest_platform_run_folder_details_dialog (toplevel, folder);
4144 g_object_unref (folder);
4150 modest_ui_actions_on_limit_error (GtkAction *action,
4153 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4155 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4160 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4161 ModestMsgEditWindow *window)
4163 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4165 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4169 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4170 ModestMsgEditWindow *window)
4172 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4174 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4179 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4180 ModestWindow *window)
4182 gboolean active, fullscreen = FALSE;
4183 ModestWindowMgr *mgr;
4185 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4187 /* Check if we want to toggle the toolbar view in fullscreen
4189 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4190 "ViewShowToolbarFullScreen")) {
4194 /* Toggle toolbar */
4195 mgr = modest_runtime_get_window_mgr ();
4196 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4200 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4201 ModestMsgEditWindow *window)
4203 modest_msg_edit_window_select_font (window);
4208 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4209 const gchar *display_name,
4212 /* don't update the display name if it was already set;
4213 * updating the display name apparently is expensive */
4214 const gchar* old_name = gtk_window_get_title (window);
4216 if (display_name == NULL)
4219 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4220 return; /* don't do anything */
4222 /* This is usually used to change the title of the main window, which
4223 * is the one that holds the folder view. Note that this change can
4224 * happen even when the widget doesn't have the focus. */
4225 gtk_window_set_title (window, display_name);
4230 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4232 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4233 modest_msg_edit_window_select_contacts (window);
4237 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4239 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4240 modest_msg_edit_window_check_names (window, FALSE);
4245 on_move_to_dialog_response (GtkDialog *dialog,
4249 GtkWidget *parent_win;
4250 MoveToInfo *helper = NULL;
4251 ModestFolderView *folder_view;
4252 gboolean unset_edit_mode = FALSE;
4254 helper = (MoveToInfo *) user_data;
4256 parent_win = (GtkWidget *) helper->win;
4257 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4258 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4260 TnyFolderStore *dst_folder;
4261 TnyFolderStore *selected;
4263 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4264 selected = modest_folder_view_get_selected (folder_view);
4265 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4266 g_object_unref (selected);
4268 case GTK_RESPONSE_NONE:
4269 case GTK_RESPONSE_CANCEL:
4270 case GTK_RESPONSE_DELETE_EVENT:
4272 case GTK_RESPONSE_OK:
4273 dst_folder = modest_folder_view_get_selected (folder_view);
4275 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4276 /* Clean list to move used for filtering */
4277 modest_folder_view_set_list_to_move (folder_view, NULL);
4279 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4282 GTK_WINDOW (parent_win));
4284 /* if the user selected a root folder
4285 (account) then do not perform any action */
4286 if (TNY_IS_ACCOUNT (dst_folder)) {
4287 g_signal_stop_emission_by_name (dialog, "response");
4291 /* Clean list to move used for filtering */
4292 modest_folder_view_set_list_to_move (folder_view, NULL);
4294 /* Moving from headers window in edit mode */
4295 modest_ui_actions_on_window_move_to (NULL, helper->list,
4297 MODEST_WINDOW (parent_win));
4301 g_object_unref (dst_folder);
4303 unset_edit_mode = TRUE;
4306 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4309 /* Free the helper and exit */
4311 g_object_unref (helper->list);
4312 if (unset_edit_mode) {
4313 #ifdef MODEST_TOOLKIT_HILDON2
4314 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4317 g_slice_free (MoveToInfo, helper);
4318 gtk_widget_destroy (GTK_WIDGET (dialog));
4322 create_move_to_dialog (GtkWindow *win,
4323 GtkWidget *folder_view,
4324 TnyList *list_to_move)
4326 GtkWidget *dialog, *tree_view = NULL;
4328 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4331 /* It could happen that we're trying to move a message from a
4332 window (msg window for example) after the main window was
4333 closed, so we can not just get the model of the folder
4335 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4336 const gchar *visible_id = NULL;
4338 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4339 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4340 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4341 MODEST_FOLDER_VIEW(tree_view));
4344 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4346 /* Show the same account than the one that is shown in the main window */
4347 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4350 const gchar *active_account_name = NULL;
4351 ModestAccountMgr *mgr = NULL;
4352 ModestAccountSettings *settings = NULL;
4353 ModestServerAccountSettings *store_settings = NULL;
4355 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4356 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4357 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
4358 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
4360 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4361 mgr = modest_runtime_get_account_mgr ();
4362 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4365 const gchar *store_account_name;
4366 store_settings = modest_account_settings_get_store_settings (settings);
4367 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4369 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4370 store_account_name);
4371 g_object_unref (store_settings);
4372 g_object_unref (settings);
4376 /* we keep a pointer to the embedded folder view, so we can
4377 * retrieve it with get_folder_view_from_move_to_dialog (see
4378 * above) later (needed for focus handling)
4380 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4382 /* Hide special folders */
4384 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4386 gtk_widget_show (GTK_WIDGET (tree_view));
4392 * Shows a confirmation dialog to the user when we're moving messages
4393 * from a remote server to the local storage. Returns the dialog
4394 * response. If it's other kind of movement then it always returns
4397 * This one is used by the next functions:
4398 * modest_ui_actions_on_paste - commented out
4399 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4402 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4403 TnyFolder *dest_folder,
4407 gint response = GTK_RESPONSE_OK;
4408 TnyAccount *account = NULL;
4409 TnyFolder *src_folder = NULL;
4410 TnyIterator *iter = NULL;
4411 TnyHeader *header = NULL;
4413 /* return with OK if the destination is a remote folder */
4414 if (modest_tny_folder_is_remote_folder (dest_folder))
4415 return GTK_RESPONSE_OK;
4417 /* Get source folder */
4418 iter = tny_list_create_iterator (headers);
4419 header = TNY_HEADER (tny_iterator_get_current (iter));
4421 src_folder = tny_header_get_folder (header);
4422 g_object_unref (header);
4424 g_object_unref (iter);
4426 /* if no src_folder, message may be an attahcment */
4427 if (src_folder == NULL)
4428 return GTK_RESPONSE_CANCEL;
4430 /* If the source is a local or MMC folder */
4431 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4432 g_object_unref (src_folder);
4433 return GTK_RESPONSE_OK;
4436 /* Get the account */
4437 account = tny_folder_get_account (src_folder);
4439 /* now if offline we ask the user */
4440 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4441 response = GTK_RESPONSE_OK;
4443 response = GTK_RESPONSE_CANCEL;
4446 g_object_unref (src_folder);
4447 g_object_unref (account);
4453 move_to_helper_destroyer (gpointer user_data)
4455 MoveToHelper *helper = (MoveToHelper *) user_data;
4457 /* Close the "Pasting" information banner */
4458 if (helper->banner) {
4459 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4460 g_object_unref (helper->banner);
4462 if (gtk_tree_row_reference_valid (helper->reference)) {
4463 gtk_tree_row_reference_free (helper->reference);
4464 helper->reference = NULL;
4470 move_to_cb (ModestMailOperation *mail_op,
4473 MoveToHelper *helper = (MoveToHelper *) user_data;
4474 GObject *object = modest_mail_operation_get_source (mail_op);
4476 /* Note that the operation could have failed, in that case do
4478 if (modest_mail_operation_get_status (mail_op) !=
4479 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4482 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4483 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4485 if (!modest_msg_view_window_select_next_message (self) &&
4486 !modest_msg_view_window_select_previous_message (self)) {
4487 /* No more messages to view, so close this window */
4488 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4491 g_object_unref (object);
4494 /* Destroy the helper */
4495 move_to_helper_destroyer (helper);
4499 folder_move_to_cb (ModestMailOperation *mail_op,
4500 TnyFolder *new_folder,
4505 object = modest_mail_operation_get_source (mail_op);
4507 move_to_cb (mail_op, user_data);
4512 msgs_move_to_cb (ModestMailOperation *mail_op,
4515 move_to_cb (mail_op, user_data);
4519 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4522 GObject *win = NULL;
4523 const GError *error;
4524 TnyAccount *account = NULL;
4526 win = modest_mail_operation_get_source (mail_op);
4527 error = modest_mail_operation_get_error (mail_op);
4529 if (TNY_IS_FOLDER (user_data))
4530 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4531 else if (TNY_IS_ACCOUNT (user_data))
4532 account = g_object_ref (user_data);
4534 /* If it's not a disk full error then show a generic error */
4535 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4536 (GtkWidget *) win, (GError *) error,
4538 modest_platform_run_information_dialog ((GtkWindow *) win,
4539 _("mail_in_ui_folder_move_target_error"),
4542 g_object_unref (account);
4544 g_object_unref (win);
4549 * Checks if we need a connection to do the transfer and if the user
4550 * wants to connect to complete it
4553 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
4554 TnyFolderStore *src_folder,
4556 TnyFolder *dst_folder,
4557 gboolean delete_originals,
4558 gboolean *need_connection,
4561 TnyAccount *src_account;
4562 gint uncached_msgs = 0;
4564 /* We don't need any further check if
4566 * 1- the source folder is local OR
4567 * 2- the device is already online
4569 if (!modest_tny_folder_store_is_remote (src_folder) ||
4570 tny_device_is_online (modest_runtime_get_device())) {
4571 *need_connection = FALSE;
4576 /* We must ask for a connection when
4578 * - the message(s) is not already cached OR
4579 * - the message(s) is cached but the leave_on_server setting
4580 * is FALSE (because we need to sync the source folder to
4581 * delete the message from the server (for IMAP we could do it
4582 * offline, it'll take place the next time we get a
4585 uncached_msgs = header_list_count_uncached_msgs (headers);
4586 src_account = get_account_from_folder_store (src_folder);
4587 if (uncached_msgs > 0) {
4591 *need_connection = TRUE;
4592 num_headers = tny_list_get_length (headers);
4593 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4595 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
4596 GTK_RESPONSE_CANCEL) {
4602 /* The transfer is possible and the user wants to */
4605 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
4606 const gchar *account_name;
4607 gboolean leave_on_server;
4609 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4610 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4613 if (leave_on_server == TRUE) {
4614 *need_connection = FALSE;
4616 *need_connection = TRUE;
4619 *need_connection = FALSE;
4624 g_object_unref (src_account);
4628 xfer_messages_error_handler (ModestMailOperation *mail_op,
4632 const GError *error;
4633 TnyAccount *account;
4635 win = modest_mail_operation_get_source (mail_op);
4636 error = modest_mail_operation_get_error (mail_op);
4638 /* We cannot get the account from the mail op as that is the
4639 source account and for checking memory full conditions we
4640 need the destination one */
4641 account = TNY_ACCOUNT (user_data);
4644 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4645 (GtkWidget *) win, (GError*) error,
4646 account, _KR("cerm_memory_card_full"))) {
4647 modest_platform_run_information_dialog ((GtkWindow *) win,
4648 _("mail_in_ui_folder_move_target_error"),
4652 g_object_unref (win);
4656 TnyFolderStore *dst_folder;
4661 * Utility function that transfer messages from both the main window
4662 * and the msg view window when using the "Move to" dialog
4665 xfer_messages_performer (gboolean canceled,
4667 GtkWindow *parent_window,
4668 TnyAccount *account,
4671 ModestWindow *win = MODEST_WINDOW (parent_window);
4672 TnyAccount *dst_account = NULL;
4673 gboolean dst_forbids_message_add = FALSE;
4674 XferMsgsHelper *helper;
4675 MoveToHelper *movehelper;
4676 ModestMailOperation *mail_op;
4678 helper = (XferMsgsHelper *) user_data;
4680 if (canceled || err) {
4681 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4682 (GtkWidget *) parent_window, err,
4684 /* Show the proper error message */
4685 modest_ui_actions_on_account_connection_error (parent_window, account);
4690 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
4692 /* tinymail will return NULL for local folders it seems */
4693 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4694 modest_tny_account_get_protocol_type (dst_account),
4695 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
4697 if (dst_forbids_message_add) {
4698 modest_platform_information_banner (GTK_WIDGET (win),
4700 ngettext("mail_in_ui_folder_move_target_error",
4701 "mail_in_ui_folder_move_targets_error",
4702 tny_list_get_length (helper->headers)));
4706 movehelper = g_new0 (MoveToHelper, 1);
4709 /* Perform the mail operation */
4710 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4711 xfer_messages_error_handler,
4712 g_object_ref (dst_account),
4714 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4717 modest_mail_operation_xfer_msgs (mail_op,
4719 TNY_FOLDER (helper->dst_folder),
4724 g_object_unref (G_OBJECT (mail_op));
4727 g_object_unref (dst_account);
4728 g_object_unref (helper->dst_folder);
4729 g_object_unref (helper->headers);
4730 g_slice_free (XferMsgsHelper, helper);
4734 TnyFolder *src_folder;
4735 TnyFolderStore *dst_folder;
4736 gboolean delete_original;
4737 GtkWidget *folder_view;
4741 on_move_folder_cb (gboolean canceled,
4743 GtkWindow *parent_window,
4744 TnyAccount *account,
4747 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4748 GtkTreeSelection *sel;
4749 ModestMailOperation *mail_op = NULL;
4751 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
4752 /* Note that the connection process can fail due to
4753 memory low conditions as it can not successfully
4754 store the summary */
4755 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4756 (GtkWidget*) parent_window, err,
4758 g_debug ("Error connecting when trying to move a folder");
4760 g_object_unref (G_OBJECT (info->src_folder));
4761 g_object_unref (G_OBJECT (info->dst_folder));
4766 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4767 #ifndef MODEST_TOOLKIT_HILDON2
4768 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4769 _CS("ckct_nw_pasting"));
4770 if (helper->banner != NULL) {
4771 g_object_ref (helper->banner);
4772 gtk_widget_show (GTK_WIDGET(helper->banner));
4775 /* Clean folder on header view before moving it */
4776 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4777 gtk_tree_selection_unselect_all (sel);
4779 /* Let gtk events run. We need that the folder
4780 view frees its reference to the source
4781 folder *before* issuing the mail operation
4782 so we need the signal handler of selection
4783 changed to happen before the mail
4785 while (gtk_events_pending ())
4786 gtk_main_iteration (); */
4789 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4790 modest_ui_actions_move_folder_error_handler,
4791 g_object_ref (info->dst_folder), g_object_unref);
4792 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4795 modest_mail_operation_xfer_folder (mail_op,
4796 TNY_FOLDER (info->src_folder),
4798 info->delete_original,
4801 g_object_unref (G_OBJECT (info->src_folder));
4803 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
4806 /* Unref mail operation */
4807 g_object_unref (G_OBJECT (mail_op));
4808 g_object_unref (G_OBJECT (info->dst_folder));
4813 get_account_from_folder_store (TnyFolderStore *folder_store)
4815 if (TNY_IS_ACCOUNT (folder_store))
4816 return g_object_ref (folder_store);
4818 return tny_folder_get_account (TNY_FOLDER (folder_store));
4822 * UI handler for the "Move to" action when invoked from the
4823 * ModestFolderWindow
4826 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
4827 TnyFolderStore *dst_folder,
4831 TnyFolderStore *src_folder = NULL;
4832 TnyIterator *iterator;
4834 if (tny_list_get_length (selection) != 1)
4837 iterator = tny_list_create_iterator (selection);
4838 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
4839 g_object_unref (iterator);
4842 gboolean do_xfer = TRUE;
4844 /* Allow only to transfer folders to the local root folder */
4845 if (TNY_IS_ACCOUNT (dst_folder) &&
4846 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
4847 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
4850 modest_platform_run_information_dialog (win,
4851 _("mail_in_ui_folder_move_target_error"),
4853 } else if (!TNY_IS_FOLDER (src_folder)) {
4854 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4859 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4860 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4862 info->src_folder = g_object_ref (src_folder);
4863 info->dst_folder = g_object_ref (dst_folder);
4864 info->delete_original = TRUE;
4865 info->folder_view = folder_view;
4867 connect_info->callback = on_move_folder_cb;
4868 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
4869 connect_info->data = info;
4871 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4872 TNY_FOLDER_STORE (src_folder),
4877 g_object_unref (src_folder);
4882 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
4883 TnyFolder *src_folder,
4885 TnyFolder *dst_folder)
4887 gboolean need_connection = TRUE;
4888 gboolean do_xfer = TRUE;
4889 XferMsgsHelper *helper;
4891 g_return_if_fail (TNY_IS_FOLDER (src_folder));
4892 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4893 g_return_if_fail (TNY_IS_LIST (headers));
4895 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
4896 headers, TNY_FOLDER (dst_folder),
4897 TRUE, &need_connection,
4900 /* If we don't want to transfer just return */
4904 /* Create the helper */
4905 helper = g_slice_new (XferMsgsHelper);
4906 helper->dst_folder = g_object_ref (dst_folder);
4907 helper->headers = g_object_ref (headers);
4909 if (need_connection) {
4910 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4911 connect_info->callback = xfer_messages_performer;
4912 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4913 connect_info->data = helper;
4915 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4916 TNY_FOLDER_STORE (src_folder),
4919 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
4920 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
4921 src_account, helper);
4922 g_object_unref (src_account);
4927 * UI handler for the "Move to" action when invoked from the
4928 * ModestMsgViewWindow
4931 modest_ui_actions_on_window_move_to (GtkAction *action,
4933 TnyFolderStore *dst_folder,
4936 TnyFolder *src_folder = NULL;
4938 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4941 TnyHeader *header = NULL;
4944 iter = tny_list_create_iterator (headers);
4945 header = (TnyHeader *) tny_iterator_get_current (iter);
4946 src_folder = tny_header_get_folder (header);
4948 /* Transfer the messages */
4949 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
4951 TNY_FOLDER (dst_folder));
4954 g_object_unref (header);
4955 g_object_unref (iter);
4956 g_object_unref (src_folder);
4961 modest_ui_actions_on_move_to (GtkAction *action,
4964 modest_ui_actions_on_edit_mode_move_to (win);
4968 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
4970 GtkWidget *dialog = NULL;
4971 MoveToInfo *helper = NULL;
4972 TnyList *list_to_move;
4974 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
4977 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
4982 if (tny_list_get_length (list_to_move) < 1) {
4983 g_object_unref (list_to_move);
4987 /* Create and run the dialog */
4988 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
4989 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
4990 GTK_WINDOW (dialog),
4994 helper = g_slice_new0 (MoveToInfo);
4995 helper->list = list_to_move;
4998 /* Listen to response signal */
4999 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5001 /* Show the dialog */
5002 gtk_widget_show (dialog);
5008 * Calls #HeadersFunc for each header already selected in the main
5009 * window or the message currently being shown in the msg view window
5012 do_headers_action (ModestWindow *win,
5016 TnyList *headers_list = NULL;
5017 TnyIterator *iter = NULL;
5018 TnyHeader *header = NULL;
5019 TnyFolder *folder = NULL;
5022 headers_list = get_selected_headers (win);
5026 /* Get the folder */
5027 iter = tny_list_create_iterator (headers_list);
5028 header = TNY_HEADER (tny_iterator_get_current (iter));
5030 folder = tny_header_get_folder (header);
5031 g_object_unref (header);
5034 /* Call the function for each header */
5035 while (!tny_iterator_is_done (iter)) {
5036 header = TNY_HEADER (tny_iterator_get_current (iter));
5037 func (header, win, user_data);
5038 g_object_unref (header);
5039 tny_iterator_next (iter);
5042 /* Trick: do a poke status in order to speed up the signaling
5045 tny_folder_poke_status (folder);
5046 g_object_unref (folder);
5050 g_object_unref (iter);
5051 g_object_unref (headers_list);
5055 modest_ui_actions_view_attachment (GtkAction *action,
5056 ModestWindow *window)
5058 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5059 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5061 /* not supported window for this action */
5062 g_return_if_reached ();
5067 modest_ui_actions_save_attachments (GtkAction *action,
5068 ModestWindow *window)
5070 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5072 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5075 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5077 /* not supported window for this action */
5078 g_return_if_reached ();
5083 modest_ui_actions_remove_attachments (GtkAction *action,
5084 ModestWindow *window)
5086 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5087 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5089 /* not supported window for this action */
5090 g_return_if_reached ();
5095 modest_ui_actions_on_settings (GtkAction *action,
5099 GtkWindow *toplevel;
5101 dialog = modest_platform_get_global_settings_dialog ();
5102 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5103 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5104 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5105 gtk_widget_show_all (dialog);
5107 gtk_dialog_run (GTK_DIALOG (dialog));
5109 gtk_widget_destroy (dialog);
5113 modest_ui_actions_on_help (GtkAction *action,
5116 /* Help app is not available at all in fremantle */
5117 #ifndef MODEST_TOOLKIT_HILDON2
5118 const gchar *help_id;
5120 g_return_if_fail (win && GTK_IS_WINDOW(win));
5122 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5125 modest_platform_show_help (GTK_WINDOW (win), help_id);
5130 modest_ui_actions_on_csm_help (GtkAction *action,
5133 /* Help app is not available at all in fremantle */
5137 retrieve_contents_cb (ModestMailOperation *mail_op,
5144 /* We only need this callback to show an error in case of
5145 memory low condition */
5146 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5147 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5152 retrieve_msg_contents_performer (gboolean canceled,
5154 GtkWindow *parent_window,
5155 TnyAccount *account,
5158 ModestMailOperation *mail_op;
5159 TnyList *headers = TNY_LIST (user_data);
5161 if (err || canceled) {
5162 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5163 (GtkWidget *) parent_window, err,
5168 /* Create mail operation */
5169 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5170 modest_ui_actions_disk_operations_error_handler,
5172 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5173 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5176 g_object_unref (mail_op);
5178 g_object_unref (headers);
5179 g_object_unref (account);
5183 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5184 ModestWindow *window)
5186 TnyList *headers = NULL;
5187 TnyAccount *account = NULL;
5188 TnyIterator *iter = NULL;
5189 TnyHeader *header = NULL;
5190 TnyFolder *folder = NULL;
5193 headers = get_selected_headers (window);
5197 /* Pick the account */
5198 iter = tny_list_create_iterator (headers);
5199 header = TNY_HEADER (tny_iterator_get_current (iter));
5200 folder = tny_header_get_folder (header);
5201 account = tny_folder_get_account (folder);
5202 g_object_unref (folder);
5203 g_object_unref (header);
5204 g_object_unref (iter);
5206 /* Connect and perform the message retrieval */
5207 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5208 g_object_ref (account),
5209 retrieve_msg_contents_performer,
5210 g_object_ref (headers));
5213 g_object_unref (account);
5214 g_object_unref (headers);
5218 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5220 g_return_if_fail (MODEST_IS_WINDOW (window));
5223 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5227 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5229 g_return_if_fail (MODEST_IS_WINDOW (window));
5232 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5236 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5237 ModestWindow *window)
5239 g_return_if_fail (MODEST_IS_WINDOW (window));
5242 modest_ui_actions_check_menu_dimming_rules (window);
5246 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5247 ModestWindow *window)
5249 g_return_if_fail (MODEST_IS_WINDOW (window));
5252 modest_ui_actions_check_menu_dimming_rules (window);
5256 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5257 ModestWindow *window)
5259 g_return_if_fail (MODEST_IS_WINDOW (window));
5262 modest_ui_actions_check_menu_dimming_rules (window);
5266 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5267 ModestWindow *window)
5269 g_return_if_fail (MODEST_IS_WINDOW (window));
5272 modest_ui_actions_check_menu_dimming_rules (window);
5276 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5277 ModestWindow *window)
5279 g_return_if_fail (MODEST_IS_WINDOW (window));
5282 modest_ui_actions_check_menu_dimming_rules (window);
5286 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5287 ModestWindow *window)
5289 g_return_if_fail (MODEST_IS_WINDOW (window));
5292 modest_ui_actions_check_menu_dimming_rules (window);
5296 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5297 ModestWindow *window)
5299 g_return_if_fail (MODEST_IS_WINDOW (window));
5302 modest_ui_actions_check_menu_dimming_rules (window);
5306 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5307 ModestWindow *window)
5309 g_return_if_fail (MODEST_IS_WINDOW (window));
5312 modest_ui_actions_check_menu_dimming_rules (window);
5316 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5317 ModestWindow *window)
5319 g_return_if_fail (MODEST_IS_WINDOW (window));
5322 modest_ui_actions_check_menu_dimming_rules (window);
5326 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5328 g_return_if_fail (MODEST_IS_WINDOW (window));
5330 /* we check for low-mem; in that case, show a warning, and don't allow
5333 if (modest_platform_check_memory_low (window, TRUE))
5336 modest_platform_show_search_messages (GTK_WINDOW (window));
5340 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5342 g_return_if_fail (MODEST_IS_WINDOW (win));
5345 /* we check for low-mem; in that case, show a warning, and don't allow
5346 * for the addressbook
5348 if (modest_platform_check_memory_low (win, TRUE))
5352 modest_platform_show_addressbook (GTK_WINDOW (win));
5357 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5358 ModestWindow *window)
5361 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5363 if (GTK_IS_TOGGLE_ACTION (action))
5364 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5368 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5374 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5380 const gchar* server_name = NULL;
5381 TnyTransportAccount *transport;
5382 gchar *message = NULL;
5383 ModestProtocol *protocol;
5385 /* Don't show anything if the user cancelled something or the
5386 * send receive request is not interactive. Authentication
5387 * errors are managed by the account store so no need to show
5388 * a dialog here again */
5389 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5390 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5391 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5395 /* Get the server name. Note that we could be using a
5396 connection specific transport account */
5397 transport = (TnyTransportAccount *)
5398 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5400 ModestTnyAccountStore *acc_store;
5401 const gchar *acc_name;
5402 TnyTransportAccount *conn_specific;
5404 acc_store = modest_runtime_get_account_store();
5405 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5406 conn_specific = (TnyTransportAccount *)
5407 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5408 if (conn_specific) {
5409 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5410 g_object_unref (conn_specific);
5412 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5414 g_object_unref (transport);
5418 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5419 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5420 tny_account_get_proto (TNY_ACCOUNT (transport)));
5422 g_warning ("%s: Account with no proto", __FUNCTION__);
5426 /* Show the appropriate message text for the GError: */
5427 switch (err->code) {
5428 case TNY_SERVICE_ERROR_CONNECT:
5429 message = modest_protocol_get_translation (protocol,
5430 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5433 case TNY_SERVICE_ERROR_SEND:
5434 message = g_strdup (_CS("sfil_ib_unable_to_send"));
5436 case TNY_SERVICE_ERROR_UNAVAILABLE:
5437 message = modest_protocol_get_translation (protocol,
5438 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5442 g_warning ("%s: unexpected ERROR %d",
5443 __FUNCTION__, err->code);
5444 message = g_strdup (_CS("sfil_ib_unable_to_send"));
5448 modest_platform_run_information_dialog (NULL, message, FALSE);
5453 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5458 ModestWindow *top_window = NULL;
5459 ModestWindowMgr *mgr = NULL;
5460 GtkWidget *header_view = NULL;
5461 TnyFolder *selected_folder = NULL;
5462 TnyFolderType folder_type;
5464 mgr = modest_runtime_get_window_mgr ();
5465 top_window = modest_window_mgr_get_current_top (mgr);
5470 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5471 header_view = (GtkWidget *)
5472 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5475 /* Get selected folder */
5477 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5478 if (!selected_folder)
5481 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5482 #if GTK_CHECK_VERSION(2, 8, 0)
5483 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5484 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5485 GtkTreeViewColumn *tree_column;
5487 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5488 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5490 gtk_tree_view_column_queue_resize (tree_column);
5492 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5493 gtk_widget_queue_draw (header_view);
5496 #ifndef MODEST_TOOLKIT_HILDON2
5497 /* Rerun dimming rules, because the message could become deletable for example */
5498 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5499 MODEST_DIMMING_RULES_TOOLBAR);
5500 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5501 MODEST_DIMMING_RULES_MENU);
5505 g_object_unref (selected_folder);
5509 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5510 TnyAccount *account)
5512 ModestProtocolType protocol_type;
5513 ModestProtocol *protocol;
5514 gchar *error_note = NULL;
5516 protocol_type = modest_tny_account_get_protocol_type (account);
5517 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5520 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5521 if (error_note == NULL) {
5522 g_warning ("%s: This should not be reached", __FUNCTION__);
5524 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
5525 g_free (error_note);
5530 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5534 TnyFolderStore *folder = NULL;
5535 TnyAccount *account = NULL;
5536 ModestProtocolType proto;
5537 ModestProtocol *protocol;
5538 TnyHeader *header = NULL;
5540 if (MODEST_IS_HEADER_WINDOW (win)) {
5541 GtkWidget *header_view;
5542 TnyList* headers = NULL;
5544 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5545 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5546 if (!headers || tny_list_get_length (headers) == 0) {
5548 g_object_unref (headers);
5551 iter = tny_list_create_iterator (headers);
5552 header = TNY_HEADER (tny_iterator_get_current (iter));
5554 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5556 g_warning ("List should contain headers");
5558 g_object_unref (iter);
5559 g_object_unref (headers);
5560 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5561 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5563 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5566 if (!header || !folder)
5569 /* Get the account type */
5570 account = tny_folder_get_account (TNY_FOLDER (folder));
5571 proto = modest_tny_account_get_protocol_type (account);
5572 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5575 subject = tny_header_dup_subject (header);
5576 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5580 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5586 g_object_unref (account);
5588 g_object_unref (folder);
5590 g_object_unref (header);
5596 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5597 const gchar *account_name,
5598 const gchar *account_title)
5600 ModestAccountMgr *account_mgr;
5603 ModestProtocol *protocol;
5604 gboolean removed = FALSE;
5606 g_return_val_if_fail (account_name, FALSE);
5607 g_return_val_if_fail (account_title, FALSE);
5609 account_mgr = modest_runtime_get_account_mgr();
5611 /* The warning text depends on the account type: */
5612 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5613 modest_account_mgr_get_store_protocol (account_mgr,
5615 txt = modest_protocol_get_translation (protocol,
5616 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
5619 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
5621 response = modest_platform_run_confirmation_dialog (parent_window, txt);
5625 if (response == GTK_RESPONSE_OK) {
5626 /* Remove account. If it succeeds then it also removes
5627 the account from the ModestAccountView: */
5628 gboolean is_default = FALSE;
5629 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
5630 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
5632 g_free (default_account_name);
5634 removed = modest_account_mgr_remove_account (account_mgr, account_name);
5636 /* Close all email notifications, we cannot
5637 distinguish if the notification belongs to
5638 this account or not, so for safety reasons
5639 we remove them all */
5640 modest_platform_remove_new_mail_notifications (FALSE);
5642 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
5649 on_fetch_images_performer (gboolean canceled,
5651 GtkWindow *parent_window,
5652 TnyAccount *account,
5655 if (err || canceled) {
5656 /* Show an unable to retrieve images ??? */
5660 /* Note that the user could have closed the window while connecting */
5661 if (GTK_WIDGET_VISIBLE (parent_window))
5662 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
5663 g_object_unref ((GObject *) user_data);
5667 modest_ui_actions_on_fetch_images (GtkAction *action,
5668 ModestWindow *window)
5670 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
5672 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5674 on_fetch_images_performer,
5675 g_object_ref (window));
5679 modest_ui_actions_on_reload_message (const gchar *msg_id)
5681 ModestWindow *window = NULL;
5683 g_return_if_fail (msg_id && msg_id[0] != '\0');
5684 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
5690 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
5693 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
5696 /** Check whether any connections are active, and cancel them if
5698 * Returns TRUE is there was no problem,
5699 * or if an operation was cancelled so we can continue.
5700 * Returns FALSE if the user chose to cancel his request instead.
5704 modest_ui_actions_check_for_active_account (ModestWindow *self,
5705 const gchar* account_name)
5707 ModestTnySendQueue *send_queue;
5708 ModestTnyAccountStore *acc_store;
5709 ModestMailOperationQueue* queue;
5710 TnyConnectionStatus store_conn_status;
5711 TnyAccount *store_account = NULL, *transport_account = NULL;
5712 gboolean retval = TRUE, sending = FALSE;
5714 acc_store = modest_runtime_get_account_store ();
5715 queue = modest_runtime_get_mail_operation_queue ();
5718 modest_tny_account_store_get_server_account (acc_store,
5720 TNY_ACCOUNT_TYPE_STORE);
5722 /* This could happen if the account was deleted before the
5723 call to this function */
5728 modest_tny_account_store_get_server_account (acc_store,
5730 TNY_ACCOUNT_TYPE_TRANSPORT);
5732 /* This could happen if the account was deleted before the
5733 call to this function */
5734 if (!transport_account) {
5735 g_object_unref (store_account);
5739 /* If the transport account was not used yet, then the send
5740 queue could not exist (it's created on demand) */
5741 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
5742 if (TNY_IS_SEND_QUEUE (send_queue))
5743 sending = modest_tny_send_queue_sending_in_progress (send_queue);
5745 store_conn_status = tny_account_get_connection_status (store_account);
5746 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
5749 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
5750 _("emev_nc_disconnect_account"));
5751 if (response == GTK_RESPONSE_OK) {
5760 /* FIXME: We should only cancel those of this account */
5761 modest_mail_operation_queue_cancel_all (queue);
5763 /* Also disconnect the account */
5764 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
5765 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
5766 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
5770 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
5776 g_object_unref (store_account);
5777 g_object_unref (transport_account);