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 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #ifdef MODEST_PLATFORM_MAEMO
63 #include "maemo/modest-osso-state-saving.h"
64 #endif /* MODEST_PLATFORM_MAEMO */
65 #ifndef MODEST_TOOLKIT_GTK
66 #include "maemo/modest-hildon-includes.h"
67 #include "maemo/modest-connection-specific-smtp-window.h"
68 #endif /* !MODEST_TOOLKIT_GTK */
69 #include <modest-utils.h>
71 #include "widgets/modest-ui-constants.h"
72 #include <widgets/modest-main-window.h>
73 #include <widgets/modest-msg-view-window.h>
74 #include <widgets/modest-account-view-window.h>
75 #include <widgets/modest-details-dialog.h>
76 #include <widgets/modest-attachments-view.h>
77 #include "widgets/modest-folder-view.h"
78 #include "widgets/modest-global-settings-dialog.h"
79 #include "modest-account-mgr-helpers.h"
80 #include "modest-mail-operation.h"
81 #include "modest-text-utils.h"
82 #include <modest-widget-memory.h>
83 #include <tny-error.h>
84 #include <tny-simple-list.h>
85 #include <tny-msg-view.h>
86 #include <tny-device.h>
87 #include <tny-merge-folder.h>
89 #include <gtkhtml/gtkhtml.h>
91 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
93 typedef struct _GetMsgAsyncHelper {
95 ModestMailOperation *mail_op;
102 typedef enum _ReplyForwardAction {
106 } ReplyForwardAction;
108 typedef struct _ReplyForwardHelper {
109 guint reply_forward_type;
110 ReplyForwardAction action;
113 GtkWidget *parent_window;
115 } ReplyForwardHelper;
117 typedef struct _MoveToHelper {
118 GtkTreeRowReference *reference;
122 typedef struct _PasteAsAttachmentHelper {
123 ModestMsgEditWindow *window;
125 } PasteAsAttachmentHelper;
133 * The do_headers_action uses this kind of functions to perform some
134 * action to each member of a list of headers
136 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
138 static void do_headers_action (ModestWindow *win,
142 static void open_msg_cb (ModestMailOperation *mail_op,
149 static void reply_forward_cb (ModestMailOperation *mail_op,
156 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
158 static void folder_refreshed_cb (ModestMailOperation *mail_op,
162 static void on_send_receive_finished (ModestMailOperation *mail_op,
165 static gint header_list_count_uncached_msgs (TnyList *header_list);
167 static gboolean connect_to_get_msg (ModestWindow *win,
168 gint num_of_uncached_msgs,
169 TnyAccount *account);
171 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
173 static void do_create_folder (GtkWindow *window,
174 TnyFolderStore *parent_folder,
175 const gchar *suggested_name);
177 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
179 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
180 GtkWidget *folder_view,
181 TnyFolderStore *dst_folder,
182 ModestMainWindow *win);
183 #ifdef MODEST_TOOLKIT_HILDON2
184 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
185 TnyFolderStore *dst_folder,
190 static void modest_ui_actions_on_window_move_to (GtkAction *action,
191 TnyList *list_to_move,
192 TnyFolderStore *dst_folder,
196 * This function checks whether a TnyFolderStore is a pop account
199 remote_folder_has_leave_on_server (TnyFolderStore *folder)
204 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
206 account = get_account_from_folder_store (folder);
207 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
208 modest_tny_account_get_protocol_type (account)));
209 g_object_unref (account);
214 /* FIXME: this should be merged with the similar code in modest-account-view-window */
215 /* Show the account creation wizard dialog.
216 * returns: TRUE if an account was created. FALSE if the user cancelled.
219 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
221 gboolean result = FALSE;
223 gint dialog_response;
225 /* there is no such wizard yet */
226 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
227 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
229 #ifndef MODEST_TOOLKIT_HILDON2
230 /* always present a main window in the background
231 * we do it here, so we cannot end up with two wizards (as this
232 * function might be called in modest_window_mgr_get_main_window as well */
234 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
235 TRUE); /* create if not existent */
239 ModestWindowMgr *mgr;
241 mgr = modest_runtime_get_window_mgr ();
243 window_list = modest_window_mgr_get_window_list (mgr);
244 if (window_list == NULL) {
245 win = MODEST_WINDOW (modest_accounts_window_new ());
246 if (modest_window_mgr_register_window (mgr, win, NULL)) {
247 gtk_widget_show_all (GTK_WIDGET (win));
249 gtk_widget_destroy (GTK_WIDGET (win));
254 g_list_free (window_list);
260 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
262 /* make sure the mainwindow is visible. We need to present the
263 wizard again to give it the focus back. show_all are needed
264 in order to get the widgets properly drawn (MainWindow main
265 paned won't be in its right position and the dialog will be
267 #ifndef MODEST_TOOLKIT_HILDON2
268 gtk_widget_show_all (GTK_WIDGET (win));
269 gtk_widget_show_all (GTK_WIDGET (wizard));
270 gtk_window_present (GTK_WINDOW (win));
271 gtk_window_present (GTK_WINDOW (wizard));
274 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
275 gtk_widget_destroy (GTK_WIDGET (wizard));
276 if (gtk_events_pending ())
277 gtk_main_iteration ();
279 if (dialog_response == GTK_RESPONSE_CANCEL) {
282 /* Check whether an account was created: */
283 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
290 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
293 const gchar *authors[] = {
294 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
297 about = gtk_about_dialog_new ();
298 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
299 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
300 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
301 _("Copyright (c) 2006, Nokia Corporation\n"
302 "All rights reserved."));
303 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
304 _("a modest e-mail client\n\n"
305 "design and implementation: Dirk-Jan C. Binnema\n"
306 "contributions from the fine people at KC and Ig\n"
307 "uses the tinymail email framework written by Philip van Hoof"));
308 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
309 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
310 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
311 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
313 gtk_dialog_run (GTK_DIALOG (about));
314 gtk_widget_destroy(about);
318 * Gets the list of currently selected messages. If the win is the
319 * main window, then it returns a newly allocated list of the headers
320 * selected in the header view. If win is the msg view window, then
321 * the value returned is a list with just a single header.
323 * The caller of this funcion must free the list.
326 get_selected_headers (ModestWindow *win)
328 if (MODEST_IS_MAIN_WINDOW(win)) {
329 GtkWidget *header_view;
331 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
332 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
333 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
335 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 /* for MsgViewWindows, we simply return a list with one element */
338 TnyList *list = NULL;
340 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
341 if (header != NULL) {
342 list = tny_simple_list_new ();
343 tny_list_prepend (list, G_OBJECT(header));
344 g_object_unref (G_OBJECT(header));
349 #ifdef MODEST_TOOLKIT_HILDON2
350 } else if (MODEST_IS_HEADER_WINDOW (win)) {
351 GtkWidget *header_view;
353 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
354 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
360 static GtkTreeRowReference *
361 get_next_after_selected_headers (ModestHeaderView *header_view)
363 GtkTreeSelection *sel;
364 GList *selected_rows, *node;
366 GtkTreeRowReference *result;
369 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
370 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
371 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
373 if (selected_rows == NULL)
376 node = g_list_last (selected_rows);
377 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
378 gtk_tree_path_next (path);
380 result = gtk_tree_row_reference_new (model, path);
382 gtk_tree_path_free (path);
383 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
384 g_list_free (selected_rows);
390 headers_action_mark_as_read (TnyHeader *header,
394 TnyHeaderFlags flags;
396 g_return_if_fail (TNY_IS_HEADER(header));
398 flags = tny_header_get_flags (header);
399 if (flags & TNY_HEADER_FLAG_SEEN) return;
400 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
404 headers_action_mark_as_unread (TnyHeader *header,
408 TnyHeaderFlags flags;
410 g_return_if_fail (TNY_IS_HEADER(header));
412 flags = tny_header_get_flags (header);
413 if (flags & TNY_HEADER_FLAG_SEEN) {
414 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
418 /** After deleing a message that is currently visible in a window,
419 * show the next message from the list, or close the window if there are no more messages.
422 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
424 /* Close msg view window or select next */
425 if (!modest_msg_view_window_select_next_message (win) &&
426 !modest_msg_view_window_select_previous_message (win)) {
428 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
434 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
436 modest_ui_actions_on_edit_mode_delete_message (win);
440 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
442 TnyList *header_list = NULL;
443 TnyIterator *iter = NULL;
444 TnyHeader *header = NULL;
445 gchar *message = NULL;
448 ModestWindowMgr *mgr;
449 GtkWidget *header_view = NULL;
450 gboolean retval = TRUE;
452 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
454 /* Check first if the header view has the focus */
455 if (MODEST_IS_MAIN_WINDOW (win)) {
457 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
458 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
459 if (!gtk_widget_is_focus (header_view))
463 /* Get the headers, either from the header view (if win is the main window),
464 * or from the message view window: */
465 header_list = get_selected_headers (win);
466 if (!header_list) return FALSE;
468 /* Check if any of the headers are already opened, or in the process of being opened */
469 if (MODEST_IS_MAIN_WINDOW (win)) {
470 gint opened_headers = 0;
472 iter = tny_list_create_iterator (header_list);
473 mgr = modest_runtime_get_window_mgr ();
474 while (!tny_iterator_is_done (iter)) {
475 header = TNY_HEADER (tny_iterator_get_current (iter));
477 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
479 g_object_unref (header);
481 tny_iterator_next (iter);
483 g_object_unref (iter);
485 if (opened_headers > 0) {
488 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
491 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
494 g_object_unref (header_list);
500 if (tny_list_get_length(header_list) == 1) {
501 iter = tny_list_create_iterator (header_list);
502 header = TNY_HEADER (tny_iterator_get_current (iter));
505 subject = tny_header_dup_subject (header);
507 subject = g_strdup (_("mail_va_no_subject"));
508 desc = g_strdup_printf ("%s", subject);
510 g_object_unref (header);
513 g_object_unref (iter);
515 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
516 tny_list_get_length(header_list)), desc);
518 /* Confirmation dialog */
519 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
523 if (response == GTK_RESPONSE_OK) {
524 ModestWindowMgr *mgr = NULL;
525 GtkTreeModel *model = NULL;
526 GtkTreeSelection *sel = NULL;
527 GList *sel_list = NULL, *tmp = NULL;
528 GtkTreeRowReference *next_row_reference = NULL;
529 GtkTreeRowReference *prev_row_reference = NULL;
530 GtkTreePath *next_path = NULL;
531 GtkTreePath *prev_path = NULL;
532 ModestMailOperation *mail_op = NULL;
534 /* Find last selected row */
535 if (MODEST_IS_MAIN_WINDOW (win)) {
536 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
537 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
538 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
539 for (tmp=sel_list; tmp; tmp=tmp->next) {
540 if (tmp->next == NULL) {
541 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
542 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
544 gtk_tree_path_prev (prev_path);
545 gtk_tree_path_next (next_path);
547 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
548 next_row_reference = gtk_tree_row_reference_new (model, next_path);
553 /* Disable window dimming management */
554 modest_window_disable_dimming (win);
556 /* Remove each header. If it's a view window header_view == NULL */
557 mail_op = modest_mail_operation_new ((GObject *) win);
558 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
560 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
561 g_object_unref (mail_op);
563 /* Enable window dimming management */
565 gtk_tree_selection_unselect_all (sel);
567 modest_window_enable_dimming (win);
569 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
570 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
572 /* Get main window */
573 mgr = modest_runtime_get_window_mgr ();
574 } else if (MODEST_IS_MAIN_WINDOW (win)) {
575 /* Select next or previous row */
576 if (gtk_tree_row_reference_valid (next_row_reference)) {
577 gtk_tree_selection_select_path (sel, next_path);
579 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
580 gtk_tree_selection_select_path (sel, prev_path);
584 if (gtk_tree_row_reference_valid (next_row_reference))
585 gtk_tree_row_reference_free (next_row_reference);
586 if (next_path != NULL)
587 gtk_tree_path_free (next_path);
588 if (gtk_tree_row_reference_valid (prev_row_reference))
589 gtk_tree_row_reference_free (prev_row_reference);
590 if (prev_path != NULL)
591 gtk_tree_path_free (prev_path);
594 /* Update toolbar dimming state */
595 modest_ui_actions_check_menu_dimming_rules (win);
596 modest_ui_actions_check_toolbar_dimming_rules (win);
599 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
600 g_list_free (sel_list);
609 g_object_unref (header_list);
617 /* delete either message or folder, based on where we are */
619 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
621 g_return_if_fail (MODEST_IS_WINDOW(win));
623 /* Check first if the header view has the focus */
624 if (MODEST_IS_MAIN_WINDOW (win)) {
626 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
627 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
628 if (gtk_widget_is_focus (w)) {
629 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
633 modest_ui_actions_on_delete_message (action, win);
637 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
639 ModestWindowMgr *mgr = NULL;
641 #ifdef MODEST_PLATFORM_MAEMO
642 modest_osso_save_state();
643 #endif /* MODEST_PLATFORM_MAEMO */
645 g_debug ("closing down, clearing %d item(s) from operation queue",
646 modest_mail_operation_queue_num_elements
647 (modest_runtime_get_mail_operation_queue()));
649 /* cancel all outstanding operations */
650 modest_mail_operation_queue_cancel_all
651 (modest_runtime_get_mail_operation_queue());
653 g_debug ("queue has been cleared");
656 /* Check if there are opened editing windows */
657 mgr = modest_runtime_get_window_mgr ();
658 modest_window_mgr_close_all_windows (mgr);
660 /* note: when modest-tny-account-store is finalized,
661 it will automatically set all network connections
664 /* gtk_main_quit (); */
668 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
672 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
674 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
675 /* gtk_widget_destroy (GTK_WIDGET (win)); */
676 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
677 /* gboolean ret_value; */
678 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
679 /* } else if (MODEST_IS_WINDOW (win)) { */
680 /* gtk_widget_destroy (GTK_WIDGET (win)); */
682 /* g_return_if_reached (); */
687 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
689 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
691 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
695 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
697 GtkClipboard *clipboard = NULL;
698 gchar *selection = NULL;
700 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
701 selection = gtk_clipboard_wait_for_text (clipboard);
703 /* Question: why is the clipboard being used here?
704 * It doesn't really make a lot of sense. */
708 modest_address_book_add_address (selection);
714 modest_ui_actions_on_new_account (GtkAction *action,
715 ModestWindow *window)
717 if (!modest_ui_actions_run_account_setup_wizard (window)) {
718 g_debug ("%s: wizard was already running", __FUNCTION__);
723 modest_ui_actions_on_accounts (GtkAction *action,
726 /* This is currently only implemented for Maemo */
727 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
728 if (!modest_ui_actions_run_account_setup_wizard (win))
729 g_debug ("%s: wizard was already running", __FUNCTION__);
733 /* Show the list of accounts */
734 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
736 /* The accounts dialog must be modal */
737 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
738 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
743 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
745 /* This is currently only implemented for Maemo,
746 * because it requires an API (libconic) to detect different connection
749 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
751 /* Create the window if necessary: */
752 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
753 modest_connection_specific_smtp_window_fill_with_connections (
754 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
755 modest_runtime_get_account_mgr());
757 /* Show the window: */
758 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
759 GTK_WINDOW (specific_window), (GtkWindow *) win);
760 gtk_widget_show (specific_window);
761 #endif /* !MODEST_TOOLKIT_GTK */
765 count_part_size (const gchar *part)
767 GnomeVFSURI *vfs_uri;
768 gchar *escaped_filename;
770 GnomeVFSFileInfo *info;
773 /* Estimation of attachment size if we cannot get it from file info */
776 vfs_uri = gnome_vfs_uri_new (part);
778 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
779 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
780 g_free (escaped_filename);
781 gnome_vfs_uri_unref (vfs_uri);
783 info = gnome_vfs_file_info_new ();
785 if (gnome_vfs_get_file_info (part,
787 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
789 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
794 gnome_vfs_file_info_unref (info);
800 count_parts_size (GSList *parts)
805 for (node = parts; node != NULL; node = g_slist_next (node)) {
806 result += count_part_size ((const gchar *) node->data);
813 modest_ui_actions_compose_msg(ModestWindow *win,
816 const gchar *bcc_str,
817 const gchar *subject_str,
818 const gchar *body_str,
820 gboolean set_as_modified)
822 gchar *account_name = NULL;
823 const gchar *mailbox;
825 TnyAccount *account = NULL;
826 TnyFolder *folder = NULL;
827 gchar *from_str = NULL, *signature = NULL, *body = NULL;
828 gchar *recipient = NULL;
829 gboolean use_signature = FALSE;
830 ModestWindow *msg_win = NULL;
831 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
832 ModestTnyAccountStore *store = modest_runtime_get_account_store();
833 GnomeVFSFileSize total_size, allowed_size;
834 guint64 available_disk, expected_size, parts_size;
837 /* we check for low-mem */
838 if (modest_platform_check_memory_low (win, TRUE))
841 available_disk = modest_utils_get_available_space (NULL);
842 parts_count = g_slist_length (attachments);
843 parts_size = count_parts_size (attachments);
844 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
846 /* Double check: disk full condition or message too big */
847 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
848 expected_size > available_disk) {
849 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
850 modest_platform_system_banner (NULL, NULL, msg);
856 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
857 modest_platform_run_information_dialog (
859 _("mail_ib_error_attachment_size"),
865 #ifdef MODEST_TOOLKIT_HILDON2
867 account_name = g_strdup (modest_window_get_active_account(win));
870 account_name = modest_account_mgr_get_default_account(mgr);
873 g_printerr ("modest: no account found\n");
878 mailbox = modest_window_get_active_mailbox (win);
881 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
883 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
886 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
888 g_printerr ("modest: failed to find Drafts folder\n");
891 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
893 g_printerr ("modest: failed get from string for '%s'\n", account_name);
897 recipient = modest_text_utils_get_email_address (from_str);
898 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
900 if (body_str != NULL) {
901 body = use_signature ? g_strconcat(body_str, "\n",
902 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
903 "\n", signature, NULL) : g_strdup(body_str);
905 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
906 "\n", signature, NULL) : g_strdup("");
909 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
911 g_printerr ("modest: failed to create new msg\n");
915 /* Create and register edit window */
916 /* This is destroyed by TODO. */
918 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
919 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
921 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
922 gtk_widget_destroy (GTK_WIDGET (msg_win));
925 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
926 gtk_widget_show_all (GTK_WIDGET (msg_win));
928 while (attachments) {
929 GnomeVFSFileSize att_size;
931 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
932 attachments->data, allowed_size);
933 total_size += att_size;
935 if (att_size > allowed_size) {
936 g_debug ("%s: total size: %u",
937 __FUNCTION__, (unsigned int)total_size);
940 allowed_size -= att_size;
942 attachments = g_slist_next(attachments);
949 g_free (account_name);
951 g_object_unref (G_OBJECT(account));
953 g_object_unref (G_OBJECT(folder));
955 g_object_unref (G_OBJECT(msg));
959 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
961 /* if there are no accounts yet, just show the wizard */
962 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
963 if (!modest_ui_actions_run_account_setup_wizard (win))
966 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
971 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
975 ModestMailOperationStatus status;
977 /* If there is no message or the operation was not successful */
978 status = modest_mail_operation_get_status (mail_op);
979 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
982 /* If it's a memory low issue, then show a banner */
983 error = modest_mail_operation_get_error (mail_op);
984 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
985 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
986 GObject *source = modest_mail_operation_get_source (mail_op);
987 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
988 _KR("memr_ib_operation_disabled"),
990 g_object_unref (source);
993 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
994 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
995 gchar *subject, *msg, *format = NULL;
998 subject = (header) ? tny_header_dup_subject (header) : NULL;
1000 subject = g_strdup (_("mail_va_no_subject"));
1002 account = modest_mail_operation_get_account (mail_op);
1004 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1005 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1008 if (tny_account_get_connection_status (account) ==
1009 TNY_CONNECTION_STATUS_CONNECTED) {
1010 format = modest_protocol_get_translation (protocol,
1011 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1014 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1015 tny_account_get_hostname (account));
1018 g_object_unref (account);
1022 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1024 msg = g_strdup_printf (format, subject);
1025 modest_platform_run_information_dialog (NULL, msg, FALSE);
1031 /* Remove the header from the preregistered uids */
1032 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1045 } OpenMsgBannerInfo;
1048 GtkTreeModel *model;
1050 ModestWindow *caller_window;
1051 OpenMsgBannerInfo *banner_info;
1052 GtkTreeRowReference *rowref;
1056 open_msg_banner_idle (gpointer userdata)
1058 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1060 gdk_threads_enter ();
1061 banner_info->idle_handler = 0;
1062 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1063 if (banner_info->banner)
1064 g_object_ref (banner_info->banner);
1066 gdk_threads_leave ();
1072 get_header_view_from_window (ModestWindow *window)
1074 GtkWidget *header_view;
1076 if (MODEST_IS_MAIN_WINDOW (window)) {
1077 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1078 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1079 #ifdef MODEST_TOOLKIT_HILDON2
1080 } else if (MODEST_IS_HEADER_WINDOW (window)){
1081 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1091 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1094 gchar *account = NULL;
1095 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1100 folder = tny_header_get_folder (header);
1101 /* Gets folder type (OUTBOX headers will be opened in edit window */
1102 if (modest_tny_folder_is_local_folder (folder)) {
1103 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1104 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1105 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1108 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1109 TnyTransportAccount *traccount = NULL;
1110 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1111 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1113 ModestTnySendQueue *send_queue = NULL;
1114 ModestTnySendQueueStatus status;
1116 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1117 TNY_ACCOUNT(traccount)));
1118 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1119 if (TNY_IS_SEND_QUEUE (send_queue)) {
1120 msg_id = modest_tny_send_queue_get_msg_id (header);
1121 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1123 /* Only open messages in outbox with the editor if they are in Failed state */
1124 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1127 #ifdef MODEST_TOOLKIT_HILDON2
1129 /* In Fremantle we can not
1130 open any message from
1131 outbox which is not in
1137 g_object_unref(traccount);
1139 g_warning("Cannot get transport account for message in outbox!!");
1141 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1142 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1146 TnyAccount *acc = tny_folder_get_account (folder);
1149 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1150 g_object_unref (acc);
1154 g_object_unref (folder);
1160 open_msg_cb (ModestMailOperation *mail_op,
1167 ModestWindowMgr *mgr = NULL;
1168 ModestWindow *parent_win = NULL;
1169 ModestWindow *win = NULL;
1170 gchar *account = NULL;
1171 gboolean open_in_editor = FALSE;
1173 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1175 /* Do nothing if there was any problem with the mail
1176 operation. The error will be shown by the error_handler of
1177 the mail operation */
1178 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1181 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1183 /* Mark header as read */
1184 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1186 account = get_info_from_header (header, &open_in_editor, &can_open);
1190 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1192 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1194 if (open_in_editor) {
1195 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1196 gchar *from_header = NULL, *acc_name;
1197 gchar *mailbox = NULL;
1199 from_header = tny_header_dup_from (header);
1201 /* we cannot edit without a valid account... */
1202 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1203 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1204 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1206 g_free (from_header);
1211 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1212 g_free (from_header);
1218 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1222 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1223 const gchar *mailbox = NULL;
1225 if (parent_win && MODEST_IS_WINDOW (parent_win))
1226 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1228 if (helper->rowref && helper->model) {
1229 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1230 helper->model, helper->rowref);
1232 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1237 /* Register and show new window */
1239 mgr = modest_runtime_get_window_mgr ();
1240 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1241 gtk_widget_destroy (GTK_WIDGET (win));
1244 gtk_widget_show_all (GTK_WIDGET(win));
1247 /* Update toolbar dimming state */
1248 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1249 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1255 g_object_unref (parent_win);
1259 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1262 const GError *error;
1263 GObject *win = NULL;
1264 ModestMailOperationStatus status;
1266 win = modest_mail_operation_get_source (mail_op);
1267 error = modest_mail_operation_get_error (mail_op);
1268 status = modest_mail_operation_get_status (mail_op);
1270 /* If the mail op has been cancelled then it's not an error:
1271 don't show any message */
1272 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1273 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1274 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1275 (GError *) error, account)) {
1276 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1277 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1279 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1280 modest_platform_information_banner ((GtkWidget *) win,
1281 NULL, _("emev_ui_imap_inbox_select_error"));
1282 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1283 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1284 modest_platform_information_banner ((GtkWidget *) win,
1285 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1286 } else if (user_data) {
1287 modest_platform_information_banner ((GtkWidget *) win,
1291 g_object_unref (account);
1295 g_object_unref (win);
1299 * Returns the account a list of headers belongs to. It returns a
1300 * *new* reference so don't forget to unref it
1303 get_account_from_header_list (TnyList *headers)
1305 TnyAccount *account = NULL;
1307 if (tny_list_get_length (headers) > 0) {
1308 TnyIterator *iter = tny_list_create_iterator (headers);
1309 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1310 TnyFolder *folder = tny_header_get_folder (header);
1313 g_object_unref (header);
1315 while (!tny_iterator_is_done (iter)) {
1316 header = TNY_HEADER (tny_iterator_get_current (iter));
1317 folder = tny_header_get_folder (header);
1320 g_object_unref (header);
1322 tny_iterator_next (iter);
1327 account = tny_folder_get_account (folder);
1328 g_object_unref (folder);
1332 g_object_unref (header);
1334 g_object_unref (iter);
1340 get_account_from_header (TnyHeader *header)
1342 TnyAccount *account = NULL;
1345 folder = tny_header_get_folder (header);
1348 account = tny_folder_get_account (folder);
1349 g_object_unref (folder);
1355 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1357 if (helper->caller_window)
1358 helper->caller_window = NULL;
1362 open_msg_helper_destroyer (gpointer user_data)
1364 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1366 if (helper->caller_window) {
1367 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1368 helper->caller_window = NULL;
1371 if (helper->banner_info) {
1372 g_free (helper->banner_info->message);
1373 if (helper->banner_info->idle_handler > 0) {
1374 g_source_remove (helper->banner_info->idle_handler);
1375 helper->banner_info->idle_handler = 0;
1377 if (helper->banner_info->banner != NULL) {
1378 gtk_widget_destroy (helper->banner_info->banner);
1379 g_object_unref (helper->banner_info->banner);
1380 helper->banner_info->banner = NULL;
1382 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1383 helper->banner_info = NULL;
1385 g_object_unref (helper->model);
1386 g_object_unref (helper->header);
1387 gtk_tree_row_reference_free (helper->rowref);
1388 g_slice_free (OpenMsgHelper, helper);
1392 open_msg_performer(gboolean canceled,
1394 GtkWindow *parent_window,
1395 TnyAccount *account,
1398 ModestMailOperation *mail_op = NULL;
1399 gchar *error_msg = NULL;
1400 ModestProtocolType proto;
1401 TnyConnectionStatus status;
1402 OpenMsgHelper *helper = NULL;
1403 ModestProtocol *protocol;
1404 ModestProtocolRegistry *protocol_registry;
1407 helper = (OpenMsgHelper *) user_data;
1409 status = tny_account_get_connection_status (account);
1410 if (err || canceled || helper->caller_window == NULL) {
1411 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1412 /* Free the helper */
1413 open_msg_helper_destroyer (helper);
1415 /* In disk full conditions we could get this error here */
1416 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1417 (GtkWidget *) parent_window, err,
1423 /* Get the error message depending on the protocol */
1424 proto = modest_tny_account_get_protocol_type (account);
1425 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1426 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1429 protocol_registry = modest_runtime_get_protocol_registry ();
1430 subject = tny_header_dup_subject (helper->header);
1432 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1433 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1437 if (error_msg == NULL) {
1438 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1441 #ifndef MODEST_TOOLKIT_HILDON2
1442 gboolean show_open_draft = FALSE;
1443 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1445 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1447 TnyFolderType folder_type;
1449 folder = tny_header_get_folder (helper->header);
1450 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1451 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1452 g_object_unref (folder);
1456 #ifdef MODEST_TOOLKIT_HILDON2
1459 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1462 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1463 g_free (account_name);
1464 open_msg_helper_destroyer (helper);
1469 ModestWindow *window;
1470 GtkWidget *header_view;
1473 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1474 uid = modest_tny_folder_get_header_unique_id (helper->header);
1476 const gchar *mailbox = NULL;
1477 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1478 window = modest_msg_view_window_new_from_header_view
1479 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1480 if (window != NULL) {
1481 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1483 gtk_widget_destroy (GTK_WIDGET (window));
1485 gtk_widget_show_all (GTK_WIDGET(window));
1489 g_free (account_name);
1491 open_msg_helper_destroyer (helper);
1494 g_free (account_name);
1496 /* Create the mail operation */
1498 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1499 modest_ui_actions_disk_operations_error_handler,
1500 g_strdup (error_msg), g_free);
1501 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1505 #ifndef MODEST_TOOLKIT_HILDON2
1506 if (show_open_draft) {
1507 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1508 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1509 helper->banner_info->banner = NULL;
1510 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1511 helper->banner_info);
1517 headers = TNY_LIST (tny_simple_list_new ());
1518 tny_list_prepend (headers, G_OBJECT (helper->header));
1519 modest_mail_operation_get_msgs_full (mail_op,
1523 open_msg_helper_destroyer);
1524 g_object_unref (headers);
1531 g_object_unref (mail_op);
1532 g_object_unref (account);
1536 * This function is used by both modest_ui_actions_on_open and
1537 * modest_ui_actions_on_header_activated. This way we always do the
1538 * same when trying to open messages.
1541 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1543 ModestWindowMgr *mgr = NULL;
1544 TnyAccount *account;
1545 gboolean cached = FALSE;
1547 GtkWidget *header_view = NULL;
1548 OpenMsgHelper *helper;
1549 ModestWindow *window;
1551 g_return_if_fail (header != NULL && rowref != NULL);
1553 mgr = modest_runtime_get_window_mgr ();
1556 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1557 if (header_view == NULL)
1560 /* Get the account */
1561 account = get_account_from_header (header);
1566 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1568 /* Do not open again the message and present the
1569 window to the user */
1572 #ifndef MODEST_TOOLKIT_HILDON2
1573 gtk_window_present (GTK_WINDOW (window));
1576 /* the header has been registered already, we don't do
1577 * anything but wait for the window to come up*/
1578 g_debug ("header %p already registered, waiting for window", header);
1583 /* Open each message */
1584 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1586 /* Allways download if we are online. */
1587 if (!tny_device_is_online (modest_runtime_get_device ())) {
1590 /* If ask for user permission to download the messages */
1591 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1592 _("mcen_nc_get_msg"));
1594 /* End if the user does not want to continue */
1595 if (response == GTK_RESPONSE_CANCEL) {
1601 /* We register the window for opening */
1602 modest_window_mgr_register_header (mgr, header, NULL);
1604 /* Create the helper. We need to get a reference to the model
1605 here because it could change while the message is readed
1606 (the user could switch between folders) */
1607 helper = g_slice_new (OpenMsgHelper);
1608 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1609 helper->caller_window = win;
1610 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1611 helper->header = g_object_ref (header);
1612 helper->rowref = gtk_tree_row_reference_copy (rowref);
1613 helper->banner_info = NULL;
1615 /* Connect to the account and perform */
1617 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1618 open_msg_performer, helper);
1620 /* Call directly the performer, do not need to connect */
1621 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1622 g_object_ref (account), helper);
1627 g_object_unref (account);
1631 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1638 /* we check for low-mem; in that case, show a warning, and don't allow
1641 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1645 headers = get_selected_headers (win);
1649 headers_count = tny_list_get_length (headers);
1650 if (headers_count != 1) {
1651 if (headers_count > 1) {
1652 /* Don't allow activation if there are more than one message selected */
1653 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1656 g_object_unref (headers);
1660 iter = tny_list_create_iterator (headers);
1661 header = TNY_HEADER (tny_iterator_get_current (iter));
1662 g_object_unref (iter);
1666 open_msg_from_header (header, NULL, win);
1667 g_object_unref (header);
1670 g_object_unref(headers);
1674 rf_helper_window_closed (gpointer data,
1677 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1679 helper->parent_window = NULL;
1682 static ReplyForwardHelper*
1683 create_reply_forward_helper (ReplyForwardAction action,
1685 guint reply_forward_type,
1688 ReplyForwardHelper *rf_helper = NULL;
1689 const gchar *active_acc = modest_window_get_active_account (win);
1690 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1692 rf_helper = g_slice_new0 (ReplyForwardHelper);
1693 rf_helper->reply_forward_type = reply_forward_type;
1694 rf_helper->action = action;
1695 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1696 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1697 rf_helper->account_name = (active_acc) ?
1698 g_strdup (active_acc) :
1699 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1700 rf_helper->mailbox = g_strdup (active_mailbox);
1702 /* Note that window could be destroyed just AFTER calling
1703 register_window so we must ensure that this pointer does
1704 not hold invalid references */
1705 if (rf_helper->parent_window)
1706 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1707 rf_helper_window_closed, rf_helper);
1713 free_reply_forward_helper (gpointer data)
1715 ReplyForwardHelper *helper;
1717 helper = (ReplyForwardHelper *) data;
1718 g_free (helper->account_name);
1719 g_free (helper->mailbox);
1721 g_object_unref (helper->header);
1722 if (helper->parent_window)
1723 g_object_weak_unref (G_OBJECT (helper->parent_window),
1724 rf_helper_window_closed, helper);
1725 g_slice_free (ReplyForwardHelper, helper);
1729 reply_forward_cb (ModestMailOperation *mail_op,
1736 TnyMsg *new_msg = NULL;
1737 ReplyForwardHelper *rf_helper;
1738 ModestWindow *msg_win = NULL;
1739 ModestEditType edit_type;
1741 TnyAccount *account = NULL;
1742 ModestWindowMgr *mgr = NULL;
1743 gchar *signature = NULL;
1744 gboolean use_signature;
1747 /* If there was any error. The mail operation could be NULL,
1748 this means that we already have the message downloaded and
1749 that we didn't do a mail operation to retrieve it */
1750 rf_helper = (ReplyForwardHelper *) user_data;
1751 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1754 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1755 rf_helper->account_name, rf_helper->mailbox);
1756 recipient = modest_text_utils_get_email_address (from);
1757 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1762 /* Create reply mail */
1763 switch (rf_helper->action) {
1764 /* Use the msg_header to ensure that we have all the
1765 information. The summary can lack some data */
1766 TnyHeader *msg_header;
1768 msg_header = tny_msg_get_header (msg);
1770 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1771 (use_signature) ? signature : NULL,
1772 rf_helper->reply_forward_type,
1773 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1774 g_object_unref (msg_header);
1776 case ACTION_REPLY_TO_ALL:
1777 msg_header = tny_msg_get_header (msg);
1779 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1780 (use_signature) ? signature : NULL,
1781 rf_helper->reply_forward_type,
1782 MODEST_TNY_MSG_REPLY_MODE_ALL);
1783 edit_type = MODEST_EDIT_TYPE_REPLY;
1784 g_object_unref (msg_header);
1786 case ACTION_FORWARD:
1788 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1789 rf_helper->reply_forward_type);
1790 edit_type = MODEST_EDIT_TYPE_FORWARD;
1793 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1795 g_return_if_reached ();
1803 g_warning ("%s: failed to create message\n", __FUNCTION__);
1807 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1808 rf_helper->account_name,
1809 TNY_ACCOUNT_TYPE_STORE);
1811 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1815 /* Create and register the windows */
1816 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1817 mgr = modest_runtime_get_window_mgr ();
1818 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1820 /* Note that register_window could have deleted the account */
1821 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1822 gdouble parent_zoom;
1824 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1825 modest_window_set_zoom (msg_win, parent_zoom);
1828 /* Show edit window */
1829 gtk_widget_show_all (GTK_WIDGET (msg_win));
1832 /* We always unregister the header because the message is
1833 forwarded or replied so the original one is no longer
1835 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1838 g_object_unref (G_OBJECT (new_msg));
1840 g_object_unref (G_OBJECT (account));
1841 free_reply_forward_helper (rf_helper);
1844 /* Checks a list of headers. If any of them are not currently
1845 * downloaded (CACHED) then returns TRUE else returns FALSE.
1848 header_list_count_uncached_msgs (TnyList *header_list)
1851 gint uncached_messages = 0;
1853 iter = tny_list_create_iterator (header_list);
1854 while (!tny_iterator_is_done (iter)) {
1857 header = TNY_HEADER (tny_iterator_get_current (iter));
1859 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1860 uncached_messages ++;
1861 g_object_unref (header);
1864 tny_iterator_next (iter);
1866 g_object_unref (iter);
1868 return uncached_messages;
1871 /* Returns FALSE if the user does not want to download the
1872 * messages. Returns TRUE if the user allowed the download.
1875 connect_to_get_msg (ModestWindow *win,
1876 gint num_of_uncached_msgs,
1877 TnyAccount *account)
1879 GtkResponseType response;
1881 /* Allways download if we are online. */
1882 if (tny_device_is_online (modest_runtime_get_device ()))
1885 /* If offline, then ask for user permission to download the messages */
1886 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1887 ngettext("mcen_nc_get_msg",
1889 num_of_uncached_msgs));
1891 if (response == GTK_RESPONSE_CANCEL)
1894 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1898 reply_forward_performer (gboolean canceled,
1900 GtkWindow *parent_window,
1901 TnyAccount *account,
1904 ReplyForwardHelper *rf_helper = NULL;
1905 ModestMailOperation *mail_op;
1907 rf_helper = (ReplyForwardHelper *) user_data;
1909 if (canceled || err) {
1910 free_reply_forward_helper (rf_helper);
1914 /* Retrieve the message */
1915 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1916 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1917 modest_ui_actions_disk_operations_error_handler,
1919 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1920 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1923 g_object_unref(mail_op);
1927 * Common code for the reply and forward actions
1930 reply_forward (ReplyForwardAction action, ModestWindow *win)
1932 ReplyForwardHelper *rf_helper = NULL;
1933 guint reply_forward_type;
1935 g_return_if_fail (MODEST_IS_WINDOW(win));
1937 /* we check for low-mem; in that case, show a warning, and don't allow
1938 * reply/forward (because it could potentially require a lot of memory */
1939 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1943 /* we need an account when editing */
1944 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1945 if (!modest_ui_actions_run_account_setup_wizard (win))
1949 reply_forward_type =
1950 modest_conf_get_int (modest_runtime_get_conf (),
1951 (action == ACTION_FORWARD) ?
1952 MODEST_CONF_FORWARD_TYPE :
1953 MODEST_CONF_REPLY_TYPE,
1956 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1958 TnyHeader *header = NULL;
1959 /* Get header and message. Do not free them here, the
1960 reply_forward_cb must do it */
1961 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1962 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1964 if (msg && header) {
1966 rf_helper = create_reply_forward_helper (action, win,
1967 reply_forward_type, header);
1968 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1970 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1974 g_object_unref (msg);
1976 g_object_unref (header);
1978 TnyHeader *header = NULL;
1980 gboolean do_retrieve = TRUE;
1981 TnyList *header_list = NULL;
1983 header_list = get_selected_headers (win);
1986 /* Check that only one message is selected for replying */
1987 if (tny_list_get_length (header_list) != 1) {
1988 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1989 NULL, _("mcen_ib_select_one_message"));
1990 g_object_unref (header_list);
1994 /* Only reply/forward to one message */
1995 iter = tny_list_create_iterator (header_list);
1996 header = TNY_HEADER (tny_iterator_get_current (iter));
1997 g_object_unref (iter);
1999 /* Retrieve messages */
2000 do_retrieve = (action == ACTION_FORWARD) ||
2001 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2004 TnyAccount *account = NULL;
2005 TnyFolder *folder = NULL;
2006 gdouble download = TRUE;
2007 guint uncached_msgs = 0;
2009 folder = tny_header_get_folder (header);
2011 goto do_retrieve_frees;
2012 account = tny_folder_get_account (folder);
2014 goto do_retrieve_frees;
2016 uncached_msgs = header_list_count_uncached_msgs (header_list);
2018 if (uncached_msgs > 0) {
2019 /* Allways download if we are online. */
2020 if (!tny_device_is_online (modest_runtime_get_device ())) {
2023 /* If ask for user permission to download the messages */
2024 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2025 ngettext("mcen_nc_get_msg",
2029 /* End if the user does not want to continue */
2030 if (response == GTK_RESPONSE_CANCEL)
2037 rf_helper = create_reply_forward_helper (action, win,
2038 reply_forward_type, header);
2039 if (uncached_msgs > 0) {
2040 modest_platform_connect_and_perform (GTK_WINDOW (win),
2042 reply_forward_performer,
2045 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2046 account, rf_helper);
2051 g_object_unref (account);
2053 g_object_unref (folder);
2055 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
2058 g_object_unref (header_list);
2059 g_object_unref (header);
2064 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2066 g_return_if_fail (MODEST_IS_WINDOW(win));
2068 reply_forward (ACTION_REPLY, win);
2072 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2074 g_return_if_fail (MODEST_IS_WINDOW(win));
2076 reply_forward (ACTION_FORWARD, win);
2080 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2082 g_return_if_fail (MODEST_IS_WINDOW(win));
2084 reply_forward (ACTION_REPLY_TO_ALL, win);
2088 modest_ui_actions_on_next (GtkAction *action,
2089 ModestWindow *window)
2091 if (MODEST_IS_MAIN_WINDOW (window)) {
2092 GtkWidget *header_view;
2094 header_view = modest_main_window_get_child_widget (
2095 MODEST_MAIN_WINDOW(window),
2096 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2100 modest_header_view_select_next (
2101 MODEST_HEADER_VIEW(header_view));
2102 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2103 modest_msg_view_window_select_next_message (
2104 MODEST_MSG_VIEW_WINDOW (window));
2106 g_return_if_reached ();
2111 modest_ui_actions_on_prev (GtkAction *action,
2112 ModestWindow *window)
2114 g_return_if_fail (MODEST_IS_WINDOW(window));
2116 if (MODEST_IS_MAIN_WINDOW (window)) {
2117 GtkWidget *header_view;
2118 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2119 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2123 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2124 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2125 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2127 g_return_if_reached ();
2132 modest_ui_actions_on_sort (GtkAction *action,
2133 ModestWindow *window)
2135 GtkWidget *header_view = NULL;
2137 g_return_if_fail (MODEST_IS_WINDOW(window));
2139 if (MODEST_IS_MAIN_WINDOW (window)) {
2140 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2141 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2142 #ifdef MODEST_TOOLKIT_HILDON2
2143 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2144 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2149 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2154 /* Show sorting dialog */
2155 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2159 new_messages_arrived (ModestMailOperation *self,
2160 TnyList *new_headers,
2164 gboolean show_visual_notifications;
2166 source = modest_mail_operation_get_source (self);
2167 show_visual_notifications = (source) ? FALSE : TRUE;
2169 g_object_unref (source);
2171 /* Notify new messages have been downloaded. If the
2172 send&receive was invoked by the user then do not show any
2173 visual notification, only play a sound and activate the LED
2174 (for the Maemo version) */
2175 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2177 /* We only notify about really new messages (not seen) we get */
2178 TnyList *actually_new_list;
2179 TnyIterator *iterator;
2180 actually_new_list = TNY_LIST (tny_simple_list_new ());
2181 for (iterator = tny_list_create_iterator (new_headers);
2182 !tny_iterator_is_done (iterator);
2183 tny_iterator_next (iterator)) {
2185 TnyHeaderFlags flags;
2186 header = TNY_HEADER (tny_iterator_get_current (iterator));
2187 flags = tny_header_get_flags (header);
2189 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2190 /* Messages are ordered from most
2191 recent to oldest. But we want to
2192 show notifications starting from
2193 the oldest message. That's why we
2195 tny_list_prepend (actually_new_list, G_OBJECT (header));
2197 g_object_unref (header);
2199 g_object_unref (iterator);
2201 if (tny_list_get_length (actually_new_list) > 0) {
2202 GList *new_headers_list = NULL;
2204 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2206 /* Send notifications */
2207 if (new_headers_list) {
2208 modest_platform_on_new_headers_received (new_headers_list,
2209 show_visual_notifications);
2211 modest_utils_free_notification_list (new_headers_list);
2214 g_object_unref (actually_new_list);
2220 retrieve_all_messages_cb (GObject *source,
2222 guint retrieve_limit)
2228 window = GTK_WINDOW (source);
2229 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2230 num_msgs, retrieve_limit);
2232 /* Ask the user if they want to retrieve all the messages */
2234 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2235 _("mcen_bd_get_all"),
2236 _("mcen_bd_newest_only"));
2237 /* Free and return */
2239 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2243 TnyAccount *account;
2245 gchar *account_name;
2246 gboolean poke_status;
2247 gboolean interactive;
2248 ModestMailOperation *mail_op;
2252 do_send_receive_performer (gboolean canceled,
2254 GtkWindow *parent_window,
2255 TnyAccount *account,
2258 SendReceiveInfo *info;
2260 info = (SendReceiveInfo *) user_data;
2262 if (err || canceled) {
2263 /* In disk full conditions we could get this error here */
2264 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2265 (GtkWidget *) parent_window, err,
2268 if (info->mail_op) {
2269 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2275 /* Set send/receive operation in progress */
2276 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2277 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2280 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2281 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2282 G_CALLBACK (on_send_receive_finished),
2285 /* Send & receive. */
2286 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2287 (info->win) ? retrieve_all_messages_cb : NULL,
2288 new_messages_arrived, info->win);
2293 g_object_unref (G_OBJECT (info->mail_op));
2294 if (info->account_name)
2295 g_free (info->account_name);
2297 g_object_unref (info->win);
2299 g_object_unref (info->account);
2300 g_slice_free (SendReceiveInfo, info);
2304 * This function performs the send & receive required actions. The
2305 * window is used to create the mail operation. Typically it should
2306 * always be the main window, but we pass it as argument in order to
2310 modest_ui_actions_do_send_receive (const gchar *account_name,
2311 gboolean force_connection,
2312 gboolean poke_status,
2313 gboolean interactive,
2316 gchar *acc_name = NULL;
2317 SendReceiveInfo *info;
2318 ModestTnyAccountStore *acc_store;
2319 TnyAccount *account;
2321 /* If no account name was provided then get the current account, and if
2322 there is no current account then pick the default one: */
2323 if (!account_name) {
2325 acc_name = g_strdup (modest_window_get_active_account (win));
2327 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2329 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2333 acc_name = g_strdup (account_name);
2336 acc_store = modest_runtime_get_account_store ();
2337 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2341 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2345 /* Do not automatically refresh accounts that are flagged as
2346 NO_AUTO_UPDATE. This could be useful for accounts that
2347 handle their own update times */
2349 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2350 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2351 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2352 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2354 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2355 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2356 g_object_unref (account);
2363 /* Create the info for the connect and perform */
2364 info = g_slice_new (SendReceiveInfo);
2365 info->account_name = acc_name;
2366 info->win = (win) ? g_object_ref (win) : NULL;
2367 info->poke_status = poke_status;
2368 info->interactive = interactive;
2369 info->account = account;
2370 /* We need to create the operation here, because otherwise it
2371 could happen that the queue emits the queue-empty signal
2372 while we're trying to connect the account */
2373 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2374 modest_ui_actions_disk_operations_error_handler,
2376 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2378 /* Invoke the connect and perform */
2379 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2380 force_connection, info->account,
2381 do_send_receive_performer, info);
2386 modest_ui_actions_do_cancel_send (const gchar *account_name,
2389 TnyTransportAccount *transport_account;
2390 TnySendQueue *send_queue = NULL;
2391 GError *error = NULL;
2393 /* Get transport account */
2395 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2396 (modest_runtime_get_account_store(),
2398 TNY_ACCOUNT_TYPE_TRANSPORT));
2399 if (!transport_account) {
2400 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2405 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2406 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2407 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2408 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2409 "modest: could not find send queue for account\n");
2411 /* Cancel the current send */
2412 tny_account_cancel (TNY_ACCOUNT (transport_account));
2414 /* Suspend all pending messages */
2415 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2419 if (transport_account != NULL)
2420 g_object_unref (G_OBJECT (transport_account));
2424 modest_ui_actions_cancel_send_all (ModestWindow *win)
2426 GSList *account_names, *iter;
2428 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2431 iter = account_names;
2433 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2434 iter = g_slist_next (iter);
2437 modest_account_mgr_free_account_names (account_names);
2438 account_names = NULL;
2442 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2445 /* Check if accounts exist */
2446 gboolean accounts_exist =
2447 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2449 /* If not, allow the user to create an account before trying to send/receive. */
2450 if (!accounts_exist)
2451 modest_ui_actions_on_accounts (NULL, win);
2453 /* Cancel all sending operaitons */
2454 modest_ui_actions_cancel_send_all (win);
2458 * Refreshes all accounts. This function will be used by automatic
2462 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2463 gboolean force_connection,
2464 gboolean poke_status,
2465 gboolean interactive)
2467 GSList *account_names, *iter;
2469 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2472 iter = account_names;
2474 modest_ui_actions_do_send_receive ((const char*) iter->data,
2476 poke_status, interactive, win);
2477 iter = g_slist_next (iter);
2480 modest_account_mgr_free_account_names (account_names);
2481 account_names = NULL;
2485 * Handler of the click on Send&Receive button in the main toolbar
2488 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2490 /* Check if accounts exist */
2491 gboolean accounts_exist;
2494 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2496 /* If not, allow the user to create an account before trying to send/receive. */
2497 if (!accounts_exist)
2498 modest_ui_actions_on_accounts (NULL, win);
2500 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2501 if (MODEST_IS_MAIN_WINDOW (win)) {
2502 GtkWidget *folder_view;
2503 TnyFolderStore *folder_store;
2506 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2507 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2511 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2514 g_object_unref (folder_store);
2515 /* Refresh the active account. Force the connection if needed
2516 and poke the status of all folders */
2517 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2518 #ifdef MODEST_TOOLKIT_HILDON2
2519 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2520 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2523 const gchar *active_account;
2524 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2526 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2533 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2536 GtkWidget *header_view;
2538 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2540 header_view = modest_main_window_get_child_widget (main_window,
2541 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2545 conf = modest_runtime_get_conf ();
2547 /* what is saved/restored is depending on the style; thus; we save with
2548 * old style, then update the style, and restore for this new style
2550 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2552 if (modest_header_view_get_style
2553 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2554 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2555 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2557 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2558 MODEST_HEADER_VIEW_STYLE_DETAILS);
2560 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2561 MODEST_CONF_HEADER_VIEW_KEY);
2566 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2568 ModestMainWindow *main_window)
2570 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2571 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2573 /* in the case the folder is empty, show the empty folder message and focus
2575 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2576 if (modest_header_view_is_empty (header_view)) {
2577 TnyFolder *folder = modest_header_view_get_folder (header_view);
2578 GtkWidget *folder_view =
2579 modest_main_window_get_child_widget (main_window,
2580 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2581 if (folder != NULL) {
2582 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2583 g_object_unref (folder);
2585 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2589 /* If no header has been selected then exit */
2594 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2595 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2597 /* Update toolbar dimming state */
2598 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2599 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2603 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2606 ModestWindow *window)
2608 GtkWidget *open_widget;
2609 GtkTreeRowReference *rowref;
2611 g_return_if_fail (MODEST_IS_WINDOW(window));
2612 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2613 g_return_if_fail (TNY_IS_HEADER (header));
2615 if (modest_header_view_count_selected_headers (header_view) > 1) {
2616 /* Don't allow activation if there are more than one message selected */
2617 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2621 /* we check for low-mem; in that case, show a warning, and don't allow
2622 * activating headers
2624 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2627 if (MODEST_IS_MAIN_WINDOW (window)) {
2628 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2629 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2630 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2634 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2635 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2636 gtk_tree_row_reference_free (rowref);
2640 set_active_account_from_tny_account (TnyAccount *account,
2641 ModestWindow *window)
2643 const gchar *server_acc_name = tny_account_get_id (account);
2645 /* We need the TnyAccount provided by the
2646 account store because that is the one that
2647 knows the name of the Modest account */
2648 TnyAccount *modest_server_account =
2649 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2650 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2652 if (!modest_server_account) {
2653 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2657 /* Update active account, but only if it's not a pseudo-account */
2658 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2659 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2660 const gchar *modest_acc_name =
2661 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2662 if (modest_acc_name)
2663 modest_window_set_active_account (window, modest_acc_name);
2666 g_object_unref (modest_server_account);
2671 folder_refreshed_cb (ModestMailOperation *mail_op,
2675 ModestMainWindow *win = NULL;
2676 GtkWidget *folder_view, *header_view;
2677 const GError *error;
2679 g_return_if_fail (TNY_IS_FOLDER (folder));
2681 win = MODEST_MAIN_WINDOW (user_data);
2683 /* Check if the operation failed due to memory low conditions */
2684 error = modest_mail_operation_get_error (mail_op);
2685 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2686 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2687 modest_platform_run_information_dialog (GTK_WINDOW (win),
2688 _KR("memr_ib_operation_disabled"),
2694 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2696 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2699 TnyFolderStore *current_folder;
2701 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2702 if (current_folder) {
2703 gboolean different = ((TnyFolderStore *) folder != current_folder);
2704 g_object_unref (current_folder);
2710 /* Check if folder is empty and set headers view contents style */
2711 if ((tny_folder_get_all_count (folder) == 0) ||
2712 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2713 modest_main_window_set_contents_style (win,
2714 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2718 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2719 TnyFolderStore *folder_store,
2721 ModestMainWindow *main_window)
2723 GtkWidget *header_view;
2725 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2727 header_view = modest_main_window_get_child_widget(main_window,
2728 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2733 if (TNY_IS_ACCOUNT (folder_store)) {
2735 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2737 /* Show account details */
2738 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2741 if (TNY_IS_FOLDER (folder_store) && selected) {
2742 TnyAccount *account;
2744 /* Update the active account */
2745 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2747 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2748 g_object_unref (account);
2752 /* Set the header style by default, it could
2753 be changed later by the refresh callback to
2755 modest_main_window_set_contents_style (main_window,
2756 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2758 /* Set folder on header view. This function
2759 will call tny_folder_refresh_async so we
2760 pass a callback that will be called when
2761 finished. We use that callback to set the
2762 empty view if there are no messages */
2763 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2764 TNY_FOLDER (folder_store),
2766 MODEST_WINDOW (main_window),
2767 folder_refreshed_cb,
2770 /* Restore configuration. We need to do this
2771 *after* the set_folder because the widget
2772 memory asks the header view about its
2774 modest_widget_memory_restore (modest_runtime_get_conf (),
2775 G_OBJECT(header_view),
2776 MODEST_CONF_HEADER_VIEW_KEY);
2778 /* No need to save the header view
2779 configuration for Maemo because it only
2780 saves the sorting stuff and that it's
2781 already being done by the sort
2782 dialog. Remove it when the GNOME version
2783 has the same behaviour */
2784 #ifdef MODEST_TOOLKIT_GTK
2785 if (modest_main_window_get_contents_style (main_window) ==
2786 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2787 modest_widget_memory_save (modest_runtime_get_conf (),
2788 G_OBJECT (header_view),
2789 MODEST_CONF_HEADER_VIEW_KEY);
2791 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2795 /* Update dimming state */
2796 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2797 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2801 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2808 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2810 online = tny_device_is_online (modest_runtime_get_device());
2813 /* already online -- the item is simply not there... */
2814 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2816 GTK_MESSAGE_WARNING,
2818 _("The %s you selected cannot be found"),
2820 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2821 gtk_dialog_run (GTK_DIALOG(dialog));
2823 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2826 _("mcen_bd_dialog_cancel"),
2827 GTK_RESPONSE_REJECT,
2828 _("mcen_bd_dialog_ok"),
2829 GTK_RESPONSE_ACCEPT,
2831 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2832 "Do you want to get online?"), item);
2833 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2834 gtk_label_new (txt), FALSE, FALSE, 0);
2835 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2838 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2839 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2840 /* TODO: Comment about why is this commented out: */
2841 /* modest_platform_connect_and_wait (); */
2844 gtk_widget_destroy (dialog);
2848 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2851 /* g_debug ("%s %s", __FUNCTION__, link); */
2856 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2859 modest_platform_activate_uri (link);
2863 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2866 modest_platform_show_uri_popup (link);
2870 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2873 /* we check for low-mem; in that case, show a warning, and don't allow
2874 * viewing attachments
2876 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2879 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2883 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2884 const gchar *address,
2887 /* g_debug ("%s %s", __FUNCTION__, address); */
2891 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2892 TnyMsg *saved_draft,
2895 ModestMsgEditWindow *edit_window;
2897 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2898 #ifndef MODEST_TOOLKIT_HILDON2
2899 ModestMainWindow *win;
2901 /* FIXME. Make the header view sensitive again. This is a
2902 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2904 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2905 modest_runtime_get_window_mgr(), FALSE));
2907 GtkWidget *hdrview = modest_main_window_get_child_widget(
2908 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2909 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2913 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2915 /* Set draft is there was no error */
2916 if (!modest_mail_operation_get_error (mail_op))
2917 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2919 g_object_unref(edit_window);
2923 enough_space_for_message (ModestMsgEditWindow *edit_window,
2926 guint64 available_disk, expected_size;
2931 available_disk = modest_utils_get_available_space (NULL);
2932 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2933 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2938 /* Double check: disk full condition or message too big */
2939 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2940 expected_size > available_disk) {
2941 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2942 modest_platform_information_banner (NULL, NULL, msg);
2949 * djcb: if we're in low-memory state, we only allow for
2950 * saving messages smaller than
2951 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2952 * should still allow for sending anything critical...
2954 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2955 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2959 * djcb: we also make sure that the attachments are smaller than the max size
2960 * this is for the case where we'd try to forward a message with attachments
2961 * bigger than our max allowed size, or sending an message from drafts which
2962 * somehow got past our checks when attaching.
2964 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2965 modest_platform_run_information_dialog (
2966 GTK_WINDOW(edit_window),
2967 _("mail_ib_error_attachment_size"),
2976 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2978 TnyTransportAccount *transport_account;
2979 ModestMailOperation *mail_operation;
2981 gchar *account_name;
2982 ModestAccountMgr *account_mgr;
2983 gboolean had_error = FALSE;
2984 ModestMainWindow *win = NULL;
2986 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2988 data = modest_msg_edit_window_get_msg_data (edit_window);
2991 if (!enough_space_for_message (edit_window, data)) {
2992 modest_msg_edit_window_free_msg_data (edit_window, data);
2996 account_name = g_strdup (data->account_name);
2997 account_mgr = modest_runtime_get_account_mgr();
2999 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3001 account_name = modest_account_mgr_get_default_account (account_mgr);
3002 if (!account_name) {
3003 g_printerr ("modest: no account found\n");
3004 modest_msg_edit_window_free_msg_data (edit_window, data);
3008 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3009 account_name = g_strdup (data->account_name);
3013 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3014 (modest_runtime_get_account_store (),
3016 TNY_ACCOUNT_TYPE_TRANSPORT));
3017 if (!transport_account) {
3018 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3019 g_free (account_name);
3020 modest_msg_edit_window_free_msg_data (edit_window, data);
3024 /* Create the mail operation */
3025 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3029 modest_mail_operation_save_to_drafts (mail_operation,
3041 data->priority_flags,
3044 on_save_to_drafts_cb,
3045 g_object_ref(edit_window));
3047 #ifdef MODEST_TOOLKIT_HILDON2
3048 /* In hildon2 we always show the information banner on saving to drafts.
3049 * It will be a system information banner in this case.
3051 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3052 modest_platform_information_banner (NULL, NULL, text);
3055 /* Use the main window as the parent of the banner, if the
3056 main window does not exist it won't be shown, if the parent
3057 window exists then it's properly shown. We don't use the
3058 editor window because it could be closed (save to drafts
3059 could happen after closing the window */
3060 win = (ModestMainWindow *)
3061 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3063 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3064 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3068 modest_msg_edit_window_set_modified (edit_window, FALSE);
3071 g_free (account_name);
3072 g_object_unref (G_OBJECT (transport_account));
3073 g_object_unref (G_OBJECT (mail_operation));
3075 modest_msg_edit_window_free_msg_data (edit_window, data);
3078 * If the drafts folder is selected then make the header view
3079 * insensitive while the message is being saved to drafts
3080 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3081 * is not very clean but it avoids letting the drafts folder
3082 * in an inconsistent state: the user could edit the message
3083 * being saved and undesirable things would happen.
3084 * In the average case the user won't notice anything at
3085 * all. In the worst case (the user is editing a really big
3086 * file from Drafts) the header view will be insensitive
3087 * during the saving process (10 or 20 seconds, depending on
3088 * the message). Anyway this is just a quick workaround: once
3089 * we find a better solution it should be removed
3090 * See NB#65125 (commend #18) for details.
3092 if (!had_error && win != NULL) {
3093 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3094 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3096 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3098 if (modest_tny_folder_is_local_folder(folder)) {
3099 TnyFolderType folder_type;
3100 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3101 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3102 GtkWidget *hdrview = modest_main_window_get_child_widget(
3103 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3104 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3108 if (folder != NULL) g_object_unref(folder);
3115 /* For instance, when clicking the Send toolbar button when editing a message: */
3117 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3119 TnyTransportAccount *transport_account = NULL;
3120 gboolean had_error = FALSE;
3122 ModestAccountMgr *account_mgr;
3123 gchar *account_name;
3124 ModestMailOperation *mail_operation;
3127 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3129 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3132 data = modest_msg_edit_window_get_msg_data (edit_window);
3134 if (data->subject == NULL || data->subject[0] == '\0') {
3135 /* Empty subject -> no send */
3136 modest_msg_edit_window_free_msg_data (edit_window, data);
3140 recipients = g_strconcat (data->to?data->to:"",
3141 data->cc?data->cc:"",
3142 data->bcc?data->bcc:"",
3144 if (recipients == NULL || recipients[0] == '\0') {
3145 /* Empty subject -> no send */
3146 g_free (recipients);
3147 modest_msg_edit_window_free_msg_data (edit_window, data);
3150 g_free (recipients);
3153 if (!enough_space_for_message (edit_window, data)) {
3154 modest_msg_edit_window_free_msg_data (edit_window, data);
3158 account_mgr = modest_runtime_get_account_mgr();
3159 account_name = g_strdup (data->account_name);
3161 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3164 account_name = modest_account_mgr_get_default_account (account_mgr);
3166 if (!account_name) {
3167 modest_msg_edit_window_free_msg_data (edit_window, data);
3168 /* Run account setup wizard */
3169 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3174 /* Get the currently-active transport account for this modest account: */
3175 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3177 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3178 (modest_runtime_get_account_store (),
3179 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3182 if (!transport_account) {
3183 modest_msg_edit_window_free_msg_data (edit_window, data);
3184 /* Run account setup wizard */
3185 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3190 /* Create the mail operation */
3191 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3192 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3194 modest_mail_operation_send_new_mail (mail_operation,
3208 data->priority_flags);
3210 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3211 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3213 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3214 const GError *error = modest_mail_operation_get_error (mail_operation);
3215 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3216 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3217 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3218 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3224 g_free (account_name);
3225 g_object_unref (G_OBJECT (transport_account));
3226 g_object_unref (G_OBJECT (mail_operation));
3228 modest_msg_edit_window_free_msg_data (edit_window, data);
3231 modest_msg_edit_window_set_sent (edit_window, TRUE);
3233 /* Save settings and close the window: */
3234 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3241 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3242 ModestMsgEditWindow *window)
3244 ModestMsgEditFormatState *format_state = NULL;
3246 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3247 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3249 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3252 format_state = modest_msg_edit_window_get_format_state (window);
3253 g_return_if_fail (format_state != NULL);
3255 format_state->bold = gtk_toggle_action_get_active (action);
3256 modest_msg_edit_window_set_format_state (window, format_state);
3257 g_free (format_state);
3262 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3263 ModestMsgEditWindow *window)
3265 ModestMsgEditFormatState *format_state = NULL;
3267 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3268 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3270 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3273 format_state = modest_msg_edit_window_get_format_state (window);
3274 g_return_if_fail (format_state != NULL);
3276 format_state->italics = gtk_toggle_action_get_active (action);
3277 modest_msg_edit_window_set_format_state (window, format_state);
3278 g_free (format_state);
3283 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3284 ModestMsgEditWindow *window)
3286 ModestMsgEditFormatState *format_state = NULL;
3288 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3289 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3291 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3294 format_state = modest_msg_edit_window_get_format_state (window);
3295 g_return_if_fail (format_state != NULL);
3297 format_state->bullet = gtk_toggle_action_get_active (action);
3298 modest_msg_edit_window_set_format_state (window, format_state);
3299 g_free (format_state);
3304 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3305 GtkRadioAction *selected,
3306 ModestMsgEditWindow *window)
3308 ModestMsgEditFormatState *format_state = NULL;
3309 GtkJustification value;
3311 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3313 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3316 value = gtk_radio_action_get_current_value (selected);
3318 format_state = modest_msg_edit_window_get_format_state (window);
3319 g_return_if_fail (format_state != NULL);
3321 format_state->justification = value;
3322 modest_msg_edit_window_set_format_state (window, format_state);
3323 g_free (format_state);
3327 modest_ui_actions_on_select_editor_color (GtkAction *action,
3328 ModestMsgEditWindow *window)
3330 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3331 g_return_if_fail (GTK_IS_ACTION (action));
3333 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3336 modest_msg_edit_window_select_color (window);
3340 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3341 ModestMsgEditWindow *window)
3343 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3344 g_return_if_fail (GTK_IS_ACTION (action));
3346 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3349 modest_msg_edit_window_select_background_color (window);
3353 modest_ui_actions_on_insert_image (GObject *object,
3354 ModestMsgEditWindow *window)
3356 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3359 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3362 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3365 modest_msg_edit_window_insert_image (window);
3369 modest_ui_actions_on_attach_file (GtkAction *action,
3370 ModestMsgEditWindow *window)
3372 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3373 g_return_if_fail (GTK_IS_ACTION (action));
3375 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3378 modest_msg_edit_window_offer_attach_file (window);
3382 modest_ui_actions_on_remove_attachments (GtkAction *action,
3383 ModestMsgEditWindow *window)
3385 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3387 modest_msg_edit_window_remove_attachments (window, NULL);
3391 do_create_folder_cb (ModestMailOperation *mail_op,
3392 TnyFolderStore *parent_folder,
3393 TnyFolder *new_folder,
3396 gchar *suggested_name = (gchar *) user_data;
3397 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3398 const GError *error;
3400 error = modest_mail_operation_get_error (mail_op);
3402 gboolean disk_full = FALSE;
3403 TnyAccount *account;
3404 /* Show an error. If there was some problem writing to
3405 disk, show it, otherwise show the generic folder
3406 create error. We do it here and not in an error
3407 handler because the call to do_create_folder will
3408 stop the main loop in a gtk_dialog_run and then,
3409 the message won't be shown until that dialog is
3411 account = modest_mail_operation_get_account (mail_op);
3414 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3415 (GtkWidget *) source_win,
3418 _("mail_in_ui_folder_create_error_memory"));
3419 g_object_unref (account);
3422 /* Show an error and try again if there is no
3423 full memory condition */
3424 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3425 _("mail_in_ui_folder_create_error"));
3426 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3430 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3431 * FIXME: any other? */
3432 GtkWidget *folder_view;
3434 if (MODEST_IS_MAIN_WINDOW(source_win))
3436 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3437 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3439 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3440 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3442 /* Select the newly created folder. It could happen
3443 that the widget is no longer there (i.e. the window
3444 has been destroyed, so we need to check this */
3446 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3448 g_object_unref (new_folder);
3450 /* Free. Note that the first time it'll be NULL so noop */
3451 g_free (suggested_name);
3452 g_object_unref (source_win);
3457 TnyFolderStore *parent;
3458 } CreateFolderConnect;
3461 do_create_folder_performer (gboolean canceled,
3463 GtkWindow *parent_window,
3464 TnyAccount *account,
3467 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3468 ModestMailOperation *mail_op;
3470 if (canceled || err) {
3471 /* In disk full conditions we could get this error here */
3472 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3473 (GtkWidget *) parent_window, err,
3474 NULL, _("mail_in_ui_folder_create_error_memory"));
3476 /* This happens if we have selected the outbox folder
3478 if (err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3479 TNY_IS_MERGE_FOLDER (helper->parent)) {
3480 /* Show an error and retry */
3481 modest_platform_information_banner ((GtkWidget *) parent_window,
3483 _("mail_in_ui_folder_create_error"));
3485 do_create_folder (parent_window, helper->parent, helper->folder_name);
3491 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3492 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3494 modest_mail_operation_create_folder (mail_op,
3496 (const gchar *) helper->folder_name,
3497 do_create_folder_cb,
3498 g_strdup (helper->folder_name));
3499 g_object_unref (mail_op);
3503 g_object_unref (helper->parent);
3504 if (helper->folder_name)
3505 g_free (helper->folder_name);
3506 g_slice_free (CreateFolderConnect, helper);
3511 do_create_folder (GtkWindow *parent_window,
3512 TnyFolderStore *suggested_parent,
3513 const gchar *suggested_name)
3516 gchar *folder_name = NULL;
3517 TnyFolderStore *parent_folder = NULL;
3519 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3521 (gchar *) suggested_name,
3525 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3526 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3527 helper->folder_name = g_strdup (folder_name);
3528 helper->parent = g_object_ref (parent_folder);
3530 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3533 do_create_folder_performer,
3538 g_free (folder_name);
3540 g_object_unref (parent_folder);
3544 modest_ui_actions_create_folder(GtkWidget *parent_window,
3545 GtkWidget *folder_view,
3546 TnyFolderStore *parent_folder)
3548 if (!parent_folder) {
3549 #ifdef MODEST_TOOLKIT_HILDON2
3550 ModestTnyAccountStore *acc_store;
3552 acc_store = modest_runtime_get_account_store ();
3554 parent_folder = (TnyFolderStore *)
3555 modest_tny_account_store_get_local_folders_account (acc_store);
3557 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3561 if (parent_folder) {
3562 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3563 g_object_unref (parent_folder);
3568 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3571 g_return_if_fail (MODEST_IS_WINDOW(window));
3573 if (MODEST_IS_MAIN_WINDOW (window)) {
3574 GtkWidget *folder_view;
3576 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3577 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3581 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3582 #ifdef MODEST_TOOLKIT_HILDON2
3583 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3584 GtkWidget *folder_view;
3586 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3587 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3590 g_assert_not_reached ();
3595 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3598 const GError *error = NULL;
3599 gchar *message = NULL;
3601 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3603 /* Get error message */
3604 error = modest_mail_operation_get_error (mail_op);
3606 g_return_if_reached ();
3608 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3609 (GError *) error, account);
3611 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3612 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3613 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3614 message = _CS("ckdg_ib_folder_already_exists");
3615 } else if (error->domain == TNY_ERROR_DOMAIN &&
3616 error->code == TNY_SERVICE_ERROR_STATE) {
3617 /* This means that the folder is already in use (a
3618 message is opened for example */
3619 message = _("emev_ni_internal_error");
3621 message = _CS("ckdg_ib_unable_to_rename");
3624 /* We don't set a parent for the dialog because the dialog
3625 will be destroyed so the banner won't appear */
3626 modest_platform_information_banner (NULL, NULL, message);
3629 g_object_unref (account);
3635 TnyFolderStore *folder;
3640 on_rename_folder_cb (ModestMailOperation *mail_op,
3641 TnyFolder *new_folder,
3644 ModestFolderView *folder_view;
3646 /* If the window was closed when renaming a folder, or if
3647 * it's not a main window this will happen */
3648 if (!MODEST_IS_FOLDER_VIEW (user_data))
3651 folder_view = MODEST_FOLDER_VIEW (user_data);
3652 /* Note that if the rename fails new_folder will be NULL */
3654 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3656 modest_folder_view_select_first_inbox_or_local (folder_view);
3658 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3662 on_rename_folder_performer (gboolean canceled,
3664 GtkWindow *parent_window,
3665 TnyAccount *account,
3668 ModestMailOperation *mail_op = NULL;
3669 GtkTreeSelection *sel = NULL;
3670 GtkWidget *folder_view = NULL;
3671 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3673 if (canceled || err) {
3674 /* In disk full conditions we could get this error here */
3675 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3676 (GtkWidget *) parent_window, err,
3681 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3682 modest_ui_actions_rename_folder_error_handler,
3683 parent_window, NULL);
3685 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3688 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3690 folder_view = modest_main_window_get_child_widget (
3691 MODEST_MAIN_WINDOW (parent_window),
3692 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3694 #ifdef MODEST_TOOLKIT_HILDON2
3695 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3696 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3697 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3701 /* Clear the folders view */
3702 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3703 gtk_tree_selection_unselect_all (sel);
3705 /* Actually rename the folder */
3706 modest_mail_operation_rename_folder (mail_op,
3707 TNY_FOLDER (data->folder),
3708 (const gchar *) (data->new_name),
3709 on_rename_folder_cb,
3711 g_object_unref (mail_op);
3714 g_object_unref (data->folder);
3715 g_free (data->new_name);
3720 modest_ui_actions_on_rename_folder (GtkAction *action,
3721 ModestWindow *window)
3723 modest_ui_actions_on_edit_mode_rename_folder (window);
3727 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3729 TnyFolderStore *folder;
3730 GtkWidget *folder_view;
3731 gboolean do_rename = TRUE;
3733 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3735 if (MODEST_IS_MAIN_WINDOW (window)) {
3736 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3737 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3741 #ifdef MODEST_TOOLKIT_HILDON2
3742 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3743 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3749 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3754 if (TNY_IS_FOLDER (folder)) {
3755 gchar *folder_name = NULL;
3757 const gchar *current_name;
3758 TnyFolderStore *parent;
3760 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3761 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3762 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3763 parent, current_name,
3765 g_object_unref (parent);
3767 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3770 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3771 rename_folder_data->folder = g_object_ref (folder);
3772 rename_folder_data->new_name = folder_name;
3773 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3774 folder, on_rename_folder_performer, rename_folder_data);
3777 g_object_unref (folder);
3782 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3785 GObject *win = modest_mail_operation_get_source (mail_op);
3787 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3788 _("mail_in_ui_folder_delete_error"),
3790 g_object_unref (win);
3794 TnyFolderStore *folder;
3795 gboolean move_to_trash;
3799 on_delete_folder_cb (gboolean canceled,
3801 GtkWindow *parent_window,
3802 TnyAccount *account,
3805 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3806 GtkWidget *folder_view;
3807 ModestMailOperation *mail_op;
3808 GtkTreeSelection *sel;
3810 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3811 /* Note that the connection process can fail due to
3812 memory low conditions as it can not successfully
3813 store the summary */
3814 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3815 (GtkWidget*) parent_window, err,
3817 g_debug ("Error connecting when trying to delete a folder");
3818 g_object_unref (G_OBJECT (info->folder));
3823 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3824 folder_view = modest_main_window_get_child_widget (
3825 MODEST_MAIN_WINDOW (parent_window),
3826 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3827 #ifdef MODEST_TOOLKIT_HILDON2
3828 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3829 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3832 g_object_unref (G_OBJECT (info->folder));
3837 /* Unselect the folder before deleting it to free the headers */
3838 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3839 gtk_tree_selection_unselect_all (sel);
3841 /* Create the mail operation */
3843 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3844 modest_ui_actions_delete_folder_error_handler,
3847 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3849 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3851 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3853 g_object_unref (G_OBJECT (mail_op));
3854 g_object_unref (G_OBJECT (info->folder));
3859 delete_folder (ModestWindow *window, gboolean move_to_trash)
3861 TnyFolderStore *folder;
3862 GtkWidget *folder_view;
3866 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3868 if (MODEST_IS_MAIN_WINDOW (window)) {
3870 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3871 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3872 #ifdef MODEST_TOOLKIT_HILDON2
3873 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3874 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3882 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3887 /* Show an error if it's an account */
3888 if (!TNY_IS_FOLDER (folder)) {
3889 modest_platform_run_information_dialog (GTK_WINDOW (window),
3890 _("mail_in_ui_folder_delete_error"),
3892 g_object_unref (G_OBJECT (folder));
3897 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3898 tny_folder_get_name (TNY_FOLDER (folder)));
3899 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3900 (const gchar *) message);
3903 if (response == GTK_RESPONSE_OK) {
3904 DeleteFolderInfo *info;
3905 info = g_new0(DeleteFolderInfo, 1);
3906 info->folder = folder;
3907 info->move_to_trash = move_to_trash;
3908 g_object_ref (G_OBJECT (info->folder));
3909 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3910 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3912 TNY_FOLDER_STORE (account),
3913 on_delete_folder_cb, info);
3914 g_object_unref (account);
3919 g_object_unref (G_OBJECT (folder));
3923 modest_ui_actions_on_delete_folder (GtkAction *action,
3924 ModestWindow *window)
3926 modest_ui_actions_on_edit_mode_delete_folder (window);
3930 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3932 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3934 return delete_folder (window, FALSE);
3938 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3940 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3942 delete_folder (MODEST_WINDOW (main_window), TRUE);
3946 typedef struct _PasswordDialogFields {
3947 GtkWidget *username;
3948 GtkWidget *password;
3950 } PasswordDialogFields;
3953 password_dialog_check_field (GtkEditable *editable,
3954 PasswordDialogFields *fields)
3957 gboolean any_value_empty = FALSE;
3959 #ifdef MODEST_TOOLKIT_HILDON2
3960 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3962 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3964 if ((value == NULL) || value[0] == '\0') {
3965 any_value_empty = TRUE;
3967 #ifdef MODEST_TOOLKIT_HILDON2
3968 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3970 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3972 if ((value == NULL) || value[0] == '\0') {
3973 any_value_empty = TRUE;
3975 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3979 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3980 const gchar* server_account_name,
3985 ModestMainWindow *main_window)
3987 g_return_if_fail(server_account_name);
3988 gboolean completed = FALSE;
3989 PasswordDialogFields *fields = NULL;
3991 /* Initalize output parameters: */
3998 #ifndef MODEST_TOOLKIT_GTK
3999 /* Maemo uses a different (awkward) button order,
4000 * It should probably just use gtk_alternative_dialog_button_order ().
4002 #ifdef MODEST_TOOLKIT_HILDON2
4004 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4007 _HL("wdgt_bd_done"),
4008 GTK_RESPONSE_ACCEPT,
4010 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4011 HILDON_MARGIN_DOUBLE);
4014 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4017 _("mcen_bd_dialog_ok"),
4018 GTK_RESPONSE_ACCEPT,
4019 _("mcen_bd_dialog_cancel"),
4020 GTK_RESPONSE_REJECT,
4022 #endif /* MODEST_TOOLKIT_HILDON2 */
4025 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4029 GTK_RESPONSE_REJECT,
4031 GTK_RESPONSE_ACCEPT,
4033 #endif /* MODEST_TOOLKIT_GTK */
4035 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4037 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4038 modest_runtime_get_account_mgr(), server_account_name);
4039 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4040 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4043 gtk_widget_destroy (dialog);
4047 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4048 GtkWidget *label = gtk_label_new (txt);
4049 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4051 g_free (server_name);
4052 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4057 gchar *initial_username = modest_account_mgr_get_server_account_username (
4058 modest_runtime_get_account_mgr(), server_account_name);
4060 #ifdef MODEST_TOOLKIT_HILDON2
4061 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4062 if (initial_username)
4063 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4065 GtkWidget *entry_username = gtk_entry_new ();
4066 if (initial_username)
4067 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4069 /* Dim this if a connection has ever succeeded with this username,
4070 * as per the UI spec: */
4071 /* const gboolean username_known = */
4072 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4073 /* modest_runtime_get_account_mgr(), server_account_name); */
4074 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4076 /* We drop the username sensitive code and disallow changing it here
4077 * as tinymail does not support really changing the username in the callback
4079 gtk_widget_set_sensitive (entry_username, FALSE);
4081 #ifndef MODEST_TOOLKIT_GTK
4082 /* Auto-capitalization is the default, so let's turn it off: */
4083 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4085 /* Create a size group to be used by all captions.
4086 * Note that HildonCaption does not create a default size group if we do not specify one.
4087 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4088 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4090 #ifdef MODEST_TOOLKIT_HILDON2
4091 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4092 _("mail_fi_username"), FALSE,
4095 GtkWidget *caption = hildon_caption_new (sizegroup,
4096 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4098 gtk_widget_show (entry_username);
4099 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4100 FALSE, FALSE, MODEST_MARGIN_HALF);
4101 gtk_widget_show (caption);
4103 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4105 #endif /* !MODEST_TOOLKIT_GTK */
4108 #ifdef MODEST_TOOLKIT_HILDON2
4109 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4111 GtkWidget *entry_password = gtk_entry_new ();
4113 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4114 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4116 #ifndef MODEST_TOOLKIT_GTK
4117 /* Auto-capitalization is the default, so let's turn it off: */
4118 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4119 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4121 #ifdef MODEST_TOOLKIT_HILDON2
4122 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4123 _("mail_fi_password"), FALSE,
4126 caption = hildon_caption_new (sizegroup,
4127 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4129 gtk_widget_show (entry_password);
4130 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4131 FALSE, FALSE, MODEST_MARGIN_HALF);
4132 gtk_widget_show (caption);
4133 g_object_unref (sizegroup);
4135 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4137 #endif /* !MODEST_TOOLKIT_GTK */
4139 if (initial_username != NULL)
4140 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4142 /* This is not in the Maemo UI spec:
4143 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4144 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4148 fields = g_slice_new0 (PasswordDialogFields);
4149 fields->username = entry_username;
4150 fields->password = entry_password;
4151 fields->dialog = dialog;
4153 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4154 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4155 password_dialog_check_field (NULL, fields);
4157 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4159 while (!completed) {
4161 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4163 #ifdef MODEST_TOOLKIT_HILDON2
4164 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4166 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4169 /* Note that an empty field becomes the "" string */
4170 if (*username && strlen (*username) > 0) {
4171 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4172 server_account_name,
4176 const gboolean username_was_changed =
4177 (strcmp (*username, initial_username) != 0);
4178 if (username_was_changed) {
4179 g_warning ("%s: tinymail does not yet support changing the "
4180 "username in the get_password() callback.\n", __FUNCTION__);
4186 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4187 _("mcen_ib_username_pw_incorrect"));
4193 #ifdef MODEST_TOOLKIT_HILDON2
4194 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4196 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4199 /* We do not save the password in the configuration,
4200 * because this function is only called for passwords that should
4201 * not be remembered:
4202 modest_server_account_set_password (
4203 modest_runtime_get_account_mgr(), server_account_name,
4210 #ifndef MODEST_TOOLKIT_HILDON2
4211 /* Set parent to NULL or the banner will disappear with its parent dialog */
4212 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4224 /* This is not in the Maemo UI spec:
4225 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4231 g_free (initial_username);
4232 gtk_widget_destroy (dialog);
4233 g_slice_free (PasswordDialogFields, fields);
4235 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4239 modest_ui_actions_on_cut (GtkAction *action,
4240 ModestWindow *window)
4242 GtkWidget *focused_widget;
4243 GtkClipboard *clipboard;
4245 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4246 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4247 if (GTK_IS_EDITABLE (focused_widget)) {
4248 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4249 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4250 gtk_clipboard_store (clipboard);
4251 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4252 GtkTextBuffer *buffer;
4254 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4255 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4256 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4257 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4258 gtk_clipboard_store (clipboard);
4260 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4261 TnyList *header_list = modest_header_view_get_selected_headers (
4262 MODEST_HEADER_VIEW (focused_widget));
4263 gboolean continue_download = FALSE;
4264 gint num_of_unc_msgs;
4266 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4268 if (num_of_unc_msgs) {
4269 TnyAccount *account = get_account_from_header_list (header_list);
4271 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4272 g_object_unref (account);
4276 if (num_of_unc_msgs == 0 || continue_download) {
4277 /* modest_platform_information_banner (
4278 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4279 modest_header_view_cut_selection (
4280 MODEST_HEADER_VIEW (focused_widget));
4283 g_object_unref (header_list);
4284 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4285 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4290 modest_ui_actions_on_copy (GtkAction *action,
4291 ModestWindow *window)
4293 GtkClipboard *clipboard;
4294 GtkWidget *focused_widget;
4295 gboolean copied = TRUE;
4297 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4298 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4300 if (GTK_IS_LABEL (focused_widget)) {
4302 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4303 gtk_clipboard_set_text (clipboard, selection, -1);
4305 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4306 gtk_clipboard_store (clipboard);
4307 } else if (GTK_IS_EDITABLE (focused_widget)) {
4308 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4309 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4310 gtk_clipboard_store (clipboard);
4311 } else if (GTK_IS_HTML (focused_widget)) {
4314 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4315 if ((sel == NULL) || (sel[0] == '\0')) {
4318 gtk_html_copy (GTK_HTML (focused_widget));
4319 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4320 gtk_clipboard_store (clipboard);
4322 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4323 GtkTextBuffer *buffer;
4324 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4325 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4326 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4327 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4328 gtk_clipboard_store (clipboard);
4330 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4331 TnyList *header_list = modest_header_view_get_selected_headers (
4332 MODEST_HEADER_VIEW (focused_widget));
4333 gboolean continue_download = FALSE;
4334 gint num_of_unc_msgs;
4336 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4338 if (num_of_unc_msgs) {
4339 TnyAccount *account = get_account_from_header_list (header_list);
4341 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4342 g_object_unref (account);
4346 if (num_of_unc_msgs == 0 || continue_download) {
4347 modest_platform_information_banner (
4348 NULL, NULL, _CS("mcen_ib_getting_items"));
4349 modest_header_view_copy_selection (
4350 MODEST_HEADER_VIEW (focused_widget));
4354 g_object_unref (header_list);
4356 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4357 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4360 /* Show information banner if there was a copy to clipboard */
4362 modest_platform_information_banner (
4363 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4367 modest_ui_actions_on_undo (GtkAction *action,
4368 ModestWindow *window)
4370 ModestEmailClipboard *clipboard = NULL;
4372 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4373 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4374 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4375 /* Clear clipboard source */
4376 clipboard = modest_runtime_get_email_clipboard ();
4377 modest_email_clipboard_clear (clipboard);
4380 g_return_if_reached ();
4385 modest_ui_actions_on_redo (GtkAction *action,
4386 ModestWindow *window)
4388 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4389 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4392 g_return_if_reached ();
4398 destroy_information_note (ModestMailOperation *mail_op,
4401 /* destroy information note */
4402 gtk_widget_destroy (GTK_WIDGET(user_data));
4406 destroy_folder_information_note (ModestMailOperation *mail_op,
4407 TnyFolder *new_folder,
4410 /* destroy information note */
4411 gtk_widget_destroy (GTK_WIDGET(user_data));
4416 paste_as_attachment_free (gpointer data)
4418 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4420 if (helper->banner) {
4421 gtk_widget_destroy (helper->banner);
4422 g_object_unref (helper->banner);
4428 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4433 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4434 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4439 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4444 modest_ui_actions_on_paste (GtkAction *action,
4445 ModestWindow *window)
4447 GtkWidget *focused_widget = NULL;
4448 GtkWidget *inf_note = NULL;
4449 ModestMailOperation *mail_op = NULL;
4451 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4452 if (GTK_IS_EDITABLE (focused_widget)) {
4453 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4454 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4455 ModestEmailClipboard *e_clipboard = NULL;
4456 e_clipboard = modest_runtime_get_email_clipboard ();
4457 if (modest_email_clipboard_cleared (e_clipboard)) {
4458 GtkTextBuffer *buffer;
4459 GtkClipboard *clipboard;
4461 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4462 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4463 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4464 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4465 ModestMailOperation *mail_op;
4466 TnyFolder *src_folder = NULL;
4467 TnyList *data = NULL;
4469 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4470 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4471 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4472 _CS("ckct_nw_pasting"));
4473 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4474 mail_op = modest_mail_operation_new (G_OBJECT (window));
4475 if (helper->banner != NULL) {
4476 g_object_ref (G_OBJECT (helper->banner));
4477 gtk_widget_show (GTK_WIDGET (helper->banner));
4481 modest_mail_operation_get_msgs_full (mail_op,
4483 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4485 paste_as_attachment_free);
4489 g_object_unref (data);
4491 g_object_unref (src_folder);
4494 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4495 ModestEmailClipboard *clipboard = NULL;
4496 TnyFolder *src_folder = NULL;
4497 TnyFolderStore *folder_store = NULL;
4498 TnyList *data = NULL;
4499 gboolean delete = FALSE;
4501 /* Check clipboard source */
4502 clipboard = modest_runtime_get_email_clipboard ();
4503 if (modest_email_clipboard_cleared (clipboard))
4506 /* Get elements to paste */
4507 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4509 /* Create a new mail operation */
4510 mail_op = modest_mail_operation_new (G_OBJECT(window));
4512 /* Get destination folder */
4513 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4515 /* transfer messages */
4519 /* Ask for user confirmation */
4521 modest_ui_actions_msgs_move_to_confirmation (window,
4522 TNY_FOLDER (folder_store),
4526 if (response == GTK_RESPONSE_OK) {
4527 /* Launch notification */
4528 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4529 _CS("ckct_nw_pasting"));
4530 if (inf_note != NULL) {
4531 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4532 gtk_widget_show (GTK_WIDGET(inf_note));
4535 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4536 modest_mail_operation_xfer_msgs (mail_op,
4538 TNY_FOLDER (folder_store),
4540 destroy_information_note,
4543 g_object_unref (mail_op);
4546 } else if (src_folder != NULL) {
4547 /* Launch notification */
4548 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4549 _CS("ckct_nw_pasting"));
4550 if (inf_note != NULL) {
4551 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4552 gtk_widget_show (GTK_WIDGET(inf_note));
4555 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4556 modest_mail_operation_xfer_folder (mail_op,
4560 destroy_folder_information_note,
4566 g_object_unref (data);
4567 if (src_folder != NULL)
4568 g_object_unref (src_folder);
4569 if (folder_store != NULL)
4570 g_object_unref (folder_store);
4576 modest_ui_actions_on_select_all (GtkAction *action,
4577 ModestWindow *window)
4579 GtkWidget *focused_widget;
4581 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4582 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4583 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4584 } else if (GTK_IS_LABEL (focused_widget)) {
4585 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4586 } else if (GTK_IS_EDITABLE (focused_widget)) {
4587 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4588 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4589 GtkTextBuffer *buffer;
4590 GtkTextIter start, end;
4592 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4593 gtk_text_buffer_get_start_iter (buffer, &start);
4594 gtk_text_buffer_get_end_iter (buffer, &end);
4595 gtk_text_buffer_select_range (buffer, &start, &end);
4596 } else if (GTK_IS_HTML (focused_widget)) {
4597 gtk_html_select_all (GTK_HTML (focused_widget));
4598 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4599 GtkWidget *header_view = focused_widget;
4600 GtkTreeSelection *selection = NULL;
4602 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4603 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4604 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4607 /* Disable window dimming management */
4608 modest_window_disable_dimming (MODEST_WINDOW(window));
4610 /* Select all messages */
4611 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4612 gtk_tree_selection_select_all (selection);
4614 /* Set focuse on header view */
4615 gtk_widget_grab_focus (header_view);
4617 /* Enable window dimming management */
4618 modest_window_enable_dimming (MODEST_WINDOW(window));
4619 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4620 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4626 modest_ui_actions_on_mark_as_read (GtkAction *action,
4627 ModestWindow *window)
4629 g_return_if_fail (MODEST_IS_WINDOW(window));
4631 /* Mark each header as read */
4632 do_headers_action (window, headers_action_mark_as_read, NULL);
4636 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4637 ModestWindow *window)
4639 g_return_if_fail (MODEST_IS_WINDOW(window));
4641 /* Mark each header as read */
4642 do_headers_action (window, headers_action_mark_as_unread, NULL);
4646 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4647 GtkRadioAction *selected,
4648 ModestWindow *window)
4652 value = gtk_radio_action_get_current_value (selected);
4653 if (MODEST_IS_WINDOW (window)) {
4654 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4659 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4660 GtkRadioAction *selected,
4661 ModestWindow *window)
4663 TnyHeaderFlags flags;
4664 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4666 flags = gtk_radio_action_get_current_value (selected);
4667 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4671 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4672 GtkRadioAction *selected,
4673 ModestWindow *window)
4677 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4679 file_format = gtk_radio_action_get_current_value (selected);
4680 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4685 modest_ui_actions_on_zoom_plus (GtkAction *action,
4686 ModestWindow *window)
4688 g_return_if_fail (MODEST_IS_WINDOW (window));
4690 modest_window_zoom_plus (MODEST_WINDOW (window));
4694 modest_ui_actions_on_zoom_minus (GtkAction *action,
4695 ModestWindow *window)
4697 g_return_if_fail (MODEST_IS_WINDOW (window));
4699 modest_window_zoom_minus (MODEST_WINDOW (window));
4703 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4704 ModestWindow *window)
4706 ModestWindowMgr *mgr;
4707 gboolean fullscreen, active;
4708 g_return_if_fail (MODEST_IS_WINDOW (window));
4710 mgr = modest_runtime_get_window_mgr ();
4712 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4713 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4715 if (active != fullscreen) {
4716 modest_window_mgr_set_fullscreen_mode (mgr, active);
4717 #ifndef MODEST_TOOLKIT_HILDON2
4718 gtk_window_present (GTK_WINDOW (window));
4724 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4725 ModestWindow *window)
4727 ModestWindowMgr *mgr;
4728 gboolean fullscreen;
4730 g_return_if_fail (MODEST_IS_WINDOW (window));
4732 mgr = modest_runtime_get_window_mgr ();
4733 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4734 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4736 #ifndef MODEST_TOOLKIT_HILDON2
4737 gtk_window_present (GTK_WINDOW (window));
4742 * Used by modest_ui_actions_on_details to call do_headers_action
4745 headers_action_show_details (TnyHeader *header,
4746 ModestWindow *window,
4750 gboolean async_retrieval;
4753 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4754 async_retrieval = TRUE;
4755 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4757 async_retrieval = FALSE;
4759 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4761 g_object_unref (msg);
4765 * Show the header details in a ModestDetailsDialog widget
4768 modest_ui_actions_on_details (GtkAction *action,
4771 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4775 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4779 header = tny_msg_get_header (msg);
4781 headers_action_show_details (header, win, NULL);
4782 g_object_unref (header);
4784 g_object_unref (msg);
4786 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4787 GtkWidget *folder_view, *header_view;
4789 /* Check which widget has the focus */
4790 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4791 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4792 if (gtk_widget_is_focus (folder_view)) {
4793 TnyFolderStore *folder_store
4794 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4795 if (!folder_store) {
4796 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4799 /* Show only when it's a folder */
4800 /* This function should not be called for account items,
4801 * because we dim the menu item for them. */
4802 if (TNY_IS_FOLDER (folder_store)) {
4803 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4804 TNY_FOLDER (folder_store));
4807 g_object_unref (folder_store);
4810 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4811 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4812 /* Show details of each header */
4813 do_headers_action (win, headers_action_show_details, header_view);
4815 #ifdef MODEST_TOOLKIT_HILDON2
4816 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4818 GtkWidget *header_view;
4820 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4821 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4823 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4825 g_object_unref (folder);
4832 modest_ui_actions_on_limit_error (GtkAction *action,
4835 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4837 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4842 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4843 ModestMsgEditWindow *window)
4845 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4847 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4851 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4852 ModestMsgEditWindow *window)
4854 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4856 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4860 modest_ui_actions_toggle_folders_view (GtkAction *action,
4861 ModestMainWindow *main_window)
4863 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4865 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4866 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4868 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4872 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4873 ModestWindow *window)
4875 gboolean active, fullscreen = FALSE;
4876 ModestWindowMgr *mgr;
4878 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4880 /* Check if we want to toggle the toolbar view in fullscreen
4882 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4883 "ViewShowToolbarFullScreen")) {
4887 /* Toggle toolbar */
4888 mgr = modest_runtime_get_window_mgr ();
4889 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4893 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4894 ModestMsgEditWindow *window)
4896 modest_msg_edit_window_select_font (window);
4901 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4902 const gchar *display_name,
4905 /* don't update the display name if it was already set;
4906 * updating the display name apparently is expensive */
4907 const gchar* old_name = gtk_window_get_title (window);
4909 if (display_name == NULL)
4912 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4913 return; /* don't do anything */
4915 /* This is usually used to change the title of the main window, which
4916 * is the one that holds the folder view. Note that this change can
4917 * happen even when the widget doesn't have the focus. */
4918 gtk_window_set_title (window, display_name);
4923 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4925 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4926 modest_msg_edit_window_select_contacts (window);
4930 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4932 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4933 modest_msg_edit_window_check_names (window, FALSE);
4936 #ifndef MODEST_TOOLKIT_HILDON2
4938 * This function is used to track changes in the selection of the
4939 * folder view that is inside the "move to" dialog to enable/disable
4940 * the OK button because we do not want the user to select a disallowed
4941 * destination for a folder.
4942 * The user also not desired to be able to use NEW button on items where
4943 * folder creation is not possibel.
4946 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4947 TnyFolderStore *folder_store,
4951 GtkWidget *dialog = NULL;
4952 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4953 gboolean moving_folder = FALSE;
4954 gboolean is_local_account = TRUE;
4955 GtkWidget *folder_view = NULL;
4956 ModestTnyFolderRules rules;
4958 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4963 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4967 /* check if folder_store is an remote account */
4968 if (TNY_IS_ACCOUNT (folder_store)) {
4969 TnyAccount *local_account = NULL;
4970 TnyAccount *mmc_account = NULL;
4971 ModestTnyAccountStore *account_store = NULL;
4973 account_store = modest_runtime_get_account_store ();
4974 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4975 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4977 if ((gpointer) local_account != (gpointer) folder_store &&
4978 (gpointer) mmc_account != (gpointer) folder_store) {
4979 ModestProtocolType proto;
4980 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4981 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4982 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4984 is_local_account = FALSE;
4985 /* New button should be dimmed on remote
4987 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4989 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4991 g_object_unref (local_account);
4993 /* It could not exist */
4995 g_object_unref (mmc_account);
4998 /* Check the target folder rules */
4999 if (TNY_IS_FOLDER (folder_store)) {
5000 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5001 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5002 ok_sensitive = FALSE;
5003 new_sensitive = FALSE;
5008 /* Check if we're moving a folder */
5009 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5010 /* Get the widgets */
5011 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5012 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5013 if (gtk_widget_is_focus (folder_view))
5014 moving_folder = TRUE;
5017 if (moving_folder) {
5018 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5020 /* Get the folder to move */
5021 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5023 /* Check that we're not moving to the same folder */
5024 if (TNY_IS_FOLDER (moved_folder)) {
5025 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5026 if (parent == folder_store)
5027 ok_sensitive = FALSE;
5028 g_object_unref (parent);
5031 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5032 /* Do not allow to move to an account unless it's the
5033 local folders account */
5034 if (!is_local_account)
5035 ok_sensitive = FALSE;
5038 if (ok_sensitive && (moved_folder == folder_store)) {
5039 /* Do not allow to move to itself */
5040 ok_sensitive = FALSE;
5042 g_object_unref (moved_folder);
5044 TnyFolder *src_folder = NULL;
5046 /* Moving a message */
5047 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5049 TnyHeader *header = NULL;
5050 header = modest_msg_view_window_get_header
5051 (MODEST_MSG_VIEW_WINDOW (user_data));
5052 if (!TNY_IS_HEADER(header))
5053 g_warning ("%s: could not get source header", __FUNCTION__);
5055 src_folder = tny_header_get_folder (header);
5058 g_object_unref (header);
5061 TNY_FOLDER (modest_folder_view_get_selected
5062 (MODEST_FOLDER_VIEW (folder_view)));
5065 if (TNY_IS_FOLDER(src_folder)) {
5066 /* Do not allow to move the msg to the same folder */
5067 /* Do not allow to move the msg to an account */
5068 if ((gpointer) src_folder == (gpointer) folder_store ||
5069 TNY_IS_ACCOUNT (folder_store))
5070 ok_sensitive = FALSE;
5071 g_object_unref (src_folder);
5073 g_warning ("%s: could not get source folder", __FUNCTION__);
5077 /* Set sensitivity of the OK and NEW button */
5078 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5079 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5084 on_move_to_dialog_response (GtkDialog *dialog,
5088 GtkWidget *parent_win;
5089 MoveToInfo *helper = NULL;
5090 ModestFolderView *folder_view;
5091 gboolean unset_edit_mode = FALSE;
5093 helper = (MoveToInfo *) user_data;
5095 parent_win = (GtkWidget *) helper->win;
5096 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5097 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5100 TnyFolderStore *dst_folder;
5101 TnyFolderStore *selected;
5103 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5104 selected = modest_folder_view_get_selected (folder_view);
5105 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5106 g_object_unref (selected);
5108 case GTK_RESPONSE_NONE:
5109 case GTK_RESPONSE_CANCEL:
5110 case GTK_RESPONSE_DELETE_EVENT:
5112 case GTK_RESPONSE_OK:
5113 dst_folder = modest_folder_view_get_selected (folder_view);
5115 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5116 /* Clean list to move used for filtering */
5117 modest_folder_view_set_list_to_move (folder_view, NULL);
5119 modest_ui_actions_on_main_window_move_to (NULL,
5120 GTK_WIDGET (folder_view),
5122 MODEST_MAIN_WINDOW (parent_win));
5123 #ifdef MODEST_TOOLKIT_HILDON2
5124 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5125 /* Clean list to move used for filtering */
5126 modest_folder_view_set_list_to_move (folder_view, NULL);
5128 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5131 GTK_WINDOW (parent_win));
5134 /* if the user selected a root folder
5135 (account) then do not perform any action */
5136 if (TNY_IS_ACCOUNT (dst_folder)) {
5137 g_signal_stop_emission_by_name (dialog, "response");
5141 /* Clean list to move used for filtering */
5142 modest_folder_view_set_list_to_move (folder_view, NULL);
5144 /* Moving from headers window in edit mode */
5145 modest_ui_actions_on_window_move_to (NULL, helper->list,
5147 MODEST_WINDOW (parent_win));
5151 g_object_unref (dst_folder);
5153 unset_edit_mode = TRUE;
5156 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5159 /* Free the helper and exit */
5161 g_object_unref (helper->list);
5162 if (unset_edit_mode) {
5163 #ifdef MODEST_TOOLKIT_HILDON2
5164 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5167 g_slice_free (MoveToInfo, helper);
5168 gtk_widget_destroy (GTK_WIDGET (dialog));
5172 create_move_to_dialog (GtkWindow *win,
5173 GtkWidget *folder_view,
5174 TnyList *list_to_move)
5176 GtkWidget *dialog, *tree_view = NULL;
5178 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5180 #ifndef MODEST_TOOLKIT_HILDON2
5181 /* Track changes in the selection to
5182 * disable the OK button whenever "Move to" is not possible
5183 * disbale NEW button whenever New is not possible */
5184 g_signal_connect (tree_view,
5185 "folder_selection_changed",
5186 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5190 /* It could happen that we're trying to move a message from a
5191 window (msg window for example) after the main window was
5192 closed, so we can not just get the model of the folder
5194 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5195 const gchar *visible_id = NULL;
5197 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5198 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5199 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5200 MODEST_FOLDER_VIEW(tree_view));
5203 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5205 /* Show the same account than the one that is shown in the main window */
5206 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5209 const gchar *active_account_name = NULL;
5210 ModestAccountMgr *mgr = NULL;
5211 ModestAccountSettings *settings = NULL;
5212 ModestServerAccountSettings *store_settings = NULL;
5214 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5215 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5216 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5217 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5219 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5220 mgr = modest_runtime_get_account_mgr ();
5221 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5224 const gchar *store_account_name;
5225 store_settings = modest_account_settings_get_store_settings (settings);
5226 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5228 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5229 store_account_name);
5230 g_object_unref (store_settings);
5231 g_object_unref (settings);
5235 /* we keep a pointer to the embedded folder view, so we can
5236 * retrieve it with get_folder_view_from_move_to_dialog (see
5237 * above) later (needed for focus handling)
5239 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5241 /* Hide special folders */
5242 #ifndef MODEST_TOOLKIT_HILDON2
5243 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5246 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5247 #ifndef MODEST_TOOLKIT_HILDON2
5248 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5251 gtk_widget_show (GTK_WIDGET (tree_view));
5257 * Shows a confirmation dialog to the user when we're moving messages
5258 * from a remote server to the local storage. Returns the dialog
5259 * response. If it's other kind of movement then it always returns
5262 * This one is used by the next functions:
5263 * modest_ui_actions_on_paste - commented out
5264 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5267 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5268 TnyFolder *dest_folder,
5272 gint response = GTK_RESPONSE_OK;
5273 TnyAccount *account = NULL;
5274 TnyFolder *src_folder = NULL;
5275 TnyIterator *iter = NULL;
5276 TnyHeader *header = NULL;
5278 /* return with OK if the destination is a remote folder */
5279 if (modest_tny_folder_is_remote_folder (dest_folder))
5280 return GTK_RESPONSE_OK;
5282 /* Get source folder */
5283 iter = tny_list_create_iterator (headers);
5284 header = TNY_HEADER (tny_iterator_get_current (iter));
5286 src_folder = tny_header_get_folder (header);
5287 g_object_unref (header);
5289 g_object_unref (iter);
5291 /* if no src_folder, message may be an attahcment */
5292 if (src_folder == NULL)
5293 return GTK_RESPONSE_CANCEL;
5295 /* If the source is a local or MMC folder */
5296 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5297 g_object_unref (src_folder);
5298 return GTK_RESPONSE_OK;
5301 /* Get the account */
5302 account = tny_folder_get_account (src_folder);
5304 /* now if offline we ask the user */
5305 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5306 response = GTK_RESPONSE_OK;
5308 response = GTK_RESPONSE_CANCEL;
5311 g_object_unref (src_folder);
5312 g_object_unref (account);
5318 move_to_helper_destroyer (gpointer user_data)
5320 MoveToHelper *helper = (MoveToHelper *) user_data;
5322 /* Close the "Pasting" information banner */
5323 if (helper->banner) {
5324 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5325 g_object_unref (helper->banner);
5327 if (gtk_tree_row_reference_valid (helper->reference)) {
5328 gtk_tree_row_reference_free (helper->reference);
5329 helper->reference = NULL;
5335 move_to_cb (ModestMailOperation *mail_op,
5338 MoveToHelper *helper = (MoveToHelper *) user_data;
5339 GObject *object = modest_mail_operation_get_source (mail_op);
5341 /* Note that the operation could have failed, in that case do
5343 if (modest_mail_operation_get_status (mail_op) !=
5344 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5347 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5348 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5350 if (!modest_msg_view_window_select_next_message (self) &&
5351 !modest_msg_view_window_select_previous_message (self)) {
5352 /* No more messages to view, so close this window */
5353 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5355 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5356 gtk_tree_row_reference_valid (helper->reference)) {
5357 GtkWidget *header_view;
5359 GtkTreeSelection *sel;
5361 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5362 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5363 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5364 path = gtk_tree_row_reference_get_path (helper->reference);
5365 /* We need to unselect the previous one
5366 because we could be copying instead of
5368 gtk_tree_selection_unselect_all (sel);
5369 gtk_tree_selection_select_path (sel, path);
5370 gtk_tree_path_free (path);
5372 g_object_unref (object);
5375 /* Destroy the helper */
5376 move_to_helper_destroyer (helper);
5380 folder_move_to_cb (ModestMailOperation *mail_op,
5381 TnyFolder *new_folder,
5384 GtkWidget *folder_view;
5387 object = modest_mail_operation_get_source (mail_op);
5388 if (MODEST_IS_MAIN_WINDOW (object)) {
5389 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5390 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5391 g_object_ref (folder_view);
5392 g_object_unref (object);
5393 move_to_cb (mail_op, user_data);
5394 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5395 g_object_unref (folder_view);
5397 move_to_cb (mail_op, user_data);
5402 msgs_move_to_cb (ModestMailOperation *mail_op,
5405 move_to_cb (mail_op, user_data);
5409 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5412 GObject *win = NULL;
5413 const GError *error;
5414 TnyAccount *account = NULL;
5416 #ifndef MODEST_TOOLKIT_HILDON2
5417 ModestWindow *main_window = NULL;
5419 /* Disable next automatic folder selection */
5420 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5421 FALSE); /* don't create */
5423 /* Show notification dialog only if the main window exists */
5425 GtkWidget *folder_view = NULL;
5427 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5428 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5429 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5431 if (user_data && TNY_IS_FOLDER (user_data)) {
5432 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5433 TNY_FOLDER (user_data), FALSE);
5437 win = modest_mail_operation_get_source (mail_op);
5438 error = modest_mail_operation_get_error (mail_op);
5440 if (TNY_IS_FOLDER (user_data))
5441 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5442 else if (TNY_IS_ACCOUNT (user_data))
5443 account = g_object_ref (user_data);
5445 /* If it's not a disk full error then show a generic error */
5446 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5447 (GtkWidget *) win, (GError *) error,
5449 modest_platform_run_information_dialog ((GtkWindow *) win,
5450 _("mail_in_ui_folder_move_target_error"),
5453 g_object_unref (account);
5455 g_object_unref (win);
5459 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5468 gint pending_purges = 0;
5469 gboolean some_purged = FALSE;
5470 ModestWindow *win = MODEST_WINDOW (user_data);
5471 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5473 /* If there was any error */
5474 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5475 modest_window_mgr_unregister_header (mgr, header);
5479 /* Once the message has been retrieved for purging, we check if
5480 * it's all ok for purging */
5482 parts = tny_simple_list_new ();
5483 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5484 iter = tny_list_create_iterator (parts);
5486 while (!tny_iterator_is_done (iter)) {
5488 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5489 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5490 if (tny_mime_part_is_purged (part))
5497 g_object_unref (part);
5499 tny_iterator_next (iter);
5501 g_object_unref (iter);
5504 if (pending_purges>0) {
5506 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5508 if (response == GTK_RESPONSE_OK) {
5511 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5512 iter = tny_list_create_iterator (parts);
5513 while (!tny_iterator_is_done (iter)) {
5516 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5517 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5518 tny_mime_part_set_purged (part);
5521 g_object_unref (part);
5523 tny_iterator_next (iter);
5525 g_object_unref (iter);
5527 tny_msg_rewrite_cache (msg);
5529 gtk_widget_destroy (info);
5533 modest_window_mgr_unregister_header (mgr, header);
5535 g_object_unref (parts);
5539 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5540 ModestMainWindow *win)
5542 GtkWidget *header_view;
5543 TnyList *header_list;
5545 TnyHeaderFlags flags;
5546 ModestWindow *msg_view_window = NULL;
5549 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5551 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5552 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5554 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5556 g_warning ("%s: no header selected", __FUNCTION__);
5560 if (tny_list_get_length (header_list) == 1) {
5561 TnyIterator *iter = tny_list_create_iterator (header_list);
5562 header = TNY_HEADER (tny_iterator_get_current (iter));
5563 g_object_unref (iter);
5567 if (!header || !TNY_IS_HEADER(header)) {
5568 g_warning ("%s: header is not valid", __FUNCTION__);
5572 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5573 header, &msg_view_window);
5574 flags = tny_header_get_flags (header);
5575 if (!(flags & TNY_HEADER_FLAG_CACHED))
5578 if (msg_view_window != NULL)
5579 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5581 /* do nothing; uid was registered before, so window is probably on it's way */
5582 g_debug ("header %p has already been registered", header);
5585 ModestMailOperation *mail_op = NULL;
5586 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5587 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5588 modest_ui_actions_disk_operations_error_handler,
5590 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5591 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5593 g_object_unref (mail_op);
5596 g_object_unref (header);
5598 g_object_unref (header_list);
5602 * Checks if we need a connection to do the transfer and if the user
5603 * wants to connect to complete it
5606 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5607 TnyFolderStore *src_folder,
5609 TnyFolder *dst_folder,
5610 gboolean delete_originals,
5611 gboolean *need_connection,
5614 TnyAccount *src_account;
5615 gint uncached_msgs = 0;
5617 /* We don't need any further check if
5619 * 1- the source folder is local OR
5620 * 2- the device is already online
5622 if (!modest_tny_folder_store_is_remote (src_folder) ||
5623 tny_device_is_online (modest_runtime_get_device())) {
5624 *need_connection = FALSE;
5629 /* We must ask for a connection when
5631 * - the message(s) is not already cached OR
5632 * - the message(s) is cached but the leave_on_server setting
5633 * is FALSE (because we need to sync the source folder to
5634 * delete the message from the server (for IMAP we could do it
5635 * offline, it'll take place the next time we get a
5638 uncached_msgs = header_list_count_uncached_msgs (headers);
5639 src_account = get_account_from_folder_store (src_folder);
5640 if (uncached_msgs > 0) {
5644 *need_connection = TRUE;
5645 num_headers = tny_list_get_length (headers);
5646 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5648 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5649 GTK_RESPONSE_CANCEL) {
5655 /* The transfer is possible and the user wants to */
5658 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5659 const gchar *account_name;
5660 gboolean leave_on_server;
5662 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5663 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5666 if (leave_on_server == TRUE) {
5667 *need_connection = FALSE;
5669 *need_connection = TRUE;
5672 *need_connection = FALSE;
5677 g_object_unref (src_account);
5681 xfer_messages_error_handler (ModestMailOperation *mail_op,
5685 const GError *error;
5686 TnyAccount *account;
5688 win = modest_mail_operation_get_source (mail_op);
5689 error = modest_mail_operation_get_error (mail_op);
5690 account = modest_mail_operation_get_account (mail_op);
5692 if (error && modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
5693 (GError *) error, account)) {
5694 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
5695 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
5698 modest_platform_run_information_dialog ((GtkWindow *) win,
5699 _("mail_in_ui_folder_move_target_error"),
5703 g_object_unref (account);
5705 g_object_unref (win);
5709 TnyFolderStore *dst_folder;
5714 * Utility function that transfer messages from both the main window
5715 * and the msg view window when using the "Move to" dialog
5718 xfer_messages_performer (gboolean canceled,
5720 GtkWindow *parent_window,
5721 TnyAccount *account,
5724 ModestWindow *win = MODEST_WINDOW (parent_window);
5725 TnyAccount *dst_account = NULL;
5726 gboolean dst_forbids_message_add = FALSE;
5727 XferMsgsHelper *helper;
5728 MoveToHelper *movehelper;
5729 ModestMailOperation *mail_op;
5731 helper = (XferMsgsHelper *) user_data;
5733 if (canceled || err) {
5734 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5735 (GtkWidget *) parent_window, err,
5737 /* Show the proper error message */
5738 modest_ui_actions_on_account_connection_error (parent_window, account);
5743 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5745 /* tinymail will return NULL for local folders it seems */
5746 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5747 modest_tny_account_get_protocol_type (dst_account),
5748 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5749 g_object_unref (dst_account);
5751 if (dst_forbids_message_add) {
5752 modest_platform_information_banner (GTK_WIDGET (win),
5754 ngettext("mail_in_ui_folder_move_target_error",
5755 "mail_in_ui_folder_move_targets_error",
5756 tny_list_get_length (helper->headers)));
5760 movehelper = g_new0 (MoveToHelper, 1);
5762 #ifndef MODEST_TOOLKIT_HILDON2
5763 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5764 _CS("ckct_nw_pasting"));
5765 if (movehelper->banner != NULL) {
5766 g_object_ref (movehelper->banner);
5767 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5771 if (MODEST_IS_MAIN_WINDOW (win)) {
5772 GtkWidget *header_view =
5773 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5774 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5775 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5778 /* Perform the mail operation */
5779 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5780 xfer_messages_error_handler,
5782 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5785 modest_mail_operation_xfer_msgs (mail_op,
5787 TNY_FOLDER (helper->dst_folder),
5792 g_object_unref (G_OBJECT (mail_op));
5794 g_object_unref (helper->dst_folder);
5795 g_object_unref (helper->headers);
5796 g_slice_free (XferMsgsHelper, helper);
5800 TnyFolder *src_folder;
5801 TnyFolderStore *dst_folder;
5802 gboolean delete_original;
5803 GtkWidget *folder_view;
5807 on_move_folder_cb (gboolean canceled,
5809 GtkWindow *parent_window,
5810 TnyAccount *account,
5813 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5814 GtkTreeSelection *sel;
5815 ModestMailOperation *mail_op = NULL;
5817 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5818 /* Note that the connection process can fail due to
5819 memory low conditions as it can not successfully
5820 store the summary */
5821 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5822 (GtkWidget*) parent_window, err,
5824 g_debug ("Error connecting when trying to move a folder");
5826 g_object_unref (G_OBJECT (info->src_folder));
5827 g_object_unref (G_OBJECT (info->dst_folder));
5832 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5833 #ifndef MODEST_TOOLKIT_HILDON2
5834 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5835 _CS("ckct_nw_pasting"));
5836 if (helper->banner != NULL) {
5837 g_object_ref (helper->banner);
5838 gtk_widget_show (GTK_WIDGET(helper->banner));
5841 /* Clean folder on header view before moving it */
5842 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5843 gtk_tree_selection_unselect_all (sel);
5845 /* Let gtk events run. We need that the folder
5846 view frees its reference to the source
5847 folder *before* issuing the mail operation
5848 so we need the signal handler of selection
5849 changed to happen before the mail
5851 while (gtk_events_pending ())
5852 gtk_main_iteration (); */
5855 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5856 modest_ui_actions_move_folder_error_handler,
5857 g_object_ref (info->dst_folder), g_object_unref);
5858 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5861 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5862 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5863 TNY_FOLDER (info->dst_folder), TRUE);
5865 modest_mail_operation_xfer_folder (mail_op,
5866 TNY_FOLDER (info->src_folder),
5868 info->delete_original,
5871 g_object_unref (G_OBJECT (info->src_folder));
5873 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5876 /* Unref mail operation */
5877 g_object_unref (G_OBJECT (mail_op));
5878 g_object_unref (G_OBJECT (info->dst_folder));
5883 get_account_from_folder_store (TnyFolderStore *folder_store)
5885 if (TNY_IS_ACCOUNT (folder_store))
5886 return g_object_ref (folder_store);
5888 return tny_folder_get_account (TNY_FOLDER (folder_store));
5892 * UI handler for the "Move to" action when invoked from the
5896 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5897 GtkWidget *folder_view,
5898 TnyFolderStore *dst_folder,
5899 ModestMainWindow *win)
5901 ModestHeaderView *header_view = NULL;
5902 TnyFolderStore *src_folder = NULL;
5904 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5906 /* Get the source folder */
5907 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5909 /* Get header view */
5910 header_view = (ModestHeaderView *)
5911 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5913 /* Get folder or messages to transfer */
5914 if (gtk_widget_is_focus (folder_view)) {
5915 gboolean do_xfer = TRUE;
5917 /* Allow only to transfer folders to the local root folder */
5918 if (TNY_IS_ACCOUNT (dst_folder) &&
5919 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5920 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5922 } else if (!TNY_IS_FOLDER (src_folder)) {
5923 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5928 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5929 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5931 info->src_folder = g_object_ref (src_folder);
5932 info->dst_folder = g_object_ref (dst_folder);
5933 info->delete_original = TRUE;
5934 info->folder_view = folder_view;
5936 connect_info->callback = on_move_folder_cb;
5937 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5938 connect_info->data = info;
5940 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5941 TNY_FOLDER_STORE (src_folder),
5944 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5947 headers = modest_header_view_get_selected_headers(header_view);
5949 /* Transfer the messages */
5950 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5951 headers, TNY_FOLDER (dst_folder));
5953 g_object_unref (headers);
5957 g_object_unref (src_folder);
5960 #ifdef MODEST_TOOLKIT_HILDON2
5962 * UI handler for the "Move to" action when invoked from the
5963 * ModestFolderWindow
5966 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5967 TnyFolderStore *dst_folder,
5971 TnyFolderStore *src_folder = NULL;
5972 TnyIterator *iterator;
5974 if (tny_list_get_length (selection) != 1)
5977 iterator = tny_list_create_iterator (selection);
5978 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5979 g_object_unref (iterator);
5982 gboolean do_xfer = TRUE;
5984 /* Allow only to transfer folders to the local root folder */
5985 if (TNY_IS_ACCOUNT (dst_folder) &&
5986 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5987 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5990 modest_platform_run_information_dialog (win,
5991 _("mail_in_ui_folder_move_target_error"),
5993 } else if (!TNY_IS_FOLDER (src_folder)) {
5994 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5999 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6000 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6002 info->src_folder = g_object_ref (src_folder);
6003 info->dst_folder = g_object_ref (dst_folder);
6004 info->delete_original = TRUE;
6005 info->folder_view = folder_view;
6007 connect_info->callback = on_move_folder_cb;
6008 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6009 connect_info->data = info;
6011 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6012 TNY_FOLDER_STORE (src_folder),
6017 g_object_unref (src_folder);
6023 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6024 TnyFolder *src_folder,
6026 TnyFolder *dst_folder)
6028 gboolean need_connection = TRUE;
6029 gboolean do_xfer = TRUE;
6030 XferMsgsHelper *helper;
6032 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6033 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6034 g_return_if_fail (TNY_IS_LIST (headers));
6036 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6037 headers, TNY_FOLDER (dst_folder),
6038 TRUE, &need_connection,
6041 /* If we don't want to transfer just return */
6045 /* Create the helper */
6046 helper = g_slice_new (XferMsgsHelper);
6047 helper->dst_folder = g_object_ref (dst_folder);
6048 helper->headers = g_object_ref (headers);
6050 if (need_connection) {
6051 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6052 connect_info->callback = xfer_messages_performer;
6053 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6054 connect_info->data = helper;
6056 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6057 TNY_FOLDER_STORE (src_folder),
6060 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6061 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6062 src_account, helper);
6063 g_object_unref (src_account);
6068 * UI handler for the "Move to" action when invoked from the
6069 * ModestMsgViewWindow
6072 modest_ui_actions_on_window_move_to (GtkAction *action,
6074 TnyFolderStore *dst_folder,
6077 TnyFolder *src_folder = NULL;
6079 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6082 TnyHeader *header = NULL;
6085 iter = tny_list_create_iterator (headers);
6086 header = (TnyHeader *) tny_iterator_get_current (iter);
6087 src_folder = tny_header_get_folder (header);
6089 /* Transfer the messages */
6090 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6092 TNY_FOLDER (dst_folder));
6095 g_object_unref (header);
6096 g_object_unref (iter);
6097 g_object_unref (src_folder);
6102 modest_ui_actions_on_move_to (GtkAction *action,
6105 modest_ui_actions_on_edit_mode_move_to (win);
6109 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6111 GtkWidget *dialog = NULL;
6112 MoveToInfo *helper = NULL;
6113 TnyList *list_to_move;
6115 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6117 #ifndef MODEST_TOOLKIT_HILDON2
6118 /* Get the main window if exists */
6119 ModestMainWindow *main_window;
6120 if (MODEST_IS_MAIN_WINDOW (win))
6121 main_window = MODEST_MAIN_WINDOW (win);
6124 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6125 FALSE)); /* don't create */
6128 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6133 if (tny_list_get_length (list_to_move) < 1) {
6134 g_object_unref (list_to_move);
6138 /* Create and run the dialog */
6139 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6140 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6141 GTK_WINDOW (dialog),
6145 helper = g_slice_new0 (MoveToInfo);
6146 helper->list = list_to_move;
6149 /* Listen to response signal */
6150 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6152 /* Show the dialog */
6153 gtk_widget_show (dialog);
6159 * Calls #HeadersFunc for each header already selected in the main
6160 * window or the message currently being shown in the msg view window
6163 do_headers_action (ModestWindow *win,
6167 TnyList *headers_list = NULL;
6168 TnyIterator *iter = NULL;
6169 TnyHeader *header = NULL;
6170 TnyFolder *folder = NULL;
6173 headers_list = get_selected_headers (win);
6177 /* Get the folder */
6178 iter = tny_list_create_iterator (headers_list);
6179 header = TNY_HEADER (tny_iterator_get_current (iter));
6181 folder = tny_header_get_folder (header);
6182 g_object_unref (header);
6185 /* Call the function for each header */
6186 while (!tny_iterator_is_done (iter)) {
6187 header = TNY_HEADER (tny_iterator_get_current (iter));
6188 func (header, win, user_data);
6189 g_object_unref (header);
6190 tny_iterator_next (iter);
6193 /* Trick: do a poke status in order to speed up the signaling
6196 tny_folder_poke_status (folder);
6197 g_object_unref (folder);
6201 g_object_unref (iter);
6202 g_object_unref (headers_list);
6206 modest_ui_actions_view_attachment (GtkAction *action,
6207 ModestWindow *window)
6209 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6210 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6212 /* not supported window for this action */
6213 g_return_if_reached ();
6218 modest_ui_actions_save_attachments (GtkAction *action,
6219 ModestWindow *window)
6221 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6223 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6226 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6228 /* not supported window for this action */
6229 g_return_if_reached ();
6234 modest_ui_actions_remove_attachments (GtkAction *action,
6235 ModestWindow *window)
6237 if (MODEST_IS_MAIN_WINDOW (window)) {
6238 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6239 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6240 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6242 /* not supported window for this action */
6243 g_return_if_reached ();
6248 modest_ui_actions_on_settings (GtkAction *action,
6253 dialog = modest_platform_get_global_settings_dialog ();
6254 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6255 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6256 gtk_widget_show_all (dialog);
6258 gtk_dialog_run (GTK_DIALOG (dialog));
6260 gtk_widget_destroy (dialog);
6264 modest_ui_actions_on_help (GtkAction *action,
6267 /* Help app is not available at all in fremantle */
6268 #ifndef MODEST_TOOLKIT_HILDON2
6269 const gchar *help_id;
6271 g_return_if_fail (win && GTK_IS_WINDOW(win));
6273 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6276 modest_platform_show_help (GTK_WINDOW (win), help_id);
6281 modest_ui_actions_on_csm_help (GtkAction *action,
6284 /* Help app is not available at all in fremantle */
6285 #ifndef MODEST_TOOLKIT_HILDON2
6287 const gchar* help_id = NULL;
6288 GtkWidget *folder_view;
6289 TnyFolderStore *folder_store;
6291 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6293 /* Get selected folder */
6294 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6295 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6296 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6298 /* Switch help_id */
6299 if (folder_store && TNY_IS_FOLDER (folder_store))
6300 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6303 g_object_unref (folder_store);
6306 modest_platform_show_help (GTK_WINDOW (win), help_id);
6308 modest_ui_actions_on_help (action, win);
6313 retrieve_contents_cb (ModestMailOperation *mail_op,
6320 /* We only need this callback to show an error in case of
6321 memory low condition */
6322 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6323 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6328 retrieve_msg_contents_performer (gboolean canceled,
6330 GtkWindow *parent_window,
6331 TnyAccount *account,
6334 ModestMailOperation *mail_op;
6335 TnyList *headers = TNY_LIST (user_data);
6337 if (err || canceled) {
6338 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6339 (GtkWidget *) parent_window, err,
6344 /* Create mail operation */
6345 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6346 modest_ui_actions_disk_operations_error_handler,
6348 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6349 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6352 g_object_unref (mail_op);
6354 g_object_unref (headers);
6355 g_object_unref (account);
6359 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6360 ModestWindow *window)
6362 TnyList *headers = NULL;
6363 TnyAccount *account = NULL;
6364 TnyIterator *iter = NULL;
6365 TnyHeader *header = NULL;
6366 TnyFolder *folder = NULL;
6369 headers = get_selected_headers (window);
6373 /* Pick the account */
6374 iter = tny_list_create_iterator (headers);
6375 header = TNY_HEADER (tny_iterator_get_current (iter));
6376 folder = tny_header_get_folder (header);
6377 account = tny_folder_get_account (folder);
6378 g_object_unref (folder);
6379 g_object_unref (header);
6380 g_object_unref (iter);
6382 /* Connect and perform the message retrieval */
6383 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6384 g_object_ref (account),
6385 retrieve_msg_contents_performer,
6386 g_object_ref (headers));
6389 g_object_unref (account);
6390 g_object_unref (headers);
6394 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6396 g_return_if_fail (MODEST_IS_WINDOW (window));
6399 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6403 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6405 g_return_if_fail (MODEST_IS_WINDOW (window));
6408 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6412 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6413 ModestWindow *window)
6415 g_return_if_fail (MODEST_IS_WINDOW (window));
6418 modest_ui_actions_check_menu_dimming_rules (window);
6422 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6423 ModestWindow *window)
6425 g_return_if_fail (MODEST_IS_WINDOW (window));
6428 modest_ui_actions_check_menu_dimming_rules (window);
6432 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6433 ModestWindow *window)
6435 g_return_if_fail (MODEST_IS_WINDOW (window));
6438 modest_ui_actions_check_menu_dimming_rules (window);
6442 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6443 ModestWindow *window)
6445 g_return_if_fail (MODEST_IS_WINDOW (window));
6448 modest_ui_actions_check_menu_dimming_rules (window);
6452 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6453 ModestWindow *window)
6455 g_return_if_fail (MODEST_IS_WINDOW (window));
6458 modest_ui_actions_check_menu_dimming_rules (window);
6462 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6463 ModestWindow *window)
6465 g_return_if_fail (MODEST_IS_WINDOW (window));
6468 modest_ui_actions_check_menu_dimming_rules (window);
6472 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6473 ModestWindow *window)
6475 g_return_if_fail (MODEST_IS_WINDOW (window));
6478 modest_ui_actions_check_menu_dimming_rules (window);
6482 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6483 ModestWindow *window)
6485 g_return_if_fail (MODEST_IS_WINDOW (window));
6488 modest_ui_actions_check_menu_dimming_rules (window);
6492 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6493 ModestWindow *window)
6495 g_return_if_fail (MODEST_IS_WINDOW (window));
6498 modest_ui_actions_check_menu_dimming_rules (window);
6502 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6504 g_return_if_fail (MODEST_IS_WINDOW (window));
6506 /* we check for low-mem; in that case, show a warning, and don't allow
6509 if (modest_platform_check_memory_low (window, TRUE))
6512 modest_platform_show_search_messages (GTK_WINDOW (window));
6516 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6518 g_return_if_fail (MODEST_IS_WINDOW (win));
6521 /* we check for low-mem; in that case, show a warning, and don't allow
6522 * for the addressbook
6524 if (modest_platform_check_memory_low (win, TRUE))
6528 modest_platform_show_addressbook (GTK_WINDOW (win));
6533 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6534 ModestWindow *window)
6537 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6539 if (GTK_IS_TOGGLE_ACTION (action))
6540 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6544 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6549 on_send_receive_finished (ModestMailOperation *mail_op,
6552 GtkWidget *header_view, *folder_view;
6553 TnyFolderStore *folder_store;
6554 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6556 /* Set send/receive operation finished */
6557 modest_main_window_notify_send_receive_completed (main_win);
6559 /* Don't refresh the current folder if there were any errors */
6560 if (modest_mail_operation_get_status (mail_op) !=
6561 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6564 /* Refresh the current folder if we're viewing a window. We do
6565 this because the user won't be able to see the new mails in
6566 the selected folder after a Send&Receive because it only
6567 performs a poke_status, i.e, only the number of read/unread
6568 messages is updated, but the new headers are not
6570 folder_view = modest_main_window_get_child_widget (main_win,
6571 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6575 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6577 /* Do not need to refresh INBOX again because the
6578 update_account does it always automatically */
6579 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6580 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6581 ModestMailOperation *refresh_op;
6583 header_view = modest_main_window_get_child_widget (main_win,
6584 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6586 /* We do not need to set the contents style
6587 because it hasn't changed. We also do not
6588 need to save the widget status. Just force
6590 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6591 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6592 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6593 folder_refreshed_cb, main_win);
6594 g_object_unref (refresh_op);
6598 g_object_unref (folder_store);
6603 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6609 const gchar* server_name = NULL;
6610 TnyTransportAccount *transport;
6611 gchar *message = NULL;
6612 ModestProtocol *protocol;
6614 /* Don't show anything if the user cancelled something or the
6615 * send receive request is not interactive. Authentication
6616 * errors are managed by the account store so no need to show
6617 * a dialog here again */
6618 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6619 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6620 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6624 /* Get the server name. Note that we could be using a
6625 connection specific transport account */
6626 transport = (TnyTransportAccount *)
6627 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6629 ModestTnyAccountStore *acc_store;
6630 const gchar *acc_name;
6631 TnyTransportAccount *conn_specific;
6633 acc_store = modest_runtime_get_account_store();
6634 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6635 conn_specific = (TnyTransportAccount *)
6636 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6637 if (conn_specific) {
6638 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6639 g_object_unref (conn_specific);
6641 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6643 g_object_unref (transport);
6647 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6648 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6649 tny_account_get_proto (TNY_ACCOUNT (transport)));
6651 g_warning ("%s: Account with no proto", __FUNCTION__);
6655 /* Show the appropriate message text for the GError: */
6656 switch (err->code) {
6657 case TNY_SERVICE_ERROR_CONNECT:
6658 message = modest_protocol_get_translation (protocol,
6659 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6662 case TNY_SERVICE_ERROR_SEND:
6663 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6665 case TNY_SERVICE_ERROR_UNAVAILABLE:
6666 message = modest_protocol_get_translation (protocol,
6667 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6671 g_warning ("%s: unexpected ERROR %d",
6672 __FUNCTION__, err->code);
6673 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6677 modest_platform_run_information_dialog (NULL, message, FALSE);
6682 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6687 ModestWindow *top_window = NULL;
6688 ModestWindowMgr *mgr = NULL;
6689 GtkWidget *header_view = NULL;
6690 TnyFolder *selected_folder = NULL;
6691 TnyFolderType folder_type;
6693 mgr = modest_runtime_get_window_mgr ();
6694 top_window = modest_window_mgr_get_current_top (mgr);
6699 #ifndef MODEST_TOOLKIT_HILDON2
6700 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6701 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6702 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6705 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6706 header_view = (GtkWidget *)
6707 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6711 /* Get selected folder */
6713 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6714 if (!selected_folder)
6717 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6718 #if GTK_CHECK_VERSION(2, 8, 0)
6719 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6720 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6721 GtkTreeViewColumn *tree_column;
6723 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6724 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6726 gtk_tree_view_column_queue_resize (tree_column);
6728 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6729 gtk_widget_queue_draw (header_view);
6732 #ifndef MODEST_TOOLKIT_HILDON2
6733 /* Rerun dimming rules, because the message could become deletable for example */
6734 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6735 MODEST_DIMMING_RULES_TOOLBAR);
6736 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6737 MODEST_DIMMING_RULES_MENU);
6741 g_object_unref (selected_folder);
6745 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6746 TnyAccount *account)
6748 ModestProtocolType protocol_type;
6749 ModestProtocol *protocol;
6750 gchar *error_note = NULL;
6752 protocol_type = modest_tny_account_get_protocol_type (account);
6753 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6756 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6757 if (error_note == NULL) {
6758 g_warning ("%s: This should not be reached", __FUNCTION__);
6760 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6761 g_free (error_note);
6766 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6770 TnyFolderStore *folder = NULL;
6771 TnyAccount *account = NULL;
6772 ModestProtocolType proto;
6773 ModestProtocol *protocol;
6774 TnyHeader *header = NULL;
6776 if (MODEST_IS_MAIN_WINDOW (win)) {
6777 GtkWidget *header_view;
6778 TnyList* headers = NULL;
6780 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6781 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6782 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6783 if (!headers || tny_list_get_length (headers) == 0) {
6785 g_object_unref (headers);
6788 iter = tny_list_create_iterator (headers);
6789 header = TNY_HEADER (tny_iterator_get_current (iter));
6790 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6791 g_object_unref (iter);
6792 g_object_unref (headers);
6793 #ifdef MODEST_TOOLKIT_HILDON2
6794 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6795 GtkWidget *header_view;
6796 TnyList* headers = NULL;
6798 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6799 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6800 if (!headers || tny_list_get_length (headers) == 0) {
6802 g_object_unref (headers);
6805 iter = tny_list_create_iterator (headers);
6806 header = TNY_HEADER (tny_iterator_get_current (iter));
6808 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6810 g_warning ("List should contain headers");
6812 g_object_unref (iter);
6813 g_object_unref (headers);
6815 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6816 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6818 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6821 if (!header || !folder)
6824 /* Get the account type */
6825 account = tny_folder_get_account (TNY_FOLDER (folder));
6826 proto = modest_tny_account_get_protocol_type (account);
6827 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6830 subject = tny_header_dup_subject (header);
6831 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6835 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6841 g_object_unref (account);
6843 g_object_unref (folder);
6845 g_object_unref (header);
6851 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6852 const gchar *account_name,
6853 const gchar *account_title)
6855 ModestAccountMgr *account_mgr;
6858 ModestProtocol *protocol;
6859 gboolean removed = FALSE;
6861 g_return_val_if_fail (account_name, FALSE);
6862 g_return_val_if_fail (account_title, FALSE);
6864 account_mgr = modest_runtime_get_account_mgr();
6866 /* The warning text depends on the account type: */
6867 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6868 modest_account_mgr_get_store_protocol (account_mgr,
6870 txt = modest_protocol_get_translation (protocol,
6871 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6874 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6876 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6880 if (response == GTK_RESPONSE_OK) {
6881 /* Remove account. If it succeeds then it also removes
6882 the account from the ModestAccountView: */
6883 gboolean is_default = FALSE;
6884 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6885 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6887 g_free (default_account_name);
6889 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6891 /* Close all email notifications, we cannot
6892 distinguish if the notification belongs to
6893 this account or not, so for safety reasons
6894 we remove them all */
6895 modest_platform_remove_new_mail_notifications (FALSE);
6897 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6904 on_fetch_images_performer (gboolean canceled,
6906 GtkWindow *parent_window,
6907 TnyAccount *account,
6910 if (err || canceled) {
6911 /* Show an unable to retrieve images ??? */
6915 /* Note that the user could have closed the window while connecting */
6916 if (GTK_WIDGET_VISIBLE (parent_window))
6917 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6918 g_object_unref ((GObject *) user_data);
6922 modest_ui_actions_on_fetch_images (GtkAction *action,
6923 ModestWindow *window)
6925 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6927 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6929 on_fetch_images_performer,
6930 g_object_ref (window));
6934 modest_ui_actions_on_reload_message (const gchar *msg_id)
6936 ModestWindow *window = NULL;
6938 g_return_if_fail (msg_id && msg_id[0] != '\0');
6939 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6945 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6948 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
6951 /** Check whether any connections are active, and cancel them if
6953 * Returns TRUE is there was no problem,
6954 * or if an operation was cancelled so we can continue.
6955 * Returns FALSE if the user chose to cancel his request instead.
6959 modest_ui_actions_check_for_active_account (ModestWindow *self,
6960 const gchar* account_name)
6962 ModestTnySendQueue *send_queue;
6963 ModestTnyAccountStore *acc_store;
6964 ModestMailOperationQueue* queue;
6965 TnyConnectionStatus store_conn_status;
6966 TnyAccount *store_account = NULL, *transport_account = NULL;
6967 gboolean retval = TRUE, sending = FALSE;
6969 acc_store = modest_runtime_get_account_store ();
6970 queue = modest_runtime_get_mail_operation_queue ();
6973 modest_tny_account_store_get_server_account (acc_store,
6975 TNY_ACCOUNT_TYPE_STORE);
6977 /* This could happen if the account was deleted before the
6978 call to this function */
6983 modest_tny_account_store_get_server_account (acc_store,
6985 TNY_ACCOUNT_TYPE_TRANSPORT);
6987 /* This could happen if the account was deleted before the
6988 call to this function */
6989 if (!transport_account) {
6990 g_object_unref (store_account);
6994 /* If the transport account was not used yet, then the send
6995 queue could not exist (it's created on demand) */
6996 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
6997 if (TNY_IS_SEND_QUEUE (send_queue))
6998 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7000 store_conn_status = tny_account_get_connection_status (store_account);
7001 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7004 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7005 _("emev_nc_disconnect_account"));
7006 if (response == GTK_RESPONSE_OK) {
7015 /* FIXME: We should only cancel those of this account */
7016 modest_mail_operation_queue_cancel_all (queue);
7018 /* Also disconnect the account */
7019 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7020 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7021 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7025 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7031 g_object_unref (store_account);
7032 g_object_unref (transport_account);