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 */
70 #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_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
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 if (MODEST_IS_MSG_VIEW_WINDOW (win))
690 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
691 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
692 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
696 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
698 GtkClipboard *clipboard = NULL;
699 gchar *selection = NULL;
701 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
702 selection = gtk_clipboard_wait_for_text (clipboard);
705 modest_address_book_add_address (selection, (GtkWindow *) win);
711 modest_ui_actions_on_new_account (GtkAction *action,
712 ModestWindow *window)
714 if (!modest_ui_actions_run_account_setup_wizard (window)) {
715 g_debug ("%s: wizard was already running", __FUNCTION__);
720 modest_ui_actions_on_accounts (GtkAction *action,
723 /* This is currently only implemented for Maemo */
724 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
725 if (!modest_ui_actions_run_account_setup_wizard (win))
726 g_debug ("%s: wizard was already running", __FUNCTION__);
730 /* Show the list of accounts */
731 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
733 /* The accounts dialog must be modal */
734 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
735 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
740 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
742 /* This is currently only implemented for Maemo,
743 * because it requires an API (libconic) to detect different connection
746 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
748 /* Create the window if necessary: */
749 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
750 modest_connection_specific_smtp_window_fill_with_connections (
751 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
752 modest_runtime_get_account_mgr());
754 /* Show the window: */
755 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
756 GTK_WINDOW (specific_window), (GtkWindow *) win);
757 gtk_widget_show (specific_window);
758 #endif /* !MODEST_TOOLKIT_GTK */
762 count_part_size (const gchar *part)
764 GnomeVFSURI *vfs_uri;
765 gchar *escaped_filename;
767 GnomeVFSFileInfo *info;
770 /* Estimation of attachment size if we cannot get it from file info */
773 vfs_uri = gnome_vfs_uri_new (part);
775 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
776 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
777 g_free (escaped_filename);
778 gnome_vfs_uri_unref (vfs_uri);
780 info = gnome_vfs_file_info_new ();
782 if (gnome_vfs_get_file_info (part,
784 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
786 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
791 gnome_vfs_file_info_unref (info);
797 count_parts_size (GSList *parts)
802 for (node = parts; node != NULL; node = g_slist_next (node)) {
803 result += count_part_size ((const gchar *) node->data);
810 modest_ui_actions_compose_msg(ModestWindow *win,
813 const gchar *bcc_str,
814 const gchar *subject_str,
815 const gchar *body_str,
817 gboolean set_as_modified)
819 gchar *account_name = NULL;
820 const gchar *mailbox;
822 TnyAccount *account = NULL;
823 TnyFolder *folder = NULL;
824 gchar *from_str = NULL, *signature = NULL, *body = NULL;
825 gchar *recipient = NULL;
826 gboolean use_signature = FALSE;
827 ModestWindow *msg_win = NULL;
828 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
829 ModestTnyAccountStore *store = modest_runtime_get_account_store();
830 GnomeVFSFileSize total_size, allowed_size;
831 guint64 available_disk, expected_size, parts_size;
834 /* we check for low-mem */
835 if (modest_platform_check_memory_low (win, TRUE))
838 available_disk = modest_utils_get_available_space (NULL);
839 parts_count = g_slist_length (attachments);
840 parts_size = count_parts_size (attachments);
841 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
843 /* Double check: disk full condition or message too big */
844 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
845 expected_size > available_disk) {
846 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
847 modest_platform_system_banner (NULL, NULL, msg);
853 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
854 modest_platform_run_information_dialog (
856 _("mail_ib_error_attachment_size"),
862 #ifdef MODEST_TOOLKIT_HILDON2
864 account_name = g_strdup (modest_window_get_active_account(win));
867 account_name = modest_account_mgr_get_default_account(mgr);
870 g_printerr ("modest: no account found\n");
875 mailbox = modest_window_get_active_mailbox (win);
878 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
880 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
883 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
885 g_printerr ("modest: failed to find Drafts folder\n");
888 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
890 g_printerr ("modest: failed get from string for '%s'\n", account_name);
894 recipient = modest_text_utils_get_email_address (from_str);
895 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
897 if (body_str != NULL) {
898 body = use_signature ? g_strconcat(body_str, "\n",
899 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
900 "\n", signature, NULL) : g_strdup(body_str);
902 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
903 "\n", signature, NULL) : g_strdup("");
906 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
908 g_printerr ("modest: failed to create new msg\n");
912 /* Create and register edit window */
913 /* This is destroyed by TODO. */
915 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
916 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
918 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
919 gtk_widget_destroy (GTK_WIDGET (msg_win));
922 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
923 gtk_widget_show_all (GTK_WIDGET (msg_win));
925 while (attachments) {
926 GnomeVFSFileSize att_size;
928 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
929 attachments->data, allowed_size);
930 total_size += att_size;
932 if (att_size > allowed_size) {
933 g_debug ("%s: total size: %u",
934 __FUNCTION__, (unsigned int)total_size);
937 allowed_size -= att_size;
939 attachments = g_slist_next(attachments);
946 g_free (account_name);
948 g_object_unref (G_OBJECT(account));
950 g_object_unref (G_OBJECT(folder));
952 g_object_unref (G_OBJECT(msg));
956 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
958 /* if there are no accounts yet, just show the wizard */
959 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
960 if (!modest_ui_actions_run_account_setup_wizard (win))
963 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
968 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
972 ModestMailOperationStatus status;
974 /* If there is no message or the operation was not successful */
975 status = modest_mail_operation_get_status (mail_op);
976 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
979 /* If it's a memory low issue, then show a banner */
980 error = modest_mail_operation_get_error (mail_op);
981 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
982 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
983 GObject *source = modest_mail_operation_get_source (mail_op);
984 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
985 _KR("memr_ib_operation_disabled"),
987 g_object_unref (source);
990 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
991 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
992 gchar *subject, *msg, *format = NULL;
995 subject = (header) ? tny_header_dup_subject (header) : NULL;
997 subject = g_strdup (_("mail_va_no_subject"));
999 account = modest_mail_operation_get_account (mail_op);
1001 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1002 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1005 if (tny_account_get_connection_status (account) ==
1006 TNY_CONNECTION_STATUS_CONNECTED) {
1008 format = modest_protocol_get_translation (protocol,
1009 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1012 format = modest_protocol_get_translation (protocol,
1013 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1016 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1017 tny_account_get_hostname (account));
1020 g_object_unref (account);
1025 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1027 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1031 msg = g_strdup_printf (format, subject);
1032 modest_platform_run_information_dialog (NULL, msg, FALSE);
1038 /* Remove the header from the preregistered uids */
1039 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1052 } OpenMsgBannerInfo;
1055 GtkTreeModel *model;
1057 ModestWindow *caller_window;
1058 OpenMsgBannerInfo *banner_info;
1059 GtkTreeRowReference *rowref;
1063 open_msg_banner_idle (gpointer userdata)
1065 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1067 gdk_threads_enter ();
1068 banner_info->idle_handler = 0;
1069 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1070 if (banner_info->banner)
1071 g_object_ref (banner_info->banner);
1073 gdk_threads_leave ();
1079 get_header_view_from_window (ModestWindow *window)
1081 GtkWidget *header_view;
1083 if (MODEST_IS_MAIN_WINDOW (window)) {
1084 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1085 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1086 #ifdef MODEST_TOOLKIT_HILDON2
1087 } else if (MODEST_IS_HEADER_WINDOW (window)){
1088 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1098 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1101 gchar *account = NULL;
1102 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1107 folder = tny_header_get_folder (header);
1108 /* Gets folder type (OUTBOX headers will be opened in edit window */
1109 if (modest_tny_folder_is_local_folder (folder)) {
1110 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1111 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1112 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1115 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1116 TnyTransportAccount *traccount = NULL;
1117 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1118 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1120 ModestTnySendQueue *send_queue = NULL;
1121 ModestTnySendQueueStatus status;
1123 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1124 TNY_ACCOUNT(traccount)));
1125 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1126 if (TNY_IS_SEND_QUEUE (send_queue)) {
1127 msg_id = modest_tny_send_queue_get_msg_id (header);
1128 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1130 /* Only open messages in outbox with the editor if they are in Failed state */
1131 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1134 #ifdef MODEST_TOOLKIT_HILDON2
1136 /* In Fremantle we can not
1137 open any message from
1138 outbox which is not in
1144 g_object_unref(traccount);
1146 g_warning("Cannot get transport account for message in outbox!!");
1148 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1149 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1153 TnyAccount *acc = tny_folder_get_account (folder);
1156 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1157 g_object_unref (acc);
1161 g_object_unref (folder);
1167 open_msg_cb (ModestMailOperation *mail_op,
1174 ModestWindowMgr *mgr = NULL;
1175 ModestWindow *parent_win = NULL;
1176 ModestWindow *win = NULL;
1177 gchar *account = NULL;
1178 gboolean open_in_editor = FALSE;
1180 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1182 /* Do nothing if there was any problem with the mail
1183 operation. The error will be shown by the error_handler of
1184 the mail operation */
1185 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1188 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1190 /* Mark header as read */
1191 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1193 account = get_info_from_header (header, &open_in_editor, &can_open);
1197 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1199 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1201 if (open_in_editor) {
1202 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1203 gchar *from_header = NULL, *acc_name;
1204 gchar *mailbox = NULL;
1206 from_header = tny_header_dup_from (header);
1208 /* we cannot edit without a valid account... */
1209 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1210 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1211 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1213 g_free (from_header);
1218 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1219 g_free (from_header);
1225 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1229 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1230 const gchar *mailbox = NULL;
1232 if (parent_win && MODEST_IS_WINDOW (parent_win))
1233 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1235 if (helper->rowref && helper->model) {
1236 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1237 helper->model, helper->rowref);
1239 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1244 /* Register and show new window */
1246 mgr = modest_runtime_get_window_mgr ();
1247 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1248 gtk_widget_destroy (GTK_WIDGET (win));
1251 gtk_widget_show_all (GTK_WIDGET(win));
1254 /* Update toolbar dimming state */
1255 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1256 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1262 g_object_unref (parent_win);
1266 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1269 const GError *error;
1270 GObject *win = NULL;
1271 ModestMailOperationStatus status;
1273 win = modest_mail_operation_get_source (mail_op);
1274 error = modest_mail_operation_get_error (mail_op);
1275 status = modest_mail_operation_get_status (mail_op);
1277 /* If the mail op has been cancelled then it's not an error:
1278 don't show any message */
1279 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1280 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1281 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1282 (GError *) error, account)) {
1283 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1284 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1286 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1287 modest_platform_information_banner ((GtkWidget *) win,
1288 NULL, _("emev_ui_imap_inbox_select_error"));
1289 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1290 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1291 modest_platform_information_banner ((GtkWidget *) win,
1292 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1293 } else if (user_data) {
1294 modest_platform_information_banner ((GtkWidget *) win,
1298 g_object_unref (account);
1302 g_object_unref (win);
1306 * Returns the account a list of headers belongs to. It returns a
1307 * *new* reference so don't forget to unref it
1310 get_account_from_header_list (TnyList *headers)
1312 TnyAccount *account = NULL;
1314 if (tny_list_get_length (headers) > 0) {
1315 TnyIterator *iter = tny_list_create_iterator (headers);
1316 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1317 TnyFolder *folder = tny_header_get_folder (header);
1320 g_object_unref (header);
1322 while (!tny_iterator_is_done (iter)) {
1323 header = TNY_HEADER (tny_iterator_get_current (iter));
1324 folder = tny_header_get_folder (header);
1327 g_object_unref (header);
1329 tny_iterator_next (iter);
1334 account = tny_folder_get_account (folder);
1335 g_object_unref (folder);
1339 g_object_unref (header);
1341 g_object_unref (iter);
1347 get_account_from_header (TnyHeader *header)
1349 TnyAccount *account = NULL;
1352 folder = tny_header_get_folder (header);
1355 account = tny_folder_get_account (folder);
1356 g_object_unref (folder);
1362 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1364 if (helper->caller_window)
1365 helper->caller_window = NULL;
1369 open_msg_helper_destroyer (gpointer user_data)
1371 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1373 if (helper->caller_window) {
1374 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1375 helper->caller_window = NULL;
1378 if (helper->banner_info) {
1379 g_free (helper->banner_info->message);
1380 if (helper->banner_info->idle_handler > 0) {
1381 g_source_remove (helper->banner_info->idle_handler);
1382 helper->banner_info->idle_handler = 0;
1384 if (helper->banner_info->banner != NULL) {
1385 gtk_widget_destroy (helper->banner_info->banner);
1386 g_object_unref (helper->banner_info->banner);
1387 helper->banner_info->banner = NULL;
1389 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1390 helper->banner_info = NULL;
1392 g_object_unref (helper->model);
1393 g_object_unref (helper->header);
1394 gtk_tree_row_reference_free (helper->rowref);
1395 g_slice_free (OpenMsgHelper, helper);
1399 open_msg_performer(gboolean canceled,
1401 GtkWindow *parent_window,
1402 TnyAccount *account,
1405 ModestMailOperation *mail_op = NULL;
1406 gchar *error_msg = NULL;
1407 ModestProtocolType proto;
1408 TnyConnectionStatus status;
1409 OpenMsgHelper *helper = NULL;
1410 ModestProtocol *protocol;
1411 ModestProtocolRegistry *protocol_registry;
1414 helper = (OpenMsgHelper *) user_data;
1416 status = tny_account_get_connection_status (account);
1417 if (err || canceled || helper->caller_window == NULL) {
1418 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1419 /* Free the helper */
1420 open_msg_helper_destroyer (helper);
1422 /* In disk full conditions we could get this error here */
1423 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1424 (GtkWidget *) parent_window, err,
1430 /* Get the error message depending on the protocol */
1431 proto = modest_tny_account_get_protocol_type (account);
1432 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1433 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1436 protocol_registry = modest_runtime_get_protocol_registry ();
1437 subject = tny_header_dup_subject (helper->header);
1439 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1440 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1444 if (error_msg == NULL) {
1445 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1448 #ifndef MODEST_TOOLKIT_HILDON2
1449 gboolean show_open_draft = FALSE;
1450 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1452 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1454 TnyFolderType folder_type;
1456 folder = tny_header_get_folder (helper->header);
1457 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1458 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1459 g_object_unref (folder);
1463 #ifdef MODEST_TOOLKIT_HILDON2
1466 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1469 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1470 g_free (account_name);
1471 open_msg_helper_destroyer (helper);
1476 ModestWindow *window;
1477 GtkWidget *header_view;
1480 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1481 uid = modest_tny_folder_get_header_unique_id (helper->header);
1483 const gchar *mailbox = NULL;
1484 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1485 window = modest_msg_view_window_new_from_header_view
1486 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1487 if (window != NULL) {
1488 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1490 gtk_widget_destroy (GTK_WIDGET (window));
1492 gtk_widget_show_all (GTK_WIDGET(window));
1496 g_free (account_name);
1498 open_msg_helper_destroyer (helper);
1501 g_free (account_name);
1503 /* Create the mail operation */
1505 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1506 modest_ui_actions_disk_operations_error_handler,
1507 g_strdup (error_msg), g_free);
1508 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1512 #ifndef MODEST_TOOLKIT_HILDON2
1513 if (show_open_draft) {
1514 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1515 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1516 helper->banner_info->banner = NULL;
1517 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1518 helper->banner_info);
1524 headers = TNY_LIST (tny_simple_list_new ());
1525 tny_list_prepend (headers, G_OBJECT (helper->header));
1526 modest_mail_operation_get_msgs_full (mail_op,
1530 open_msg_helper_destroyer);
1531 g_object_unref (headers);
1538 g_object_unref (mail_op);
1539 g_object_unref (account);
1543 * This function is used by both modest_ui_actions_on_open and
1544 * modest_ui_actions_on_header_activated. This way we always do the
1545 * same when trying to open messages.
1548 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1550 ModestWindowMgr *mgr = NULL;
1551 TnyAccount *account;
1552 gboolean cached = FALSE;
1554 GtkWidget *header_view = NULL;
1555 OpenMsgHelper *helper;
1556 ModestWindow *window;
1558 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1560 mgr = modest_runtime_get_window_mgr ();
1563 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1564 if (header_view == NULL)
1567 /* Get the account */
1568 account = get_account_from_header (header);
1573 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1575 /* Do not open again the message and present the
1576 window to the user */
1579 #ifndef MODEST_TOOLKIT_HILDON2
1580 gtk_window_present (GTK_WINDOW (window));
1583 /* the header has been registered already, we don't do
1584 * anything but wait for the window to come up*/
1585 g_debug ("header %p already registered, waiting for window", header);
1590 /* Open each message */
1591 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1593 /* Allways download if we are online. */
1594 if (!tny_device_is_online (modest_runtime_get_device ())) {
1597 /* If ask for user permission to download the messages */
1598 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1599 _("mcen_nc_get_msg"));
1601 /* End if the user does not want to continue */
1602 if (response == GTK_RESPONSE_CANCEL) {
1608 /* We register the window for opening */
1609 modest_window_mgr_register_header (mgr, header, NULL);
1611 /* Create the helper. We need to get a reference to the model
1612 here because it could change while the message is readed
1613 (the user could switch between folders) */
1614 helper = g_slice_new (OpenMsgHelper);
1615 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1616 helper->caller_window = win;
1617 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1618 helper->header = g_object_ref (header);
1619 helper->rowref = gtk_tree_row_reference_copy (rowref);
1620 helper->banner_info = NULL;
1622 /* Connect to the account and perform */
1624 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1625 open_msg_performer, helper);
1627 /* Call directly the performer, do not need to connect */
1628 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1629 g_object_ref (account), helper);
1634 g_object_unref (account);
1638 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1645 /* we check for low-mem; in that case, show a warning, and don't allow
1648 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1652 headers = get_selected_headers (win);
1656 headers_count = tny_list_get_length (headers);
1657 if (headers_count != 1) {
1658 if (headers_count > 1) {
1659 /* Don't allow activation if there are more than one message selected */
1660 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1663 g_object_unref (headers);
1667 iter = tny_list_create_iterator (headers);
1668 header = TNY_HEADER (tny_iterator_get_current (iter));
1669 g_object_unref (iter);
1673 open_msg_from_header (header, NULL, win);
1674 g_object_unref (header);
1677 g_object_unref(headers);
1681 rf_helper_window_closed (gpointer data,
1684 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1686 helper->parent_window = NULL;
1689 static ReplyForwardHelper*
1690 create_reply_forward_helper (ReplyForwardAction action,
1692 guint reply_forward_type,
1695 ReplyForwardHelper *rf_helper = NULL;
1696 const gchar *active_acc = modest_window_get_active_account (win);
1697 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1699 rf_helper = g_slice_new0 (ReplyForwardHelper);
1700 rf_helper->reply_forward_type = reply_forward_type;
1701 rf_helper->action = action;
1702 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1703 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1704 rf_helper->account_name = (active_acc) ?
1705 g_strdup (active_acc) :
1706 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1707 rf_helper->mailbox = g_strdup (active_mailbox);
1709 /* Note that window could be destroyed just AFTER calling
1710 register_window so we must ensure that this pointer does
1711 not hold invalid references */
1712 if (rf_helper->parent_window)
1713 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1714 rf_helper_window_closed, rf_helper);
1720 free_reply_forward_helper (gpointer data)
1722 ReplyForwardHelper *helper;
1724 helper = (ReplyForwardHelper *) data;
1725 g_free (helper->account_name);
1726 g_free (helper->mailbox);
1728 g_object_unref (helper->header);
1729 if (helper->parent_window)
1730 g_object_weak_unref (G_OBJECT (helper->parent_window),
1731 rf_helper_window_closed, helper);
1732 g_slice_free (ReplyForwardHelper, helper);
1736 reply_forward_cb (ModestMailOperation *mail_op,
1743 TnyMsg *new_msg = NULL;
1744 ReplyForwardHelper *rf_helper;
1745 ModestWindow *msg_win = NULL;
1746 ModestEditType edit_type;
1748 TnyAccount *account = NULL;
1749 ModestWindowMgr *mgr = NULL;
1750 gchar *signature = NULL;
1751 gboolean use_signature;
1754 /* If there was any error. The mail operation could be NULL,
1755 this means that we already have the message downloaded and
1756 that we didn't do a mail operation to retrieve it */
1757 rf_helper = (ReplyForwardHelper *) user_data;
1758 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1761 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1762 rf_helper->account_name, rf_helper->mailbox);
1763 recipient = modest_text_utils_get_email_address (from);
1764 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1769 /* Create reply mail */
1770 switch (rf_helper->action) {
1771 /* Use the msg_header to ensure that we have all the
1772 information. The summary can lack some data */
1773 TnyHeader *msg_header;
1775 msg_header = tny_msg_get_header (msg);
1777 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1778 (use_signature) ? signature : NULL,
1779 rf_helper->reply_forward_type,
1780 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1781 g_object_unref (msg_header);
1783 case ACTION_REPLY_TO_ALL:
1784 msg_header = tny_msg_get_header (msg);
1786 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1787 (use_signature) ? signature : NULL,
1788 rf_helper->reply_forward_type,
1789 MODEST_TNY_MSG_REPLY_MODE_ALL);
1790 edit_type = MODEST_EDIT_TYPE_REPLY;
1791 g_object_unref (msg_header);
1793 case ACTION_FORWARD:
1795 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1796 rf_helper->reply_forward_type);
1797 edit_type = MODEST_EDIT_TYPE_FORWARD;
1800 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1802 g_return_if_reached ();
1810 g_warning ("%s: failed to create message\n", __FUNCTION__);
1814 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1815 rf_helper->account_name,
1816 TNY_ACCOUNT_TYPE_STORE);
1818 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1822 /* Create and register the windows */
1823 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1824 mgr = modest_runtime_get_window_mgr ();
1825 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1827 /* Note that register_window could have deleted the account */
1828 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1829 gdouble parent_zoom;
1831 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1832 modest_window_set_zoom (msg_win, parent_zoom);
1835 /* Show edit window */
1836 gtk_widget_show_all (GTK_WIDGET (msg_win));
1839 /* We always unregister the header because the message is
1840 forwarded or replied so the original one is no longer
1842 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1845 g_object_unref (G_OBJECT (new_msg));
1847 g_object_unref (G_OBJECT (account));
1848 free_reply_forward_helper (rf_helper);
1851 /* Checks a list of headers. If any of them are not currently
1852 * downloaded (CACHED) then returns TRUE else returns FALSE.
1855 header_list_count_uncached_msgs (TnyList *header_list)
1858 gint uncached_messages = 0;
1860 iter = tny_list_create_iterator (header_list);
1861 while (!tny_iterator_is_done (iter)) {
1864 header = TNY_HEADER (tny_iterator_get_current (iter));
1866 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1867 uncached_messages ++;
1868 g_object_unref (header);
1871 tny_iterator_next (iter);
1873 g_object_unref (iter);
1875 return uncached_messages;
1878 /* Returns FALSE if the user does not want to download the
1879 * messages. Returns TRUE if the user allowed the download.
1882 connect_to_get_msg (ModestWindow *win,
1883 gint num_of_uncached_msgs,
1884 TnyAccount *account)
1886 GtkResponseType response;
1888 /* Allways download if we are online. */
1889 if (tny_device_is_online (modest_runtime_get_device ()))
1892 /* If offline, then ask for user permission to download the messages */
1893 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1894 ngettext("mcen_nc_get_msg",
1896 num_of_uncached_msgs));
1898 if (response == GTK_RESPONSE_CANCEL)
1901 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1905 reply_forward_performer (gboolean canceled,
1907 GtkWindow *parent_window,
1908 TnyAccount *account,
1911 ReplyForwardHelper *rf_helper = NULL;
1912 ModestMailOperation *mail_op;
1914 rf_helper = (ReplyForwardHelper *) user_data;
1916 if (canceled || err) {
1917 free_reply_forward_helper (rf_helper);
1921 /* Retrieve the message */
1922 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1923 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1924 modest_ui_actions_disk_operations_error_handler,
1926 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1927 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1930 g_object_unref(mail_op);
1934 * Common code for the reply and forward actions
1937 reply_forward (ReplyForwardAction action, ModestWindow *win)
1939 ReplyForwardHelper *rf_helper = NULL;
1940 guint reply_forward_type;
1942 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1944 /* we check for low-mem; in that case, show a warning, and don't allow
1945 * reply/forward (because it could potentially require a lot of memory */
1946 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1950 /* we need an account when editing */
1951 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1952 if (!modest_ui_actions_run_account_setup_wizard (win))
1956 reply_forward_type =
1957 modest_conf_get_int (modest_runtime_get_conf (),
1958 (action == ACTION_FORWARD) ?
1959 MODEST_CONF_FORWARD_TYPE :
1960 MODEST_CONF_REPLY_TYPE,
1963 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1965 TnyHeader *header = NULL;
1966 /* Get header and message. Do not free them here, the
1967 reply_forward_cb must do it */
1968 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1969 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1971 if (msg && header) {
1973 rf_helper = create_reply_forward_helper (action, win,
1974 reply_forward_type, header);
1975 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1977 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1981 g_object_unref (msg);
1983 g_object_unref (header);
1985 TnyHeader *header = NULL;
1987 gboolean do_retrieve = TRUE;
1988 TnyList *header_list = NULL;
1990 header_list = get_selected_headers (win);
1993 /* Check that only one message is selected for replying */
1994 if (tny_list_get_length (header_list) != 1) {
1995 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1996 NULL, _("mcen_ib_select_one_message"));
1997 g_object_unref (header_list);
2001 /* Only reply/forward to one message */
2002 iter = tny_list_create_iterator (header_list);
2003 header = TNY_HEADER (tny_iterator_get_current (iter));
2004 g_object_unref (iter);
2006 /* Retrieve messages */
2007 do_retrieve = (action == ACTION_FORWARD) ||
2008 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2011 TnyAccount *account = NULL;
2012 TnyFolder *folder = NULL;
2013 gdouble download = TRUE;
2014 guint uncached_msgs = 0;
2016 folder = tny_header_get_folder (header);
2018 goto do_retrieve_frees;
2019 account = tny_folder_get_account (folder);
2021 goto do_retrieve_frees;
2023 uncached_msgs = header_list_count_uncached_msgs (header_list);
2025 if (uncached_msgs > 0) {
2026 /* Allways download if we are online. */
2027 if (!tny_device_is_online (modest_runtime_get_device ())) {
2030 /* If ask for user permission to download the messages */
2031 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2032 ngettext("mcen_nc_get_msg",
2036 /* End if the user does not want to continue */
2037 if (response == GTK_RESPONSE_CANCEL)
2044 rf_helper = create_reply_forward_helper (action, win,
2045 reply_forward_type, header);
2046 if (uncached_msgs > 0) {
2047 modest_platform_connect_and_perform (GTK_WINDOW (win),
2049 reply_forward_performer,
2052 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2053 account, rf_helper);
2058 g_object_unref (account);
2060 g_object_unref (folder);
2062 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2065 g_object_unref (header_list);
2066 g_object_unref (header);
2071 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2073 g_return_if_fail (MODEST_IS_WINDOW(win));
2075 reply_forward (ACTION_REPLY, win);
2079 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2081 g_return_if_fail (MODEST_IS_WINDOW(win));
2083 reply_forward (ACTION_FORWARD, win);
2087 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2089 g_return_if_fail (MODEST_IS_WINDOW(win));
2091 reply_forward (ACTION_REPLY_TO_ALL, win);
2095 modest_ui_actions_on_next (GtkAction *action,
2096 ModestWindow *window)
2098 if (MODEST_IS_MAIN_WINDOW (window)) {
2099 GtkWidget *header_view;
2101 header_view = modest_main_window_get_child_widget (
2102 MODEST_MAIN_WINDOW(window),
2103 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2107 modest_header_view_select_next (
2108 MODEST_HEADER_VIEW(header_view));
2109 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2110 modest_msg_view_window_select_next_message (
2111 MODEST_MSG_VIEW_WINDOW (window));
2113 g_return_if_reached ();
2118 modest_ui_actions_on_prev (GtkAction *action,
2119 ModestWindow *window)
2121 g_return_if_fail (MODEST_IS_WINDOW(window));
2123 if (MODEST_IS_MAIN_WINDOW (window)) {
2124 GtkWidget *header_view;
2125 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2126 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2130 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2131 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2132 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2134 g_return_if_reached ();
2139 modest_ui_actions_on_sort (GtkAction *action,
2140 ModestWindow *window)
2142 GtkWidget *header_view = NULL;
2144 g_return_if_fail (MODEST_IS_WINDOW(window));
2146 if (MODEST_IS_MAIN_WINDOW (window)) {
2147 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2148 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2149 #ifdef MODEST_TOOLKIT_HILDON2
2150 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2151 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2156 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2161 /* Show sorting dialog */
2162 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2166 sync_folder_cb (ModestMailOperation *mail_op,
2170 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2172 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2173 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2175 /* We must clear first, because otherwise set_folder will ignore */
2176 /* the change as the folders are the same */
2177 modest_header_view_clear (header_view);
2178 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2180 g_object_unref (parent);
2183 g_object_unref (header_view);
2187 idle_refresh_folder (gpointer source)
2189 ModestHeaderView *header_view = NULL;
2191 /* If the window still exists */
2192 if (!GTK_IS_WIDGET (source) ||
2193 !GTK_WIDGET_VISIBLE (source))
2196 /* Refresh the current view */
2197 #ifdef MODEST_TOOLKIT_HILDON2
2198 if (MODEST_IS_HEADER_WINDOW (source))
2199 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2201 if (MODEST_IS_MAIN_WINDOW (source))
2202 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2203 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2206 TnyFolder *folder = modest_header_view_get_folder (header_view);
2208 /* Sync the folder status */
2209 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2210 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2211 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2212 g_object_unref (folder);
2213 g_object_unref (mail_op);
2221 update_account_cb (ModestMailOperation *self,
2222 TnyList *new_headers,
2226 gboolean show_visual_notifications;
2228 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2229 show_visual_notifications = (top) ? FALSE : TRUE;
2231 /* Notify new messages have been downloaded. If the
2232 send&receive was invoked by the user then do not show any
2233 visual notification, only play a sound and activate the LED
2234 (for the Maemo version) */
2235 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2237 /* We only notify about really new messages (not seen) we get */
2238 TnyList *actually_new_list;
2239 TnyIterator *iterator;
2240 actually_new_list = TNY_LIST (tny_simple_list_new ());
2241 for (iterator = tny_list_create_iterator (new_headers);
2242 !tny_iterator_is_done (iterator);
2243 tny_iterator_next (iterator)) {
2245 TnyHeaderFlags flags;
2246 header = TNY_HEADER (tny_iterator_get_current (iterator));
2247 flags = tny_header_get_flags (header);
2249 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2250 /* Messages are ordered from most
2251 recent to oldest. But we want to
2252 show notifications starting from
2253 the oldest message. That's why we
2255 tny_list_prepend (actually_new_list, G_OBJECT (header));
2257 g_object_unref (header);
2259 g_object_unref (iterator);
2261 if (tny_list_get_length (actually_new_list) > 0) {
2262 GList *new_headers_list = NULL;
2264 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2266 /* Send notifications */
2267 if (new_headers_list) {
2268 modest_platform_on_new_headers_received (new_headers_list,
2269 show_visual_notifications);
2271 modest_utils_free_notification_list (new_headers_list);
2274 g_object_unref (actually_new_list);
2278 /* Refresh the current folder in an idle. We do this
2279 in order to avoid refresh cancelations if the
2280 currently viewed folder is the inbox */
2281 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2282 idle_refresh_folder,
2289 TnyAccount *account;
2291 gchar *account_name;
2292 gboolean poke_status;
2293 gboolean interactive;
2294 ModestMailOperation *mail_op;
2298 do_send_receive_performer (gboolean canceled,
2300 GtkWindow *parent_window,
2301 TnyAccount *account,
2304 SendReceiveInfo *info;
2306 info = (SendReceiveInfo *) user_data;
2308 if (err || canceled) {
2309 /* In disk full conditions we could get this error here */
2310 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2311 (GtkWidget *) parent_window, err,
2314 if (info->mail_op) {
2315 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2321 /* Set send/receive operation in progress */
2322 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2323 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2326 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2327 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2328 G_CALLBACK (on_send_receive_finished),
2331 /* Send & receive. */
2332 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2333 update_account_cb, info->win);
2338 g_object_unref (G_OBJECT (info->mail_op));
2339 if (info->account_name)
2340 g_free (info->account_name);
2342 g_object_unref (info->win);
2344 g_object_unref (info->account);
2345 g_slice_free (SendReceiveInfo, info);
2349 * This function performs the send & receive required actions. The
2350 * window is used to create the mail operation. Typically it should
2351 * always be the main window, but we pass it as argument in order to
2355 modest_ui_actions_do_send_receive (const gchar *account_name,
2356 gboolean force_connection,
2357 gboolean poke_status,
2358 gboolean interactive,
2361 gchar *acc_name = NULL;
2362 SendReceiveInfo *info;
2363 ModestTnyAccountStore *acc_store;
2364 TnyAccount *account;
2366 /* If no account name was provided then get the current account, and if
2367 there is no current account then pick the default one: */
2368 if (!account_name) {
2370 acc_name = g_strdup (modest_window_get_active_account (win));
2372 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2374 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2378 acc_name = g_strdup (account_name);
2381 acc_store = modest_runtime_get_account_store ();
2382 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2386 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2390 /* Do not automatically refresh accounts that are flagged as
2391 NO_AUTO_UPDATE. This could be useful for accounts that
2392 handle their own update times */
2394 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2395 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2396 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2397 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2399 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2400 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2401 g_object_unref (account);
2408 /* Create the info for the connect and perform */
2409 info = g_slice_new (SendReceiveInfo);
2410 info->account_name = acc_name;
2411 info->win = (win) ? g_object_ref (win) : NULL;
2412 info->poke_status = poke_status;
2413 info->interactive = interactive;
2414 info->account = account;
2415 /* We need to create the operation here, because otherwise it
2416 could happen that the queue emits the queue-empty signal
2417 while we're trying to connect the account */
2418 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2419 modest_ui_actions_disk_operations_error_handler,
2421 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2423 /* Invoke the connect and perform */
2424 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2425 force_connection, info->account,
2426 do_send_receive_performer, info);
2431 modest_ui_actions_do_cancel_send (const gchar *account_name,
2434 TnyTransportAccount *transport_account;
2435 TnySendQueue *send_queue = NULL;
2436 GError *error = NULL;
2438 /* Get transport account */
2440 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2441 (modest_runtime_get_account_store(),
2443 TNY_ACCOUNT_TYPE_TRANSPORT));
2444 if (!transport_account) {
2445 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2450 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2451 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2452 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2453 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2454 "modest: could not find send queue for account\n");
2456 /* Cancel the current send */
2457 tny_account_cancel (TNY_ACCOUNT (transport_account));
2459 /* Suspend all pending messages */
2460 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2464 if (transport_account != NULL)
2465 g_object_unref (G_OBJECT (transport_account));
2469 modest_ui_actions_cancel_send_all (ModestWindow *win)
2471 GSList *account_names, *iter;
2473 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2476 iter = account_names;
2478 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2479 iter = g_slist_next (iter);
2482 modest_account_mgr_free_account_names (account_names);
2483 account_names = NULL;
2487 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2490 /* Check if accounts exist */
2491 gboolean accounts_exist =
2492 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2494 /* If not, allow the user to create an account before trying to send/receive. */
2495 if (!accounts_exist)
2496 modest_ui_actions_on_accounts (NULL, win);
2498 /* Cancel all sending operaitons */
2499 modest_ui_actions_cancel_send_all (win);
2503 * Refreshes all accounts. This function will be used by automatic
2507 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2508 gboolean force_connection,
2509 gboolean poke_status,
2510 gboolean interactive)
2512 GSList *account_names, *iter;
2514 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2517 iter = account_names;
2519 modest_ui_actions_do_send_receive ((const char*) iter->data,
2521 poke_status, interactive, win);
2522 iter = g_slist_next (iter);
2525 modest_account_mgr_free_account_names (account_names);
2526 account_names = NULL;
2530 * Handler of the click on Send&Receive button in the main toolbar
2533 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2535 /* Check if accounts exist */
2536 gboolean accounts_exist;
2539 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2541 /* If not, allow the user to create an account before trying to send/receive. */
2542 if (!accounts_exist)
2543 modest_ui_actions_on_accounts (NULL, win);
2545 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2546 if (MODEST_IS_MAIN_WINDOW (win)) {
2547 GtkWidget *folder_view;
2548 TnyFolderStore *folder_store;
2551 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2552 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2556 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2559 g_object_unref (folder_store);
2560 /* Refresh the active account. Force the connection if needed
2561 and poke the status of all folders */
2562 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2563 #ifdef MODEST_TOOLKIT_HILDON2
2564 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2565 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2568 const gchar *active_account;
2569 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2571 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2578 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2581 GtkWidget *header_view;
2583 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2585 header_view = modest_main_window_get_child_widget (main_window,
2586 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2590 conf = modest_runtime_get_conf ();
2592 /* what is saved/restored is depending on the style; thus; we save with
2593 * old style, then update the style, and restore for this new style
2595 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2597 if (modest_header_view_get_style
2598 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2599 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2600 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2602 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2603 MODEST_HEADER_VIEW_STYLE_DETAILS);
2605 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2606 MODEST_CONF_HEADER_VIEW_KEY);
2611 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2613 ModestMainWindow *main_window)
2615 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2616 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2618 /* in the case the folder is empty, show the empty folder message and focus
2620 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2621 if (modest_header_view_is_empty (header_view)) {
2622 TnyFolder *folder = modest_header_view_get_folder (header_view);
2623 GtkWidget *folder_view =
2624 modest_main_window_get_child_widget (main_window,
2625 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2626 if (folder != NULL) {
2627 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2628 g_object_unref (folder);
2630 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2634 /* If no header has been selected then exit */
2639 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2640 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2642 /* Update toolbar dimming state */
2643 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2644 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2648 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2651 ModestWindow *window)
2653 GtkWidget *open_widget;
2654 GtkTreeRowReference *rowref;
2656 g_return_if_fail (MODEST_IS_WINDOW(window));
2657 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2658 g_return_if_fail (TNY_IS_HEADER (header));
2660 if (modest_header_view_count_selected_headers (header_view) > 1) {
2661 /* Don't allow activation if there are more than one message selected */
2662 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2666 /* we check for low-mem; in that case, show a warning, and don't allow
2667 * activating headers
2669 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2672 if (MODEST_IS_MAIN_WINDOW (window)) {
2673 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2674 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2675 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2679 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2680 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2681 gtk_tree_row_reference_free (rowref);
2685 set_active_account_from_tny_account (TnyAccount *account,
2686 ModestWindow *window)
2688 const gchar *server_acc_name = tny_account_get_id (account);
2690 /* We need the TnyAccount provided by the
2691 account store because that is the one that
2692 knows the name of the Modest account */
2693 TnyAccount *modest_server_account =
2694 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2695 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2697 if (!modest_server_account) {
2698 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2702 /* Update active account, but only if it's not a pseudo-account */
2703 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2704 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2705 const gchar *modest_acc_name =
2706 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2707 if (modest_acc_name)
2708 modest_window_set_active_account (window, modest_acc_name);
2711 g_object_unref (modest_server_account);
2716 folder_refreshed_cb (ModestMailOperation *mail_op,
2720 ModestMainWindow *win = NULL;
2721 GtkWidget *folder_view, *header_view;
2722 const GError *error;
2724 g_return_if_fail (TNY_IS_FOLDER (folder));
2726 win = MODEST_MAIN_WINDOW (user_data);
2728 /* Check if the operation failed due to memory low conditions */
2729 error = modest_mail_operation_get_error (mail_op);
2730 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2731 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2732 modest_platform_run_information_dialog (GTK_WINDOW (win),
2733 _KR("memr_ib_operation_disabled"),
2739 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2741 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2744 TnyFolderStore *current_folder;
2746 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2747 if (current_folder) {
2748 gboolean different = ((TnyFolderStore *) folder != current_folder);
2749 g_object_unref (current_folder);
2755 /* Check if folder is empty and set headers view contents style */
2756 if ((tny_folder_get_all_count (folder) == 0) ||
2757 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2758 modest_main_window_set_contents_style (win,
2759 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2763 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2764 TnyFolderStore *folder_store,
2766 ModestMainWindow *main_window)
2768 GtkWidget *header_view;
2770 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2772 header_view = modest_main_window_get_child_widget(main_window,
2773 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2778 if (TNY_IS_ACCOUNT (folder_store)) {
2780 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2782 /* Show account details */
2783 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2786 if (TNY_IS_FOLDER (folder_store) && selected) {
2787 TnyAccount *account;
2789 /* Update the active account */
2790 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2792 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2793 g_object_unref (account);
2797 /* Set the header style by default, it could
2798 be changed later by the refresh callback to
2800 modest_main_window_set_contents_style (main_window,
2801 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2803 /* Set folder on header view. This function
2804 will call tny_folder_refresh_async so we
2805 pass a callback that will be called when
2806 finished. We use that callback to set the
2807 empty view if there are no messages */
2808 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2809 TNY_FOLDER (folder_store),
2811 MODEST_WINDOW (main_window),
2812 folder_refreshed_cb,
2815 /* Restore configuration. We need to do this
2816 *after* the set_folder because the widget
2817 memory asks the header view about its
2819 modest_widget_memory_restore (modest_runtime_get_conf (),
2820 G_OBJECT(header_view),
2821 MODEST_CONF_HEADER_VIEW_KEY);
2823 /* No need to save the header view
2824 configuration for Maemo because it only
2825 saves the sorting stuff and that it's
2826 already being done by the sort
2827 dialog. Remove it when the GNOME version
2828 has the same behaviour */
2829 #ifdef MODEST_TOOLKIT_GTK
2830 if (modest_main_window_get_contents_style (main_window) ==
2831 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2832 modest_widget_memory_save (modest_runtime_get_conf (),
2833 G_OBJECT (header_view),
2834 MODEST_CONF_HEADER_VIEW_KEY);
2836 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2840 /* Update dimming state */
2841 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2842 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2846 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2853 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2855 online = tny_device_is_online (modest_runtime_get_device());
2858 /* already online -- the item is simply not there... */
2859 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2861 GTK_MESSAGE_WARNING,
2863 _("The %s you selected cannot be found"),
2865 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2866 gtk_dialog_run (GTK_DIALOG(dialog));
2868 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2871 _("mcen_bd_dialog_cancel"),
2872 GTK_RESPONSE_REJECT,
2873 _("mcen_bd_dialog_ok"),
2874 GTK_RESPONSE_ACCEPT,
2876 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2877 "Do you want to get online?"), item);
2878 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2879 gtk_label_new (txt), FALSE, FALSE, 0);
2880 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2883 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2884 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2885 /* TODO: Comment about why is this commented out: */
2886 /* modest_platform_connect_and_wait (); */
2889 gtk_widget_destroy (dialog);
2893 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2896 /* g_debug ("%s %s", __FUNCTION__, link); */
2901 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2904 modest_platform_activate_uri (link);
2908 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2911 modest_platform_show_uri_popup (link);
2915 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2918 /* we check for low-mem; in that case, show a warning, and don't allow
2919 * viewing attachments
2921 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2924 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2928 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2929 const gchar *address,
2932 /* g_debug ("%s %s", __FUNCTION__, address); */
2936 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2937 TnyMsg *saved_draft,
2940 ModestMsgEditWindow *edit_window;
2942 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2943 #ifndef MODEST_TOOLKIT_HILDON2
2944 ModestMainWindow *win;
2946 /* FIXME. Make the header view sensitive again. This is a
2947 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2949 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2950 modest_runtime_get_window_mgr(), FALSE));
2952 GtkWidget *hdrview = modest_main_window_get_child_widget(
2953 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2954 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2958 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2960 /* Set draft is there was no error */
2961 if (!modest_mail_operation_get_error (mail_op))
2962 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2964 g_object_unref(edit_window);
2968 enough_space_for_message (ModestMsgEditWindow *edit_window,
2971 guint64 available_disk, expected_size;
2976 available_disk = modest_utils_get_available_space (NULL);
2977 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2978 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2983 /* Double check: disk full condition or message too big */
2984 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2985 expected_size > available_disk) {
2986 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2987 modest_platform_information_banner (NULL, NULL, msg);
2994 * djcb: if we're in low-memory state, we only allow for
2995 * saving messages smaller than
2996 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2997 * should still allow for sending anything critical...
2999 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3000 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3004 * djcb: we also make sure that the attachments are smaller than the max size
3005 * this is for the case where we'd try to forward a message with attachments
3006 * bigger than our max allowed size, or sending an message from drafts which
3007 * somehow got past our checks when attaching.
3009 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3010 modest_platform_run_information_dialog (
3011 GTK_WINDOW(edit_window),
3012 _("mail_ib_error_attachment_size"),
3021 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3023 TnyTransportAccount *transport_account;
3024 ModestMailOperation *mail_operation;
3026 gchar *account_name;
3027 ModestAccountMgr *account_mgr;
3028 gboolean had_error = FALSE;
3029 ModestMainWindow *win = NULL;
3031 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3033 data = modest_msg_edit_window_get_msg_data (edit_window);
3036 if (!enough_space_for_message (edit_window, data)) {
3037 modest_msg_edit_window_free_msg_data (edit_window, data);
3041 account_name = g_strdup (data->account_name);
3042 account_mgr = modest_runtime_get_account_mgr();
3044 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3046 account_name = modest_account_mgr_get_default_account (account_mgr);
3047 if (!account_name) {
3048 g_printerr ("modest: no account found\n");
3049 modest_msg_edit_window_free_msg_data (edit_window, data);
3053 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3054 account_name = g_strdup (data->account_name);
3058 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3059 (modest_runtime_get_account_store (),
3061 TNY_ACCOUNT_TYPE_TRANSPORT));
3062 if (!transport_account) {
3063 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3064 g_free (account_name);
3065 modest_msg_edit_window_free_msg_data (edit_window, data);
3069 /* Create the mail operation */
3070 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3072 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3074 modest_mail_operation_save_to_drafts (mail_operation,
3086 data->priority_flags,
3089 on_save_to_drafts_cb,
3090 g_object_ref(edit_window));
3092 #ifdef MODEST_TOOLKIT_HILDON2
3093 /* In hildon2 we always show the information banner on saving to drafts.
3094 * It will be a system information banner in this case.
3096 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3097 modest_platform_information_banner (NULL, NULL, text);
3100 /* Use the main window as the parent of the banner, if the
3101 main window does not exist it won't be shown, if the parent
3102 window exists then it's properly shown. We don't use the
3103 editor window because it could be closed (save to drafts
3104 could happen after closing the window */
3105 win = (ModestMainWindow *)
3106 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3108 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3109 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3113 modest_msg_edit_window_set_modified (edit_window, FALSE);
3116 g_free (account_name);
3117 g_object_unref (G_OBJECT (transport_account));
3118 g_object_unref (G_OBJECT (mail_operation));
3120 modest_msg_edit_window_free_msg_data (edit_window, data);
3123 * If the drafts folder is selected then make the header view
3124 * insensitive while the message is being saved to drafts
3125 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3126 * is not very clean but it avoids letting the drafts folder
3127 * in an inconsistent state: the user could edit the message
3128 * being saved and undesirable things would happen.
3129 * In the average case the user won't notice anything at
3130 * all. In the worst case (the user is editing a really big
3131 * file from Drafts) the header view will be insensitive
3132 * during the saving process (10 or 20 seconds, depending on
3133 * the message). Anyway this is just a quick workaround: once
3134 * we find a better solution it should be removed
3135 * See NB#65125 (commend #18) for details.
3137 if (!had_error && win != NULL) {
3138 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3139 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3141 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3143 if (modest_tny_folder_is_local_folder(folder)) {
3144 TnyFolderType folder_type;
3145 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3146 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3147 GtkWidget *hdrview = modest_main_window_get_child_widget(
3148 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3149 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3153 if (folder != NULL) g_object_unref(folder);
3160 /* For instance, when clicking the Send toolbar button when editing a message: */
3162 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3164 TnyTransportAccount *transport_account = NULL;
3165 gboolean had_error = FALSE;
3167 ModestAccountMgr *account_mgr;
3168 gchar *account_name;
3169 ModestMailOperation *mail_operation;
3172 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3174 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3177 data = modest_msg_edit_window_get_msg_data (edit_window);
3179 recipients = g_strconcat (data->to?data->to:"",
3180 data->cc?data->cc:"",
3181 data->bcc?data->bcc:"",
3183 if (recipients == NULL || recipients[0] == '\0') {
3184 /* Empty subject -> no send */
3185 g_free (recipients);
3186 modest_msg_edit_window_free_msg_data (edit_window, data);
3189 g_free (recipients);
3192 if (!enough_space_for_message (edit_window, data)) {
3193 modest_msg_edit_window_free_msg_data (edit_window, data);
3197 account_mgr = modest_runtime_get_account_mgr();
3198 account_name = g_strdup (data->account_name);
3200 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3203 account_name = modest_account_mgr_get_default_account (account_mgr);
3205 if (!account_name) {
3206 modest_msg_edit_window_free_msg_data (edit_window, data);
3207 /* Run account setup wizard */
3208 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3213 /* Get the currently-active transport account for this modest account: */
3214 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3216 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3217 (modest_runtime_get_account_store (),
3218 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3221 if (!transport_account) {
3222 modest_msg_edit_window_free_msg_data (edit_window, data);
3223 /* Run account setup wizard */
3224 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3229 /* Create the mail operation */
3230 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3231 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3233 modest_mail_operation_send_new_mail (mail_operation,
3247 data->priority_flags);
3249 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3250 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3252 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3253 const GError *error = modest_mail_operation_get_error (mail_operation);
3254 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3255 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3256 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3257 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3263 g_free (account_name);
3264 g_object_unref (G_OBJECT (transport_account));
3265 g_object_unref (G_OBJECT (mail_operation));
3267 modest_msg_edit_window_free_msg_data (edit_window, data);
3270 modest_msg_edit_window_set_sent (edit_window, TRUE);
3272 /* Save settings and close the window: */
3273 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3280 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3281 ModestMsgEditWindow *window)
3283 ModestMsgEditFormatState *format_state = NULL;
3285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3286 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3288 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3291 format_state = modest_msg_edit_window_get_format_state (window);
3292 g_return_if_fail (format_state != NULL);
3294 format_state->bold = gtk_toggle_action_get_active (action);
3295 modest_msg_edit_window_set_format_state (window, format_state);
3296 g_free (format_state);
3301 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3302 ModestMsgEditWindow *window)
3304 ModestMsgEditFormatState *format_state = NULL;
3306 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3307 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3309 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3312 format_state = modest_msg_edit_window_get_format_state (window);
3313 g_return_if_fail (format_state != NULL);
3315 format_state->italics = gtk_toggle_action_get_active (action);
3316 modest_msg_edit_window_set_format_state (window, format_state);
3317 g_free (format_state);
3322 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3323 ModestMsgEditWindow *window)
3325 ModestMsgEditFormatState *format_state = NULL;
3327 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3328 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3330 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3333 format_state = modest_msg_edit_window_get_format_state (window);
3334 g_return_if_fail (format_state != NULL);
3336 format_state->bullet = gtk_toggle_action_get_active (action);
3337 modest_msg_edit_window_set_format_state (window, format_state);
3338 g_free (format_state);
3343 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3344 GtkRadioAction *selected,
3345 ModestMsgEditWindow *window)
3347 ModestMsgEditFormatState *format_state = NULL;
3348 GtkJustification value;
3350 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3352 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3355 value = gtk_radio_action_get_current_value (selected);
3357 format_state = modest_msg_edit_window_get_format_state (window);
3358 g_return_if_fail (format_state != NULL);
3360 format_state->justification = value;
3361 modest_msg_edit_window_set_format_state (window, format_state);
3362 g_free (format_state);
3366 modest_ui_actions_on_select_editor_color (GtkAction *action,
3367 ModestMsgEditWindow *window)
3369 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3370 g_return_if_fail (GTK_IS_ACTION (action));
3372 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3375 modest_msg_edit_window_select_color (window);
3379 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3380 ModestMsgEditWindow *window)
3382 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3383 g_return_if_fail (GTK_IS_ACTION (action));
3385 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3388 modest_msg_edit_window_select_background_color (window);
3392 modest_ui_actions_on_insert_image (GObject *object,
3393 ModestMsgEditWindow *window)
3395 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3398 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3401 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3404 modest_msg_edit_window_insert_image (window);
3408 modest_ui_actions_on_attach_file (GtkAction *action,
3409 ModestMsgEditWindow *window)
3411 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3412 g_return_if_fail (GTK_IS_ACTION (action));
3414 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3417 modest_msg_edit_window_offer_attach_file (window);
3421 modest_ui_actions_on_remove_attachments (GtkAction *action,
3422 ModestMsgEditWindow *window)
3424 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3426 modest_msg_edit_window_remove_attachments (window, NULL);
3430 do_create_folder_cb (ModestMailOperation *mail_op,
3431 TnyFolderStore *parent_folder,
3432 TnyFolder *new_folder,
3435 gchar *suggested_name = (gchar *) user_data;
3436 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3437 const GError *error;
3439 error = modest_mail_operation_get_error (mail_op);
3441 gboolean disk_full = FALSE;
3442 TnyAccount *account;
3443 /* Show an error. If there was some problem writing to
3444 disk, show it, otherwise show the generic folder
3445 create error. We do it here and not in an error
3446 handler because the call to do_create_folder will
3447 stop the main loop in a gtk_dialog_run and then,
3448 the message won't be shown until that dialog is
3450 account = modest_mail_operation_get_account (mail_op);
3453 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3454 (GtkWidget *) source_win,
3457 _("mail_in_ui_folder_create_error_memory"));
3458 g_object_unref (account);
3461 /* Show an error and try again if there is no
3462 full memory condition */
3463 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3464 _("mail_in_ui_folder_create_error"));
3465 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3469 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3470 * FIXME: any other? */
3471 GtkWidget *folder_view;
3473 if (MODEST_IS_MAIN_WINDOW(source_win))
3475 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3476 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3478 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3479 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3481 /* Select the newly created folder. It could happen
3482 that the widget is no longer there (i.e. the window
3483 has been destroyed, so we need to check this */
3485 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3487 g_object_unref (new_folder);
3489 /* Free. Note that the first time it'll be NULL so noop */
3490 g_free (suggested_name);
3491 g_object_unref (source_win);
3496 TnyFolderStore *parent;
3497 } CreateFolderConnect;
3500 do_create_folder_performer (gboolean canceled,
3502 GtkWindow *parent_window,
3503 TnyAccount *account,
3506 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3507 ModestMailOperation *mail_op;
3509 if (canceled || err) {
3510 /* In disk full conditions we could get this error here */
3511 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3512 (GtkWidget *) parent_window, err,
3513 NULL, _("mail_in_ui_folder_create_error_memory"));
3515 /* This happens if we have selected the outbox folder
3517 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3518 TNY_IS_MERGE_FOLDER (helper->parent)) {
3519 /* Show an error and retry */
3520 modest_platform_information_banner ((GtkWidget *) parent_window,
3522 _("mail_in_ui_folder_create_error"));
3524 do_create_folder (parent_window, helper->parent, helper->folder_name);
3530 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3531 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3533 modest_mail_operation_create_folder (mail_op,
3535 (const gchar *) helper->folder_name,
3536 do_create_folder_cb,
3537 g_strdup (helper->folder_name));
3538 g_object_unref (mail_op);
3542 g_object_unref (helper->parent);
3543 if (helper->folder_name)
3544 g_free (helper->folder_name);
3545 g_slice_free (CreateFolderConnect, helper);
3550 do_create_folder (GtkWindow *parent_window,
3551 TnyFolderStore *suggested_parent,
3552 const gchar *suggested_name)
3555 gchar *folder_name = NULL;
3556 TnyFolderStore *parent_folder = NULL;
3558 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3560 (gchar *) suggested_name,
3564 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3565 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3566 helper->folder_name = g_strdup (folder_name);
3567 helper->parent = g_object_ref (parent_folder);
3569 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3572 do_create_folder_performer,
3577 g_free (folder_name);
3579 g_object_unref (parent_folder);
3583 modest_ui_actions_create_folder(GtkWidget *parent_window,
3584 GtkWidget *folder_view,
3585 TnyFolderStore *parent_folder)
3587 if (!parent_folder) {
3588 #ifdef MODEST_TOOLKIT_HILDON2
3589 ModestTnyAccountStore *acc_store;
3591 acc_store = modest_runtime_get_account_store ();
3593 parent_folder = (TnyFolderStore *)
3594 modest_tny_account_store_get_local_folders_account (acc_store);
3596 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3600 if (parent_folder) {
3601 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3602 g_object_unref (parent_folder);
3607 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3610 g_return_if_fail (MODEST_IS_WINDOW(window));
3612 if (MODEST_IS_MAIN_WINDOW (window)) {
3613 GtkWidget *folder_view;
3615 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3616 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3620 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3621 #ifdef MODEST_TOOLKIT_HILDON2
3622 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3623 GtkWidget *folder_view;
3625 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3626 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3629 g_assert_not_reached ();
3634 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3637 const GError *error = NULL;
3638 gchar *message = NULL;
3640 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3642 /* Get error message */
3643 error = modest_mail_operation_get_error (mail_op);
3645 g_return_if_reached ();
3647 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3648 (GError *) error, account);
3650 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3651 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3652 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3653 message = _CS("ckdg_ib_folder_already_exists");
3654 } else if (error->domain == TNY_ERROR_DOMAIN &&
3655 error->code == TNY_SERVICE_ERROR_STATE) {
3656 /* This means that the folder is already in use (a
3657 message is opened for example */
3658 message = _("emev_ni_internal_error");
3660 message = _CS("ckdg_ib_unable_to_rename");
3663 /* We don't set a parent for the dialog because the dialog
3664 will be destroyed so the banner won't appear */
3665 modest_platform_information_banner (NULL, NULL, message);
3668 g_object_unref (account);
3674 TnyFolderStore *folder;
3679 on_rename_folder_cb (ModestMailOperation *mail_op,
3680 TnyFolder *new_folder,
3683 ModestFolderView *folder_view;
3685 /* If the window was closed when renaming a folder, or if
3686 * it's not a main window this will happen */
3687 if (!MODEST_IS_FOLDER_VIEW (user_data))
3690 folder_view = MODEST_FOLDER_VIEW (user_data);
3691 /* Note that if the rename fails new_folder will be NULL */
3693 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3695 modest_folder_view_select_first_inbox_or_local (folder_view);
3697 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3701 on_rename_folder_performer (gboolean canceled,
3703 GtkWindow *parent_window,
3704 TnyAccount *account,
3707 ModestMailOperation *mail_op = NULL;
3708 GtkTreeSelection *sel = NULL;
3709 GtkWidget *folder_view = NULL;
3710 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3712 if (canceled || err) {
3713 /* In disk full conditions we could get this error here */
3714 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3715 (GtkWidget *) parent_window, err,
3720 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3721 modest_ui_actions_rename_folder_error_handler,
3722 parent_window, NULL);
3724 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3727 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3729 folder_view = modest_main_window_get_child_widget (
3730 MODEST_MAIN_WINDOW (parent_window),
3731 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3733 #ifdef MODEST_TOOLKIT_HILDON2
3734 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3735 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3736 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3740 /* Clear the folders view */
3741 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3742 gtk_tree_selection_unselect_all (sel);
3744 /* Actually rename the folder */
3745 modest_mail_operation_rename_folder (mail_op,
3746 TNY_FOLDER (data->folder),
3747 (const gchar *) (data->new_name),
3748 on_rename_folder_cb,
3750 g_object_unref (mail_op);
3753 g_object_unref (data->folder);
3754 g_free (data->new_name);
3759 modest_ui_actions_on_rename_folder (GtkAction *action,
3760 ModestWindow *window)
3762 modest_ui_actions_on_edit_mode_rename_folder (window);
3766 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3768 TnyFolderStore *folder;
3769 GtkWidget *folder_view;
3770 gboolean do_rename = TRUE;
3772 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3774 if (MODEST_IS_MAIN_WINDOW (window)) {
3775 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3776 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3780 #ifdef MODEST_TOOLKIT_HILDON2
3781 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3782 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3788 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3793 if (TNY_IS_FOLDER (folder)) {
3794 gchar *folder_name = NULL;
3796 const gchar *current_name;
3797 TnyFolderStore *parent;
3799 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3800 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3801 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3802 parent, current_name,
3804 g_object_unref (parent);
3806 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3809 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3810 rename_folder_data->folder = g_object_ref (folder);
3811 rename_folder_data->new_name = folder_name;
3812 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3813 folder, on_rename_folder_performer, rename_folder_data);
3816 g_object_unref (folder);
3821 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3824 GObject *win = modest_mail_operation_get_source (mail_op);
3826 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3827 _("mail_in_ui_folder_delete_error"),
3829 g_object_unref (win);
3833 TnyFolderStore *folder;
3834 gboolean move_to_trash;
3838 on_delete_folder_cb (gboolean canceled,
3840 GtkWindow *parent_window,
3841 TnyAccount *account,
3844 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3845 GtkWidget *folder_view;
3846 ModestMailOperation *mail_op;
3847 GtkTreeSelection *sel;
3849 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3850 /* Note that the connection process can fail due to
3851 memory low conditions as it can not successfully
3852 store the summary */
3853 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3854 (GtkWidget*) parent_window, err,
3856 g_debug ("Error connecting when trying to delete a folder");
3857 g_object_unref (G_OBJECT (info->folder));
3862 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3863 folder_view = modest_main_window_get_child_widget (
3864 MODEST_MAIN_WINDOW (parent_window),
3865 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3866 #ifdef MODEST_TOOLKIT_HILDON2
3867 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3868 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3871 g_object_unref (G_OBJECT (info->folder));
3876 /* Unselect the folder before deleting it to free the headers */
3877 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3878 gtk_tree_selection_unselect_all (sel);
3880 /* Create the mail operation */
3882 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3883 modest_ui_actions_delete_folder_error_handler,
3886 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3888 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3890 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3892 g_object_unref (mail_op);
3893 g_object_unref (info->folder);
3898 delete_folder (ModestWindow *window, gboolean move_to_trash)
3900 TnyFolderStore *folder;
3901 GtkWidget *folder_view;
3905 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3907 if (MODEST_IS_MAIN_WINDOW (window)) {
3909 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3910 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3911 #ifdef MODEST_TOOLKIT_HILDON2
3912 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3913 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3921 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3926 /* Show an error if it's an account */
3927 if (!TNY_IS_FOLDER (folder)) {
3928 modest_platform_run_information_dialog (GTK_WINDOW (window),
3929 _("mail_in_ui_folder_delete_error"),
3931 g_object_unref (G_OBJECT (folder));
3936 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3937 tny_folder_get_name (TNY_FOLDER (folder)));
3938 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3939 (const gchar *) message);
3942 if (response == GTK_RESPONSE_OK) {
3943 TnyAccount *account = NULL;
3944 DeleteFolderInfo *info = NULL;
3945 info = g_new0(DeleteFolderInfo, 1);
3946 info->folder = g_object_ref (folder);
3947 info->move_to_trash = move_to_trash;
3949 account = tny_folder_get_account (TNY_FOLDER (folder));
3950 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3952 TNY_FOLDER_STORE (account),
3953 on_delete_folder_cb, info);
3954 g_object_unref (account);
3955 g_object_unref (folder);
3963 modest_ui_actions_on_delete_folder (GtkAction *action,
3964 ModestWindow *window)
3966 modest_ui_actions_on_edit_mode_delete_folder (window);
3970 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3972 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3974 return delete_folder (window, FALSE);
3978 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3980 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3982 delete_folder (MODEST_WINDOW (main_window), TRUE);
3986 typedef struct _PasswordDialogFields {
3987 GtkWidget *username;
3988 GtkWidget *password;
3990 } PasswordDialogFields;
3993 password_dialog_check_field (GtkEditable *editable,
3994 PasswordDialogFields *fields)
3997 gboolean any_value_empty = FALSE;
3999 #ifdef MODEST_TOOLKIT_HILDON2
4000 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4002 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4004 if ((value == NULL) || value[0] == '\0') {
4005 any_value_empty = TRUE;
4007 #ifdef MODEST_TOOLKIT_HILDON2
4008 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4010 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4012 if ((value == NULL) || value[0] == '\0') {
4013 any_value_empty = TRUE;
4015 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4019 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4020 const gchar* server_account_name,
4025 ModestMainWindow *main_window)
4027 g_return_if_fail(server_account_name);
4028 gboolean completed = FALSE;
4029 PasswordDialogFields *fields = NULL;
4031 /* Initalize output parameters: */
4038 #ifndef MODEST_TOOLKIT_GTK
4039 /* Maemo uses a different (awkward) button order,
4040 * It should probably just use gtk_alternative_dialog_button_order ().
4042 #ifdef MODEST_TOOLKIT_HILDON2
4044 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4047 _HL("wdgt_bd_done"),
4048 GTK_RESPONSE_ACCEPT,
4050 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4051 HILDON_MARGIN_DOUBLE);
4054 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4057 _("mcen_bd_dialog_ok"),
4058 GTK_RESPONSE_ACCEPT,
4059 _("mcen_bd_dialog_cancel"),
4060 GTK_RESPONSE_REJECT,
4062 #endif /* MODEST_TOOLKIT_HILDON2 */
4065 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4069 GTK_RESPONSE_REJECT,
4071 GTK_RESPONSE_ACCEPT,
4073 #endif /* MODEST_TOOLKIT_GTK */
4075 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4077 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4078 modest_runtime_get_account_mgr(), server_account_name);
4079 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4080 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4083 gtk_widget_destroy (dialog);
4087 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4088 GtkWidget *label = gtk_label_new (txt);
4089 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4091 g_free (server_name);
4092 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4097 gchar *initial_username = modest_account_mgr_get_server_account_username (
4098 modest_runtime_get_account_mgr(), server_account_name);
4100 #ifdef MODEST_TOOLKIT_HILDON2
4101 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4102 if (initial_username)
4103 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4105 GtkWidget *entry_username = gtk_entry_new ();
4106 if (initial_username)
4107 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4109 /* Dim this if a connection has ever succeeded with this username,
4110 * as per the UI spec: */
4111 /* const gboolean username_known = */
4112 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4113 /* modest_runtime_get_account_mgr(), server_account_name); */
4114 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4116 /* We drop the username sensitive code and disallow changing it here
4117 * as tinymail does not support really changing the username in the callback
4119 gtk_widget_set_sensitive (entry_username, FALSE);
4121 #ifndef MODEST_TOOLKIT_GTK
4122 /* Auto-capitalization is the default, so let's turn it off: */
4123 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4125 /* Create a size group to be used by all captions.
4126 * Note that HildonCaption does not create a default size group if we do not specify one.
4127 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4128 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4130 #ifdef MODEST_TOOLKIT_HILDON2
4131 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4132 _("mail_fi_username"), FALSE,
4135 GtkWidget *caption = hildon_caption_new (sizegroup,
4136 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4138 gtk_widget_show (entry_username);
4139 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4140 FALSE, FALSE, MODEST_MARGIN_HALF);
4141 gtk_widget_show (caption);
4143 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4145 #endif /* !MODEST_TOOLKIT_GTK */
4148 #ifdef MODEST_TOOLKIT_HILDON2
4149 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4151 GtkWidget *entry_password = gtk_entry_new ();
4153 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4154 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4156 #ifndef MODEST_TOOLKIT_GTK
4157 /* Auto-capitalization is the default, so let's turn it off: */
4158 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4159 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4161 #ifdef MODEST_TOOLKIT_HILDON2
4162 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4163 _("mail_fi_password"), FALSE,
4166 caption = hildon_caption_new (sizegroup,
4167 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4169 gtk_widget_show (entry_password);
4170 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4171 FALSE, FALSE, MODEST_MARGIN_HALF);
4172 gtk_widget_show (caption);
4173 g_object_unref (sizegroup);
4175 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4177 #endif /* !MODEST_TOOLKIT_GTK */
4179 if (initial_username != NULL)
4180 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4182 /* This is not in the Maemo UI spec:
4183 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4184 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4188 fields = g_slice_new0 (PasswordDialogFields);
4189 fields->username = entry_username;
4190 fields->password = entry_password;
4191 fields->dialog = dialog;
4193 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4194 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4195 password_dialog_check_field (NULL, fields);
4197 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4199 while (!completed) {
4201 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4203 #ifdef MODEST_TOOLKIT_HILDON2
4204 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4206 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4209 /* Note that an empty field becomes the "" string */
4210 if (*username && strlen (*username) > 0) {
4211 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4212 server_account_name,
4216 const gboolean username_was_changed =
4217 (strcmp (*username, initial_username) != 0);
4218 if (username_was_changed) {
4219 g_warning ("%s: tinymail does not yet support changing the "
4220 "username in the get_password() callback.\n", __FUNCTION__);
4226 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4227 _("mcen_ib_username_pw_incorrect"));
4233 #ifdef MODEST_TOOLKIT_HILDON2
4234 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4236 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4239 /* We do not save the password in the configuration,
4240 * because this function is only called for passwords that should
4241 * not be remembered:
4242 modest_server_account_set_password (
4243 modest_runtime_get_account_mgr(), server_account_name,
4250 #ifndef MODEST_TOOLKIT_HILDON2
4251 /* Set parent to NULL or the banner will disappear with its parent dialog */
4252 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4264 /* This is not in the Maemo UI spec:
4265 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4271 g_free (initial_username);
4272 gtk_widget_destroy (dialog);
4273 g_slice_free (PasswordDialogFields, fields);
4275 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4279 modest_ui_actions_on_cut (GtkAction *action,
4280 ModestWindow *window)
4282 GtkWidget *focused_widget;
4283 GtkClipboard *clipboard;
4285 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4286 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4287 if (GTK_IS_EDITABLE (focused_widget)) {
4288 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4289 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4290 gtk_clipboard_store (clipboard);
4291 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4292 GtkTextBuffer *buffer;
4294 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4295 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4296 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4297 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4298 gtk_clipboard_store (clipboard);
4300 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4301 TnyList *header_list = modest_header_view_get_selected_headers (
4302 MODEST_HEADER_VIEW (focused_widget));
4303 gboolean continue_download = FALSE;
4304 gint num_of_unc_msgs;
4306 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4308 if (num_of_unc_msgs) {
4309 TnyAccount *account = get_account_from_header_list (header_list);
4311 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4312 g_object_unref (account);
4316 if (num_of_unc_msgs == 0 || continue_download) {
4317 /* modest_platform_information_banner (
4318 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4319 modest_header_view_cut_selection (
4320 MODEST_HEADER_VIEW (focused_widget));
4323 g_object_unref (header_list);
4324 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4325 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4330 modest_ui_actions_on_copy (GtkAction *action,
4331 ModestWindow *window)
4333 GtkClipboard *clipboard;
4334 GtkWidget *focused_widget;
4335 gboolean copied = TRUE;
4337 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4338 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4340 if (GTK_IS_LABEL (focused_widget)) {
4342 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4343 gtk_clipboard_set_text (clipboard, selection, -1);
4345 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4346 gtk_clipboard_store (clipboard);
4347 } else if (GTK_IS_EDITABLE (focused_widget)) {
4348 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4349 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4350 gtk_clipboard_store (clipboard);
4351 } else if (GTK_IS_HTML (focused_widget)) {
4354 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4355 if ((sel == NULL) || (sel[0] == '\0')) {
4358 gtk_html_copy (GTK_HTML (focused_widget));
4359 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4360 gtk_clipboard_store (clipboard);
4362 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4363 GtkTextBuffer *buffer;
4364 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4365 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4366 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4367 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4368 gtk_clipboard_store (clipboard);
4370 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4371 TnyList *header_list = modest_header_view_get_selected_headers (
4372 MODEST_HEADER_VIEW (focused_widget));
4373 gboolean continue_download = FALSE;
4374 gint num_of_unc_msgs;
4376 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4378 if (num_of_unc_msgs) {
4379 TnyAccount *account = get_account_from_header_list (header_list);
4381 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4382 g_object_unref (account);
4386 if (num_of_unc_msgs == 0 || continue_download) {
4387 modest_platform_information_banner (
4388 NULL, NULL, _CS("mcen_ib_getting_items"));
4389 modest_header_view_copy_selection (
4390 MODEST_HEADER_VIEW (focused_widget));
4394 g_object_unref (header_list);
4396 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4397 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4400 /* Show information banner if there was a copy to clipboard */
4402 modest_platform_information_banner (
4403 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4407 modest_ui_actions_on_undo (GtkAction *action,
4408 ModestWindow *window)
4410 ModestEmailClipboard *clipboard = NULL;
4412 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4413 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4414 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4415 /* Clear clipboard source */
4416 clipboard = modest_runtime_get_email_clipboard ();
4417 modest_email_clipboard_clear (clipboard);
4420 g_return_if_reached ();
4425 modest_ui_actions_on_redo (GtkAction *action,
4426 ModestWindow *window)
4428 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4429 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4432 g_return_if_reached ();
4438 destroy_information_note (ModestMailOperation *mail_op,
4441 /* destroy information note */
4442 gtk_widget_destroy (GTK_WIDGET(user_data));
4446 destroy_folder_information_note (ModestMailOperation *mail_op,
4447 TnyFolder *new_folder,
4450 /* destroy information note */
4451 gtk_widget_destroy (GTK_WIDGET(user_data));
4456 paste_as_attachment_free (gpointer data)
4458 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4460 if (helper->banner) {
4461 gtk_widget_destroy (helper->banner);
4462 g_object_unref (helper->banner);
4468 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4473 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4474 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4479 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4484 modest_ui_actions_on_paste (GtkAction *action,
4485 ModestWindow *window)
4487 GtkWidget *focused_widget = NULL;
4488 GtkWidget *inf_note = NULL;
4489 ModestMailOperation *mail_op = NULL;
4491 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4492 if (GTK_IS_EDITABLE (focused_widget)) {
4493 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4494 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4495 ModestEmailClipboard *e_clipboard = NULL;
4496 e_clipboard = modest_runtime_get_email_clipboard ();
4497 if (modest_email_clipboard_cleared (e_clipboard)) {
4498 GtkTextBuffer *buffer;
4499 GtkClipboard *clipboard;
4501 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4502 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4503 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4504 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4505 ModestMailOperation *mail_op;
4506 TnyFolder *src_folder = NULL;
4507 TnyList *data = NULL;
4509 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4510 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4511 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4512 _CS("ckct_nw_pasting"));
4513 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4514 mail_op = modest_mail_operation_new (G_OBJECT (window));
4515 if (helper->banner != NULL) {
4516 g_object_ref (G_OBJECT (helper->banner));
4517 gtk_widget_show (GTK_WIDGET (helper->banner));
4521 modest_mail_operation_get_msgs_full (mail_op,
4523 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4525 paste_as_attachment_free);
4529 g_object_unref (data);
4531 g_object_unref (src_folder);
4534 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4535 ModestEmailClipboard *clipboard = NULL;
4536 TnyFolder *src_folder = NULL;
4537 TnyFolderStore *folder_store = NULL;
4538 TnyList *data = NULL;
4539 gboolean delete = FALSE;
4541 /* Check clipboard source */
4542 clipboard = modest_runtime_get_email_clipboard ();
4543 if (modest_email_clipboard_cleared (clipboard))
4546 /* Get elements to paste */
4547 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4549 /* Create a new mail operation */
4550 mail_op = modest_mail_operation_new (G_OBJECT(window));
4552 /* Get destination folder */
4553 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4555 /* transfer messages */
4559 /* Ask for user confirmation */
4561 modest_ui_actions_msgs_move_to_confirmation (window,
4562 TNY_FOLDER (folder_store),
4566 if (response == GTK_RESPONSE_OK) {
4567 /* Launch notification */
4568 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4569 _CS("ckct_nw_pasting"));
4570 if (inf_note != NULL) {
4571 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4572 gtk_widget_show (GTK_WIDGET(inf_note));
4575 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4576 modest_mail_operation_xfer_msgs (mail_op,
4578 TNY_FOLDER (folder_store),
4580 destroy_information_note,
4583 g_object_unref (mail_op);
4586 } else if (src_folder != NULL) {
4587 /* Launch notification */
4588 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4589 _CS("ckct_nw_pasting"));
4590 if (inf_note != NULL) {
4591 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4592 gtk_widget_show (GTK_WIDGET(inf_note));
4595 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4596 modest_mail_operation_xfer_folder (mail_op,
4600 destroy_folder_information_note,
4606 g_object_unref (data);
4607 if (src_folder != NULL)
4608 g_object_unref (src_folder);
4609 if (folder_store != NULL)
4610 g_object_unref (folder_store);
4616 modest_ui_actions_on_select_all (GtkAction *action,
4617 ModestWindow *window)
4619 GtkWidget *focused_widget;
4621 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4622 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4623 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4624 } else if (GTK_IS_LABEL (focused_widget)) {
4625 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4626 } else if (GTK_IS_EDITABLE (focused_widget)) {
4627 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4628 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4629 GtkTextBuffer *buffer;
4630 GtkTextIter start, end;
4632 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4633 gtk_text_buffer_get_start_iter (buffer, &start);
4634 gtk_text_buffer_get_end_iter (buffer, &end);
4635 gtk_text_buffer_select_range (buffer, &start, &end);
4636 } else if (GTK_IS_HTML (focused_widget)) {
4637 gtk_html_select_all (GTK_HTML (focused_widget));
4638 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4639 GtkWidget *header_view = focused_widget;
4640 GtkTreeSelection *selection = NULL;
4642 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4643 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4644 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4647 /* Disable window dimming management */
4648 modest_window_disable_dimming (MODEST_WINDOW(window));
4650 /* Select all messages */
4651 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4652 gtk_tree_selection_select_all (selection);
4654 /* Set focuse on header view */
4655 gtk_widget_grab_focus (header_view);
4657 /* Enable window dimming management */
4658 modest_window_enable_dimming (MODEST_WINDOW(window));
4659 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4660 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4666 modest_ui_actions_on_mark_as_read (GtkAction *action,
4667 ModestWindow *window)
4669 g_return_if_fail (MODEST_IS_WINDOW(window));
4671 /* Mark each header as read */
4672 do_headers_action (window, headers_action_mark_as_read, NULL);
4676 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4677 ModestWindow *window)
4679 g_return_if_fail (MODEST_IS_WINDOW(window));
4681 /* Mark each header as read */
4682 do_headers_action (window, headers_action_mark_as_unread, NULL);
4686 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4687 GtkRadioAction *selected,
4688 ModestWindow *window)
4692 value = gtk_radio_action_get_current_value (selected);
4693 if (MODEST_IS_WINDOW (window)) {
4694 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4699 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4700 GtkRadioAction *selected,
4701 ModestWindow *window)
4703 TnyHeaderFlags flags;
4704 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4706 flags = gtk_radio_action_get_current_value (selected);
4707 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4711 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4712 GtkRadioAction *selected,
4713 ModestWindow *window)
4717 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4719 file_format = gtk_radio_action_get_current_value (selected);
4720 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4725 modest_ui_actions_on_zoom_plus (GtkAction *action,
4726 ModestWindow *window)
4728 g_return_if_fail (MODEST_IS_WINDOW (window));
4730 modest_window_zoom_plus (MODEST_WINDOW (window));
4734 modest_ui_actions_on_zoom_minus (GtkAction *action,
4735 ModestWindow *window)
4737 g_return_if_fail (MODEST_IS_WINDOW (window));
4739 modest_window_zoom_minus (MODEST_WINDOW (window));
4743 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4744 ModestWindow *window)
4746 ModestWindowMgr *mgr;
4747 gboolean fullscreen, active;
4748 g_return_if_fail (MODEST_IS_WINDOW (window));
4750 mgr = modest_runtime_get_window_mgr ();
4752 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4753 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4755 if (active != fullscreen) {
4756 modest_window_mgr_set_fullscreen_mode (mgr, active);
4757 #ifndef MODEST_TOOLKIT_HILDON2
4758 gtk_window_present (GTK_WINDOW (window));
4764 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4765 ModestWindow *window)
4767 ModestWindowMgr *mgr;
4768 gboolean fullscreen;
4770 g_return_if_fail (MODEST_IS_WINDOW (window));
4772 mgr = modest_runtime_get_window_mgr ();
4773 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4774 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4776 #ifndef MODEST_TOOLKIT_HILDON2
4777 gtk_window_present (GTK_WINDOW (window));
4782 * Used by modest_ui_actions_on_details to call do_headers_action
4785 headers_action_show_details (TnyHeader *header,
4786 ModestWindow *window,
4790 gboolean async_retrieval;
4793 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4794 async_retrieval = TRUE;
4795 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4797 async_retrieval = FALSE;
4799 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4801 g_object_unref (msg);
4805 * Show the header details in a ModestDetailsDialog widget
4808 modest_ui_actions_on_details (GtkAction *action,
4811 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4815 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4819 header = tny_msg_get_header (msg);
4821 headers_action_show_details (header, win, NULL);
4822 g_object_unref (header);
4824 g_object_unref (msg);
4826 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4827 GtkWidget *folder_view, *header_view;
4829 /* Check which widget has the focus */
4830 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4831 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4832 if (gtk_widget_is_focus (folder_view)) {
4833 TnyFolderStore *folder_store
4834 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4835 if (!folder_store) {
4836 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4839 /* Show only when it's a folder */
4840 /* This function should not be called for account items,
4841 * because we dim the menu item for them. */
4842 if (TNY_IS_FOLDER (folder_store)) {
4843 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4844 TNY_FOLDER (folder_store));
4847 g_object_unref (folder_store);
4850 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4851 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4852 /* Show details of each header */
4853 do_headers_action (win, headers_action_show_details, header_view);
4855 #ifdef MODEST_TOOLKIT_HILDON2
4856 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4858 GtkWidget *header_view;
4860 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4861 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4863 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4865 g_object_unref (folder);
4872 modest_ui_actions_on_limit_error (GtkAction *action,
4875 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4877 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4882 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4883 ModestMsgEditWindow *window)
4885 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4887 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4891 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4892 ModestMsgEditWindow *window)
4894 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4896 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4900 modest_ui_actions_toggle_folders_view (GtkAction *action,
4901 ModestMainWindow *main_window)
4903 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4905 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4906 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4908 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4912 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4913 ModestWindow *window)
4915 gboolean active, fullscreen = FALSE;
4916 ModestWindowMgr *mgr;
4918 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4920 /* Check if we want to toggle the toolbar view in fullscreen
4922 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4923 "ViewShowToolbarFullScreen")) {
4927 /* Toggle toolbar */
4928 mgr = modest_runtime_get_window_mgr ();
4929 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4933 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4934 ModestMsgEditWindow *window)
4936 modest_msg_edit_window_select_font (window);
4941 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4942 const gchar *display_name,
4945 /* don't update the display name if it was already set;
4946 * updating the display name apparently is expensive */
4947 const gchar* old_name = gtk_window_get_title (window);
4949 if (display_name == NULL)
4952 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4953 return; /* don't do anything */
4955 /* This is usually used to change the title of the main window, which
4956 * is the one that holds the folder view. Note that this change can
4957 * happen even when the widget doesn't have the focus. */
4958 gtk_window_set_title (window, display_name);
4963 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4965 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4966 modest_msg_edit_window_select_contacts (window);
4970 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4972 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4973 modest_msg_edit_window_check_names (window, FALSE);
4976 #ifndef MODEST_TOOLKIT_HILDON2
4978 * This function is used to track changes in the selection of the
4979 * folder view that is inside the "move to" dialog to enable/disable
4980 * the OK button because we do not want the user to select a disallowed
4981 * destination for a folder.
4982 * The user also not desired to be able to use NEW button on items where
4983 * folder creation is not possibel.
4986 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4987 TnyFolderStore *folder_store,
4991 GtkWidget *dialog = NULL;
4992 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4993 gboolean moving_folder = FALSE;
4994 gboolean is_local_account = TRUE;
4995 GtkWidget *folder_view = NULL;
4996 ModestTnyFolderRules rules;
4998 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5003 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5007 /* check if folder_store is an remote account */
5008 if (TNY_IS_ACCOUNT (folder_store)) {
5009 TnyAccount *local_account = NULL;
5010 TnyAccount *mmc_account = NULL;
5011 ModestTnyAccountStore *account_store = NULL;
5013 account_store = modest_runtime_get_account_store ();
5014 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5015 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5017 if ((gpointer) local_account != (gpointer) folder_store &&
5018 (gpointer) mmc_account != (gpointer) folder_store) {
5019 ModestProtocolType proto;
5020 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5021 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5022 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5024 is_local_account = FALSE;
5025 /* New button should be dimmed on remote
5027 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5029 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5031 g_object_unref (local_account);
5033 /* It could not exist */
5035 g_object_unref (mmc_account);
5038 /* Check the target folder rules */
5039 if (TNY_IS_FOLDER (folder_store)) {
5040 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5041 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5042 ok_sensitive = FALSE;
5043 new_sensitive = FALSE;
5048 /* Check if we're moving a folder */
5049 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5050 /* Get the widgets */
5051 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5052 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5053 if (gtk_widget_is_focus (folder_view))
5054 moving_folder = TRUE;
5057 if (moving_folder) {
5058 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5060 /* Get the folder to move */
5061 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5063 /* Check that we're not moving to the same folder */
5064 if (TNY_IS_FOLDER (moved_folder)) {
5065 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5066 if (parent == folder_store)
5067 ok_sensitive = FALSE;
5068 g_object_unref (parent);
5071 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5072 /* Do not allow to move to an account unless it's the
5073 local folders account */
5074 if (!is_local_account)
5075 ok_sensitive = FALSE;
5078 if (ok_sensitive && (moved_folder == folder_store)) {
5079 /* Do not allow to move to itself */
5080 ok_sensitive = FALSE;
5082 g_object_unref (moved_folder);
5084 TnyFolder *src_folder = NULL;
5086 /* Moving a message */
5087 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5089 TnyHeader *header = NULL;
5090 header = modest_msg_view_window_get_header
5091 (MODEST_MSG_VIEW_WINDOW (user_data));
5092 if (!TNY_IS_HEADER(header))
5093 g_warning ("%s: could not get source header", __FUNCTION__);
5095 src_folder = tny_header_get_folder (header);
5098 g_object_unref (header);
5101 TNY_FOLDER (modest_folder_view_get_selected
5102 (MODEST_FOLDER_VIEW (folder_view)));
5105 if (TNY_IS_FOLDER(src_folder)) {
5106 /* Do not allow to move the msg to the same folder */
5107 /* Do not allow to move the msg to an account */
5108 if ((gpointer) src_folder == (gpointer) folder_store ||
5109 TNY_IS_ACCOUNT (folder_store))
5110 ok_sensitive = FALSE;
5111 g_object_unref (src_folder);
5113 g_warning ("%s: could not get source folder", __FUNCTION__);
5117 /* Set sensitivity of the OK and NEW button */
5118 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5119 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5124 on_move_to_dialog_response (GtkDialog *dialog,
5128 GtkWidget *parent_win;
5129 MoveToInfo *helper = NULL;
5130 ModestFolderView *folder_view;
5131 gboolean unset_edit_mode = FALSE;
5133 helper = (MoveToInfo *) user_data;
5135 parent_win = (GtkWidget *) helper->win;
5136 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5137 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5139 TnyFolderStore *dst_folder;
5140 TnyFolderStore *selected;
5142 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5143 selected = modest_folder_view_get_selected (folder_view);
5144 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5145 g_object_unref (selected);
5147 case GTK_RESPONSE_NONE:
5148 case GTK_RESPONSE_CANCEL:
5149 case GTK_RESPONSE_DELETE_EVENT:
5151 case GTK_RESPONSE_OK:
5152 dst_folder = modest_folder_view_get_selected (folder_view);
5154 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5155 /* Clean list to move used for filtering */
5156 modest_folder_view_set_list_to_move (folder_view, NULL);
5158 modest_ui_actions_on_main_window_move_to (NULL,
5159 GTK_WIDGET (folder_view),
5161 MODEST_MAIN_WINDOW (parent_win));
5162 #ifdef MODEST_TOOLKIT_HILDON2
5163 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5164 /* Clean list to move used for filtering */
5165 modest_folder_view_set_list_to_move (folder_view, NULL);
5167 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5170 GTK_WINDOW (parent_win));
5173 /* if the user selected a root folder
5174 (account) then do not perform any action */
5175 if (TNY_IS_ACCOUNT (dst_folder)) {
5176 g_signal_stop_emission_by_name (dialog, "response");
5180 /* Clean list to move used for filtering */
5181 modest_folder_view_set_list_to_move (folder_view, NULL);
5183 /* Moving from headers window in edit mode */
5184 modest_ui_actions_on_window_move_to (NULL, helper->list,
5186 MODEST_WINDOW (parent_win));
5190 g_object_unref (dst_folder);
5192 unset_edit_mode = TRUE;
5195 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5198 /* Free the helper and exit */
5200 g_object_unref (helper->list);
5201 if (unset_edit_mode) {
5202 #ifdef MODEST_TOOLKIT_HILDON2
5203 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5206 g_slice_free (MoveToInfo, helper);
5207 gtk_widget_destroy (GTK_WIDGET (dialog));
5211 create_move_to_dialog (GtkWindow *win,
5212 GtkWidget *folder_view,
5213 TnyList *list_to_move)
5215 GtkWidget *dialog, *tree_view = NULL;
5217 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5219 #ifndef MODEST_TOOLKIT_HILDON2
5220 /* Track changes in the selection to
5221 * disable the OK button whenever "Move to" is not possible
5222 * disbale NEW button whenever New is not possible */
5223 g_signal_connect (tree_view,
5224 "folder_selection_changed",
5225 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5229 /* It could happen that we're trying to move a message from a
5230 window (msg window for example) after the main window was
5231 closed, so we can not just get the model of the folder
5233 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5234 const gchar *visible_id = NULL;
5236 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5237 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5238 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5239 MODEST_FOLDER_VIEW(tree_view));
5242 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5244 /* Show the same account than the one that is shown in the main window */
5245 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5248 const gchar *active_account_name = NULL;
5249 ModestAccountMgr *mgr = NULL;
5250 ModestAccountSettings *settings = NULL;
5251 ModestServerAccountSettings *store_settings = NULL;
5253 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5254 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5255 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5256 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5258 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5259 mgr = modest_runtime_get_account_mgr ();
5260 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5263 const gchar *store_account_name;
5264 store_settings = modest_account_settings_get_store_settings (settings);
5265 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5267 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5268 store_account_name);
5269 g_object_unref (store_settings);
5270 g_object_unref (settings);
5274 /* we keep a pointer to the embedded folder view, so we can
5275 * retrieve it with get_folder_view_from_move_to_dialog (see
5276 * above) later (needed for focus handling)
5278 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5280 /* Hide special folders */
5281 #ifndef MODEST_TOOLKIT_HILDON2
5282 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5285 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5286 #ifndef MODEST_TOOLKIT_HILDON2
5287 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5290 gtk_widget_show (GTK_WIDGET (tree_view));
5296 * Shows a confirmation dialog to the user when we're moving messages
5297 * from a remote server to the local storage. Returns the dialog
5298 * response. If it's other kind of movement then it always returns
5301 * This one is used by the next functions:
5302 * modest_ui_actions_on_paste - commented out
5303 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5306 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5307 TnyFolder *dest_folder,
5311 gint response = GTK_RESPONSE_OK;
5312 TnyAccount *account = NULL;
5313 TnyFolder *src_folder = NULL;
5314 TnyIterator *iter = NULL;
5315 TnyHeader *header = NULL;
5317 /* return with OK if the destination is a remote folder */
5318 if (modest_tny_folder_is_remote_folder (dest_folder))
5319 return GTK_RESPONSE_OK;
5321 /* Get source folder */
5322 iter = tny_list_create_iterator (headers);
5323 header = TNY_HEADER (tny_iterator_get_current (iter));
5325 src_folder = tny_header_get_folder (header);
5326 g_object_unref (header);
5328 g_object_unref (iter);
5330 /* if no src_folder, message may be an attahcment */
5331 if (src_folder == NULL)
5332 return GTK_RESPONSE_CANCEL;
5334 /* If the source is a local or MMC folder */
5335 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5336 g_object_unref (src_folder);
5337 return GTK_RESPONSE_OK;
5340 /* Get the account */
5341 account = tny_folder_get_account (src_folder);
5343 /* now if offline we ask the user */
5344 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5345 response = GTK_RESPONSE_OK;
5347 response = GTK_RESPONSE_CANCEL;
5350 g_object_unref (src_folder);
5351 g_object_unref (account);
5357 move_to_helper_destroyer (gpointer user_data)
5359 MoveToHelper *helper = (MoveToHelper *) user_data;
5361 /* Close the "Pasting" information banner */
5362 if (helper->banner) {
5363 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5364 g_object_unref (helper->banner);
5366 if (gtk_tree_row_reference_valid (helper->reference)) {
5367 gtk_tree_row_reference_free (helper->reference);
5368 helper->reference = NULL;
5374 move_to_cb (ModestMailOperation *mail_op,
5377 MoveToHelper *helper = (MoveToHelper *) user_data;
5378 GObject *object = modest_mail_operation_get_source (mail_op);
5380 /* Note that the operation could have failed, in that case do
5382 if (modest_mail_operation_get_status (mail_op) !=
5383 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5386 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5387 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5389 if (!modest_msg_view_window_select_next_message (self) &&
5390 !modest_msg_view_window_select_previous_message (self)) {
5391 /* No more messages to view, so close this window */
5392 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5394 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5395 gtk_tree_row_reference_valid (helper->reference)) {
5396 GtkWidget *header_view;
5398 GtkTreeSelection *sel;
5400 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5401 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5402 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5403 path = gtk_tree_row_reference_get_path (helper->reference);
5404 /* We need to unselect the previous one
5405 because we could be copying instead of
5407 gtk_tree_selection_unselect_all (sel);
5408 gtk_tree_selection_select_path (sel, path);
5409 gtk_tree_path_free (path);
5411 g_object_unref (object);
5414 /* Destroy the helper */
5415 move_to_helper_destroyer (helper);
5419 folder_move_to_cb (ModestMailOperation *mail_op,
5420 TnyFolder *new_folder,
5423 GtkWidget *folder_view;
5426 object = modest_mail_operation_get_source (mail_op);
5427 if (MODEST_IS_MAIN_WINDOW (object)) {
5428 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5429 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5430 g_object_ref (folder_view);
5431 g_object_unref (object);
5432 move_to_cb (mail_op, user_data);
5433 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5434 g_object_unref (folder_view);
5436 move_to_cb (mail_op, user_data);
5441 msgs_move_to_cb (ModestMailOperation *mail_op,
5444 move_to_cb (mail_op, user_data);
5448 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5451 GObject *win = NULL;
5452 const GError *error;
5453 TnyAccount *account = NULL;
5455 #ifndef MODEST_TOOLKIT_HILDON2
5456 ModestWindow *main_window = NULL;
5458 /* Disable next automatic folder selection */
5459 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5460 FALSE); /* don't create */
5462 /* Show notification dialog only if the main window exists */
5464 GtkWidget *folder_view = NULL;
5466 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5467 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5468 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5470 if (user_data && TNY_IS_FOLDER (user_data)) {
5471 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5472 TNY_FOLDER (user_data), FALSE);
5476 win = modest_mail_operation_get_source (mail_op);
5477 error = modest_mail_operation_get_error (mail_op);
5479 if (TNY_IS_FOLDER (user_data))
5480 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5481 else if (TNY_IS_ACCOUNT (user_data))
5482 account = g_object_ref (user_data);
5484 /* If it's not a disk full error then show a generic error */
5485 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5486 (GtkWidget *) win, (GError *) error,
5488 modest_platform_run_information_dialog ((GtkWindow *) win,
5489 _("mail_in_ui_folder_move_target_error"),
5492 g_object_unref (account);
5494 g_object_unref (win);
5498 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5507 gint pending_purges = 0;
5508 gboolean some_purged = FALSE;
5509 ModestWindow *win = MODEST_WINDOW (user_data);
5510 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5512 /* If there was any error */
5513 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5514 modest_window_mgr_unregister_header (mgr, header);
5518 /* Once the message has been retrieved for purging, we check if
5519 * it's all ok for purging */
5521 parts = tny_simple_list_new ();
5522 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5523 iter = tny_list_create_iterator (parts);
5525 while (!tny_iterator_is_done (iter)) {
5527 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5528 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5529 if (tny_mime_part_is_purged (part))
5536 g_object_unref (part);
5538 tny_iterator_next (iter);
5540 g_object_unref (iter);
5543 if (pending_purges>0) {
5545 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5547 if (response == GTK_RESPONSE_OK) {
5550 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5551 iter = tny_list_create_iterator (parts);
5552 while (!tny_iterator_is_done (iter)) {
5555 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5556 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5557 tny_mime_part_set_purged (part);
5560 g_object_unref (part);
5562 tny_iterator_next (iter);
5564 g_object_unref (iter);
5566 tny_msg_rewrite_cache (msg);
5568 gtk_widget_destroy (info);
5572 modest_window_mgr_unregister_header (mgr, header);
5574 g_object_unref (parts);
5578 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5579 ModestMainWindow *win)
5581 GtkWidget *header_view;
5582 TnyList *header_list;
5584 TnyHeaderFlags flags;
5585 ModestWindow *msg_view_window = NULL;
5588 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5590 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5591 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5593 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5595 g_warning ("%s: no header selected", __FUNCTION__);
5599 if (tny_list_get_length (header_list) == 1) {
5600 TnyIterator *iter = tny_list_create_iterator (header_list);
5601 header = TNY_HEADER (tny_iterator_get_current (iter));
5602 g_object_unref (iter);
5606 if (!header || !TNY_IS_HEADER(header)) {
5607 g_warning ("%s: header is not valid", __FUNCTION__);
5611 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5612 header, &msg_view_window);
5613 flags = tny_header_get_flags (header);
5614 if (!(flags & TNY_HEADER_FLAG_CACHED))
5617 if (msg_view_window != NULL)
5618 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5620 /* do nothing; uid was registered before, so window is probably on it's way */
5621 g_debug ("header %p has already been registered", header);
5624 ModestMailOperation *mail_op = NULL;
5625 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5626 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5627 modest_ui_actions_disk_operations_error_handler,
5629 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5630 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5632 g_object_unref (mail_op);
5635 g_object_unref (header);
5637 g_object_unref (header_list);
5641 * Checks if we need a connection to do the transfer and if the user
5642 * wants to connect to complete it
5645 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5646 TnyFolderStore *src_folder,
5648 TnyFolder *dst_folder,
5649 gboolean delete_originals,
5650 gboolean *need_connection,
5653 TnyAccount *src_account;
5654 gint uncached_msgs = 0;
5656 /* We don't need any further check if
5658 * 1- the source folder is local OR
5659 * 2- the device is already online
5661 if (!modest_tny_folder_store_is_remote (src_folder) ||
5662 tny_device_is_online (modest_runtime_get_device())) {
5663 *need_connection = FALSE;
5668 /* We must ask for a connection when
5670 * - the message(s) is not already cached OR
5671 * - the message(s) is cached but the leave_on_server setting
5672 * is FALSE (because we need to sync the source folder to
5673 * delete the message from the server (for IMAP we could do it
5674 * offline, it'll take place the next time we get a
5677 uncached_msgs = header_list_count_uncached_msgs (headers);
5678 src_account = get_account_from_folder_store (src_folder);
5679 if (uncached_msgs > 0) {
5683 *need_connection = TRUE;
5684 num_headers = tny_list_get_length (headers);
5685 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5687 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5688 GTK_RESPONSE_CANCEL) {
5694 /* The transfer is possible and the user wants to */
5697 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5698 const gchar *account_name;
5699 gboolean leave_on_server;
5701 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5702 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5705 if (leave_on_server == TRUE) {
5706 *need_connection = FALSE;
5708 *need_connection = TRUE;
5711 *need_connection = FALSE;
5716 g_object_unref (src_account);
5720 xfer_messages_error_handler (ModestMailOperation *mail_op,
5724 const GError *error;
5725 TnyAccount *account;
5727 win = modest_mail_operation_get_source (mail_op);
5728 error = modest_mail_operation_get_error (mail_op);
5730 /* We cannot get the account from the mail op as that is the
5731 source account and for checking memory full conditions we
5732 need the destination one */
5733 account = TNY_ACCOUNT (user_data);
5736 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5737 (GtkWidget *) win, (GError*) error,
5738 account, _KR("cerm_memory_card_full"))) {
5739 modest_platform_run_information_dialog ((GtkWindow *) win,
5740 _("mail_in_ui_folder_move_target_error"),
5744 g_object_unref (win);
5748 TnyFolderStore *dst_folder;
5753 * Utility function that transfer messages from both the main window
5754 * and the msg view window when using the "Move to" dialog
5757 xfer_messages_performer (gboolean canceled,
5759 GtkWindow *parent_window,
5760 TnyAccount *account,
5763 ModestWindow *win = MODEST_WINDOW (parent_window);
5764 TnyAccount *dst_account = NULL;
5765 gboolean dst_forbids_message_add = FALSE;
5766 XferMsgsHelper *helper;
5767 MoveToHelper *movehelper;
5768 ModestMailOperation *mail_op;
5770 helper = (XferMsgsHelper *) user_data;
5772 if (canceled || err) {
5773 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5774 (GtkWidget *) parent_window, err,
5776 /* Show the proper error message */
5777 modest_ui_actions_on_account_connection_error (parent_window, account);
5782 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5784 /* tinymail will return NULL for local folders it seems */
5785 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5786 modest_tny_account_get_protocol_type (dst_account),
5787 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5789 if (dst_forbids_message_add) {
5790 modest_platform_information_banner (GTK_WIDGET (win),
5792 ngettext("mail_in_ui_folder_move_target_error",
5793 "mail_in_ui_folder_move_targets_error",
5794 tny_list_get_length (helper->headers)));
5798 movehelper = g_new0 (MoveToHelper, 1);
5800 #ifndef MODEST_TOOLKIT_HILDON2
5801 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5802 _CS("ckct_nw_pasting"));
5803 if (movehelper->banner != NULL) {
5804 g_object_ref (movehelper->banner);
5805 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5809 if (MODEST_IS_MAIN_WINDOW (win)) {
5810 GtkWidget *header_view =
5811 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5812 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5813 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5816 /* Perform the mail operation */
5817 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5818 xfer_messages_error_handler,
5819 g_object_ref (dst_account),
5821 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5824 modest_mail_operation_xfer_msgs (mail_op,
5826 TNY_FOLDER (helper->dst_folder),
5831 g_object_unref (G_OBJECT (mail_op));
5834 g_object_unref (dst_account);
5835 g_object_unref (helper->dst_folder);
5836 g_object_unref (helper->headers);
5837 g_slice_free (XferMsgsHelper, helper);
5841 TnyFolder *src_folder;
5842 TnyFolderStore *dst_folder;
5843 gboolean delete_original;
5844 GtkWidget *folder_view;
5848 on_move_folder_cb (gboolean canceled,
5850 GtkWindow *parent_window,
5851 TnyAccount *account,
5854 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5855 GtkTreeSelection *sel;
5856 ModestMailOperation *mail_op = NULL;
5858 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5859 /* Note that the connection process can fail due to
5860 memory low conditions as it can not successfully
5861 store the summary */
5862 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5863 (GtkWidget*) parent_window, err,
5865 g_debug ("Error connecting when trying to move a folder");
5867 g_object_unref (G_OBJECT (info->src_folder));
5868 g_object_unref (G_OBJECT (info->dst_folder));
5873 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5874 #ifndef MODEST_TOOLKIT_HILDON2
5875 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5876 _CS("ckct_nw_pasting"));
5877 if (helper->banner != NULL) {
5878 g_object_ref (helper->banner);
5879 gtk_widget_show (GTK_WIDGET(helper->banner));
5882 /* Clean folder on header view before moving it */
5883 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5884 gtk_tree_selection_unselect_all (sel);
5886 /* Let gtk events run. We need that the folder
5887 view frees its reference to the source
5888 folder *before* issuing the mail operation
5889 so we need the signal handler of selection
5890 changed to happen before the mail
5892 while (gtk_events_pending ())
5893 gtk_main_iteration (); */
5896 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5897 modest_ui_actions_move_folder_error_handler,
5898 g_object_ref (info->dst_folder), g_object_unref);
5899 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5902 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5903 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5904 TNY_FOLDER (info->dst_folder), TRUE);
5906 modest_mail_operation_xfer_folder (mail_op,
5907 TNY_FOLDER (info->src_folder),
5909 info->delete_original,
5912 g_object_unref (G_OBJECT (info->src_folder));
5914 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5917 /* Unref mail operation */
5918 g_object_unref (G_OBJECT (mail_op));
5919 g_object_unref (G_OBJECT (info->dst_folder));
5924 get_account_from_folder_store (TnyFolderStore *folder_store)
5926 if (TNY_IS_ACCOUNT (folder_store))
5927 return g_object_ref (folder_store);
5929 return tny_folder_get_account (TNY_FOLDER (folder_store));
5933 * UI handler for the "Move to" action when invoked from the
5937 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5938 GtkWidget *folder_view,
5939 TnyFolderStore *dst_folder,
5940 ModestMainWindow *win)
5942 ModestHeaderView *header_view = NULL;
5943 TnyFolderStore *src_folder = NULL;
5945 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5947 /* Get the source folder */
5948 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5950 /* Get header view */
5951 header_view = (ModestHeaderView *)
5952 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5954 /* Get folder or messages to transfer */
5955 if (gtk_widget_is_focus (folder_view)) {
5956 gboolean do_xfer = TRUE;
5958 /* Allow only to transfer folders to the local root folder */
5959 if (TNY_IS_ACCOUNT (dst_folder) &&
5960 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5961 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5963 } else if (!TNY_IS_FOLDER (src_folder)) {
5964 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5969 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5970 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5972 info->src_folder = g_object_ref (src_folder);
5973 info->dst_folder = g_object_ref (dst_folder);
5974 info->delete_original = TRUE;
5975 info->folder_view = folder_view;
5977 connect_info->callback = on_move_folder_cb;
5978 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5979 connect_info->data = info;
5981 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5982 TNY_FOLDER_STORE (src_folder),
5985 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5988 headers = modest_header_view_get_selected_headers(header_view);
5990 /* Transfer the messages */
5991 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5992 headers, TNY_FOLDER (dst_folder));
5994 g_object_unref (headers);
5998 g_object_unref (src_folder);
6001 #ifdef MODEST_TOOLKIT_HILDON2
6003 * UI handler for the "Move to" action when invoked from the
6004 * ModestFolderWindow
6007 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6008 TnyFolderStore *dst_folder,
6012 TnyFolderStore *src_folder = NULL;
6013 TnyIterator *iterator;
6015 if (tny_list_get_length (selection) != 1)
6018 iterator = tny_list_create_iterator (selection);
6019 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6020 g_object_unref (iterator);
6023 gboolean do_xfer = TRUE;
6025 /* Allow only to transfer folders to the local root folder */
6026 if (TNY_IS_ACCOUNT (dst_folder) &&
6027 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6028 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6031 modest_platform_run_information_dialog (win,
6032 _("mail_in_ui_folder_move_target_error"),
6034 } else if (!TNY_IS_FOLDER (src_folder)) {
6035 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6040 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6041 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6043 info->src_folder = g_object_ref (src_folder);
6044 info->dst_folder = g_object_ref (dst_folder);
6045 info->delete_original = TRUE;
6046 info->folder_view = folder_view;
6048 connect_info->callback = on_move_folder_cb;
6049 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6050 connect_info->data = info;
6052 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6053 TNY_FOLDER_STORE (src_folder),
6058 g_object_unref (src_folder);
6064 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6065 TnyFolder *src_folder,
6067 TnyFolder *dst_folder)
6069 gboolean need_connection = TRUE;
6070 gboolean do_xfer = TRUE;
6071 XferMsgsHelper *helper;
6073 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6074 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6075 g_return_if_fail (TNY_IS_LIST (headers));
6077 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6078 headers, TNY_FOLDER (dst_folder),
6079 TRUE, &need_connection,
6082 /* If we don't want to transfer just return */
6086 /* Create the helper */
6087 helper = g_slice_new (XferMsgsHelper);
6088 helper->dst_folder = g_object_ref (dst_folder);
6089 helper->headers = g_object_ref (headers);
6091 if (need_connection) {
6092 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6093 connect_info->callback = xfer_messages_performer;
6094 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6095 connect_info->data = helper;
6097 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6098 TNY_FOLDER_STORE (src_folder),
6101 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6102 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6103 src_account, helper);
6104 g_object_unref (src_account);
6109 * UI handler for the "Move to" action when invoked from the
6110 * ModestMsgViewWindow
6113 modest_ui_actions_on_window_move_to (GtkAction *action,
6115 TnyFolderStore *dst_folder,
6118 TnyFolder *src_folder = NULL;
6120 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6123 TnyHeader *header = NULL;
6126 iter = tny_list_create_iterator (headers);
6127 header = (TnyHeader *) tny_iterator_get_current (iter);
6128 src_folder = tny_header_get_folder (header);
6130 /* Transfer the messages */
6131 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6133 TNY_FOLDER (dst_folder));
6136 g_object_unref (header);
6137 g_object_unref (iter);
6138 g_object_unref (src_folder);
6143 modest_ui_actions_on_move_to (GtkAction *action,
6146 modest_ui_actions_on_edit_mode_move_to (win);
6150 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6152 GtkWidget *dialog = NULL;
6153 MoveToInfo *helper = NULL;
6154 TnyList *list_to_move;
6156 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6158 #ifndef MODEST_TOOLKIT_HILDON2
6159 /* Get the main window if exists */
6160 ModestMainWindow *main_window;
6161 if (MODEST_IS_MAIN_WINDOW (win))
6162 main_window = MODEST_MAIN_WINDOW (win);
6165 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6166 FALSE)); /* don't create */
6169 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6174 if (tny_list_get_length (list_to_move) < 1) {
6175 g_object_unref (list_to_move);
6179 /* Create and run the dialog */
6180 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6181 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6182 GTK_WINDOW (dialog),
6186 helper = g_slice_new0 (MoveToInfo);
6187 helper->list = list_to_move;
6190 /* Listen to response signal */
6191 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6193 /* Show the dialog */
6194 gtk_widget_show (dialog);
6200 * Calls #HeadersFunc for each header already selected in the main
6201 * window or the message currently being shown in the msg view window
6204 do_headers_action (ModestWindow *win,
6208 TnyList *headers_list = NULL;
6209 TnyIterator *iter = NULL;
6210 TnyHeader *header = NULL;
6211 TnyFolder *folder = NULL;
6214 headers_list = get_selected_headers (win);
6218 /* Get the folder */
6219 iter = tny_list_create_iterator (headers_list);
6220 header = TNY_HEADER (tny_iterator_get_current (iter));
6222 folder = tny_header_get_folder (header);
6223 g_object_unref (header);
6226 /* Call the function for each header */
6227 while (!tny_iterator_is_done (iter)) {
6228 header = TNY_HEADER (tny_iterator_get_current (iter));
6229 func (header, win, user_data);
6230 g_object_unref (header);
6231 tny_iterator_next (iter);
6234 /* Trick: do a poke status in order to speed up the signaling
6237 tny_folder_poke_status (folder);
6238 g_object_unref (folder);
6242 g_object_unref (iter);
6243 g_object_unref (headers_list);
6247 modest_ui_actions_view_attachment (GtkAction *action,
6248 ModestWindow *window)
6250 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6251 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6253 /* not supported window for this action */
6254 g_return_if_reached ();
6259 modest_ui_actions_save_attachments (GtkAction *action,
6260 ModestWindow *window)
6262 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6264 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6267 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6269 /* not supported window for this action */
6270 g_return_if_reached ();
6275 modest_ui_actions_remove_attachments (GtkAction *action,
6276 ModestWindow *window)
6278 if (MODEST_IS_MAIN_WINDOW (window)) {
6279 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6280 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6281 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6283 /* not supported window for this action */
6284 g_return_if_reached ();
6289 modest_ui_actions_on_settings (GtkAction *action,
6294 dialog = modest_platform_get_global_settings_dialog ();
6295 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6296 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6297 gtk_widget_show_all (dialog);
6299 gtk_dialog_run (GTK_DIALOG (dialog));
6301 gtk_widget_destroy (dialog);
6305 modest_ui_actions_on_help (GtkAction *action,
6308 /* Help app is not available at all in fremantle */
6309 #ifndef MODEST_TOOLKIT_HILDON2
6310 const gchar *help_id;
6312 g_return_if_fail (win && GTK_IS_WINDOW(win));
6314 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6317 modest_platform_show_help (GTK_WINDOW (win), help_id);
6322 modest_ui_actions_on_csm_help (GtkAction *action,
6325 /* Help app is not available at all in fremantle */
6326 #ifndef MODEST_TOOLKIT_HILDON2
6328 const gchar* help_id = NULL;
6329 GtkWidget *folder_view;
6330 TnyFolderStore *folder_store;
6332 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6334 /* Get selected folder */
6335 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6336 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6337 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6339 /* Switch help_id */
6340 if (folder_store && TNY_IS_FOLDER (folder_store))
6341 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6344 g_object_unref (folder_store);
6347 modest_platform_show_help (GTK_WINDOW (win), help_id);
6349 modest_ui_actions_on_help (action, win);
6354 retrieve_contents_cb (ModestMailOperation *mail_op,
6361 /* We only need this callback to show an error in case of
6362 memory low condition */
6363 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6364 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6369 retrieve_msg_contents_performer (gboolean canceled,
6371 GtkWindow *parent_window,
6372 TnyAccount *account,
6375 ModestMailOperation *mail_op;
6376 TnyList *headers = TNY_LIST (user_data);
6378 if (err || canceled) {
6379 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6380 (GtkWidget *) parent_window, err,
6385 /* Create mail operation */
6386 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6387 modest_ui_actions_disk_operations_error_handler,
6389 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6390 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6393 g_object_unref (mail_op);
6395 g_object_unref (headers);
6396 g_object_unref (account);
6400 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6401 ModestWindow *window)
6403 TnyList *headers = NULL;
6404 TnyAccount *account = NULL;
6405 TnyIterator *iter = NULL;
6406 TnyHeader *header = NULL;
6407 TnyFolder *folder = NULL;
6410 headers = get_selected_headers (window);
6414 /* Pick the account */
6415 iter = tny_list_create_iterator (headers);
6416 header = TNY_HEADER (tny_iterator_get_current (iter));
6417 folder = tny_header_get_folder (header);
6418 account = tny_folder_get_account (folder);
6419 g_object_unref (folder);
6420 g_object_unref (header);
6421 g_object_unref (iter);
6423 /* Connect and perform the message retrieval */
6424 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6425 g_object_ref (account),
6426 retrieve_msg_contents_performer,
6427 g_object_ref (headers));
6430 g_object_unref (account);
6431 g_object_unref (headers);
6435 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6437 g_return_if_fail (MODEST_IS_WINDOW (window));
6440 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6444 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6446 g_return_if_fail (MODEST_IS_WINDOW (window));
6449 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6453 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6454 ModestWindow *window)
6456 g_return_if_fail (MODEST_IS_WINDOW (window));
6459 modest_ui_actions_check_menu_dimming_rules (window);
6463 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6464 ModestWindow *window)
6466 g_return_if_fail (MODEST_IS_WINDOW (window));
6469 modest_ui_actions_check_menu_dimming_rules (window);
6473 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6474 ModestWindow *window)
6476 g_return_if_fail (MODEST_IS_WINDOW (window));
6479 modest_ui_actions_check_menu_dimming_rules (window);
6483 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6484 ModestWindow *window)
6486 g_return_if_fail (MODEST_IS_WINDOW (window));
6489 modest_ui_actions_check_menu_dimming_rules (window);
6493 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6494 ModestWindow *window)
6496 g_return_if_fail (MODEST_IS_WINDOW (window));
6499 modest_ui_actions_check_menu_dimming_rules (window);
6503 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6504 ModestWindow *window)
6506 g_return_if_fail (MODEST_IS_WINDOW (window));
6509 modest_ui_actions_check_menu_dimming_rules (window);
6513 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6514 ModestWindow *window)
6516 g_return_if_fail (MODEST_IS_WINDOW (window));
6519 modest_ui_actions_check_menu_dimming_rules (window);
6523 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6524 ModestWindow *window)
6526 g_return_if_fail (MODEST_IS_WINDOW (window));
6529 modest_ui_actions_check_menu_dimming_rules (window);
6533 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6534 ModestWindow *window)
6536 g_return_if_fail (MODEST_IS_WINDOW (window));
6539 modest_ui_actions_check_menu_dimming_rules (window);
6543 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6545 g_return_if_fail (MODEST_IS_WINDOW (window));
6547 /* we check for low-mem; in that case, show a warning, and don't allow
6550 if (modest_platform_check_memory_low (window, TRUE))
6553 modest_platform_show_search_messages (GTK_WINDOW (window));
6557 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6559 g_return_if_fail (MODEST_IS_WINDOW (win));
6562 /* we check for low-mem; in that case, show a warning, and don't allow
6563 * for the addressbook
6565 if (modest_platform_check_memory_low (win, TRUE))
6569 modest_platform_show_addressbook (GTK_WINDOW (win));
6574 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6575 ModestWindow *window)
6578 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6580 if (GTK_IS_TOGGLE_ACTION (action))
6581 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6585 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6590 on_send_receive_finished (ModestMailOperation *mail_op,
6593 GtkWidget *header_view, *folder_view;
6594 TnyFolderStore *folder_store;
6595 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6597 /* Set send/receive operation finished */
6598 modest_main_window_notify_send_receive_completed (main_win);
6600 /* Don't refresh the current folder if there were any errors */
6601 if (modest_mail_operation_get_status (mail_op) !=
6602 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6605 /* Refresh the current folder if we're viewing a window. We do
6606 this because the user won't be able to see the new mails in
6607 the selected folder after a Send&Receive because it only
6608 performs a poke_status, i.e, only the number of read/unread
6609 messages is updated, but the new headers are not
6611 folder_view = modest_main_window_get_child_widget (main_win,
6612 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6616 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6618 /* Do not need to refresh INBOX again because the
6619 update_account does it always automatically */
6620 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6621 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6622 ModestMailOperation *refresh_op;
6624 header_view = modest_main_window_get_child_widget (main_win,
6625 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6627 /* We do not need to set the contents style
6628 because it hasn't changed. We also do not
6629 need to save the widget status. Just force
6631 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6632 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6633 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6634 folder_refreshed_cb, main_win);
6635 g_object_unref (refresh_op);
6639 g_object_unref (folder_store);
6644 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6650 const gchar* server_name = NULL;
6651 TnyTransportAccount *transport;
6652 gchar *message = NULL;
6653 ModestProtocol *protocol;
6655 /* Don't show anything if the user cancelled something or the
6656 * send receive request is not interactive. Authentication
6657 * errors are managed by the account store so no need to show
6658 * a dialog here again */
6659 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6660 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6661 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6665 /* Get the server name. Note that we could be using a
6666 connection specific transport account */
6667 transport = (TnyTransportAccount *)
6668 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6670 ModestTnyAccountStore *acc_store;
6671 const gchar *acc_name;
6672 TnyTransportAccount *conn_specific;
6674 acc_store = modest_runtime_get_account_store();
6675 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6676 conn_specific = (TnyTransportAccount *)
6677 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6678 if (conn_specific) {
6679 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6680 g_object_unref (conn_specific);
6682 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6684 g_object_unref (transport);
6688 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6689 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6690 tny_account_get_proto (TNY_ACCOUNT (transport)));
6692 g_warning ("%s: Account with no proto", __FUNCTION__);
6696 /* Show the appropriate message text for the GError: */
6697 switch (err->code) {
6698 case TNY_SERVICE_ERROR_CONNECT:
6699 message = modest_protocol_get_translation (protocol,
6700 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6703 case TNY_SERVICE_ERROR_SEND:
6704 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6706 case TNY_SERVICE_ERROR_UNAVAILABLE:
6707 message = modest_protocol_get_translation (protocol,
6708 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6712 g_warning ("%s: unexpected ERROR %d",
6713 __FUNCTION__, err->code);
6714 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6718 modest_platform_run_information_dialog (NULL, message, FALSE);
6723 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6728 ModestWindow *top_window = NULL;
6729 ModestWindowMgr *mgr = NULL;
6730 GtkWidget *header_view = NULL;
6731 TnyFolder *selected_folder = NULL;
6732 TnyFolderType folder_type;
6734 mgr = modest_runtime_get_window_mgr ();
6735 top_window = modest_window_mgr_get_current_top (mgr);
6740 #ifndef MODEST_TOOLKIT_HILDON2
6741 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6742 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6743 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6746 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6747 header_view = (GtkWidget *)
6748 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6752 /* Get selected folder */
6754 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6755 if (!selected_folder)
6758 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6759 #if GTK_CHECK_VERSION(2, 8, 0)
6760 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6761 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6762 GtkTreeViewColumn *tree_column;
6764 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6765 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6767 gtk_tree_view_column_queue_resize (tree_column);
6769 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6770 gtk_widget_queue_draw (header_view);
6773 #ifndef MODEST_TOOLKIT_HILDON2
6774 /* Rerun dimming rules, because the message could become deletable for example */
6775 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6776 MODEST_DIMMING_RULES_TOOLBAR);
6777 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6778 MODEST_DIMMING_RULES_MENU);
6782 g_object_unref (selected_folder);
6786 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6787 TnyAccount *account)
6789 ModestProtocolType protocol_type;
6790 ModestProtocol *protocol;
6791 gchar *error_note = NULL;
6793 protocol_type = modest_tny_account_get_protocol_type (account);
6794 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6797 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6798 if (error_note == NULL) {
6799 g_warning ("%s: This should not be reached", __FUNCTION__);
6801 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6802 g_free (error_note);
6807 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6811 TnyFolderStore *folder = NULL;
6812 TnyAccount *account = NULL;
6813 ModestProtocolType proto;
6814 ModestProtocol *protocol;
6815 TnyHeader *header = NULL;
6817 if (MODEST_IS_MAIN_WINDOW (win)) {
6818 GtkWidget *header_view;
6819 TnyList* headers = NULL;
6821 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6822 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6823 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6824 if (!headers || tny_list_get_length (headers) == 0) {
6826 g_object_unref (headers);
6829 iter = tny_list_create_iterator (headers);
6830 header = TNY_HEADER (tny_iterator_get_current (iter));
6831 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6832 g_object_unref (iter);
6833 g_object_unref (headers);
6834 #ifdef MODEST_TOOLKIT_HILDON2
6835 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6836 GtkWidget *header_view;
6837 TnyList* headers = NULL;
6839 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6840 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6841 if (!headers || tny_list_get_length (headers) == 0) {
6843 g_object_unref (headers);
6846 iter = tny_list_create_iterator (headers);
6847 header = TNY_HEADER (tny_iterator_get_current (iter));
6849 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6851 g_warning ("List should contain headers");
6853 g_object_unref (iter);
6854 g_object_unref (headers);
6856 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6857 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6859 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6862 if (!header || !folder)
6865 /* Get the account type */
6866 account = tny_folder_get_account (TNY_FOLDER (folder));
6867 proto = modest_tny_account_get_protocol_type (account);
6868 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6871 subject = tny_header_dup_subject (header);
6872 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6876 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6882 g_object_unref (account);
6884 g_object_unref (folder);
6886 g_object_unref (header);
6892 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6893 const gchar *account_name,
6894 const gchar *account_title)
6896 ModestAccountMgr *account_mgr;
6899 ModestProtocol *protocol;
6900 gboolean removed = FALSE;
6902 g_return_val_if_fail (account_name, FALSE);
6903 g_return_val_if_fail (account_title, FALSE);
6905 account_mgr = modest_runtime_get_account_mgr();
6907 /* The warning text depends on the account type: */
6908 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6909 modest_account_mgr_get_store_protocol (account_mgr,
6911 txt = modest_protocol_get_translation (protocol,
6912 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6915 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6917 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6921 if (response == GTK_RESPONSE_OK) {
6922 /* Remove account. If it succeeds then it also removes
6923 the account from the ModestAccountView: */
6924 gboolean is_default = FALSE;
6925 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6926 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6928 g_free (default_account_name);
6930 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6932 /* Close all email notifications, we cannot
6933 distinguish if the notification belongs to
6934 this account or not, so for safety reasons
6935 we remove them all */
6936 modest_platform_remove_new_mail_notifications (FALSE);
6938 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6945 on_fetch_images_performer (gboolean canceled,
6947 GtkWindow *parent_window,
6948 TnyAccount *account,
6951 if (err || canceled) {
6952 /* Show an unable to retrieve images ??? */
6956 /* Note that the user could have closed the window while connecting */
6957 if (GTK_WIDGET_VISIBLE (parent_window))
6958 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6959 g_object_unref ((GObject *) user_data);
6963 modest_ui_actions_on_fetch_images (GtkAction *action,
6964 ModestWindow *window)
6966 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6968 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6970 on_fetch_images_performer,
6971 g_object_ref (window));
6975 modest_ui_actions_on_reload_message (const gchar *msg_id)
6977 ModestWindow *window = NULL;
6979 g_return_if_fail (msg_id && msg_id[0] != '\0');
6980 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6986 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6989 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
6992 /** Check whether any connections are active, and cancel them if
6994 * Returns TRUE is there was no problem,
6995 * or if an operation was cancelled so we can continue.
6996 * Returns FALSE if the user chose to cancel his request instead.
7000 modest_ui_actions_check_for_active_account (ModestWindow *self,
7001 const gchar* account_name)
7003 ModestTnySendQueue *send_queue;
7004 ModestTnyAccountStore *acc_store;
7005 ModestMailOperationQueue* queue;
7006 TnyConnectionStatus store_conn_status;
7007 TnyAccount *store_account = NULL, *transport_account = NULL;
7008 gboolean retval = TRUE, sending = FALSE;
7010 acc_store = modest_runtime_get_account_store ();
7011 queue = modest_runtime_get_mail_operation_queue ();
7014 modest_tny_account_store_get_server_account (acc_store,
7016 TNY_ACCOUNT_TYPE_STORE);
7018 /* This could happen if the account was deleted before the
7019 call to this function */
7024 modest_tny_account_store_get_server_account (acc_store,
7026 TNY_ACCOUNT_TYPE_TRANSPORT);
7028 /* This could happen if the account was deleted before the
7029 call to this function */
7030 if (!transport_account) {
7031 g_object_unref (store_account);
7035 /* If the transport account was not used yet, then the send
7036 queue could not exist (it's created on demand) */
7037 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7038 if (TNY_IS_SEND_QUEUE (send_queue))
7039 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7041 store_conn_status = tny_account_get_connection_status (store_account);
7042 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7045 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7046 _("emev_nc_disconnect_account"));
7047 if (response == GTK_RESPONSE_OK) {
7056 /* FIXME: We should only cancel those of this account */
7057 modest_mail_operation_queue_cancel_all (queue);
7059 /* Also disconnect the account */
7060 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7061 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7062 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7066 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7072 g_object_unref (store_account);
7073 g_object_unref (transport_account);