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);
1024 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1026 msg = g_strdup_printf (format, subject);
1027 modest_platform_run_information_dialog (NULL, msg, FALSE);
1033 /* Remove the header from the preregistered uids */
1034 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1047 } OpenMsgBannerInfo;
1050 GtkTreeModel *model;
1052 ModestWindow *caller_window;
1053 OpenMsgBannerInfo *banner_info;
1054 GtkTreeRowReference *rowref;
1058 open_msg_banner_idle (gpointer userdata)
1060 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1062 gdk_threads_enter ();
1063 banner_info->idle_handler = 0;
1064 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1065 if (banner_info->banner)
1066 g_object_ref (banner_info->banner);
1068 gdk_threads_leave ();
1074 get_header_view_from_window (ModestWindow *window)
1076 GtkWidget *header_view;
1078 if (MODEST_IS_MAIN_WINDOW (window)) {
1079 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1080 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1081 #ifdef MODEST_TOOLKIT_HILDON2
1082 } else if (MODEST_IS_HEADER_WINDOW (window)){
1083 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1093 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1096 gchar *account = NULL;
1097 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1102 folder = tny_header_get_folder (header);
1103 /* Gets folder type (OUTBOX headers will be opened in edit window */
1104 if (modest_tny_folder_is_local_folder (folder)) {
1105 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1106 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1107 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1110 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1111 TnyTransportAccount *traccount = NULL;
1112 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1113 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1115 ModestTnySendQueue *send_queue = NULL;
1116 ModestTnySendQueueStatus status;
1118 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1119 TNY_ACCOUNT(traccount)));
1120 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1121 if (TNY_IS_SEND_QUEUE (send_queue)) {
1122 msg_id = modest_tny_send_queue_get_msg_id (header);
1123 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1125 /* Only open messages in outbox with the editor if they are in Failed state */
1126 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1129 #ifdef MODEST_TOOLKIT_HILDON2
1131 /* In Fremantle we can not
1132 open any message from
1133 outbox which is not in
1139 g_object_unref(traccount);
1141 g_warning("Cannot get transport account for message in outbox!!");
1143 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1144 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1148 TnyAccount *acc = tny_folder_get_account (folder);
1151 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1152 g_object_unref (acc);
1156 g_object_unref (folder);
1162 open_msg_cb (ModestMailOperation *mail_op,
1169 ModestWindowMgr *mgr = NULL;
1170 ModestWindow *parent_win = NULL;
1171 ModestWindow *win = NULL;
1172 gchar *account = NULL;
1173 gboolean open_in_editor = FALSE;
1175 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1177 /* Do nothing if there was any problem with the mail
1178 operation. The error will be shown by the error_handler of
1179 the mail operation */
1180 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1183 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1185 /* Mark header as read */
1186 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1188 account = get_info_from_header (header, &open_in_editor, &can_open);
1192 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1194 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1196 if (open_in_editor) {
1197 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1198 gchar *from_header = NULL, *acc_name;
1199 gchar *mailbox = NULL;
1201 from_header = tny_header_dup_from (header);
1203 /* we cannot edit without a valid account... */
1204 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1205 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1206 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1208 g_free (from_header);
1213 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1214 g_free (from_header);
1220 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1224 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1225 const gchar *mailbox = NULL;
1227 if (parent_win && MODEST_IS_WINDOW (parent_win))
1228 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1230 if (helper->rowref && helper->model) {
1231 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1232 helper->model, helper->rowref);
1234 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1239 /* Register and show new window */
1241 mgr = modest_runtime_get_window_mgr ();
1242 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1243 gtk_widget_destroy (GTK_WIDGET (win));
1246 gtk_widget_show_all (GTK_WIDGET(win));
1249 /* Update toolbar dimming state */
1250 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1251 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1257 g_object_unref (parent_win);
1261 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1264 const GError *error;
1265 GObject *win = NULL;
1266 ModestMailOperationStatus status;
1268 win = modest_mail_operation_get_source (mail_op);
1269 error = modest_mail_operation_get_error (mail_op);
1270 status = modest_mail_operation_get_status (mail_op);
1272 /* If the mail op has been cancelled then it's not an error:
1273 don't show any message */
1274 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1275 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1276 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1277 (GError *) error, account)) {
1278 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1279 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1281 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1282 modest_platform_information_banner ((GtkWidget *) win,
1283 NULL, _("emev_ui_imap_inbox_select_error"));
1284 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1285 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1286 modest_platform_information_banner ((GtkWidget *) win,
1287 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1288 } else if (user_data) {
1289 modest_platform_information_banner ((GtkWidget *) win,
1293 g_object_unref (account);
1297 g_object_unref (win);
1301 * Returns the account a list of headers belongs to. It returns a
1302 * *new* reference so don't forget to unref it
1305 get_account_from_header_list (TnyList *headers)
1307 TnyAccount *account = NULL;
1309 if (tny_list_get_length (headers) > 0) {
1310 TnyIterator *iter = tny_list_create_iterator (headers);
1311 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1312 TnyFolder *folder = tny_header_get_folder (header);
1315 g_object_unref (header);
1317 while (!tny_iterator_is_done (iter)) {
1318 header = TNY_HEADER (tny_iterator_get_current (iter));
1319 folder = tny_header_get_folder (header);
1322 g_object_unref (header);
1324 tny_iterator_next (iter);
1329 account = tny_folder_get_account (folder);
1330 g_object_unref (folder);
1334 g_object_unref (header);
1336 g_object_unref (iter);
1342 get_account_from_header (TnyHeader *header)
1344 TnyAccount *account = NULL;
1347 folder = tny_header_get_folder (header);
1350 account = tny_folder_get_account (folder);
1351 g_object_unref (folder);
1357 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1359 if (helper->caller_window)
1360 helper->caller_window = NULL;
1364 open_msg_helper_destroyer (gpointer user_data)
1366 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1368 if (helper->caller_window) {
1369 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1370 helper->caller_window = NULL;
1373 if (helper->banner_info) {
1374 g_free (helper->banner_info->message);
1375 if (helper->banner_info->idle_handler > 0) {
1376 g_source_remove (helper->banner_info->idle_handler);
1377 helper->banner_info->idle_handler = 0;
1379 if (helper->banner_info->banner != NULL) {
1380 gtk_widget_destroy (helper->banner_info->banner);
1381 g_object_unref (helper->banner_info->banner);
1382 helper->banner_info->banner = NULL;
1384 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1385 helper->banner_info = NULL;
1387 g_object_unref (helper->model);
1388 g_object_unref (helper->header);
1389 gtk_tree_row_reference_free (helper->rowref);
1390 g_slice_free (OpenMsgHelper, helper);
1394 open_msg_performer(gboolean canceled,
1396 GtkWindow *parent_window,
1397 TnyAccount *account,
1400 ModestMailOperation *mail_op = NULL;
1401 gchar *error_msg = NULL;
1402 ModestProtocolType proto;
1403 TnyConnectionStatus status;
1404 OpenMsgHelper *helper = NULL;
1405 ModestProtocol *protocol;
1406 ModestProtocolRegistry *protocol_registry;
1409 helper = (OpenMsgHelper *) user_data;
1411 status = tny_account_get_connection_status (account);
1412 if (err || canceled || helper->caller_window == NULL) {
1413 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1414 /* Free the helper */
1415 open_msg_helper_destroyer (helper);
1417 /* In disk full conditions we could get this error here */
1418 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1419 (GtkWidget *) parent_window, err,
1425 /* Get the error message depending on the protocol */
1426 proto = modest_tny_account_get_protocol_type (account);
1427 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1428 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1431 protocol_registry = modest_runtime_get_protocol_registry ();
1432 subject = tny_header_dup_subject (helper->header);
1434 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1435 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1439 if (error_msg == NULL) {
1440 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1443 #ifndef MODEST_TOOLKIT_HILDON2
1444 gboolean show_open_draft = FALSE;
1445 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1447 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1449 TnyFolderType folder_type;
1451 folder = tny_header_get_folder (helper->header);
1452 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1453 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1454 g_object_unref (folder);
1458 #ifdef MODEST_TOOLKIT_HILDON2
1461 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1464 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1465 g_free (account_name);
1466 open_msg_helper_destroyer (helper);
1471 ModestWindow *window;
1472 GtkWidget *header_view;
1475 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1476 uid = modest_tny_folder_get_header_unique_id (helper->header);
1478 const gchar *mailbox = NULL;
1479 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1480 window = modest_msg_view_window_new_from_header_view
1481 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1482 if (window != NULL) {
1483 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1485 gtk_widget_destroy (GTK_WIDGET (window));
1487 gtk_widget_show_all (GTK_WIDGET(window));
1491 g_free (account_name);
1493 open_msg_helper_destroyer (helper);
1496 g_free (account_name);
1498 /* Create the mail operation */
1500 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1501 modest_ui_actions_disk_operations_error_handler,
1502 g_strdup (error_msg), g_free);
1503 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1507 #ifndef MODEST_TOOLKIT_HILDON2
1508 if (show_open_draft) {
1509 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1510 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1511 helper->banner_info->banner = NULL;
1512 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1513 helper->banner_info);
1519 headers = TNY_LIST (tny_simple_list_new ());
1520 tny_list_prepend (headers, G_OBJECT (helper->header));
1521 modest_mail_operation_get_msgs_full (mail_op,
1525 open_msg_helper_destroyer);
1526 g_object_unref (headers);
1533 g_object_unref (mail_op);
1534 g_object_unref (account);
1538 * This function is used by both modest_ui_actions_on_open and
1539 * modest_ui_actions_on_header_activated. This way we always do the
1540 * same when trying to open messages.
1543 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1545 ModestWindowMgr *mgr = NULL;
1546 TnyAccount *account;
1547 gboolean cached = FALSE;
1549 GtkWidget *header_view = NULL;
1550 OpenMsgHelper *helper;
1551 ModestWindow *window;
1553 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1555 mgr = modest_runtime_get_window_mgr ();
1558 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1559 if (header_view == NULL)
1562 /* Get the account */
1563 account = get_account_from_header (header);
1568 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1570 /* Do not open again the message and present the
1571 window to the user */
1574 #ifndef MODEST_TOOLKIT_HILDON2
1575 gtk_window_present (GTK_WINDOW (window));
1578 /* the header has been registered already, we don't do
1579 * anything but wait for the window to come up*/
1580 g_debug ("header %p already registered, waiting for window", header);
1585 /* Open each message */
1586 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1588 /* Allways download if we are online. */
1589 if (!tny_device_is_online (modest_runtime_get_device ())) {
1592 /* If ask for user permission to download the messages */
1593 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1594 _("mcen_nc_get_msg"));
1596 /* End if the user does not want to continue */
1597 if (response == GTK_RESPONSE_CANCEL) {
1603 /* We register the window for opening */
1604 modest_window_mgr_register_header (mgr, header, NULL);
1606 /* Create the helper. We need to get a reference to the model
1607 here because it could change while the message is readed
1608 (the user could switch between folders) */
1609 helper = g_slice_new (OpenMsgHelper);
1610 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1611 helper->caller_window = win;
1612 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1613 helper->header = g_object_ref (header);
1614 helper->rowref = gtk_tree_row_reference_copy (rowref);
1615 helper->banner_info = NULL;
1617 /* Connect to the account and perform */
1619 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1620 open_msg_performer, helper);
1622 /* Call directly the performer, do not need to connect */
1623 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1624 g_object_ref (account), helper);
1629 g_object_unref (account);
1633 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1640 /* we check for low-mem; in that case, show a warning, and don't allow
1643 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1647 headers = get_selected_headers (win);
1651 headers_count = tny_list_get_length (headers);
1652 if (headers_count != 1) {
1653 if (headers_count > 1) {
1654 /* Don't allow activation if there are more than one message selected */
1655 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1658 g_object_unref (headers);
1662 iter = tny_list_create_iterator (headers);
1663 header = TNY_HEADER (tny_iterator_get_current (iter));
1664 g_object_unref (iter);
1668 open_msg_from_header (header, NULL, win);
1669 g_object_unref (header);
1672 g_object_unref(headers);
1676 rf_helper_window_closed (gpointer data,
1679 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1681 helper->parent_window = NULL;
1684 static ReplyForwardHelper*
1685 create_reply_forward_helper (ReplyForwardAction action,
1687 guint reply_forward_type,
1690 ReplyForwardHelper *rf_helper = NULL;
1691 const gchar *active_acc = modest_window_get_active_account (win);
1692 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1694 rf_helper = g_slice_new0 (ReplyForwardHelper);
1695 rf_helper->reply_forward_type = reply_forward_type;
1696 rf_helper->action = action;
1697 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1698 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1699 rf_helper->account_name = (active_acc) ?
1700 g_strdup (active_acc) :
1701 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1702 rf_helper->mailbox = g_strdup (active_mailbox);
1704 /* Note that window could be destroyed just AFTER calling
1705 register_window so we must ensure that this pointer does
1706 not hold invalid references */
1707 if (rf_helper->parent_window)
1708 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1709 rf_helper_window_closed, rf_helper);
1715 free_reply_forward_helper (gpointer data)
1717 ReplyForwardHelper *helper;
1719 helper = (ReplyForwardHelper *) data;
1720 g_free (helper->account_name);
1721 g_free (helper->mailbox);
1723 g_object_unref (helper->header);
1724 if (helper->parent_window)
1725 g_object_weak_unref (G_OBJECT (helper->parent_window),
1726 rf_helper_window_closed, helper);
1727 g_slice_free (ReplyForwardHelper, helper);
1731 reply_forward_cb (ModestMailOperation *mail_op,
1738 TnyMsg *new_msg = NULL;
1739 ReplyForwardHelper *rf_helper;
1740 ModestWindow *msg_win = NULL;
1741 ModestEditType edit_type;
1743 TnyAccount *account = NULL;
1744 ModestWindowMgr *mgr = NULL;
1745 gchar *signature = NULL;
1746 gboolean use_signature;
1749 /* If there was any error. The mail operation could be NULL,
1750 this means that we already have the message downloaded and
1751 that we didn't do a mail operation to retrieve it */
1752 rf_helper = (ReplyForwardHelper *) user_data;
1753 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1756 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1757 rf_helper->account_name, rf_helper->mailbox);
1758 recipient = modest_text_utils_get_email_address (from);
1759 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1764 /* Create reply mail */
1765 switch (rf_helper->action) {
1766 /* Use the msg_header to ensure that we have all the
1767 information. The summary can lack some data */
1768 TnyHeader *msg_header;
1770 msg_header = tny_msg_get_header (msg);
1772 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1773 (use_signature) ? signature : NULL,
1774 rf_helper->reply_forward_type,
1775 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1776 g_object_unref (msg_header);
1778 case ACTION_REPLY_TO_ALL:
1779 msg_header = tny_msg_get_header (msg);
1781 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1782 (use_signature) ? signature : NULL,
1783 rf_helper->reply_forward_type,
1784 MODEST_TNY_MSG_REPLY_MODE_ALL);
1785 edit_type = MODEST_EDIT_TYPE_REPLY;
1786 g_object_unref (msg_header);
1788 case ACTION_FORWARD:
1790 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1791 rf_helper->reply_forward_type);
1792 edit_type = MODEST_EDIT_TYPE_FORWARD;
1795 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1797 g_return_if_reached ();
1805 g_warning ("%s: failed to create message\n", __FUNCTION__);
1809 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1810 rf_helper->account_name,
1811 TNY_ACCOUNT_TYPE_STORE);
1813 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1817 /* Create and register the windows */
1818 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1819 mgr = modest_runtime_get_window_mgr ();
1820 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1822 /* Note that register_window could have deleted the account */
1823 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1824 gdouble parent_zoom;
1826 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1827 modest_window_set_zoom (msg_win, parent_zoom);
1830 /* Show edit window */
1831 gtk_widget_show_all (GTK_WIDGET (msg_win));
1834 /* We always unregister the header because the message is
1835 forwarded or replied so the original one is no longer
1837 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1840 g_object_unref (G_OBJECT (new_msg));
1842 g_object_unref (G_OBJECT (account));
1843 free_reply_forward_helper (rf_helper);
1846 /* Checks a list of headers. If any of them are not currently
1847 * downloaded (CACHED) then returns TRUE else returns FALSE.
1850 header_list_count_uncached_msgs (TnyList *header_list)
1853 gint uncached_messages = 0;
1855 iter = tny_list_create_iterator (header_list);
1856 while (!tny_iterator_is_done (iter)) {
1859 header = TNY_HEADER (tny_iterator_get_current (iter));
1861 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1862 uncached_messages ++;
1863 g_object_unref (header);
1866 tny_iterator_next (iter);
1868 g_object_unref (iter);
1870 return uncached_messages;
1873 /* Returns FALSE if the user does not want to download the
1874 * messages. Returns TRUE if the user allowed the download.
1877 connect_to_get_msg (ModestWindow *win,
1878 gint num_of_uncached_msgs,
1879 TnyAccount *account)
1881 GtkResponseType response;
1883 /* Allways download if we are online. */
1884 if (tny_device_is_online (modest_runtime_get_device ()))
1887 /* If offline, then ask for user permission to download the messages */
1888 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1889 ngettext("mcen_nc_get_msg",
1891 num_of_uncached_msgs));
1893 if (response == GTK_RESPONSE_CANCEL)
1896 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1900 reply_forward_performer (gboolean canceled,
1902 GtkWindow *parent_window,
1903 TnyAccount *account,
1906 ReplyForwardHelper *rf_helper = NULL;
1907 ModestMailOperation *mail_op;
1909 rf_helper = (ReplyForwardHelper *) user_data;
1911 if (canceled || err) {
1912 free_reply_forward_helper (rf_helper);
1916 /* Retrieve the message */
1917 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1918 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1919 modest_ui_actions_disk_operations_error_handler,
1921 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1922 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1925 g_object_unref(mail_op);
1929 * Common code for the reply and forward actions
1932 reply_forward (ReplyForwardAction action, ModestWindow *win)
1934 ReplyForwardHelper *rf_helper = NULL;
1935 guint reply_forward_type;
1937 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1939 /* we check for low-mem; in that case, show a warning, and don't allow
1940 * reply/forward (because it could potentially require a lot of memory */
1941 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1945 /* we need an account when editing */
1946 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1947 if (!modest_ui_actions_run_account_setup_wizard (win))
1951 reply_forward_type =
1952 modest_conf_get_int (modest_runtime_get_conf (),
1953 (action == ACTION_FORWARD) ?
1954 MODEST_CONF_FORWARD_TYPE :
1955 MODEST_CONF_REPLY_TYPE,
1958 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1960 TnyHeader *header = NULL;
1961 /* Get header and message. Do not free them here, the
1962 reply_forward_cb must do it */
1963 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1964 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1966 if (msg && header) {
1968 rf_helper = create_reply_forward_helper (action, win,
1969 reply_forward_type, header);
1970 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1972 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1976 g_object_unref (msg);
1978 g_object_unref (header);
1980 TnyHeader *header = NULL;
1982 gboolean do_retrieve = TRUE;
1983 TnyList *header_list = NULL;
1985 header_list = get_selected_headers (win);
1988 /* Check that only one message is selected for replying */
1989 if (tny_list_get_length (header_list) != 1) {
1990 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1991 NULL, _("mcen_ib_select_one_message"));
1992 g_object_unref (header_list);
1996 /* Only reply/forward to one message */
1997 iter = tny_list_create_iterator (header_list);
1998 header = TNY_HEADER (tny_iterator_get_current (iter));
1999 g_object_unref (iter);
2001 /* Retrieve messages */
2002 do_retrieve = (action == ACTION_FORWARD) ||
2003 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2006 TnyAccount *account = NULL;
2007 TnyFolder *folder = NULL;
2008 gdouble download = TRUE;
2009 guint uncached_msgs = 0;
2011 folder = tny_header_get_folder (header);
2013 goto do_retrieve_frees;
2014 account = tny_folder_get_account (folder);
2016 goto do_retrieve_frees;
2018 uncached_msgs = header_list_count_uncached_msgs (header_list);
2020 if (uncached_msgs > 0) {
2021 /* Allways download if we are online. */
2022 if (!tny_device_is_online (modest_runtime_get_device ())) {
2025 /* If ask for user permission to download the messages */
2026 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2027 ngettext("mcen_nc_get_msg",
2031 /* End if the user does not want to continue */
2032 if (response == GTK_RESPONSE_CANCEL)
2039 rf_helper = create_reply_forward_helper (action, win,
2040 reply_forward_type, header);
2041 if (uncached_msgs > 0) {
2042 modest_platform_connect_and_perform (GTK_WINDOW (win),
2044 reply_forward_performer,
2047 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2048 account, rf_helper);
2053 g_object_unref (account);
2055 g_object_unref (folder);
2057 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2060 g_object_unref (header_list);
2061 g_object_unref (header);
2066 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2068 g_return_if_fail (MODEST_IS_WINDOW(win));
2070 reply_forward (ACTION_REPLY, win);
2074 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2076 g_return_if_fail (MODEST_IS_WINDOW(win));
2078 reply_forward (ACTION_FORWARD, win);
2082 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2084 g_return_if_fail (MODEST_IS_WINDOW(win));
2086 reply_forward (ACTION_REPLY_TO_ALL, win);
2090 modest_ui_actions_on_next (GtkAction *action,
2091 ModestWindow *window)
2093 if (MODEST_IS_MAIN_WINDOW (window)) {
2094 GtkWidget *header_view;
2096 header_view = modest_main_window_get_child_widget (
2097 MODEST_MAIN_WINDOW(window),
2098 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2102 modest_header_view_select_next (
2103 MODEST_HEADER_VIEW(header_view));
2104 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2105 modest_msg_view_window_select_next_message (
2106 MODEST_MSG_VIEW_WINDOW (window));
2108 g_return_if_reached ();
2113 modest_ui_actions_on_prev (GtkAction *action,
2114 ModestWindow *window)
2116 g_return_if_fail (MODEST_IS_WINDOW(window));
2118 if (MODEST_IS_MAIN_WINDOW (window)) {
2119 GtkWidget *header_view;
2120 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2121 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2125 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2126 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2127 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2129 g_return_if_reached ();
2134 modest_ui_actions_on_sort (GtkAction *action,
2135 ModestWindow *window)
2137 GtkWidget *header_view = NULL;
2139 g_return_if_fail (MODEST_IS_WINDOW(window));
2141 if (MODEST_IS_MAIN_WINDOW (window)) {
2142 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2143 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2144 #ifdef MODEST_TOOLKIT_HILDON2
2145 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2146 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2151 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2156 /* Show sorting dialog */
2157 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2161 sync_folder_cb (ModestMailOperation *mail_op,
2165 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2167 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2168 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2170 /* We must clear first, because otherwise set_folder will ignore */
2171 /* the change as the folders are the same */
2172 modest_header_view_clear (header_view);
2173 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2175 g_object_unref (parent);
2178 g_object_unref (header_view);
2182 idle_refresh_folder (gpointer source)
2184 ModestHeaderView *header_view = NULL;
2186 /* If the window still exists */
2187 if (!GTK_IS_WIDGET (source) ||
2188 !GTK_WIDGET_VISIBLE (source))
2191 /* Refresh the current view */
2192 #ifdef MODEST_TOOLKIT_HILDON2
2193 if (MODEST_IS_HEADER_WINDOW (source))
2194 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2196 if (MODEST_IS_MAIN_WINDOW (source))
2197 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2198 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2201 TnyFolder *folder = modest_header_view_get_folder (header_view);
2203 /* Sync the folder status */
2204 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2205 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2206 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2207 g_object_unref (folder);
2208 g_object_unref (mail_op);
2216 update_account_cb (ModestMailOperation *self,
2217 TnyList *new_headers,
2221 gboolean show_visual_notifications;
2223 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2224 show_visual_notifications = (top) ? FALSE : TRUE;
2226 /* Notify new messages have been downloaded. If the
2227 send&receive was invoked by the user then do not show any
2228 visual notification, only play a sound and activate the LED
2229 (for the Maemo version) */
2230 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2232 /* We only notify about really new messages (not seen) we get */
2233 TnyList *actually_new_list;
2234 TnyIterator *iterator;
2235 actually_new_list = TNY_LIST (tny_simple_list_new ());
2236 for (iterator = tny_list_create_iterator (new_headers);
2237 !tny_iterator_is_done (iterator);
2238 tny_iterator_next (iterator)) {
2240 TnyHeaderFlags flags;
2241 header = TNY_HEADER (tny_iterator_get_current (iterator));
2242 flags = tny_header_get_flags (header);
2244 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2245 /* Messages are ordered from most
2246 recent to oldest. But we want to
2247 show notifications starting from
2248 the oldest message. That's why we
2250 tny_list_prepend (actually_new_list, G_OBJECT (header));
2252 g_object_unref (header);
2254 g_object_unref (iterator);
2256 if (tny_list_get_length (actually_new_list) > 0) {
2257 GList *new_headers_list = NULL;
2259 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2261 /* Send notifications */
2262 if (new_headers_list) {
2263 modest_platform_on_new_headers_received (new_headers_list,
2264 show_visual_notifications);
2266 modest_utils_free_notification_list (new_headers_list);
2269 g_object_unref (actually_new_list);
2273 /* Refresh the current folder in an idle. We do this
2274 in order to avoid refresh cancelations if the
2275 currently viewed folder is the inbox */
2276 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2277 idle_refresh_folder,
2284 TnyAccount *account;
2286 gchar *account_name;
2287 gboolean poke_status;
2288 gboolean interactive;
2289 ModestMailOperation *mail_op;
2293 do_send_receive_performer (gboolean canceled,
2295 GtkWindow *parent_window,
2296 TnyAccount *account,
2299 SendReceiveInfo *info;
2301 info = (SendReceiveInfo *) user_data;
2303 if (err || canceled) {
2304 /* In disk full conditions we could get this error here */
2305 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2306 (GtkWidget *) parent_window, err,
2309 if (info->mail_op) {
2310 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2316 /* Set send/receive operation in progress */
2317 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2318 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2321 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2322 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2323 G_CALLBACK (on_send_receive_finished),
2326 /* Send & receive. */
2327 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2328 update_account_cb, info->win);
2333 g_object_unref (G_OBJECT (info->mail_op));
2334 if (info->account_name)
2335 g_free (info->account_name);
2337 g_object_unref (info->win);
2339 g_object_unref (info->account);
2340 g_slice_free (SendReceiveInfo, info);
2344 * This function performs the send & receive required actions. The
2345 * window is used to create the mail operation. Typically it should
2346 * always be the main window, but we pass it as argument in order to
2350 modest_ui_actions_do_send_receive (const gchar *account_name,
2351 gboolean force_connection,
2352 gboolean poke_status,
2353 gboolean interactive,
2356 gchar *acc_name = NULL;
2357 SendReceiveInfo *info;
2358 ModestTnyAccountStore *acc_store;
2359 TnyAccount *account;
2361 /* If no account name was provided then get the current account, and if
2362 there is no current account then pick the default one: */
2363 if (!account_name) {
2365 acc_name = g_strdup (modest_window_get_active_account (win));
2367 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2369 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2373 acc_name = g_strdup (account_name);
2376 acc_store = modest_runtime_get_account_store ();
2377 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2381 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2385 /* Do not automatically refresh accounts that are flagged as
2386 NO_AUTO_UPDATE. This could be useful for accounts that
2387 handle their own update times */
2389 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2390 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2391 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2392 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2394 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2395 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2396 g_object_unref (account);
2403 /* Create the info for the connect and perform */
2404 info = g_slice_new (SendReceiveInfo);
2405 info->account_name = acc_name;
2406 info->win = (win) ? g_object_ref (win) : NULL;
2407 info->poke_status = poke_status;
2408 info->interactive = interactive;
2409 info->account = account;
2410 /* We need to create the operation here, because otherwise it
2411 could happen that the queue emits the queue-empty signal
2412 while we're trying to connect the account */
2413 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2414 modest_ui_actions_disk_operations_error_handler,
2416 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2418 /* Invoke the connect and perform */
2419 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2420 force_connection, info->account,
2421 do_send_receive_performer, info);
2426 modest_ui_actions_do_cancel_send (const gchar *account_name,
2429 TnyTransportAccount *transport_account;
2430 TnySendQueue *send_queue = NULL;
2431 GError *error = NULL;
2433 /* Get transport account */
2435 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2436 (modest_runtime_get_account_store(),
2438 TNY_ACCOUNT_TYPE_TRANSPORT));
2439 if (!transport_account) {
2440 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2445 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2446 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2447 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2448 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2449 "modest: could not find send queue for account\n");
2451 /* Cancel the current send */
2452 tny_account_cancel (TNY_ACCOUNT (transport_account));
2454 /* Suspend all pending messages */
2455 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2459 if (transport_account != NULL)
2460 g_object_unref (G_OBJECT (transport_account));
2464 modest_ui_actions_cancel_send_all (ModestWindow *win)
2466 GSList *account_names, *iter;
2468 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2471 iter = account_names;
2473 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2474 iter = g_slist_next (iter);
2477 modest_account_mgr_free_account_names (account_names);
2478 account_names = NULL;
2482 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2485 /* Check if accounts exist */
2486 gboolean accounts_exist =
2487 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2489 /* If not, allow the user to create an account before trying to send/receive. */
2490 if (!accounts_exist)
2491 modest_ui_actions_on_accounts (NULL, win);
2493 /* Cancel all sending operaitons */
2494 modest_ui_actions_cancel_send_all (win);
2498 * Refreshes all accounts. This function will be used by automatic
2502 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2503 gboolean force_connection,
2504 gboolean poke_status,
2505 gboolean interactive)
2507 GSList *account_names, *iter;
2509 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2512 iter = account_names;
2514 modest_ui_actions_do_send_receive ((const char*) iter->data,
2516 poke_status, interactive, win);
2517 iter = g_slist_next (iter);
2520 modest_account_mgr_free_account_names (account_names);
2521 account_names = NULL;
2525 * Handler of the click on Send&Receive button in the main toolbar
2528 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2530 /* Check if accounts exist */
2531 gboolean accounts_exist;
2534 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2536 /* If not, allow the user to create an account before trying to send/receive. */
2537 if (!accounts_exist)
2538 modest_ui_actions_on_accounts (NULL, win);
2540 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2541 if (MODEST_IS_MAIN_WINDOW (win)) {
2542 GtkWidget *folder_view;
2543 TnyFolderStore *folder_store;
2546 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2547 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2551 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2554 g_object_unref (folder_store);
2555 /* Refresh the active account. Force the connection if needed
2556 and poke the status of all folders */
2557 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2558 #ifdef MODEST_TOOLKIT_HILDON2
2559 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2560 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2563 const gchar *active_account;
2564 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2566 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2573 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2576 GtkWidget *header_view;
2578 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2580 header_view = modest_main_window_get_child_widget (main_window,
2581 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2585 conf = modest_runtime_get_conf ();
2587 /* what is saved/restored is depending on the style; thus; we save with
2588 * old style, then update the style, and restore for this new style
2590 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2592 if (modest_header_view_get_style
2593 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2594 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2595 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2597 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2598 MODEST_HEADER_VIEW_STYLE_DETAILS);
2600 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2601 MODEST_CONF_HEADER_VIEW_KEY);
2606 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2608 ModestMainWindow *main_window)
2610 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2611 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2613 /* in the case the folder is empty, show the empty folder message and focus
2615 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2616 if (modest_header_view_is_empty (header_view)) {
2617 TnyFolder *folder = modest_header_view_get_folder (header_view);
2618 GtkWidget *folder_view =
2619 modest_main_window_get_child_widget (main_window,
2620 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2621 if (folder != NULL) {
2622 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2623 g_object_unref (folder);
2625 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2629 /* If no header has been selected then exit */
2634 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2635 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2637 /* Update toolbar dimming state */
2638 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2639 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2643 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2646 ModestWindow *window)
2648 GtkWidget *open_widget;
2649 GtkTreeRowReference *rowref;
2651 g_return_if_fail (MODEST_IS_WINDOW(window));
2652 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2653 g_return_if_fail (TNY_IS_HEADER (header));
2655 if (modest_header_view_count_selected_headers (header_view) > 1) {
2656 /* Don't allow activation if there are more than one message selected */
2657 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2661 /* we check for low-mem; in that case, show a warning, and don't allow
2662 * activating headers
2664 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2667 if (MODEST_IS_MAIN_WINDOW (window)) {
2668 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2669 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2670 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2674 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2675 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2676 gtk_tree_row_reference_free (rowref);
2680 set_active_account_from_tny_account (TnyAccount *account,
2681 ModestWindow *window)
2683 const gchar *server_acc_name = tny_account_get_id (account);
2685 /* We need the TnyAccount provided by the
2686 account store because that is the one that
2687 knows the name of the Modest account */
2688 TnyAccount *modest_server_account =
2689 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2690 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2692 if (!modest_server_account) {
2693 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2697 /* Update active account, but only if it's not a pseudo-account */
2698 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2699 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2700 const gchar *modest_acc_name =
2701 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2702 if (modest_acc_name)
2703 modest_window_set_active_account (window, modest_acc_name);
2706 g_object_unref (modest_server_account);
2711 folder_refreshed_cb (ModestMailOperation *mail_op,
2715 ModestMainWindow *win = NULL;
2716 GtkWidget *folder_view, *header_view;
2717 const GError *error;
2719 g_return_if_fail (TNY_IS_FOLDER (folder));
2721 win = MODEST_MAIN_WINDOW (user_data);
2723 /* Check if the operation failed due to memory low conditions */
2724 error = modest_mail_operation_get_error (mail_op);
2725 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2726 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2727 modest_platform_run_information_dialog (GTK_WINDOW (win),
2728 _KR("memr_ib_operation_disabled"),
2734 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2736 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2739 TnyFolderStore *current_folder;
2741 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2742 if (current_folder) {
2743 gboolean different = ((TnyFolderStore *) folder != current_folder);
2744 g_object_unref (current_folder);
2750 /* Check if folder is empty and set headers view contents style */
2751 if ((tny_folder_get_all_count (folder) == 0) ||
2752 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2753 modest_main_window_set_contents_style (win,
2754 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2758 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2759 TnyFolderStore *folder_store,
2761 ModestMainWindow *main_window)
2763 GtkWidget *header_view;
2765 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2767 header_view = modest_main_window_get_child_widget(main_window,
2768 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2773 if (TNY_IS_ACCOUNT (folder_store)) {
2775 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2777 /* Show account details */
2778 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2781 if (TNY_IS_FOLDER (folder_store) && selected) {
2782 TnyAccount *account;
2784 /* Update the active account */
2785 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2787 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2788 g_object_unref (account);
2792 /* Set the header style by default, it could
2793 be changed later by the refresh callback to
2795 modest_main_window_set_contents_style (main_window,
2796 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2798 /* Set folder on header view. This function
2799 will call tny_folder_refresh_async so we
2800 pass a callback that will be called when
2801 finished. We use that callback to set the
2802 empty view if there are no messages */
2803 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2804 TNY_FOLDER (folder_store),
2806 MODEST_WINDOW (main_window),
2807 folder_refreshed_cb,
2810 /* Restore configuration. We need to do this
2811 *after* the set_folder because the widget
2812 memory asks the header view about its
2814 modest_widget_memory_restore (modest_runtime_get_conf (),
2815 G_OBJECT(header_view),
2816 MODEST_CONF_HEADER_VIEW_KEY);
2818 /* No need to save the header view
2819 configuration for Maemo because it only
2820 saves the sorting stuff and that it's
2821 already being done by the sort
2822 dialog. Remove it when the GNOME version
2823 has the same behaviour */
2824 #ifdef MODEST_TOOLKIT_GTK
2825 if (modest_main_window_get_contents_style (main_window) ==
2826 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2827 modest_widget_memory_save (modest_runtime_get_conf (),
2828 G_OBJECT (header_view),
2829 MODEST_CONF_HEADER_VIEW_KEY);
2831 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2835 /* Update dimming state */
2836 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2837 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2841 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2848 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2850 online = tny_device_is_online (modest_runtime_get_device());
2853 /* already online -- the item is simply not there... */
2854 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2856 GTK_MESSAGE_WARNING,
2858 _("The %s you selected cannot be found"),
2860 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2861 gtk_dialog_run (GTK_DIALOG(dialog));
2863 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2866 _("mcen_bd_dialog_cancel"),
2867 GTK_RESPONSE_REJECT,
2868 _("mcen_bd_dialog_ok"),
2869 GTK_RESPONSE_ACCEPT,
2871 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2872 "Do you want to get online?"), item);
2873 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2874 gtk_label_new (txt), FALSE, FALSE, 0);
2875 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2878 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2879 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2880 /* TODO: Comment about why is this commented out: */
2881 /* modest_platform_connect_and_wait (); */
2884 gtk_widget_destroy (dialog);
2888 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2891 /* g_debug ("%s %s", __FUNCTION__, link); */
2896 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2899 modest_platform_activate_uri (link);
2903 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2906 modest_platform_show_uri_popup (link);
2910 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2913 /* we check for low-mem; in that case, show a warning, and don't allow
2914 * viewing attachments
2916 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2919 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2923 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2924 const gchar *address,
2927 /* g_debug ("%s %s", __FUNCTION__, address); */
2931 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2932 TnyMsg *saved_draft,
2935 ModestMsgEditWindow *edit_window;
2937 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2938 #ifndef MODEST_TOOLKIT_HILDON2
2939 ModestMainWindow *win;
2941 /* FIXME. Make the header view sensitive again. This is a
2942 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2944 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2945 modest_runtime_get_window_mgr(), FALSE));
2947 GtkWidget *hdrview = modest_main_window_get_child_widget(
2948 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2949 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2953 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2955 /* Set draft is there was no error */
2956 if (!modest_mail_operation_get_error (mail_op))
2957 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2959 g_object_unref(edit_window);
2963 enough_space_for_message (ModestMsgEditWindow *edit_window,
2966 guint64 available_disk, expected_size;
2971 available_disk = modest_utils_get_available_space (NULL);
2972 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2973 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2978 /* Double check: disk full condition or message too big */
2979 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2980 expected_size > available_disk) {
2981 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2982 modest_platform_information_banner (NULL, NULL, msg);
2989 * djcb: if we're in low-memory state, we only allow for
2990 * saving messages smaller than
2991 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2992 * should still allow for sending anything critical...
2994 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2995 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2999 * djcb: we also make sure that the attachments are smaller than the max size
3000 * this is for the case where we'd try to forward a message with attachments
3001 * bigger than our max allowed size, or sending an message from drafts which
3002 * somehow got past our checks when attaching.
3004 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3005 modest_platform_run_information_dialog (
3006 GTK_WINDOW(edit_window),
3007 _("mail_ib_error_attachment_size"),
3016 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3018 TnyTransportAccount *transport_account;
3019 ModestMailOperation *mail_operation;
3021 gchar *account_name;
3022 ModestAccountMgr *account_mgr;
3023 gboolean had_error = FALSE;
3024 ModestMainWindow *win = NULL;
3026 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3028 data = modest_msg_edit_window_get_msg_data (edit_window);
3031 if (!enough_space_for_message (edit_window, data)) {
3032 modest_msg_edit_window_free_msg_data (edit_window, data);
3036 account_name = g_strdup (data->account_name);
3037 account_mgr = modest_runtime_get_account_mgr();
3039 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3041 account_name = modest_account_mgr_get_default_account (account_mgr);
3042 if (!account_name) {
3043 g_printerr ("modest: no account found\n");
3044 modest_msg_edit_window_free_msg_data (edit_window, data);
3048 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3049 account_name = g_strdup (data->account_name);
3053 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3054 (modest_runtime_get_account_store (),
3056 TNY_ACCOUNT_TYPE_TRANSPORT));
3057 if (!transport_account) {
3058 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3059 g_free (account_name);
3060 modest_msg_edit_window_free_msg_data (edit_window, data);
3064 /* Create the mail operation */
3065 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3067 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3069 modest_mail_operation_save_to_drafts (mail_operation,
3081 data->priority_flags,
3084 on_save_to_drafts_cb,
3085 g_object_ref(edit_window));
3087 #ifdef MODEST_TOOLKIT_HILDON2
3088 /* In hildon2 we always show the information banner on saving to drafts.
3089 * It will be a system information banner in this case.
3091 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3092 modest_platform_information_banner (NULL, NULL, text);
3095 /* Use the main window as the parent of the banner, if the
3096 main window does not exist it won't be shown, if the parent
3097 window exists then it's properly shown. We don't use the
3098 editor window because it could be closed (save to drafts
3099 could happen after closing the window */
3100 win = (ModestMainWindow *)
3101 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3103 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3104 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3108 modest_msg_edit_window_set_modified (edit_window, FALSE);
3111 g_free (account_name);
3112 g_object_unref (G_OBJECT (transport_account));
3113 g_object_unref (G_OBJECT (mail_operation));
3115 modest_msg_edit_window_free_msg_data (edit_window, data);
3118 * If the drafts folder is selected then make the header view
3119 * insensitive while the message is being saved to drafts
3120 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3121 * is not very clean but it avoids letting the drafts folder
3122 * in an inconsistent state: the user could edit the message
3123 * being saved and undesirable things would happen.
3124 * In the average case the user won't notice anything at
3125 * all. In the worst case (the user is editing a really big
3126 * file from Drafts) the header view will be insensitive
3127 * during the saving process (10 or 20 seconds, depending on
3128 * the message). Anyway this is just a quick workaround: once
3129 * we find a better solution it should be removed
3130 * See NB#65125 (commend #18) for details.
3132 if (!had_error && win != NULL) {
3133 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3134 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3136 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3138 if (modest_tny_folder_is_local_folder(folder)) {
3139 TnyFolderType folder_type;
3140 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3141 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3142 GtkWidget *hdrview = modest_main_window_get_child_widget(
3143 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3144 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3148 if (folder != NULL) g_object_unref(folder);
3155 /* For instance, when clicking the Send toolbar button when editing a message: */
3157 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3159 TnyTransportAccount *transport_account = NULL;
3160 gboolean had_error = FALSE;
3162 ModestAccountMgr *account_mgr;
3163 gchar *account_name;
3164 ModestMailOperation *mail_operation;
3167 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3169 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3172 data = modest_msg_edit_window_get_msg_data (edit_window);
3174 recipients = g_strconcat (data->to?data->to:"",
3175 data->cc?data->cc:"",
3176 data->bcc?data->bcc:"",
3178 if (recipients == NULL || recipients[0] == '\0') {
3179 /* Empty subject -> no send */
3180 g_free (recipients);
3181 modest_msg_edit_window_free_msg_data (edit_window, data);
3184 g_free (recipients);
3187 if (!enough_space_for_message (edit_window, data)) {
3188 modest_msg_edit_window_free_msg_data (edit_window, data);
3192 account_mgr = modest_runtime_get_account_mgr();
3193 account_name = g_strdup (data->account_name);
3195 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3198 account_name = modest_account_mgr_get_default_account (account_mgr);
3200 if (!account_name) {
3201 modest_msg_edit_window_free_msg_data (edit_window, data);
3202 /* Run account setup wizard */
3203 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3208 /* Get the currently-active transport account for this modest account: */
3209 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3211 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3212 (modest_runtime_get_account_store (),
3213 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3216 if (!transport_account) {
3217 modest_msg_edit_window_free_msg_data (edit_window, data);
3218 /* Run account setup wizard */
3219 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3224 /* Create the mail operation */
3225 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3226 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3228 modest_mail_operation_send_new_mail (mail_operation,
3242 data->priority_flags);
3244 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3245 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3247 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3248 const GError *error = modest_mail_operation_get_error (mail_operation);
3249 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3250 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3251 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3252 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3258 g_free (account_name);
3259 g_object_unref (G_OBJECT (transport_account));
3260 g_object_unref (G_OBJECT (mail_operation));
3262 modest_msg_edit_window_free_msg_data (edit_window, data);
3265 modest_msg_edit_window_set_sent (edit_window, TRUE);
3267 /* Save settings and close the window: */
3268 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3275 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3276 ModestMsgEditWindow *window)
3278 ModestMsgEditFormatState *format_state = NULL;
3280 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3281 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3283 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3286 format_state = modest_msg_edit_window_get_format_state (window);
3287 g_return_if_fail (format_state != NULL);
3289 format_state->bold = gtk_toggle_action_get_active (action);
3290 modest_msg_edit_window_set_format_state (window, format_state);
3291 g_free (format_state);
3296 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3297 ModestMsgEditWindow *window)
3299 ModestMsgEditFormatState *format_state = NULL;
3301 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3302 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3304 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3307 format_state = modest_msg_edit_window_get_format_state (window);
3308 g_return_if_fail (format_state != NULL);
3310 format_state->italics = gtk_toggle_action_get_active (action);
3311 modest_msg_edit_window_set_format_state (window, format_state);
3312 g_free (format_state);
3317 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3318 ModestMsgEditWindow *window)
3320 ModestMsgEditFormatState *format_state = NULL;
3322 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3323 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3325 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3328 format_state = modest_msg_edit_window_get_format_state (window);
3329 g_return_if_fail (format_state != NULL);
3331 format_state->bullet = gtk_toggle_action_get_active (action);
3332 modest_msg_edit_window_set_format_state (window, format_state);
3333 g_free (format_state);
3338 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3339 GtkRadioAction *selected,
3340 ModestMsgEditWindow *window)
3342 ModestMsgEditFormatState *format_state = NULL;
3343 GtkJustification value;
3345 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3347 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3350 value = gtk_radio_action_get_current_value (selected);
3352 format_state = modest_msg_edit_window_get_format_state (window);
3353 g_return_if_fail (format_state != NULL);
3355 format_state->justification = value;
3356 modest_msg_edit_window_set_format_state (window, format_state);
3357 g_free (format_state);
3361 modest_ui_actions_on_select_editor_color (GtkAction *action,
3362 ModestMsgEditWindow *window)
3364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3365 g_return_if_fail (GTK_IS_ACTION (action));
3367 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3370 modest_msg_edit_window_select_color (window);
3374 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3375 ModestMsgEditWindow *window)
3377 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3378 g_return_if_fail (GTK_IS_ACTION (action));
3380 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3383 modest_msg_edit_window_select_background_color (window);
3387 modest_ui_actions_on_insert_image (GObject *object,
3388 ModestMsgEditWindow *window)
3390 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3393 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3396 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3399 modest_msg_edit_window_insert_image (window);
3403 modest_ui_actions_on_attach_file (GtkAction *action,
3404 ModestMsgEditWindow *window)
3406 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3407 g_return_if_fail (GTK_IS_ACTION (action));
3409 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3412 modest_msg_edit_window_offer_attach_file (window);
3416 modest_ui_actions_on_remove_attachments (GtkAction *action,
3417 ModestMsgEditWindow *window)
3419 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3421 modest_msg_edit_window_remove_attachments (window, NULL);
3425 do_create_folder_cb (ModestMailOperation *mail_op,
3426 TnyFolderStore *parent_folder,
3427 TnyFolder *new_folder,
3430 gchar *suggested_name = (gchar *) user_data;
3431 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3432 const GError *error;
3434 error = modest_mail_operation_get_error (mail_op);
3436 gboolean disk_full = FALSE;
3437 TnyAccount *account;
3438 /* Show an error. If there was some problem writing to
3439 disk, show it, otherwise show the generic folder
3440 create error. We do it here and not in an error
3441 handler because the call to do_create_folder will
3442 stop the main loop in a gtk_dialog_run and then,
3443 the message won't be shown until that dialog is
3445 account = modest_mail_operation_get_account (mail_op);
3448 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3449 (GtkWidget *) source_win,
3452 _("mail_in_ui_folder_create_error_memory"));
3453 g_object_unref (account);
3456 /* Show an error and try again if there is no
3457 full memory condition */
3458 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3459 _("mail_in_ui_folder_create_error"));
3460 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3464 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3465 * FIXME: any other? */
3466 GtkWidget *folder_view;
3468 if (MODEST_IS_MAIN_WINDOW(source_win))
3470 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3471 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3473 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3474 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3476 /* Select the newly created folder. It could happen
3477 that the widget is no longer there (i.e. the window
3478 has been destroyed, so we need to check this */
3480 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3482 g_object_unref (new_folder);
3484 /* Free. Note that the first time it'll be NULL so noop */
3485 g_free (suggested_name);
3486 g_object_unref (source_win);
3491 TnyFolderStore *parent;
3492 } CreateFolderConnect;
3495 do_create_folder_performer (gboolean canceled,
3497 GtkWindow *parent_window,
3498 TnyAccount *account,
3501 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3502 ModestMailOperation *mail_op;
3504 if (canceled || err) {
3505 /* In disk full conditions we could get this error here */
3506 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3507 (GtkWidget *) parent_window, err,
3508 NULL, _("mail_in_ui_folder_create_error_memory"));
3510 /* This happens if we have selected the outbox folder
3512 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3513 TNY_IS_MERGE_FOLDER (helper->parent)) {
3514 /* Show an error and retry */
3515 modest_platform_information_banner ((GtkWidget *) parent_window,
3517 _("mail_in_ui_folder_create_error"));
3519 do_create_folder (parent_window, helper->parent, helper->folder_name);
3525 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3526 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3528 modest_mail_operation_create_folder (mail_op,
3530 (const gchar *) helper->folder_name,
3531 do_create_folder_cb,
3532 g_strdup (helper->folder_name));
3533 g_object_unref (mail_op);
3537 g_object_unref (helper->parent);
3538 if (helper->folder_name)
3539 g_free (helper->folder_name);
3540 g_slice_free (CreateFolderConnect, helper);
3545 do_create_folder (GtkWindow *parent_window,
3546 TnyFolderStore *suggested_parent,
3547 const gchar *suggested_name)
3550 gchar *folder_name = NULL;
3551 TnyFolderStore *parent_folder = NULL;
3553 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3555 (gchar *) suggested_name,
3559 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3560 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3561 helper->folder_name = g_strdup (folder_name);
3562 helper->parent = g_object_ref (parent_folder);
3564 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3567 do_create_folder_performer,
3572 g_free (folder_name);
3574 g_object_unref (parent_folder);
3578 modest_ui_actions_create_folder(GtkWidget *parent_window,
3579 GtkWidget *folder_view,
3580 TnyFolderStore *parent_folder)
3582 if (!parent_folder) {
3583 #ifdef MODEST_TOOLKIT_HILDON2
3584 ModestTnyAccountStore *acc_store;
3586 acc_store = modest_runtime_get_account_store ();
3588 parent_folder = (TnyFolderStore *)
3589 modest_tny_account_store_get_local_folders_account (acc_store);
3591 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3595 if (parent_folder) {
3596 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3597 g_object_unref (parent_folder);
3602 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3605 g_return_if_fail (MODEST_IS_WINDOW(window));
3607 if (MODEST_IS_MAIN_WINDOW (window)) {
3608 GtkWidget *folder_view;
3610 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3611 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3615 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3616 #ifdef MODEST_TOOLKIT_HILDON2
3617 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3618 GtkWidget *folder_view;
3620 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3621 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3624 g_assert_not_reached ();
3629 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3632 const GError *error = NULL;
3633 gchar *message = NULL;
3635 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3637 /* Get error message */
3638 error = modest_mail_operation_get_error (mail_op);
3640 g_return_if_reached ();
3642 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3643 (GError *) error, account);
3645 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3646 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3647 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3648 message = _CS("ckdg_ib_folder_already_exists");
3649 } else if (error->domain == TNY_ERROR_DOMAIN &&
3650 error->code == TNY_SERVICE_ERROR_STATE) {
3651 /* This means that the folder is already in use (a
3652 message is opened for example */
3653 message = _("emev_ni_internal_error");
3655 message = _CS("ckdg_ib_unable_to_rename");
3658 /* We don't set a parent for the dialog because the dialog
3659 will be destroyed so the banner won't appear */
3660 modest_platform_information_banner (NULL, NULL, message);
3663 g_object_unref (account);
3669 TnyFolderStore *folder;
3674 on_rename_folder_cb (ModestMailOperation *mail_op,
3675 TnyFolder *new_folder,
3678 ModestFolderView *folder_view;
3680 /* If the window was closed when renaming a folder, or if
3681 * it's not a main window this will happen */
3682 if (!MODEST_IS_FOLDER_VIEW (user_data))
3685 folder_view = MODEST_FOLDER_VIEW (user_data);
3686 /* Note that if the rename fails new_folder will be NULL */
3688 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3690 modest_folder_view_select_first_inbox_or_local (folder_view);
3692 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3696 on_rename_folder_performer (gboolean canceled,
3698 GtkWindow *parent_window,
3699 TnyAccount *account,
3702 ModestMailOperation *mail_op = NULL;
3703 GtkTreeSelection *sel = NULL;
3704 GtkWidget *folder_view = NULL;
3705 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3707 if (canceled || err) {
3708 /* In disk full conditions we could get this error here */
3709 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3710 (GtkWidget *) parent_window, err,
3715 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3716 modest_ui_actions_rename_folder_error_handler,
3717 parent_window, NULL);
3719 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3722 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3724 folder_view = modest_main_window_get_child_widget (
3725 MODEST_MAIN_WINDOW (parent_window),
3726 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3728 #ifdef MODEST_TOOLKIT_HILDON2
3729 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3730 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3731 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3735 /* Clear the folders view */
3736 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3737 gtk_tree_selection_unselect_all (sel);
3739 /* Actually rename the folder */
3740 modest_mail_operation_rename_folder (mail_op,
3741 TNY_FOLDER (data->folder),
3742 (const gchar *) (data->new_name),
3743 on_rename_folder_cb,
3745 g_object_unref (mail_op);
3748 g_object_unref (data->folder);
3749 g_free (data->new_name);
3754 modest_ui_actions_on_rename_folder (GtkAction *action,
3755 ModestWindow *window)
3757 modest_ui_actions_on_edit_mode_rename_folder (window);
3761 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3763 TnyFolderStore *folder;
3764 GtkWidget *folder_view;
3765 gboolean do_rename = TRUE;
3767 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3769 if (MODEST_IS_MAIN_WINDOW (window)) {
3770 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3771 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3775 #ifdef MODEST_TOOLKIT_HILDON2
3776 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3777 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3783 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3788 if (TNY_IS_FOLDER (folder)) {
3789 gchar *folder_name = NULL;
3791 const gchar *current_name;
3792 TnyFolderStore *parent;
3794 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3795 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3796 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3797 parent, current_name,
3799 g_object_unref (parent);
3801 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3804 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3805 rename_folder_data->folder = g_object_ref (folder);
3806 rename_folder_data->new_name = folder_name;
3807 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3808 folder, on_rename_folder_performer, rename_folder_data);
3811 g_object_unref (folder);
3816 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3819 GObject *win = modest_mail_operation_get_source (mail_op);
3821 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3822 _("mail_in_ui_folder_delete_error"),
3824 g_object_unref (win);
3828 TnyFolderStore *folder;
3829 gboolean move_to_trash;
3833 on_delete_folder_cb (gboolean canceled,
3835 GtkWindow *parent_window,
3836 TnyAccount *account,
3839 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3840 GtkWidget *folder_view;
3841 ModestMailOperation *mail_op;
3842 GtkTreeSelection *sel;
3844 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3845 /* Note that the connection process can fail due to
3846 memory low conditions as it can not successfully
3847 store the summary */
3848 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3849 (GtkWidget*) parent_window, err,
3851 g_debug ("Error connecting when trying to delete a folder");
3852 g_object_unref (G_OBJECT (info->folder));
3857 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3858 folder_view = modest_main_window_get_child_widget (
3859 MODEST_MAIN_WINDOW (parent_window),
3860 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3861 #ifdef MODEST_TOOLKIT_HILDON2
3862 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3863 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3866 g_object_unref (G_OBJECT (info->folder));
3871 /* Unselect the folder before deleting it to free the headers */
3872 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3873 gtk_tree_selection_unselect_all (sel);
3875 /* Create the mail operation */
3877 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3878 modest_ui_actions_delete_folder_error_handler,
3881 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3883 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3885 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3887 g_object_unref (mail_op);
3888 g_object_unref (info->folder);
3893 delete_folder (ModestWindow *window, gboolean move_to_trash)
3895 TnyFolderStore *folder;
3896 GtkWidget *folder_view;
3900 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3902 if (MODEST_IS_MAIN_WINDOW (window)) {
3904 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3905 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3906 #ifdef MODEST_TOOLKIT_HILDON2
3907 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3908 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3916 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3921 /* Show an error if it's an account */
3922 if (!TNY_IS_FOLDER (folder)) {
3923 modest_platform_run_information_dialog (GTK_WINDOW (window),
3924 _("mail_in_ui_folder_delete_error"),
3926 g_object_unref (G_OBJECT (folder));
3931 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3932 tny_folder_get_name (TNY_FOLDER (folder)));
3933 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3934 (const gchar *) message);
3937 if (response == GTK_RESPONSE_OK) {
3938 TnyAccount *account = NULL;
3939 DeleteFolderInfo *info = NULL;
3940 info = g_new0(DeleteFolderInfo, 1);
3941 info->folder = g_object_ref (folder);
3942 info->move_to_trash = move_to_trash;
3944 account = tny_folder_get_account (TNY_FOLDER (folder));
3945 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3947 TNY_FOLDER_STORE (account),
3948 on_delete_folder_cb, info);
3949 g_object_unref (account);
3950 g_object_unref (folder);
3958 modest_ui_actions_on_delete_folder (GtkAction *action,
3959 ModestWindow *window)
3961 modest_ui_actions_on_edit_mode_delete_folder (window);
3965 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3967 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3969 return delete_folder (window, FALSE);
3973 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3975 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3977 delete_folder (MODEST_WINDOW (main_window), TRUE);
3981 typedef struct _PasswordDialogFields {
3982 GtkWidget *username;
3983 GtkWidget *password;
3985 } PasswordDialogFields;
3988 password_dialog_check_field (GtkEditable *editable,
3989 PasswordDialogFields *fields)
3992 gboolean any_value_empty = FALSE;
3994 #ifdef MODEST_TOOLKIT_HILDON2
3995 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3997 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3999 if ((value == NULL) || value[0] == '\0') {
4000 any_value_empty = TRUE;
4002 #ifdef MODEST_TOOLKIT_HILDON2
4003 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4005 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4007 if ((value == NULL) || value[0] == '\0') {
4008 any_value_empty = TRUE;
4010 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4014 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4015 const gchar* server_account_name,
4020 ModestMainWindow *main_window)
4022 g_return_if_fail(server_account_name);
4023 gboolean completed = FALSE;
4024 PasswordDialogFields *fields = NULL;
4026 /* Initalize output parameters: */
4033 #ifndef MODEST_TOOLKIT_GTK
4034 /* Maemo uses a different (awkward) button order,
4035 * It should probably just use gtk_alternative_dialog_button_order ().
4037 #ifdef MODEST_TOOLKIT_HILDON2
4039 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4042 _HL("wdgt_bd_done"),
4043 GTK_RESPONSE_ACCEPT,
4045 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4046 HILDON_MARGIN_DOUBLE);
4049 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4052 _("mcen_bd_dialog_ok"),
4053 GTK_RESPONSE_ACCEPT,
4054 _("mcen_bd_dialog_cancel"),
4055 GTK_RESPONSE_REJECT,
4057 #endif /* MODEST_TOOLKIT_HILDON2 */
4060 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4064 GTK_RESPONSE_REJECT,
4066 GTK_RESPONSE_ACCEPT,
4068 #endif /* MODEST_TOOLKIT_GTK */
4070 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4072 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4073 modest_runtime_get_account_mgr(), server_account_name);
4074 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4075 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4078 gtk_widget_destroy (dialog);
4082 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4083 GtkWidget *label = gtk_label_new (txt);
4084 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4086 g_free (server_name);
4087 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4092 gchar *initial_username = modest_account_mgr_get_server_account_username (
4093 modest_runtime_get_account_mgr(), server_account_name);
4095 #ifdef MODEST_TOOLKIT_HILDON2
4096 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4097 if (initial_username)
4098 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4100 GtkWidget *entry_username = gtk_entry_new ();
4101 if (initial_username)
4102 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4104 /* Dim this if a connection has ever succeeded with this username,
4105 * as per the UI spec: */
4106 /* const gboolean username_known = */
4107 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4108 /* modest_runtime_get_account_mgr(), server_account_name); */
4109 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4111 /* We drop the username sensitive code and disallow changing it here
4112 * as tinymail does not support really changing the username in the callback
4114 gtk_widget_set_sensitive (entry_username, FALSE);
4116 #ifndef MODEST_TOOLKIT_GTK
4117 /* Auto-capitalization is the default, so let's turn it off: */
4118 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4120 /* Create a size group to be used by all captions.
4121 * Note that HildonCaption does not create a default size group if we do not specify one.
4122 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4123 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4125 #ifdef MODEST_TOOLKIT_HILDON2
4126 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4127 _("mail_fi_username"), FALSE,
4130 GtkWidget *caption = hildon_caption_new (sizegroup,
4131 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4133 gtk_widget_show (entry_username);
4134 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4135 FALSE, FALSE, MODEST_MARGIN_HALF);
4136 gtk_widget_show (caption);
4138 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4140 #endif /* !MODEST_TOOLKIT_GTK */
4143 #ifdef MODEST_TOOLKIT_HILDON2
4144 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4146 GtkWidget *entry_password = gtk_entry_new ();
4148 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4149 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4151 #ifndef MODEST_TOOLKIT_GTK
4152 /* Auto-capitalization is the default, so let's turn it off: */
4153 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4154 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4156 #ifdef MODEST_TOOLKIT_HILDON2
4157 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4158 _("mail_fi_password"), FALSE,
4161 caption = hildon_caption_new (sizegroup,
4162 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4164 gtk_widget_show (entry_password);
4165 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4166 FALSE, FALSE, MODEST_MARGIN_HALF);
4167 gtk_widget_show (caption);
4168 g_object_unref (sizegroup);
4170 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4172 #endif /* !MODEST_TOOLKIT_GTK */
4174 if (initial_username != NULL)
4175 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4177 /* This is not in the Maemo UI spec:
4178 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4179 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4183 fields = g_slice_new0 (PasswordDialogFields);
4184 fields->username = entry_username;
4185 fields->password = entry_password;
4186 fields->dialog = dialog;
4188 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4189 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4190 password_dialog_check_field (NULL, fields);
4192 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4194 while (!completed) {
4196 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4198 #ifdef MODEST_TOOLKIT_HILDON2
4199 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4201 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4204 /* Note that an empty field becomes the "" string */
4205 if (*username && strlen (*username) > 0) {
4206 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4207 server_account_name,
4211 const gboolean username_was_changed =
4212 (strcmp (*username, initial_username) != 0);
4213 if (username_was_changed) {
4214 g_warning ("%s: tinymail does not yet support changing the "
4215 "username in the get_password() callback.\n", __FUNCTION__);
4221 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4222 _("mcen_ib_username_pw_incorrect"));
4228 #ifdef MODEST_TOOLKIT_HILDON2
4229 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4231 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4234 /* We do not save the password in the configuration,
4235 * because this function is only called for passwords that should
4236 * not be remembered:
4237 modest_server_account_set_password (
4238 modest_runtime_get_account_mgr(), server_account_name,
4245 #ifndef MODEST_TOOLKIT_HILDON2
4246 /* Set parent to NULL or the banner will disappear with its parent dialog */
4247 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4259 /* This is not in the Maemo UI spec:
4260 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4266 g_free (initial_username);
4267 gtk_widget_destroy (dialog);
4268 g_slice_free (PasswordDialogFields, fields);
4270 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4274 modest_ui_actions_on_cut (GtkAction *action,
4275 ModestWindow *window)
4277 GtkWidget *focused_widget;
4278 GtkClipboard *clipboard;
4280 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4281 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4282 if (GTK_IS_EDITABLE (focused_widget)) {
4283 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4284 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4285 gtk_clipboard_store (clipboard);
4286 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4287 GtkTextBuffer *buffer;
4289 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4290 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4291 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4292 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4293 gtk_clipboard_store (clipboard);
4295 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4296 TnyList *header_list = modest_header_view_get_selected_headers (
4297 MODEST_HEADER_VIEW (focused_widget));
4298 gboolean continue_download = FALSE;
4299 gint num_of_unc_msgs;
4301 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4303 if (num_of_unc_msgs) {
4304 TnyAccount *account = get_account_from_header_list (header_list);
4306 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4307 g_object_unref (account);
4311 if (num_of_unc_msgs == 0 || continue_download) {
4312 /* modest_platform_information_banner (
4313 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4314 modest_header_view_cut_selection (
4315 MODEST_HEADER_VIEW (focused_widget));
4318 g_object_unref (header_list);
4319 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4320 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4325 modest_ui_actions_on_copy (GtkAction *action,
4326 ModestWindow *window)
4328 GtkClipboard *clipboard;
4329 GtkWidget *focused_widget;
4330 gboolean copied = TRUE;
4332 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4333 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4335 if (GTK_IS_LABEL (focused_widget)) {
4337 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4338 gtk_clipboard_set_text (clipboard, selection, -1);
4340 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4341 gtk_clipboard_store (clipboard);
4342 } else if (GTK_IS_EDITABLE (focused_widget)) {
4343 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4344 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4345 gtk_clipboard_store (clipboard);
4346 } else if (GTK_IS_HTML (focused_widget)) {
4349 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4350 if ((sel == NULL) || (sel[0] == '\0')) {
4353 gtk_html_copy (GTK_HTML (focused_widget));
4354 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4355 gtk_clipboard_store (clipboard);
4357 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4358 GtkTextBuffer *buffer;
4359 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4360 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4361 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4362 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4363 gtk_clipboard_store (clipboard);
4365 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4366 TnyList *header_list = modest_header_view_get_selected_headers (
4367 MODEST_HEADER_VIEW (focused_widget));
4368 gboolean continue_download = FALSE;
4369 gint num_of_unc_msgs;
4371 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4373 if (num_of_unc_msgs) {
4374 TnyAccount *account = get_account_from_header_list (header_list);
4376 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4377 g_object_unref (account);
4381 if (num_of_unc_msgs == 0 || continue_download) {
4382 modest_platform_information_banner (
4383 NULL, NULL, _CS("mcen_ib_getting_items"));
4384 modest_header_view_copy_selection (
4385 MODEST_HEADER_VIEW (focused_widget));
4389 g_object_unref (header_list);
4391 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4392 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4395 /* Show information banner if there was a copy to clipboard */
4397 modest_platform_information_banner (
4398 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4402 modest_ui_actions_on_undo (GtkAction *action,
4403 ModestWindow *window)
4405 ModestEmailClipboard *clipboard = NULL;
4407 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4408 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4409 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4410 /* Clear clipboard source */
4411 clipboard = modest_runtime_get_email_clipboard ();
4412 modest_email_clipboard_clear (clipboard);
4415 g_return_if_reached ();
4420 modest_ui_actions_on_redo (GtkAction *action,
4421 ModestWindow *window)
4423 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4424 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4427 g_return_if_reached ();
4433 destroy_information_note (ModestMailOperation *mail_op,
4436 /* destroy information note */
4437 gtk_widget_destroy (GTK_WIDGET(user_data));
4441 destroy_folder_information_note (ModestMailOperation *mail_op,
4442 TnyFolder *new_folder,
4445 /* destroy information note */
4446 gtk_widget_destroy (GTK_WIDGET(user_data));
4451 paste_as_attachment_free (gpointer data)
4453 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4455 if (helper->banner) {
4456 gtk_widget_destroy (helper->banner);
4457 g_object_unref (helper->banner);
4463 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4468 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4469 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4474 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4479 modest_ui_actions_on_paste (GtkAction *action,
4480 ModestWindow *window)
4482 GtkWidget *focused_widget = NULL;
4483 GtkWidget *inf_note = NULL;
4484 ModestMailOperation *mail_op = NULL;
4486 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4487 if (GTK_IS_EDITABLE (focused_widget)) {
4488 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4489 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4490 ModestEmailClipboard *e_clipboard = NULL;
4491 e_clipboard = modest_runtime_get_email_clipboard ();
4492 if (modest_email_clipboard_cleared (e_clipboard)) {
4493 GtkTextBuffer *buffer;
4494 GtkClipboard *clipboard;
4496 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4497 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4498 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4499 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4500 ModestMailOperation *mail_op;
4501 TnyFolder *src_folder = NULL;
4502 TnyList *data = NULL;
4504 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4505 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4506 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4507 _CS("ckct_nw_pasting"));
4508 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4509 mail_op = modest_mail_operation_new (G_OBJECT (window));
4510 if (helper->banner != NULL) {
4511 g_object_ref (G_OBJECT (helper->banner));
4512 gtk_widget_show (GTK_WIDGET (helper->banner));
4516 modest_mail_operation_get_msgs_full (mail_op,
4518 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4520 paste_as_attachment_free);
4524 g_object_unref (data);
4526 g_object_unref (src_folder);
4529 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4530 ModestEmailClipboard *clipboard = NULL;
4531 TnyFolder *src_folder = NULL;
4532 TnyFolderStore *folder_store = NULL;
4533 TnyList *data = NULL;
4534 gboolean delete = FALSE;
4536 /* Check clipboard source */
4537 clipboard = modest_runtime_get_email_clipboard ();
4538 if (modest_email_clipboard_cleared (clipboard))
4541 /* Get elements to paste */
4542 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4544 /* Create a new mail operation */
4545 mail_op = modest_mail_operation_new (G_OBJECT(window));
4547 /* Get destination folder */
4548 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4550 /* transfer messages */
4554 /* Ask for user confirmation */
4556 modest_ui_actions_msgs_move_to_confirmation (window,
4557 TNY_FOLDER (folder_store),
4561 if (response == GTK_RESPONSE_OK) {
4562 /* Launch notification */
4563 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4564 _CS("ckct_nw_pasting"));
4565 if (inf_note != NULL) {
4566 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4567 gtk_widget_show (GTK_WIDGET(inf_note));
4570 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4571 modest_mail_operation_xfer_msgs (mail_op,
4573 TNY_FOLDER (folder_store),
4575 destroy_information_note,
4578 g_object_unref (mail_op);
4581 } else if (src_folder != NULL) {
4582 /* Launch notification */
4583 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4584 _CS("ckct_nw_pasting"));
4585 if (inf_note != NULL) {
4586 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4587 gtk_widget_show (GTK_WIDGET(inf_note));
4590 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4591 modest_mail_operation_xfer_folder (mail_op,
4595 destroy_folder_information_note,
4601 g_object_unref (data);
4602 if (src_folder != NULL)
4603 g_object_unref (src_folder);
4604 if (folder_store != NULL)
4605 g_object_unref (folder_store);
4611 modest_ui_actions_on_select_all (GtkAction *action,
4612 ModestWindow *window)
4614 GtkWidget *focused_widget;
4616 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4617 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4618 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4619 } else if (GTK_IS_LABEL (focused_widget)) {
4620 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4621 } else if (GTK_IS_EDITABLE (focused_widget)) {
4622 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4623 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4624 GtkTextBuffer *buffer;
4625 GtkTextIter start, end;
4627 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4628 gtk_text_buffer_get_start_iter (buffer, &start);
4629 gtk_text_buffer_get_end_iter (buffer, &end);
4630 gtk_text_buffer_select_range (buffer, &start, &end);
4631 } else if (GTK_IS_HTML (focused_widget)) {
4632 gtk_html_select_all (GTK_HTML (focused_widget));
4633 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4634 GtkWidget *header_view = focused_widget;
4635 GtkTreeSelection *selection = NULL;
4637 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4638 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4639 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4642 /* Disable window dimming management */
4643 modest_window_disable_dimming (MODEST_WINDOW(window));
4645 /* Select all messages */
4646 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4647 gtk_tree_selection_select_all (selection);
4649 /* Set focuse on header view */
4650 gtk_widget_grab_focus (header_view);
4652 /* Enable window dimming management */
4653 modest_window_enable_dimming (MODEST_WINDOW(window));
4654 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4655 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4661 modest_ui_actions_on_mark_as_read (GtkAction *action,
4662 ModestWindow *window)
4664 g_return_if_fail (MODEST_IS_WINDOW(window));
4666 /* Mark each header as read */
4667 do_headers_action (window, headers_action_mark_as_read, NULL);
4671 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4672 ModestWindow *window)
4674 g_return_if_fail (MODEST_IS_WINDOW(window));
4676 /* Mark each header as read */
4677 do_headers_action (window, headers_action_mark_as_unread, NULL);
4681 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4682 GtkRadioAction *selected,
4683 ModestWindow *window)
4687 value = gtk_radio_action_get_current_value (selected);
4688 if (MODEST_IS_WINDOW (window)) {
4689 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4694 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4695 GtkRadioAction *selected,
4696 ModestWindow *window)
4698 TnyHeaderFlags flags;
4699 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4701 flags = gtk_radio_action_get_current_value (selected);
4702 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4706 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4707 GtkRadioAction *selected,
4708 ModestWindow *window)
4712 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4714 file_format = gtk_radio_action_get_current_value (selected);
4715 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4720 modest_ui_actions_on_zoom_plus (GtkAction *action,
4721 ModestWindow *window)
4723 g_return_if_fail (MODEST_IS_WINDOW (window));
4725 modest_window_zoom_plus (MODEST_WINDOW (window));
4729 modest_ui_actions_on_zoom_minus (GtkAction *action,
4730 ModestWindow *window)
4732 g_return_if_fail (MODEST_IS_WINDOW (window));
4734 modest_window_zoom_minus (MODEST_WINDOW (window));
4738 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4739 ModestWindow *window)
4741 ModestWindowMgr *mgr;
4742 gboolean fullscreen, active;
4743 g_return_if_fail (MODEST_IS_WINDOW (window));
4745 mgr = modest_runtime_get_window_mgr ();
4747 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4748 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4750 if (active != fullscreen) {
4751 modest_window_mgr_set_fullscreen_mode (mgr, active);
4752 #ifndef MODEST_TOOLKIT_HILDON2
4753 gtk_window_present (GTK_WINDOW (window));
4759 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4760 ModestWindow *window)
4762 ModestWindowMgr *mgr;
4763 gboolean fullscreen;
4765 g_return_if_fail (MODEST_IS_WINDOW (window));
4767 mgr = modest_runtime_get_window_mgr ();
4768 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4769 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4771 #ifndef MODEST_TOOLKIT_HILDON2
4772 gtk_window_present (GTK_WINDOW (window));
4777 * Used by modest_ui_actions_on_details to call do_headers_action
4780 headers_action_show_details (TnyHeader *header,
4781 ModestWindow *window,
4785 gboolean async_retrieval;
4788 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4789 async_retrieval = TRUE;
4790 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4792 async_retrieval = FALSE;
4794 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4796 g_object_unref (msg);
4800 * Show the header details in a ModestDetailsDialog widget
4803 modest_ui_actions_on_details (GtkAction *action,
4806 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4810 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4814 header = tny_msg_get_header (msg);
4816 headers_action_show_details (header, win, NULL);
4817 g_object_unref (header);
4819 g_object_unref (msg);
4821 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4822 GtkWidget *folder_view, *header_view;
4824 /* Check which widget has the focus */
4825 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4826 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4827 if (gtk_widget_is_focus (folder_view)) {
4828 TnyFolderStore *folder_store
4829 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4830 if (!folder_store) {
4831 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4834 /* Show only when it's a folder */
4835 /* This function should not be called for account items,
4836 * because we dim the menu item for them. */
4837 if (TNY_IS_FOLDER (folder_store)) {
4838 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4839 TNY_FOLDER (folder_store));
4842 g_object_unref (folder_store);
4845 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4846 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4847 /* Show details of each header */
4848 do_headers_action (win, headers_action_show_details, header_view);
4850 #ifdef MODEST_TOOLKIT_HILDON2
4851 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4853 GtkWidget *header_view;
4855 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4856 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4858 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4860 g_object_unref (folder);
4867 modest_ui_actions_on_limit_error (GtkAction *action,
4870 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4872 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4877 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4878 ModestMsgEditWindow *window)
4880 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4882 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4886 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4887 ModestMsgEditWindow *window)
4889 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4891 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4895 modest_ui_actions_toggle_folders_view (GtkAction *action,
4896 ModestMainWindow *main_window)
4898 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4900 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4901 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4903 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4907 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4908 ModestWindow *window)
4910 gboolean active, fullscreen = FALSE;
4911 ModestWindowMgr *mgr;
4913 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4915 /* Check if we want to toggle the toolbar view in fullscreen
4917 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4918 "ViewShowToolbarFullScreen")) {
4922 /* Toggle toolbar */
4923 mgr = modest_runtime_get_window_mgr ();
4924 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4928 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4929 ModestMsgEditWindow *window)
4931 modest_msg_edit_window_select_font (window);
4936 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4937 const gchar *display_name,
4940 /* don't update the display name if it was already set;
4941 * updating the display name apparently is expensive */
4942 const gchar* old_name = gtk_window_get_title (window);
4944 if (display_name == NULL)
4947 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4948 return; /* don't do anything */
4950 /* This is usually used to change the title of the main window, which
4951 * is the one that holds the folder view. Note that this change can
4952 * happen even when the widget doesn't have the focus. */
4953 gtk_window_set_title (window, display_name);
4958 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4960 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4961 modest_msg_edit_window_select_contacts (window);
4965 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4967 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4968 modest_msg_edit_window_check_names (window, FALSE);
4971 #ifndef MODEST_TOOLKIT_HILDON2
4973 * This function is used to track changes in the selection of the
4974 * folder view that is inside the "move to" dialog to enable/disable
4975 * the OK button because we do not want the user to select a disallowed
4976 * destination for a folder.
4977 * The user also not desired to be able to use NEW button on items where
4978 * folder creation is not possibel.
4981 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4982 TnyFolderStore *folder_store,
4986 GtkWidget *dialog = NULL;
4987 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4988 gboolean moving_folder = FALSE;
4989 gboolean is_local_account = TRUE;
4990 GtkWidget *folder_view = NULL;
4991 ModestTnyFolderRules rules;
4993 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4998 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5002 /* check if folder_store is an remote account */
5003 if (TNY_IS_ACCOUNT (folder_store)) {
5004 TnyAccount *local_account = NULL;
5005 TnyAccount *mmc_account = NULL;
5006 ModestTnyAccountStore *account_store = NULL;
5008 account_store = modest_runtime_get_account_store ();
5009 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5010 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5012 if ((gpointer) local_account != (gpointer) folder_store &&
5013 (gpointer) mmc_account != (gpointer) folder_store) {
5014 ModestProtocolType proto;
5015 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5016 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5017 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5019 is_local_account = FALSE;
5020 /* New button should be dimmed on remote
5022 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5024 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5026 g_object_unref (local_account);
5028 /* It could not exist */
5030 g_object_unref (mmc_account);
5033 /* Check the target folder rules */
5034 if (TNY_IS_FOLDER (folder_store)) {
5035 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5036 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5037 ok_sensitive = FALSE;
5038 new_sensitive = FALSE;
5043 /* Check if we're moving a folder */
5044 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5045 /* Get the widgets */
5046 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5047 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5048 if (gtk_widget_is_focus (folder_view))
5049 moving_folder = TRUE;
5052 if (moving_folder) {
5053 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5055 /* Get the folder to move */
5056 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5058 /* Check that we're not moving to the same folder */
5059 if (TNY_IS_FOLDER (moved_folder)) {
5060 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5061 if (parent == folder_store)
5062 ok_sensitive = FALSE;
5063 g_object_unref (parent);
5066 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5067 /* Do not allow to move to an account unless it's the
5068 local folders account */
5069 if (!is_local_account)
5070 ok_sensitive = FALSE;
5073 if (ok_sensitive && (moved_folder == folder_store)) {
5074 /* Do not allow to move to itself */
5075 ok_sensitive = FALSE;
5077 g_object_unref (moved_folder);
5079 TnyFolder *src_folder = NULL;
5081 /* Moving a message */
5082 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5084 TnyHeader *header = NULL;
5085 header = modest_msg_view_window_get_header
5086 (MODEST_MSG_VIEW_WINDOW (user_data));
5087 if (!TNY_IS_HEADER(header))
5088 g_warning ("%s: could not get source header", __FUNCTION__);
5090 src_folder = tny_header_get_folder (header);
5093 g_object_unref (header);
5096 TNY_FOLDER (modest_folder_view_get_selected
5097 (MODEST_FOLDER_VIEW (folder_view)));
5100 if (TNY_IS_FOLDER(src_folder)) {
5101 /* Do not allow to move the msg to the same folder */
5102 /* Do not allow to move the msg to an account */
5103 if ((gpointer) src_folder == (gpointer) folder_store ||
5104 TNY_IS_ACCOUNT (folder_store))
5105 ok_sensitive = FALSE;
5106 g_object_unref (src_folder);
5108 g_warning ("%s: could not get source folder", __FUNCTION__);
5112 /* Set sensitivity of the OK and NEW button */
5113 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5114 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5119 on_move_to_dialog_response (GtkDialog *dialog,
5123 GtkWidget *parent_win;
5124 MoveToInfo *helper = NULL;
5125 ModestFolderView *folder_view;
5126 gboolean unset_edit_mode = FALSE;
5128 helper = (MoveToInfo *) user_data;
5130 parent_win = (GtkWidget *) helper->win;
5131 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5132 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5134 TnyFolderStore *dst_folder;
5135 TnyFolderStore *selected;
5137 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5138 selected = modest_folder_view_get_selected (folder_view);
5139 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5140 g_object_unref (selected);
5142 case GTK_RESPONSE_NONE:
5143 case GTK_RESPONSE_CANCEL:
5144 case GTK_RESPONSE_DELETE_EVENT:
5146 case GTK_RESPONSE_OK:
5147 dst_folder = modest_folder_view_get_selected (folder_view);
5149 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5150 /* Clean list to move used for filtering */
5151 modest_folder_view_set_list_to_move (folder_view, NULL);
5153 modest_ui_actions_on_main_window_move_to (NULL,
5154 GTK_WIDGET (folder_view),
5156 MODEST_MAIN_WINDOW (parent_win));
5157 #ifdef MODEST_TOOLKIT_HILDON2
5158 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5159 /* Clean list to move used for filtering */
5160 modest_folder_view_set_list_to_move (folder_view, NULL);
5162 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5165 GTK_WINDOW (parent_win));
5168 /* if the user selected a root folder
5169 (account) then do not perform any action */
5170 if (TNY_IS_ACCOUNT (dst_folder)) {
5171 g_signal_stop_emission_by_name (dialog, "response");
5175 /* Clean list to move used for filtering */
5176 modest_folder_view_set_list_to_move (folder_view, NULL);
5178 /* Moving from headers window in edit mode */
5179 modest_ui_actions_on_window_move_to (NULL, helper->list,
5181 MODEST_WINDOW (parent_win));
5185 g_object_unref (dst_folder);
5187 unset_edit_mode = TRUE;
5190 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5193 /* Free the helper and exit */
5195 g_object_unref (helper->list);
5196 if (unset_edit_mode) {
5197 #ifdef MODEST_TOOLKIT_HILDON2
5198 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5201 g_slice_free (MoveToInfo, helper);
5202 gtk_widget_destroy (GTK_WIDGET (dialog));
5206 create_move_to_dialog (GtkWindow *win,
5207 GtkWidget *folder_view,
5208 TnyList *list_to_move)
5210 GtkWidget *dialog, *tree_view = NULL;
5212 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5214 #ifndef MODEST_TOOLKIT_HILDON2
5215 /* Track changes in the selection to
5216 * disable the OK button whenever "Move to" is not possible
5217 * disbale NEW button whenever New is not possible */
5218 g_signal_connect (tree_view,
5219 "folder_selection_changed",
5220 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5224 /* It could happen that we're trying to move a message from a
5225 window (msg window for example) after the main window was
5226 closed, so we can not just get the model of the folder
5228 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5229 const gchar *visible_id = NULL;
5231 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5232 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5233 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5234 MODEST_FOLDER_VIEW(tree_view));
5237 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5239 /* Show the same account than the one that is shown in the main window */
5240 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5243 const gchar *active_account_name = NULL;
5244 ModestAccountMgr *mgr = NULL;
5245 ModestAccountSettings *settings = NULL;
5246 ModestServerAccountSettings *store_settings = NULL;
5248 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5249 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5250 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5251 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5253 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5254 mgr = modest_runtime_get_account_mgr ();
5255 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5258 const gchar *store_account_name;
5259 store_settings = modest_account_settings_get_store_settings (settings);
5260 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5262 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5263 store_account_name);
5264 g_object_unref (store_settings);
5265 g_object_unref (settings);
5269 /* we keep a pointer to the embedded folder view, so we can
5270 * retrieve it with get_folder_view_from_move_to_dialog (see
5271 * above) later (needed for focus handling)
5273 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5275 /* Hide special folders */
5276 #ifndef MODEST_TOOLKIT_HILDON2
5277 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5280 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5281 #ifndef MODEST_TOOLKIT_HILDON2
5282 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5285 gtk_widget_show (GTK_WIDGET (tree_view));
5291 * Shows a confirmation dialog to the user when we're moving messages
5292 * from a remote server to the local storage. Returns the dialog
5293 * response. If it's other kind of movement then it always returns
5296 * This one is used by the next functions:
5297 * modest_ui_actions_on_paste - commented out
5298 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5301 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5302 TnyFolder *dest_folder,
5306 gint response = GTK_RESPONSE_OK;
5307 TnyAccount *account = NULL;
5308 TnyFolder *src_folder = NULL;
5309 TnyIterator *iter = NULL;
5310 TnyHeader *header = NULL;
5312 /* return with OK if the destination is a remote folder */
5313 if (modest_tny_folder_is_remote_folder (dest_folder))
5314 return GTK_RESPONSE_OK;
5316 /* Get source folder */
5317 iter = tny_list_create_iterator (headers);
5318 header = TNY_HEADER (tny_iterator_get_current (iter));
5320 src_folder = tny_header_get_folder (header);
5321 g_object_unref (header);
5323 g_object_unref (iter);
5325 /* if no src_folder, message may be an attahcment */
5326 if (src_folder == NULL)
5327 return GTK_RESPONSE_CANCEL;
5329 /* If the source is a local or MMC folder */
5330 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5331 g_object_unref (src_folder);
5332 return GTK_RESPONSE_OK;
5335 /* Get the account */
5336 account = tny_folder_get_account (src_folder);
5338 /* now if offline we ask the user */
5339 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5340 response = GTK_RESPONSE_OK;
5342 response = GTK_RESPONSE_CANCEL;
5345 g_object_unref (src_folder);
5346 g_object_unref (account);
5352 move_to_helper_destroyer (gpointer user_data)
5354 MoveToHelper *helper = (MoveToHelper *) user_data;
5356 /* Close the "Pasting" information banner */
5357 if (helper->banner) {
5358 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5359 g_object_unref (helper->banner);
5361 if (gtk_tree_row_reference_valid (helper->reference)) {
5362 gtk_tree_row_reference_free (helper->reference);
5363 helper->reference = NULL;
5369 move_to_cb (ModestMailOperation *mail_op,
5372 MoveToHelper *helper = (MoveToHelper *) user_data;
5373 GObject *object = modest_mail_operation_get_source (mail_op);
5375 /* Note that the operation could have failed, in that case do
5377 if (modest_mail_operation_get_status (mail_op) !=
5378 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5381 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5382 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5384 if (!modest_msg_view_window_select_next_message (self) &&
5385 !modest_msg_view_window_select_previous_message (self)) {
5386 /* No more messages to view, so close this window */
5387 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5389 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5390 gtk_tree_row_reference_valid (helper->reference)) {
5391 GtkWidget *header_view;
5393 GtkTreeSelection *sel;
5395 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5396 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5397 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5398 path = gtk_tree_row_reference_get_path (helper->reference);
5399 /* We need to unselect the previous one
5400 because we could be copying instead of
5402 gtk_tree_selection_unselect_all (sel);
5403 gtk_tree_selection_select_path (sel, path);
5404 gtk_tree_path_free (path);
5406 g_object_unref (object);
5409 /* Destroy the helper */
5410 move_to_helper_destroyer (helper);
5414 folder_move_to_cb (ModestMailOperation *mail_op,
5415 TnyFolder *new_folder,
5418 GtkWidget *folder_view;
5421 object = modest_mail_operation_get_source (mail_op);
5422 if (MODEST_IS_MAIN_WINDOW (object)) {
5423 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5424 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5425 g_object_ref (folder_view);
5426 g_object_unref (object);
5427 move_to_cb (mail_op, user_data);
5428 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5429 g_object_unref (folder_view);
5431 move_to_cb (mail_op, user_data);
5436 msgs_move_to_cb (ModestMailOperation *mail_op,
5439 move_to_cb (mail_op, user_data);
5443 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5446 GObject *win = NULL;
5447 const GError *error;
5448 TnyAccount *account = NULL;
5450 #ifndef MODEST_TOOLKIT_HILDON2
5451 ModestWindow *main_window = NULL;
5453 /* Disable next automatic folder selection */
5454 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5455 FALSE); /* don't create */
5457 /* Show notification dialog only if the main window exists */
5459 GtkWidget *folder_view = NULL;
5461 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5462 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5463 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5465 if (user_data && TNY_IS_FOLDER (user_data)) {
5466 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5467 TNY_FOLDER (user_data), FALSE);
5471 win = modest_mail_operation_get_source (mail_op);
5472 error = modest_mail_operation_get_error (mail_op);
5474 if (TNY_IS_FOLDER (user_data))
5475 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5476 else if (TNY_IS_ACCOUNT (user_data))
5477 account = g_object_ref (user_data);
5479 /* If it's not a disk full error then show a generic error */
5480 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5481 (GtkWidget *) win, (GError *) error,
5483 modest_platform_run_information_dialog ((GtkWindow *) win,
5484 _("mail_in_ui_folder_move_target_error"),
5487 g_object_unref (account);
5489 g_object_unref (win);
5493 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5502 gint pending_purges = 0;
5503 gboolean some_purged = FALSE;
5504 ModestWindow *win = MODEST_WINDOW (user_data);
5505 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5507 /* If there was any error */
5508 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5509 modest_window_mgr_unregister_header (mgr, header);
5513 /* Once the message has been retrieved for purging, we check if
5514 * it's all ok for purging */
5516 parts = tny_simple_list_new ();
5517 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5518 iter = tny_list_create_iterator (parts);
5520 while (!tny_iterator_is_done (iter)) {
5522 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5523 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5524 if (tny_mime_part_is_purged (part))
5531 g_object_unref (part);
5533 tny_iterator_next (iter);
5535 g_object_unref (iter);
5538 if (pending_purges>0) {
5540 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5542 if (response == GTK_RESPONSE_OK) {
5545 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5546 iter = tny_list_create_iterator (parts);
5547 while (!tny_iterator_is_done (iter)) {
5550 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5551 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5552 tny_mime_part_set_purged (part);
5555 g_object_unref (part);
5557 tny_iterator_next (iter);
5559 g_object_unref (iter);
5561 tny_msg_rewrite_cache (msg);
5563 gtk_widget_destroy (info);
5567 modest_window_mgr_unregister_header (mgr, header);
5569 g_object_unref (parts);
5573 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5574 ModestMainWindow *win)
5576 GtkWidget *header_view;
5577 TnyList *header_list;
5579 TnyHeaderFlags flags;
5580 ModestWindow *msg_view_window = NULL;
5583 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5585 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5586 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5588 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5590 g_warning ("%s: no header selected", __FUNCTION__);
5594 if (tny_list_get_length (header_list) == 1) {
5595 TnyIterator *iter = tny_list_create_iterator (header_list);
5596 header = TNY_HEADER (tny_iterator_get_current (iter));
5597 g_object_unref (iter);
5601 if (!header || !TNY_IS_HEADER(header)) {
5602 g_warning ("%s: header is not valid", __FUNCTION__);
5606 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5607 header, &msg_view_window);
5608 flags = tny_header_get_flags (header);
5609 if (!(flags & TNY_HEADER_FLAG_CACHED))
5612 if (msg_view_window != NULL)
5613 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5615 /* do nothing; uid was registered before, so window is probably on it's way */
5616 g_debug ("header %p has already been registered", header);
5619 ModestMailOperation *mail_op = NULL;
5620 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5621 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5622 modest_ui_actions_disk_operations_error_handler,
5624 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5625 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5627 g_object_unref (mail_op);
5630 g_object_unref (header);
5632 g_object_unref (header_list);
5636 * Checks if we need a connection to do the transfer and if the user
5637 * wants to connect to complete it
5640 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5641 TnyFolderStore *src_folder,
5643 TnyFolder *dst_folder,
5644 gboolean delete_originals,
5645 gboolean *need_connection,
5648 TnyAccount *src_account;
5649 gint uncached_msgs = 0;
5651 /* We don't need any further check if
5653 * 1- the source folder is local OR
5654 * 2- the device is already online
5656 if (!modest_tny_folder_store_is_remote (src_folder) ||
5657 tny_device_is_online (modest_runtime_get_device())) {
5658 *need_connection = FALSE;
5663 /* We must ask for a connection when
5665 * - the message(s) is not already cached OR
5666 * - the message(s) is cached but the leave_on_server setting
5667 * is FALSE (because we need to sync the source folder to
5668 * delete the message from the server (for IMAP we could do it
5669 * offline, it'll take place the next time we get a
5672 uncached_msgs = header_list_count_uncached_msgs (headers);
5673 src_account = get_account_from_folder_store (src_folder);
5674 if (uncached_msgs > 0) {
5678 *need_connection = TRUE;
5679 num_headers = tny_list_get_length (headers);
5680 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5682 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5683 GTK_RESPONSE_CANCEL) {
5689 /* The transfer is possible and the user wants to */
5692 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5693 const gchar *account_name;
5694 gboolean leave_on_server;
5696 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5697 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5700 if (leave_on_server == TRUE) {
5701 *need_connection = FALSE;
5703 *need_connection = TRUE;
5706 *need_connection = FALSE;
5711 g_object_unref (src_account);
5715 xfer_messages_error_handler (ModestMailOperation *mail_op,
5719 const GError *error;
5720 TnyAccount *account;
5722 win = modest_mail_operation_get_source (mail_op);
5723 error = modest_mail_operation_get_error (mail_op);
5725 /* We cannot get the account from the mail op as that is the
5726 source account and for checking memory full conditions we
5727 need the destination one */
5728 account = TNY_ACCOUNT (user_data);
5731 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5732 (GtkWidget *) win, (GError*) error,
5733 account, _KR("cerm_memory_card_full"))) {
5734 modest_platform_run_information_dialog ((GtkWindow *) win,
5735 _("mail_in_ui_folder_move_target_error"),
5739 g_object_unref (win);
5743 TnyFolderStore *dst_folder;
5748 * Utility function that transfer messages from both the main window
5749 * and the msg view window when using the "Move to" dialog
5752 xfer_messages_performer (gboolean canceled,
5754 GtkWindow *parent_window,
5755 TnyAccount *account,
5758 ModestWindow *win = MODEST_WINDOW (parent_window);
5759 TnyAccount *dst_account = NULL;
5760 gboolean dst_forbids_message_add = FALSE;
5761 XferMsgsHelper *helper;
5762 MoveToHelper *movehelper;
5763 ModestMailOperation *mail_op;
5765 helper = (XferMsgsHelper *) user_data;
5767 if (canceled || err) {
5768 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5769 (GtkWidget *) parent_window, err,
5771 /* Show the proper error message */
5772 modest_ui_actions_on_account_connection_error (parent_window, account);
5777 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5779 /* tinymail will return NULL for local folders it seems */
5780 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5781 modest_tny_account_get_protocol_type (dst_account),
5782 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5784 if (dst_forbids_message_add) {
5785 modest_platform_information_banner (GTK_WIDGET (win),
5787 ngettext("mail_in_ui_folder_move_target_error",
5788 "mail_in_ui_folder_move_targets_error",
5789 tny_list_get_length (helper->headers)));
5793 movehelper = g_new0 (MoveToHelper, 1);
5795 #ifndef MODEST_TOOLKIT_HILDON2
5796 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5797 _CS("ckct_nw_pasting"));
5798 if (movehelper->banner != NULL) {
5799 g_object_ref (movehelper->banner);
5800 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5804 if (MODEST_IS_MAIN_WINDOW (win)) {
5805 GtkWidget *header_view =
5806 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5807 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5808 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5811 /* Perform the mail operation */
5812 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5813 xfer_messages_error_handler,
5814 g_object_ref (dst_account),
5816 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5819 modest_mail_operation_xfer_msgs (mail_op,
5821 TNY_FOLDER (helper->dst_folder),
5826 g_object_unref (G_OBJECT (mail_op));
5829 g_object_unref (dst_account);
5830 g_object_unref (helper->dst_folder);
5831 g_object_unref (helper->headers);
5832 g_slice_free (XferMsgsHelper, helper);
5836 TnyFolder *src_folder;
5837 TnyFolderStore *dst_folder;
5838 gboolean delete_original;
5839 GtkWidget *folder_view;
5843 on_move_folder_cb (gboolean canceled,
5845 GtkWindow *parent_window,
5846 TnyAccount *account,
5849 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5850 GtkTreeSelection *sel;
5851 ModestMailOperation *mail_op = NULL;
5853 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5854 /* Note that the connection process can fail due to
5855 memory low conditions as it can not successfully
5856 store the summary */
5857 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5858 (GtkWidget*) parent_window, err,
5860 g_debug ("Error connecting when trying to move a folder");
5862 g_object_unref (G_OBJECT (info->src_folder));
5863 g_object_unref (G_OBJECT (info->dst_folder));
5868 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5869 #ifndef MODEST_TOOLKIT_HILDON2
5870 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5871 _CS("ckct_nw_pasting"));
5872 if (helper->banner != NULL) {
5873 g_object_ref (helper->banner);
5874 gtk_widget_show (GTK_WIDGET(helper->banner));
5877 /* Clean folder on header view before moving it */
5878 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5879 gtk_tree_selection_unselect_all (sel);
5881 /* Let gtk events run. We need that the folder
5882 view frees its reference to the source
5883 folder *before* issuing the mail operation
5884 so we need the signal handler of selection
5885 changed to happen before the mail
5887 while (gtk_events_pending ())
5888 gtk_main_iteration (); */
5891 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5892 modest_ui_actions_move_folder_error_handler,
5893 g_object_ref (info->dst_folder), g_object_unref);
5894 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5897 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5898 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5899 TNY_FOLDER (info->dst_folder), TRUE);
5901 modest_mail_operation_xfer_folder (mail_op,
5902 TNY_FOLDER (info->src_folder),
5904 info->delete_original,
5907 g_object_unref (G_OBJECT (info->src_folder));
5909 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5912 /* Unref mail operation */
5913 g_object_unref (G_OBJECT (mail_op));
5914 g_object_unref (G_OBJECT (info->dst_folder));
5919 get_account_from_folder_store (TnyFolderStore *folder_store)
5921 if (TNY_IS_ACCOUNT (folder_store))
5922 return g_object_ref (folder_store);
5924 return tny_folder_get_account (TNY_FOLDER (folder_store));
5928 * UI handler for the "Move to" action when invoked from the
5932 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5933 GtkWidget *folder_view,
5934 TnyFolderStore *dst_folder,
5935 ModestMainWindow *win)
5937 ModestHeaderView *header_view = NULL;
5938 TnyFolderStore *src_folder = NULL;
5940 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5942 /* Get the source folder */
5943 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5945 /* Get header view */
5946 header_view = (ModestHeaderView *)
5947 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5949 /* Get folder or messages to transfer */
5950 if (gtk_widget_is_focus (folder_view)) {
5951 gboolean do_xfer = TRUE;
5953 /* Allow only to transfer folders to the local root folder */
5954 if (TNY_IS_ACCOUNT (dst_folder) &&
5955 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5956 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5958 } else if (!TNY_IS_FOLDER (src_folder)) {
5959 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5964 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5965 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5967 info->src_folder = g_object_ref (src_folder);
5968 info->dst_folder = g_object_ref (dst_folder);
5969 info->delete_original = TRUE;
5970 info->folder_view = folder_view;
5972 connect_info->callback = on_move_folder_cb;
5973 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5974 connect_info->data = info;
5976 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5977 TNY_FOLDER_STORE (src_folder),
5980 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5983 headers = modest_header_view_get_selected_headers(header_view);
5985 /* Transfer the messages */
5986 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5987 headers, TNY_FOLDER (dst_folder));
5989 g_object_unref (headers);
5993 g_object_unref (src_folder);
5996 #ifdef MODEST_TOOLKIT_HILDON2
5998 * UI handler for the "Move to" action when invoked from the
5999 * ModestFolderWindow
6002 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6003 TnyFolderStore *dst_folder,
6007 TnyFolderStore *src_folder = NULL;
6008 TnyIterator *iterator;
6010 if (tny_list_get_length (selection) != 1)
6013 iterator = tny_list_create_iterator (selection);
6014 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6015 g_object_unref (iterator);
6018 gboolean do_xfer = TRUE;
6020 /* Allow only to transfer folders to the local root folder */
6021 if (TNY_IS_ACCOUNT (dst_folder) &&
6022 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6023 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6026 modest_platform_run_information_dialog (win,
6027 _("mail_in_ui_folder_move_target_error"),
6029 } else if (!TNY_IS_FOLDER (src_folder)) {
6030 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6035 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6036 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6038 info->src_folder = g_object_ref (src_folder);
6039 info->dst_folder = g_object_ref (dst_folder);
6040 info->delete_original = TRUE;
6041 info->folder_view = folder_view;
6043 connect_info->callback = on_move_folder_cb;
6044 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6045 connect_info->data = info;
6047 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6048 TNY_FOLDER_STORE (src_folder),
6053 g_object_unref (src_folder);
6059 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6060 TnyFolder *src_folder,
6062 TnyFolder *dst_folder)
6064 gboolean need_connection = TRUE;
6065 gboolean do_xfer = TRUE;
6066 XferMsgsHelper *helper;
6068 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6069 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6070 g_return_if_fail (TNY_IS_LIST (headers));
6072 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6073 headers, TNY_FOLDER (dst_folder),
6074 TRUE, &need_connection,
6077 /* If we don't want to transfer just return */
6081 /* Create the helper */
6082 helper = g_slice_new (XferMsgsHelper);
6083 helper->dst_folder = g_object_ref (dst_folder);
6084 helper->headers = g_object_ref (headers);
6086 if (need_connection) {
6087 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6088 connect_info->callback = xfer_messages_performer;
6089 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6090 connect_info->data = helper;
6092 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6093 TNY_FOLDER_STORE (src_folder),
6096 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6097 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6098 src_account, helper);
6099 g_object_unref (src_account);
6104 * UI handler for the "Move to" action when invoked from the
6105 * ModestMsgViewWindow
6108 modest_ui_actions_on_window_move_to (GtkAction *action,
6110 TnyFolderStore *dst_folder,
6113 TnyFolder *src_folder = NULL;
6115 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6118 TnyHeader *header = NULL;
6121 iter = tny_list_create_iterator (headers);
6122 header = (TnyHeader *) tny_iterator_get_current (iter);
6123 src_folder = tny_header_get_folder (header);
6125 /* Transfer the messages */
6126 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6128 TNY_FOLDER (dst_folder));
6131 g_object_unref (header);
6132 g_object_unref (iter);
6133 g_object_unref (src_folder);
6138 modest_ui_actions_on_move_to (GtkAction *action,
6141 modest_ui_actions_on_edit_mode_move_to (win);
6145 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6147 GtkWidget *dialog = NULL;
6148 MoveToInfo *helper = NULL;
6149 TnyList *list_to_move;
6151 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6153 #ifndef MODEST_TOOLKIT_HILDON2
6154 /* Get the main window if exists */
6155 ModestMainWindow *main_window;
6156 if (MODEST_IS_MAIN_WINDOW (win))
6157 main_window = MODEST_MAIN_WINDOW (win);
6160 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6161 FALSE)); /* don't create */
6164 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6169 if (tny_list_get_length (list_to_move) < 1) {
6170 g_object_unref (list_to_move);
6174 /* Create and run the dialog */
6175 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6176 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6177 GTK_WINDOW (dialog),
6181 helper = g_slice_new0 (MoveToInfo);
6182 helper->list = list_to_move;
6185 /* Listen to response signal */
6186 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6188 /* Show the dialog */
6189 gtk_widget_show (dialog);
6195 * Calls #HeadersFunc for each header already selected in the main
6196 * window or the message currently being shown in the msg view window
6199 do_headers_action (ModestWindow *win,
6203 TnyList *headers_list = NULL;
6204 TnyIterator *iter = NULL;
6205 TnyHeader *header = NULL;
6206 TnyFolder *folder = NULL;
6209 headers_list = get_selected_headers (win);
6213 /* Get the folder */
6214 iter = tny_list_create_iterator (headers_list);
6215 header = TNY_HEADER (tny_iterator_get_current (iter));
6217 folder = tny_header_get_folder (header);
6218 g_object_unref (header);
6221 /* Call the function for each header */
6222 while (!tny_iterator_is_done (iter)) {
6223 header = TNY_HEADER (tny_iterator_get_current (iter));
6224 func (header, win, user_data);
6225 g_object_unref (header);
6226 tny_iterator_next (iter);
6229 /* Trick: do a poke status in order to speed up the signaling
6232 tny_folder_poke_status (folder);
6233 g_object_unref (folder);
6237 g_object_unref (iter);
6238 g_object_unref (headers_list);
6242 modest_ui_actions_view_attachment (GtkAction *action,
6243 ModestWindow *window)
6245 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6246 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6248 /* not supported window for this action */
6249 g_return_if_reached ();
6254 modest_ui_actions_save_attachments (GtkAction *action,
6255 ModestWindow *window)
6257 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6259 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6262 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6264 /* not supported window for this action */
6265 g_return_if_reached ();
6270 modest_ui_actions_remove_attachments (GtkAction *action,
6271 ModestWindow *window)
6273 if (MODEST_IS_MAIN_WINDOW (window)) {
6274 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6275 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6276 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6278 /* not supported window for this action */
6279 g_return_if_reached ();
6284 modest_ui_actions_on_settings (GtkAction *action,
6289 dialog = modest_platform_get_global_settings_dialog ();
6290 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6291 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6292 gtk_widget_show_all (dialog);
6294 gtk_dialog_run (GTK_DIALOG (dialog));
6296 gtk_widget_destroy (dialog);
6300 modest_ui_actions_on_help (GtkAction *action,
6303 /* Help app is not available at all in fremantle */
6304 #ifndef MODEST_TOOLKIT_HILDON2
6305 const gchar *help_id;
6307 g_return_if_fail (win && GTK_IS_WINDOW(win));
6309 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6312 modest_platform_show_help (GTK_WINDOW (win), help_id);
6317 modest_ui_actions_on_csm_help (GtkAction *action,
6320 /* Help app is not available at all in fremantle */
6321 #ifndef MODEST_TOOLKIT_HILDON2
6323 const gchar* help_id = NULL;
6324 GtkWidget *folder_view;
6325 TnyFolderStore *folder_store;
6327 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6329 /* Get selected folder */
6330 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6331 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6332 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6334 /* Switch help_id */
6335 if (folder_store && TNY_IS_FOLDER (folder_store))
6336 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6339 g_object_unref (folder_store);
6342 modest_platform_show_help (GTK_WINDOW (win), help_id);
6344 modest_ui_actions_on_help (action, win);
6349 retrieve_contents_cb (ModestMailOperation *mail_op,
6356 /* We only need this callback to show an error in case of
6357 memory low condition */
6358 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6359 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6364 retrieve_msg_contents_performer (gboolean canceled,
6366 GtkWindow *parent_window,
6367 TnyAccount *account,
6370 ModestMailOperation *mail_op;
6371 TnyList *headers = TNY_LIST (user_data);
6373 if (err || canceled) {
6374 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6375 (GtkWidget *) parent_window, err,
6380 /* Create mail operation */
6381 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6382 modest_ui_actions_disk_operations_error_handler,
6384 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6385 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6388 g_object_unref (mail_op);
6390 g_object_unref (headers);
6391 g_object_unref (account);
6395 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6396 ModestWindow *window)
6398 TnyList *headers = NULL;
6399 TnyAccount *account = NULL;
6400 TnyIterator *iter = NULL;
6401 TnyHeader *header = NULL;
6402 TnyFolder *folder = NULL;
6405 headers = get_selected_headers (window);
6409 /* Pick the account */
6410 iter = tny_list_create_iterator (headers);
6411 header = TNY_HEADER (tny_iterator_get_current (iter));
6412 folder = tny_header_get_folder (header);
6413 account = tny_folder_get_account (folder);
6414 g_object_unref (folder);
6415 g_object_unref (header);
6416 g_object_unref (iter);
6418 /* Connect and perform the message retrieval */
6419 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6420 g_object_ref (account),
6421 retrieve_msg_contents_performer,
6422 g_object_ref (headers));
6425 g_object_unref (account);
6426 g_object_unref (headers);
6430 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6432 g_return_if_fail (MODEST_IS_WINDOW (window));
6435 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6439 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6441 g_return_if_fail (MODEST_IS_WINDOW (window));
6444 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6448 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6449 ModestWindow *window)
6451 g_return_if_fail (MODEST_IS_WINDOW (window));
6454 modest_ui_actions_check_menu_dimming_rules (window);
6458 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6459 ModestWindow *window)
6461 g_return_if_fail (MODEST_IS_WINDOW (window));
6464 modest_ui_actions_check_menu_dimming_rules (window);
6468 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6469 ModestWindow *window)
6471 g_return_if_fail (MODEST_IS_WINDOW (window));
6474 modest_ui_actions_check_menu_dimming_rules (window);
6478 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6479 ModestWindow *window)
6481 g_return_if_fail (MODEST_IS_WINDOW (window));
6484 modest_ui_actions_check_menu_dimming_rules (window);
6488 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6489 ModestWindow *window)
6491 g_return_if_fail (MODEST_IS_WINDOW (window));
6494 modest_ui_actions_check_menu_dimming_rules (window);
6498 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6499 ModestWindow *window)
6501 g_return_if_fail (MODEST_IS_WINDOW (window));
6504 modest_ui_actions_check_menu_dimming_rules (window);
6508 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6509 ModestWindow *window)
6511 g_return_if_fail (MODEST_IS_WINDOW (window));
6514 modest_ui_actions_check_menu_dimming_rules (window);
6518 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6519 ModestWindow *window)
6521 g_return_if_fail (MODEST_IS_WINDOW (window));
6524 modest_ui_actions_check_menu_dimming_rules (window);
6528 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6529 ModestWindow *window)
6531 g_return_if_fail (MODEST_IS_WINDOW (window));
6534 modest_ui_actions_check_menu_dimming_rules (window);
6538 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6540 g_return_if_fail (MODEST_IS_WINDOW (window));
6542 /* we check for low-mem; in that case, show a warning, and don't allow
6545 if (modest_platform_check_memory_low (window, TRUE))
6548 modest_platform_show_search_messages (GTK_WINDOW (window));
6552 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6554 g_return_if_fail (MODEST_IS_WINDOW (win));
6557 /* we check for low-mem; in that case, show a warning, and don't allow
6558 * for the addressbook
6560 if (modest_platform_check_memory_low (win, TRUE))
6564 modest_platform_show_addressbook (GTK_WINDOW (win));
6569 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6570 ModestWindow *window)
6573 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6575 if (GTK_IS_TOGGLE_ACTION (action))
6576 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6580 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6585 on_send_receive_finished (ModestMailOperation *mail_op,
6588 GtkWidget *header_view, *folder_view;
6589 TnyFolderStore *folder_store;
6590 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6592 /* Set send/receive operation finished */
6593 modest_main_window_notify_send_receive_completed (main_win);
6595 /* Don't refresh the current folder if there were any errors */
6596 if (modest_mail_operation_get_status (mail_op) !=
6597 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6600 /* Refresh the current folder if we're viewing a window. We do
6601 this because the user won't be able to see the new mails in
6602 the selected folder after a Send&Receive because it only
6603 performs a poke_status, i.e, only the number of read/unread
6604 messages is updated, but the new headers are not
6606 folder_view = modest_main_window_get_child_widget (main_win,
6607 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6611 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6613 /* Do not need to refresh INBOX again because the
6614 update_account does it always automatically */
6615 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6616 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6617 ModestMailOperation *refresh_op;
6619 header_view = modest_main_window_get_child_widget (main_win,
6620 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6622 /* We do not need to set the contents style
6623 because it hasn't changed. We also do not
6624 need to save the widget status. Just force
6626 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6627 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6628 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6629 folder_refreshed_cb, main_win);
6630 g_object_unref (refresh_op);
6634 g_object_unref (folder_store);
6639 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6645 const gchar* server_name = NULL;
6646 TnyTransportAccount *transport;
6647 gchar *message = NULL;
6648 ModestProtocol *protocol;
6650 /* Don't show anything if the user cancelled something or the
6651 * send receive request is not interactive. Authentication
6652 * errors are managed by the account store so no need to show
6653 * a dialog here again */
6654 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6655 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6656 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6660 /* Get the server name. Note that we could be using a
6661 connection specific transport account */
6662 transport = (TnyTransportAccount *)
6663 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6665 ModestTnyAccountStore *acc_store;
6666 const gchar *acc_name;
6667 TnyTransportAccount *conn_specific;
6669 acc_store = modest_runtime_get_account_store();
6670 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6671 conn_specific = (TnyTransportAccount *)
6672 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6673 if (conn_specific) {
6674 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6675 g_object_unref (conn_specific);
6677 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6679 g_object_unref (transport);
6683 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6684 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6685 tny_account_get_proto (TNY_ACCOUNT (transport)));
6687 g_warning ("%s: Account with no proto", __FUNCTION__);
6691 /* Show the appropriate message text for the GError: */
6692 switch (err->code) {
6693 case TNY_SERVICE_ERROR_CONNECT:
6694 message = modest_protocol_get_translation (protocol,
6695 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6698 case TNY_SERVICE_ERROR_SEND:
6699 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6701 case TNY_SERVICE_ERROR_UNAVAILABLE:
6702 message = modest_protocol_get_translation (protocol,
6703 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6707 g_warning ("%s: unexpected ERROR %d",
6708 __FUNCTION__, err->code);
6709 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6713 modest_platform_run_information_dialog (NULL, message, FALSE);
6718 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6723 ModestWindow *top_window = NULL;
6724 ModestWindowMgr *mgr = NULL;
6725 GtkWidget *header_view = NULL;
6726 TnyFolder *selected_folder = NULL;
6727 TnyFolderType folder_type;
6729 mgr = modest_runtime_get_window_mgr ();
6730 top_window = modest_window_mgr_get_current_top (mgr);
6735 #ifndef MODEST_TOOLKIT_HILDON2
6736 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6737 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6738 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6741 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6742 header_view = (GtkWidget *)
6743 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6747 /* Get selected folder */
6749 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6750 if (!selected_folder)
6753 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6754 #if GTK_CHECK_VERSION(2, 8, 0)
6755 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6756 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6757 GtkTreeViewColumn *tree_column;
6759 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6760 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6762 gtk_tree_view_column_queue_resize (tree_column);
6764 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6765 gtk_widget_queue_draw (header_view);
6768 #ifndef MODEST_TOOLKIT_HILDON2
6769 /* Rerun dimming rules, because the message could become deletable for example */
6770 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6771 MODEST_DIMMING_RULES_TOOLBAR);
6772 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6773 MODEST_DIMMING_RULES_MENU);
6777 g_object_unref (selected_folder);
6781 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6782 TnyAccount *account)
6784 ModestProtocolType protocol_type;
6785 ModestProtocol *protocol;
6786 gchar *error_note = NULL;
6788 protocol_type = modest_tny_account_get_protocol_type (account);
6789 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6792 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6793 if (error_note == NULL) {
6794 g_warning ("%s: This should not be reached", __FUNCTION__);
6796 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6797 g_free (error_note);
6802 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6806 TnyFolderStore *folder = NULL;
6807 TnyAccount *account = NULL;
6808 ModestProtocolType proto;
6809 ModestProtocol *protocol;
6810 TnyHeader *header = NULL;
6812 if (MODEST_IS_MAIN_WINDOW (win)) {
6813 GtkWidget *header_view;
6814 TnyList* headers = NULL;
6816 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6817 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6818 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6819 if (!headers || tny_list_get_length (headers) == 0) {
6821 g_object_unref (headers);
6824 iter = tny_list_create_iterator (headers);
6825 header = TNY_HEADER (tny_iterator_get_current (iter));
6826 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6827 g_object_unref (iter);
6828 g_object_unref (headers);
6829 #ifdef MODEST_TOOLKIT_HILDON2
6830 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6831 GtkWidget *header_view;
6832 TnyList* headers = NULL;
6834 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6835 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6836 if (!headers || tny_list_get_length (headers) == 0) {
6838 g_object_unref (headers);
6841 iter = tny_list_create_iterator (headers);
6842 header = TNY_HEADER (tny_iterator_get_current (iter));
6844 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6846 g_warning ("List should contain headers");
6848 g_object_unref (iter);
6849 g_object_unref (headers);
6851 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6852 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6854 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6857 if (!header || !folder)
6860 /* Get the account type */
6861 account = tny_folder_get_account (TNY_FOLDER (folder));
6862 proto = modest_tny_account_get_protocol_type (account);
6863 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6866 subject = tny_header_dup_subject (header);
6867 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6871 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6877 g_object_unref (account);
6879 g_object_unref (folder);
6881 g_object_unref (header);
6887 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6888 const gchar *account_name,
6889 const gchar *account_title)
6891 ModestAccountMgr *account_mgr;
6894 ModestProtocol *protocol;
6895 gboolean removed = FALSE;
6897 g_return_val_if_fail (account_name, FALSE);
6898 g_return_val_if_fail (account_title, FALSE);
6900 account_mgr = modest_runtime_get_account_mgr();
6902 /* The warning text depends on the account type: */
6903 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6904 modest_account_mgr_get_store_protocol (account_mgr,
6906 txt = modest_protocol_get_translation (protocol,
6907 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6910 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6912 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6916 if (response == GTK_RESPONSE_OK) {
6917 /* Remove account. If it succeeds then it also removes
6918 the account from the ModestAccountView: */
6919 gboolean is_default = FALSE;
6920 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6921 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6923 g_free (default_account_name);
6925 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6927 /* Close all email notifications, we cannot
6928 distinguish if the notification belongs to
6929 this account or not, so for safety reasons
6930 we remove them all */
6931 modest_platform_remove_new_mail_notifications (FALSE);
6933 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6940 on_fetch_images_performer (gboolean canceled,
6942 GtkWindow *parent_window,
6943 TnyAccount *account,
6946 if (err || canceled) {
6947 /* Show an unable to retrieve images ??? */
6951 /* Note that the user could have closed the window while connecting */
6952 if (GTK_WIDGET_VISIBLE (parent_window))
6953 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6954 g_object_unref ((GObject *) user_data);
6958 modest_ui_actions_on_fetch_images (GtkAction *action,
6959 ModestWindow *window)
6961 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6963 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6965 on_fetch_images_performer,
6966 g_object_ref (window));
6970 modest_ui_actions_on_reload_message (const gchar *msg_id)
6972 ModestWindow *window = NULL;
6974 g_return_if_fail (msg_id && msg_id[0] != '\0');
6975 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6981 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6984 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
6987 /** Check whether any connections are active, and cancel them if
6989 * Returns TRUE is there was no problem,
6990 * or if an operation was cancelled so we can continue.
6991 * Returns FALSE if the user chose to cancel his request instead.
6995 modest_ui_actions_check_for_active_account (ModestWindow *self,
6996 const gchar* account_name)
6998 ModestTnySendQueue *send_queue;
6999 ModestTnyAccountStore *acc_store;
7000 ModestMailOperationQueue* queue;
7001 TnyConnectionStatus store_conn_status;
7002 TnyAccount *store_account = NULL, *transport_account = NULL;
7003 gboolean retval = TRUE, sending = FALSE;
7005 acc_store = modest_runtime_get_account_store ();
7006 queue = modest_runtime_get_mail_operation_queue ();
7009 modest_tny_account_store_get_server_account (acc_store,
7011 TNY_ACCOUNT_TYPE_STORE);
7013 /* This could happen if the account was deleted before the
7014 call to this function */
7019 modest_tny_account_store_get_server_account (acc_store,
7021 TNY_ACCOUNT_TYPE_TRANSPORT);
7023 /* This could happen if the account was deleted before the
7024 call to this function */
7025 if (!transport_account) {
7026 g_object_unref (store_account);
7030 /* If the transport account was not used yet, then the send
7031 queue could not exist (it's created on demand) */
7032 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7033 if (TNY_IS_SEND_QUEUE (send_queue))
7034 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7036 store_conn_status = tny_account_get_connection_status (store_account);
7037 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7040 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7041 _("emev_nc_disconnect_account"));
7042 if (response == GTK_RESPONSE_OK) {
7051 /* FIXME: We should only cancel those of this account */
7052 modest_mail_operation_queue_cancel_all (queue);
7054 /* Also disconnect the account */
7055 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7056 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7057 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7061 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7067 g_object_unref (store_account);
7068 g_object_unref (transport_account);