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>
88 #include <tny-camel-bs-msg.h>
89 #include <tny-camel-bs-mime-part.h>
92 #include <gtkhtml/gtkhtml.h>
94 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
96 typedef struct _GetMsgAsyncHelper {
98 ModestMailOperation *mail_op;
105 typedef enum _ReplyForwardAction {
109 } ReplyForwardAction;
111 typedef struct _ReplyForwardHelper {
112 guint reply_forward_type;
113 ReplyForwardAction action;
116 GtkWidget *parent_window;
119 } ReplyForwardHelper;
121 typedef struct _MoveToHelper {
122 GtkTreeRowReference *reference;
126 typedef struct _PasteAsAttachmentHelper {
127 ModestMsgEditWindow *window;
129 } PasteAsAttachmentHelper;
137 * The do_headers_action uses this kind of functions to perform some
138 * action to each member of a list of headers
140 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
142 static void do_headers_action (ModestWindow *win,
146 static void open_msg_cb (ModestMailOperation *mail_op,
153 static void reply_forward_cb (ModestMailOperation *mail_op,
160 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
162 static void folder_refreshed_cb (ModestMailOperation *mail_op,
166 static void on_send_receive_finished (ModestMailOperation *mail_op,
169 static gint header_list_count_uncached_msgs (TnyList *header_list);
171 static gboolean connect_to_get_msg (ModestWindow *win,
172 gint num_of_uncached_msgs,
173 TnyAccount *account);
175 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
177 static void do_create_folder (GtkWindow *window,
178 TnyFolderStore *parent_folder,
179 const gchar *suggested_name);
181 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
183 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
184 GtkWidget *folder_view,
185 TnyFolderStore *dst_folder,
186 ModestMainWindow *win);
187 #ifdef MODEST_TOOLKIT_HILDON2
188 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
189 TnyFolderStore *dst_folder,
194 static void modest_ui_actions_on_window_move_to (GtkAction *action,
195 TnyList *list_to_move,
196 TnyFolderStore *dst_folder,
200 * This function checks whether a TnyFolderStore is a pop account
203 remote_folder_has_leave_on_server (TnyFolderStore *folder)
208 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
210 account = get_account_from_folder_store (folder);
211 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
212 modest_tny_account_get_protocol_type (account)));
213 g_object_unref (account);
218 /* FIXME: this should be merged with the similar code in modest-account-view-window */
219 /* Show the account creation wizard dialog.
220 * returns: TRUE if an account was created. FALSE if the user cancelled.
223 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
225 gboolean result = FALSE;
227 gint dialog_response;
229 /* there is no such wizard yet */
230 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
231 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
233 #ifndef MODEST_TOOLKIT_HILDON2
234 /* always present a main window in the background
235 * we do it here, so we cannot end up with two wizards (as this
236 * function might be called in modest_window_mgr_get_main_window as well */
238 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
239 TRUE); /* create if not existent */
243 ModestWindowMgr *mgr;
245 mgr = modest_runtime_get_window_mgr ();
247 window_list = modest_window_mgr_get_window_list (mgr);
248 if (window_list == NULL) {
249 win = MODEST_WINDOW (modest_accounts_window_new ());
250 if (modest_window_mgr_register_window (mgr, win, NULL)) {
251 gtk_widget_show_all (GTK_WIDGET (win));
253 gtk_widget_destroy (GTK_WIDGET (win));
258 g_list_free (window_list);
264 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
266 /* make sure the mainwindow is visible. We need to present the
267 wizard again to give it the focus back. show_all are needed
268 in order to get the widgets properly drawn (MainWindow main
269 paned won't be in its right position and the dialog will be
271 #ifndef MODEST_TOOLKIT_HILDON2
272 gtk_widget_show_all (GTK_WIDGET (win));
273 gtk_widget_show_all (GTK_WIDGET (wizard));
274 gtk_window_present (GTK_WINDOW (win));
275 gtk_window_present (GTK_WINDOW (wizard));
278 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
279 gtk_widget_destroy (GTK_WIDGET (wizard));
280 if (gtk_events_pending ())
281 gtk_main_iteration ();
283 if (dialog_response == GTK_RESPONSE_CANCEL) {
286 /* Check whether an account was created: */
287 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
294 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
297 const gchar *authors[] = {
298 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
301 about = gtk_about_dialog_new ();
302 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
303 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
304 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
305 _("Copyright (c) 2006, Nokia Corporation\n"
306 "All rights reserved."));
307 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
308 _("a modest e-mail client\n\n"
309 "design and implementation: Dirk-Jan C. Binnema\n"
310 "contributions from the fine people at KC and Ig\n"
311 "uses the tinymail email framework written by Philip van Hoof"));
312 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
313 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
314 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
315 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
317 gtk_dialog_run (GTK_DIALOG (about));
318 gtk_widget_destroy(about);
322 * Gets the list of currently selected messages. If the win is the
323 * main window, then it returns a newly allocated list of the headers
324 * selected in the header view. If win is the msg view window, then
325 * the value returned is a list with just a single header.
327 * The caller of this funcion must free the list.
330 get_selected_headers (ModestWindow *win)
332 if (MODEST_IS_MAIN_WINDOW(win)) {
333 GtkWidget *header_view;
335 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
336 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
337 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
339 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
340 /* for MsgViewWindows, we simply return a list with one element */
342 TnyList *list = NULL;
344 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
345 if (header != NULL) {
346 list = tny_simple_list_new ();
347 tny_list_prepend (list, G_OBJECT(header));
348 g_object_unref (G_OBJECT(header));
353 #ifdef MODEST_TOOLKIT_HILDON2
354 } else if (MODEST_IS_HEADER_WINDOW (win)) {
355 GtkWidget *header_view;
357 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
358 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
364 static GtkTreeRowReference *
365 get_next_after_selected_headers (ModestHeaderView *header_view)
367 GtkTreeSelection *sel;
368 GList *selected_rows, *node;
370 GtkTreeRowReference *result;
373 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
374 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
375 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
377 if (selected_rows == NULL)
380 node = g_list_last (selected_rows);
381 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
382 gtk_tree_path_next (path);
384 result = gtk_tree_row_reference_new (model, path);
386 gtk_tree_path_free (path);
387 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
388 g_list_free (selected_rows);
394 headers_action_mark_as_read (TnyHeader *header,
398 TnyHeaderFlags flags;
400 g_return_if_fail (TNY_IS_HEADER(header));
402 flags = tny_header_get_flags (header);
403 if (flags & TNY_HEADER_FLAG_SEEN) return;
404 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
408 headers_action_mark_as_unread (TnyHeader *header,
412 TnyHeaderFlags flags;
414 g_return_if_fail (TNY_IS_HEADER(header));
416 flags = tny_header_get_flags (header);
417 if (flags & TNY_HEADER_FLAG_SEEN) {
418 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
422 /** After deleing a message that is currently visible in a window,
423 * show the next message from the list, or close the window if there are no more messages.
426 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
428 /* Close msg view window or select next */
429 if (!modest_msg_view_window_select_next_message (win) &&
430 !modest_msg_view_window_select_previous_message (win)) {
432 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
438 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
440 modest_ui_actions_on_edit_mode_delete_message (win);
444 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
446 TnyList *header_list = NULL;
447 TnyIterator *iter = NULL;
448 TnyHeader *header = NULL;
449 gchar *message = NULL;
452 ModestWindowMgr *mgr;
453 GtkWidget *header_view = NULL;
454 gboolean retval = TRUE;
456 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
458 /* Check first if the header view has the focus */
459 if (MODEST_IS_MAIN_WINDOW (win)) {
461 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
462 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
463 if (!gtk_widget_is_focus (header_view))
467 /* Get the headers, either from the header view (if win is the main window),
468 * or from the message view window: */
469 header_list = get_selected_headers (win);
470 if (!header_list) return FALSE;
472 /* Check if any of the headers are already opened, or in the process of being opened */
473 if (MODEST_IS_MAIN_WINDOW (win)) {
474 gint opened_headers = 0;
476 iter = tny_list_create_iterator (header_list);
477 mgr = modest_runtime_get_window_mgr ();
478 while (!tny_iterator_is_done (iter)) {
479 header = TNY_HEADER (tny_iterator_get_current (iter));
481 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
483 g_object_unref (header);
485 tny_iterator_next (iter);
487 g_object_unref (iter);
489 if (opened_headers > 0) {
492 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
495 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
498 g_object_unref (header_list);
504 if (tny_list_get_length(header_list) == 1) {
505 iter = tny_list_create_iterator (header_list);
506 header = TNY_HEADER (tny_iterator_get_current (iter));
509 subject = tny_header_dup_subject (header);
511 subject = g_strdup (_("mail_va_no_subject"));
512 desc = g_strdup_printf ("%s", subject);
514 g_object_unref (header);
517 g_object_unref (iter);
519 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
520 tny_list_get_length(header_list)), desc);
522 /* Confirmation dialog */
523 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
527 if (response == GTK_RESPONSE_OK) {
528 ModestWindowMgr *mgr = NULL;
529 GtkTreeModel *model = NULL;
530 GtkTreeSelection *sel = NULL;
531 GList *sel_list = NULL, *tmp = NULL;
532 GtkTreeRowReference *next_row_reference = NULL;
533 GtkTreeRowReference *prev_row_reference = NULL;
534 GtkTreePath *next_path = NULL;
535 GtkTreePath *prev_path = NULL;
536 ModestMailOperation *mail_op = NULL;
538 /* Find last selected row */
539 if (MODEST_IS_MAIN_WINDOW (win)) {
540 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
541 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
542 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
543 for (tmp=sel_list; tmp; tmp=tmp->next) {
544 if (tmp->next == NULL) {
545 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
546 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
548 gtk_tree_path_prev (prev_path);
549 gtk_tree_path_next (next_path);
551 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
552 next_row_reference = gtk_tree_row_reference_new (model, next_path);
557 /* Disable window dimming management */
558 modest_window_disable_dimming (win);
560 /* Remove each header. If it's a view window header_view == NULL */
561 mail_op = modest_mail_operation_new ((GObject *) win);
562 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
564 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
565 g_object_unref (mail_op);
567 /* Enable window dimming management */
569 gtk_tree_selection_unselect_all (sel);
571 modest_window_enable_dimming (win);
573 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
574 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
576 /* Get main window */
577 mgr = modest_runtime_get_window_mgr ();
578 } else if (MODEST_IS_MAIN_WINDOW (win)) {
579 /* Select next or previous row */
580 if (gtk_tree_row_reference_valid (next_row_reference)) {
581 gtk_tree_selection_select_path (sel, next_path);
583 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
584 gtk_tree_selection_select_path (sel, prev_path);
588 if (gtk_tree_row_reference_valid (next_row_reference))
589 gtk_tree_row_reference_free (next_row_reference);
590 if (next_path != NULL)
591 gtk_tree_path_free (next_path);
592 if (gtk_tree_row_reference_valid (prev_row_reference))
593 gtk_tree_row_reference_free (prev_row_reference);
594 if (prev_path != NULL)
595 gtk_tree_path_free (prev_path);
598 /* Update toolbar dimming state */
599 modest_ui_actions_check_menu_dimming_rules (win);
600 modest_ui_actions_check_toolbar_dimming_rules (win);
603 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
604 g_list_free (sel_list);
613 g_object_unref (header_list);
621 /* delete either message or folder, based on where we are */
623 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
625 g_return_if_fail (MODEST_IS_WINDOW(win));
627 /* Check first if the header view has the focus */
628 if (MODEST_IS_MAIN_WINDOW (win)) {
630 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
631 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
632 if (gtk_widget_is_focus (w)) {
633 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
637 modest_ui_actions_on_delete_message (action, win);
641 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
643 ModestWindowMgr *mgr = NULL;
645 #ifdef MODEST_PLATFORM_MAEMO
646 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
647 #endif /* MODEST_PLATFORM_MAEMO */
649 g_debug ("closing down, clearing %d item(s) from operation queue",
650 modest_mail_operation_queue_num_elements
651 (modest_runtime_get_mail_operation_queue()));
653 /* cancel all outstanding operations */
654 modest_mail_operation_queue_cancel_all
655 (modest_runtime_get_mail_operation_queue());
657 g_debug ("queue has been cleared");
660 /* Check if there are opened editing windows */
661 mgr = modest_runtime_get_window_mgr ();
662 modest_window_mgr_close_all_windows (mgr);
664 /* note: when modest-tny-account-store is finalized,
665 it will automatically set all network connections
668 /* gtk_main_quit (); */
672 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
676 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
678 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
679 /* gtk_widget_destroy (GTK_WIDGET (win)); */
680 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
681 /* gboolean ret_value; */
682 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
683 /* } else if (MODEST_IS_WINDOW (win)) { */
684 /* gtk_widget_destroy (GTK_WIDGET (win)); */
686 /* g_return_if_reached (); */
691 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
693 if (MODEST_IS_MSG_VIEW_WINDOW (win))
694 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
695 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
696 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
700 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
702 GtkClipboard *clipboard = NULL;
703 gchar *selection = NULL;
705 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
706 selection = gtk_clipboard_wait_for_text (clipboard);
709 modest_address_book_add_address (selection, (GtkWindow *) win);
715 modest_ui_actions_on_new_account (GtkAction *action,
716 ModestWindow *window)
718 if (!modest_ui_actions_run_account_setup_wizard (window)) {
719 g_debug ("%s: wizard was already running", __FUNCTION__);
724 modest_ui_actions_on_accounts (GtkAction *action,
727 /* This is currently only implemented for Maemo */
728 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
729 if (!modest_ui_actions_run_account_setup_wizard (win))
730 g_debug ("%s: wizard was already running", __FUNCTION__);
734 /* Show the list of accounts */
735 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
737 /* The accounts dialog must be modal */
738 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
739 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
744 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
746 /* This is currently only implemented for Maemo,
747 * because it requires an API (libconic) to detect different connection
750 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
752 /* Create the window if necessary: */
753 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
754 modest_connection_specific_smtp_window_fill_with_connections (
755 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
756 modest_runtime_get_account_mgr());
758 /* Show the window: */
759 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
760 GTK_WINDOW (specific_window), (GtkWindow *) win);
761 gtk_widget_show (specific_window);
762 #endif /* !MODEST_TOOLKIT_GTK */
766 count_part_size (const gchar *part)
768 GnomeVFSURI *vfs_uri;
769 gchar *escaped_filename;
771 GnomeVFSFileInfo *info;
774 /* Estimation of attachment size if we cannot get it from file info */
777 vfs_uri = gnome_vfs_uri_new (part);
779 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
780 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
781 g_free (escaped_filename);
782 gnome_vfs_uri_unref (vfs_uri);
784 info = gnome_vfs_file_info_new ();
786 if (gnome_vfs_get_file_info (part,
788 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
790 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
795 gnome_vfs_file_info_unref (info);
801 count_parts_size (GSList *parts)
806 for (node = parts; node != NULL; node = g_slist_next (node)) {
807 result += count_part_size ((const gchar *) node->data);
814 modest_ui_actions_compose_msg(ModestWindow *win,
817 const gchar *bcc_str,
818 const gchar *subject_str,
819 const gchar *body_str,
821 gboolean set_as_modified)
823 gchar *account_name = NULL;
824 const gchar *mailbox;
826 TnyAccount *account = NULL;
827 TnyFolder *folder = NULL;
828 gchar *from_str = NULL, *signature = NULL, *body = NULL;
829 gchar *recipient = NULL;
830 gboolean use_signature = FALSE;
831 ModestWindow *msg_win = NULL;
832 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
833 ModestTnyAccountStore *store = modest_runtime_get_account_store();
834 GnomeVFSFileSize total_size, allowed_size;
835 guint64 available_disk, expected_size, parts_size;
838 /* we check for low-mem */
839 if (modest_platform_check_memory_low (win, TRUE))
842 available_disk = modest_utils_get_available_space (NULL);
843 parts_count = g_slist_length (attachments);
844 parts_size = count_parts_size (attachments);
845 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
847 /* Double check: disk full condition or message too big */
848 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
849 expected_size > available_disk) {
850 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
851 modest_platform_system_banner (NULL, NULL, msg);
857 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
858 modest_platform_run_information_dialog (
860 _("mail_ib_error_attachment_size"),
866 #ifdef MODEST_TOOLKIT_HILDON2
868 account_name = g_strdup (modest_window_get_active_account(win));
871 account_name = modest_account_mgr_get_default_account(mgr);
874 g_printerr ("modest: no account found\n");
879 mailbox = modest_window_get_active_mailbox (win);
882 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
884 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
887 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
889 g_printerr ("modest: failed to find Drafts folder\n");
892 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
894 g_printerr ("modest: failed get from string for '%s'\n", account_name);
898 recipient = modest_text_utils_get_email_address (from_str);
899 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
901 if (body_str != NULL) {
902 body = use_signature ? g_strconcat(body_str, "\n",
903 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
904 "\n", signature, NULL) : g_strdup(body_str);
907 gchar *gray_color_markup = NULL, *color_begin = NULL, *color_end = NULL;
910 if (win && gtk_style_lookup_color (gtk_widget_get_style ((GtkWidget *) win),
911 "SecondaryTextColor", &color))
912 gray_color_markup = modest_text_utils_get_color_string (&color);
913 if (!gray_color_markup)
914 gray_color_markup = g_strdup ("#babababababa");
916 color_begin = g_strdup_printf ("<font color=\"%s\">", gray_color_markup);
917 color_end = "</font>";
919 body = use_signature ? g_strconcat("<br/>\n", color_begin,
920 MODEST_TEXT_UTILS_SIGNATURE_MARKER, "<br/>\n",
921 signature, color_end, NULL) : g_strdup("");
923 g_free (gray_color_markup);
924 g_free (color_begin);
927 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
928 NULL, NULL, body, NULL, NULL, NULL, NULL, NULL);
930 g_printerr ("modest: failed to create new msg\n");
934 /* Create and register edit window */
935 /* This is destroyed by TODO. */
937 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
938 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
940 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
941 gtk_widget_destroy (GTK_WIDGET (msg_win));
944 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
945 gtk_widget_show_all (GTK_WIDGET (msg_win));
947 while (attachments) {
948 GnomeVFSFileSize att_size;
950 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
951 attachments->data, allowed_size);
952 total_size += att_size;
954 if (att_size > allowed_size) {
955 g_debug ("%s: total size: %u",
956 __FUNCTION__, (unsigned int)total_size);
959 allowed_size -= att_size;
961 attachments = g_slist_next(attachments);
968 g_free (account_name);
970 g_object_unref (G_OBJECT(account));
972 g_object_unref (G_OBJECT(folder));
974 g_object_unref (G_OBJECT(msg));
978 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
980 /* if there are no accounts yet, just show the wizard */
981 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
982 if (!modest_ui_actions_run_account_setup_wizard (win))
985 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
990 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
994 ModestMailOperationStatus status;
996 /* If there is no message or the operation was not successful */
997 status = modest_mail_operation_get_status (mail_op);
998 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
1001 /* If it's a memory low issue, then show a banner */
1002 error = modest_mail_operation_get_error (mail_op);
1003 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
1004 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
1005 GObject *source = modest_mail_operation_get_source (mail_op);
1006 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
1007 _KR("memr_ib_operation_disabled"),
1009 g_object_unref (source);
1012 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
1013 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
1014 gchar *subject, *msg, *format = NULL;
1015 TnyAccount *account;
1017 subject = (header) ? tny_header_dup_subject (header) : NULL;
1019 subject = g_strdup (_("mail_va_no_subject"));
1021 account = modest_mail_operation_get_account (mail_op);
1023 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1024 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1027 if (tny_account_get_connection_status (account) ==
1028 TNY_CONNECTION_STATUS_CONNECTED) {
1030 format = modest_protocol_get_translation (protocol,
1031 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1034 format = modest_protocol_get_translation (protocol,
1035 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1038 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1039 tny_account_get_hostname (account));
1042 g_object_unref (account);
1047 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1049 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1053 msg = g_strdup_printf (format, subject);
1054 modest_platform_run_information_dialog (NULL, msg, FALSE);
1060 /* Remove the header from the preregistered uids */
1061 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1074 } OpenMsgBannerInfo;
1077 GtkTreeModel *model;
1079 ModestWindow *caller_window;
1080 OpenMsgBannerInfo *banner_info;
1081 GtkTreeRowReference *rowref;
1085 open_msg_banner_idle (gpointer userdata)
1087 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1089 gdk_threads_enter ();
1090 banner_info->idle_handler = 0;
1091 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1092 if (banner_info->banner)
1093 g_object_ref (banner_info->banner);
1095 gdk_threads_leave ();
1101 get_header_view_from_window (ModestWindow *window)
1103 GtkWidget *header_view;
1105 if (MODEST_IS_MAIN_WINDOW (window)) {
1106 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1107 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1108 #ifdef MODEST_TOOLKIT_HILDON2
1109 } else if (MODEST_IS_HEADER_WINDOW (window)){
1110 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1120 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1123 gchar *account = NULL;
1124 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1129 folder = tny_header_get_folder (header);
1130 /* Gets folder type (OUTBOX headers will be opened in edit window */
1131 if (modest_tny_folder_is_local_folder (folder)) {
1132 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1133 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1134 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1137 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1138 TnyTransportAccount *traccount = NULL;
1139 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1140 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1142 ModestTnySendQueue *send_queue = NULL;
1143 ModestTnySendQueueStatus status;
1145 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1146 TNY_ACCOUNT(traccount)));
1147 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1148 if (TNY_IS_SEND_QUEUE (send_queue)) {
1149 msg_id = modest_tny_send_queue_get_msg_id (header);
1150 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1152 /* Only open messages in outbox with the editor if they are in Failed state */
1153 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1156 #ifdef MODEST_TOOLKIT_HILDON2
1158 /* In Fremantle we can not
1159 open any message from
1160 outbox which is not in
1166 g_object_unref(traccount);
1168 g_warning("Cannot get transport account for message in outbox!!");
1170 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1171 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1175 TnyAccount *acc = tny_folder_get_account (folder);
1178 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1179 g_object_unref (acc);
1183 g_object_unref (folder);
1189 open_msg_cb (ModestMailOperation *mail_op,
1196 ModestWindowMgr *mgr = NULL;
1197 ModestWindow *parent_win = NULL;
1198 ModestWindow *win = NULL;
1199 gchar *account = NULL;
1200 gboolean open_in_editor = FALSE;
1202 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1204 /* Do nothing if there was any problem with the mail
1205 operation. The error will be shown by the error_handler of
1206 the mail operation */
1207 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1210 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1212 /* Mark header as read */
1213 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1215 account = get_info_from_header (header, &open_in_editor, &can_open);
1219 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1221 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1223 if (open_in_editor) {
1224 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1225 gchar *from_header = NULL, *acc_name;
1226 gchar *mailbox = NULL;
1228 from_header = tny_header_dup_from (header);
1230 /* we cannot edit without a valid account... */
1231 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1232 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1233 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1235 g_free (from_header);
1240 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1241 g_free (from_header);
1247 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1251 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1252 const gchar *mailbox = NULL;
1254 if (parent_win && MODEST_IS_WINDOW (parent_win))
1255 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1257 if (helper->rowref && helper->model) {
1258 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1259 helper->model, helper->rowref);
1261 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1266 /* Register and show new window */
1268 mgr = modest_runtime_get_window_mgr ();
1269 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1270 gtk_widget_destroy (GTK_WIDGET (win));
1273 gtk_widget_show_all (GTK_WIDGET(win));
1276 /* Update toolbar dimming state */
1277 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1278 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1284 g_object_unref (parent_win);
1288 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1291 const GError *error;
1292 GObject *win = NULL;
1293 ModestMailOperationStatus status;
1295 win = modest_mail_operation_get_source (mail_op);
1296 error = modest_mail_operation_get_error (mail_op);
1297 status = modest_mail_operation_get_status (mail_op);
1299 /* If the mail op has been cancelled then it's not an error:
1300 don't show any message */
1301 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1302 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1303 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1304 (GError *) error, account)) {
1305 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1306 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1308 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1309 modest_platform_information_banner ((GtkWidget *) win,
1310 NULL, _("emev_ui_imap_inbox_select_error"));
1311 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1312 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1313 modest_platform_information_banner ((GtkWidget *) win,
1314 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1315 } else if (user_data) {
1316 modest_platform_information_banner ((GtkWidget *) win,
1320 g_object_unref (account);
1324 g_object_unref (win);
1328 * Returns the account a list of headers belongs to. It returns a
1329 * *new* reference so don't forget to unref it
1332 get_account_from_header_list (TnyList *headers)
1334 TnyAccount *account = NULL;
1336 if (tny_list_get_length (headers) > 0) {
1337 TnyIterator *iter = tny_list_create_iterator (headers);
1338 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1339 TnyFolder *folder = tny_header_get_folder (header);
1342 g_object_unref (header);
1344 while (!tny_iterator_is_done (iter)) {
1345 header = TNY_HEADER (tny_iterator_get_current (iter));
1346 folder = tny_header_get_folder (header);
1349 g_object_unref (header);
1351 tny_iterator_next (iter);
1356 account = tny_folder_get_account (folder);
1357 g_object_unref (folder);
1361 g_object_unref (header);
1363 g_object_unref (iter);
1369 get_account_from_header (TnyHeader *header)
1371 TnyAccount *account = NULL;
1374 folder = tny_header_get_folder (header);
1377 account = tny_folder_get_account (folder);
1378 g_object_unref (folder);
1384 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1386 if (helper->caller_window)
1387 helper->caller_window = NULL;
1391 open_msg_helper_destroyer (gpointer user_data)
1393 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1395 if (helper->caller_window) {
1396 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1397 helper->caller_window = NULL;
1400 if (helper->banner_info) {
1401 g_free (helper->banner_info->message);
1402 if (helper->banner_info->idle_handler > 0) {
1403 g_source_remove (helper->banner_info->idle_handler);
1404 helper->banner_info->idle_handler = 0;
1406 if (helper->banner_info->banner != NULL) {
1407 gtk_widget_destroy (helper->banner_info->banner);
1408 g_object_unref (helper->banner_info->banner);
1409 helper->banner_info->banner = NULL;
1411 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1412 helper->banner_info = NULL;
1414 g_object_unref (helper->model);
1415 g_object_unref (helper->header);
1416 gtk_tree_row_reference_free (helper->rowref);
1417 g_slice_free (OpenMsgHelper, helper);
1421 open_msg_performer(gboolean canceled,
1423 GtkWindow *parent_window,
1424 TnyAccount *account,
1427 ModestMailOperation *mail_op = NULL;
1428 gchar *error_msg = NULL;
1429 ModestProtocolType proto;
1430 TnyConnectionStatus status;
1431 OpenMsgHelper *helper = NULL;
1432 ModestProtocol *protocol;
1433 ModestProtocolRegistry *protocol_registry;
1436 helper = (OpenMsgHelper *) user_data;
1438 status = tny_account_get_connection_status (account);
1439 if (err || canceled || helper->caller_window == NULL) {
1440 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1441 /* Free the helper */
1442 open_msg_helper_destroyer (helper);
1444 /* In disk full conditions we could get this error here */
1445 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1446 (GtkWidget *) parent_window, err,
1452 /* Get the error message depending on the protocol */
1453 proto = modest_tny_account_get_protocol_type (account);
1454 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1455 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1458 protocol_registry = modest_runtime_get_protocol_registry ();
1459 subject = tny_header_dup_subject (helper->header);
1461 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1462 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1466 if (error_msg == NULL) {
1467 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1470 #ifndef MODEST_TOOLKIT_HILDON2
1471 gboolean show_open_draft = FALSE;
1472 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1474 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1476 TnyFolderType folder_type;
1478 folder = tny_header_get_folder (helper->header);
1479 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1480 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1481 g_object_unref (folder);
1485 #ifdef MODEST_TOOLKIT_HILDON2
1488 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1490 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1491 g_free (account_name);
1492 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1496 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1497 g_free (account_name);
1498 open_msg_helper_destroyer (helper);
1503 ModestWindow *window;
1504 GtkWidget *header_view;
1507 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1508 uid = modest_tny_folder_get_header_unique_id (helper->header);
1510 const gchar *mailbox = NULL;
1511 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1512 window = modest_msg_view_window_new_from_header_view
1513 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1514 if (window != NULL) {
1515 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1517 gtk_widget_destroy (GTK_WIDGET (window));
1519 gtk_widget_show_all (GTK_WIDGET(window));
1523 g_free (account_name);
1525 open_msg_helper_destroyer (helper);
1528 g_free (account_name);
1530 /* Create the mail operation */
1532 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1533 modest_ui_actions_disk_operations_error_handler,
1534 g_strdup (error_msg), g_free);
1535 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1539 #ifndef MODEST_TOOLKIT_HILDON2
1540 if (show_open_draft) {
1541 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1542 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1543 helper->banner_info->banner = NULL;
1544 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1545 helper->banner_info);
1551 headers = TNY_LIST (tny_simple_list_new ());
1552 tny_list_prepend (headers, G_OBJECT (helper->header));
1553 modest_mail_operation_get_msgs_full (mail_op,
1557 open_msg_helper_destroyer);
1558 g_object_unref (headers);
1565 g_object_unref (mail_op);
1566 g_object_unref (account);
1570 * This function is used by both modest_ui_actions_on_open and
1571 * modest_ui_actions_on_header_activated. This way we always do the
1572 * same when trying to open messages.
1575 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1577 ModestWindowMgr *mgr = NULL;
1578 TnyAccount *account;
1579 gboolean cached = FALSE;
1581 GtkWidget *header_view = NULL;
1582 OpenMsgHelper *helper;
1583 ModestWindow *window;
1585 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1587 mgr = modest_runtime_get_window_mgr ();
1590 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1591 if (header_view == NULL)
1594 /* Get the account */
1595 account = get_account_from_header (header);
1600 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1602 /* Do not open again the message and present the
1603 window to the user */
1606 #ifndef MODEST_TOOLKIT_HILDON2
1607 gtk_window_present (GTK_WINDOW (window));
1610 /* the header has been registered already, we don't do
1611 * anything but wait for the window to come up*/
1612 g_debug ("header %p already registered, waiting for window", header);
1617 /* Open each message */
1618 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1620 /* Allways download if we are online. */
1621 if (!tny_device_is_online (modest_runtime_get_device ())) {
1624 /* If ask for user permission to download the messages */
1625 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1626 _("mcen_nc_get_msg"));
1628 /* End if the user does not want to continue */
1629 if (response == GTK_RESPONSE_CANCEL) {
1635 /* We register the window for opening */
1636 modest_window_mgr_register_header (mgr, header, NULL);
1638 /* Create the helper. We need to get a reference to the model
1639 here because it could change while the message is readed
1640 (the user could switch between folders) */
1641 helper = g_slice_new (OpenMsgHelper);
1642 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1643 helper->caller_window = win;
1644 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1645 helper->header = g_object_ref (header);
1646 helper->rowref = gtk_tree_row_reference_copy (rowref);
1647 helper->banner_info = NULL;
1649 /* Connect to the account and perform */
1651 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1652 open_msg_performer, helper);
1654 /* Call directly the performer, do not need to connect */
1655 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1656 g_object_ref (account), helper);
1661 g_object_unref (account);
1665 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1672 /* we check for low-mem; in that case, show a warning, and don't allow
1675 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1679 headers = get_selected_headers (win);
1683 headers_count = tny_list_get_length (headers);
1684 if (headers_count != 1) {
1685 if (headers_count > 1) {
1686 /* Don't allow activation if there are more than one message selected */
1687 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1690 g_object_unref (headers);
1694 iter = tny_list_create_iterator (headers);
1695 header = TNY_HEADER (tny_iterator_get_current (iter));
1696 g_object_unref (iter);
1700 open_msg_from_header (header, NULL, win);
1701 g_object_unref (header);
1704 g_object_unref(headers);
1708 rf_helper_window_closed (gpointer data,
1711 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1713 helper->parent_window = NULL;
1716 static ReplyForwardHelper*
1717 create_reply_forward_helper (ReplyForwardAction action,
1719 guint reply_forward_type,
1723 ReplyForwardHelper *rf_helper = NULL;
1724 const gchar *active_acc = modest_window_get_active_account (win);
1725 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1727 rf_helper = g_slice_new0 (ReplyForwardHelper);
1728 rf_helper->reply_forward_type = reply_forward_type;
1729 rf_helper->action = action;
1730 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1731 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1732 rf_helper->account_name = (active_acc) ?
1733 g_strdup (active_acc) :
1734 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1735 rf_helper->mailbox = g_strdup (active_mailbox);
1737 rf_helper->parts = g_object_ref (parts);
1739 rf_helper->parts = NULL;
1741 /* Note that window could be destroyed just AFTER calling
1742 register_window so we must ensure that this pointer does
1743 not hold invalid references */
1744 if (rf_helper->parent_window)
1745 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1746 rf_helper_window_closed, rf_helper);
1752 free_reply_forward_helper (gpointer data)
1754 ReplyForwardHelper *helper;
1756 helper = (ReplyForwardHelper *) data;
1757 g_free (helper->account_name);
1758 g_free (helper->mailbox);
1760 g_object_unref (helper->header);
1762 g_object_unref (helper->parts);
1763 if (helper->parent_window)
1764 g_object_weak_unref (G_OBJECT (helper->parent_window),
1765 rf_helper_window_closed, helper);
1766 g_slice_free (ReplyForwardHelper, helper);
1770 reply_forward_cb (ModestMailOperation *mail_op,
1777 TnyMsg *new_msg = NULL;
1778 ReplyForwardHelper *rf_helper;
1779 ModestWindow *msg_win = NULL;
1780 ModestEditType edit_type;
1782 TnyAccount *account = NULL;
1783 ModestWindowMgr *mgr = NULL;
1784 gchar *signature = NULL;
1785 gboolean use_signature;
1788 /* If there was any error. The mail operation could be NULL,
1789 this means that we already have the message downloaded and
1790 that we didn't do a mail operation to retrieve it */
1791 rf_helper = (ReplyForwardHelper *) user_data;
1792 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1795 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1796 rf_helper->account_name, rf_helper->mailbox);
1797 recipient = modest_text_utils_get_email_address (from);
1798 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1803 /* Create reply mail */
1804 switch (rf_helper->action) {
1805 /* Use the msg_header to ensure that we have all the
1806 information. The summary can lack some data */
1807 TnyHeader *msg_header;
1809 msg_header = tny_msg_get_header (msg);
1811 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1812 (use_signature) ? signature : NULL,
1813 rf_helper->reply_forward_type,
1814 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1815 g_object_unref (msg_header);
1817 case ACTION_REPLY_TO_ALL:
1818 msg_header = tny_msg_get_header (msg);
1820 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1821 (use_signature) ? signature : NULL,
1822 rf_helper->reply_forward_type,
1823 MODEST_TNY_MSG_REPLY_MODE_ALL);
1824 edit_type = MODEST_EDIT_TYPE_REPLY;
1825 g_object_unref (msg_header);
1827 case ACTION_FORWARD:
1829 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1830 rf_helper->reply_forward_type);
1831 edit_type = MODEST_EDIT_TYPE_FORWARD;
1834 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1836 g_return_if_reached ();
1844 g_warning ("%s: failed to create message\n", __FUNCTION__);
1848 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1849 rf_helper->account_name,
1850 TNY_ACCOUNT_TYPE_STORE);
1852 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1856 /* Create and register the windows */
1857 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1858 mgr = modest_runtime_get_window_mgr ();
1859 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1861 /* Note that register_window could have deleted the account */
1862 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1863 gdouble parent_zoom;
1865 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1866 modest_window_set_zoom (msg_win, parent_zoom);
1869 /* Show edit window */
1870 gtk_widget_show_all (GTK_WIDGET (msg_win));
1873 /* We always unregister the header because the message is
1874 forwarded or replied so the original one is no longer
1876 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1879 g_object_unref (G_OBJECT (new_msg));
1881 g_object_unref (G_OBJECT (account));
1882 free_reply_forward_helper (rf_helper);
1885 /* Checks a list of headers. If any of them are not currently
1886 * downloaded (CACHED) then returns TRUE else returns FALSE.
1889 header_list_count_uncached_msgs (TnyList *header_list)
1892 gint uncached_messages = 0;
1894 iter = tny_list_create_iterator (header_list);
1895 while (!tny_iterator_is_done (iter)) {
1898 header = TNY_HEADER (tny_iterator_get_current (iter));
1900 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1901 uncached_messages ++;
1902 g_object_unref (header);
1905 tny_iterator_next (iter);
1907 g_object_unref (iter);
1909 return uncached_messages;
1912 /* Returns FALSE if the user does not want to download the
1913 * messages. Returns TRUE if the user allowed the download.
1916 connect_to_get_msg (ModestWindow *win,
1917 gint num_of_uncached_msgs,
1918 TnyAccount *account)
1920 GtkResponseType response;
1922 /* Allways download if we are online. */
1923 if (tny_device_is_online (modest_runtime_get_device ()))
1926 /* If offline, then ask for user permission to download the messages */
1927 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1928 ngettext("mcen_nc_get_msg",
1930 num_of_uncached_msgs));
1932 if (response == GTK_RESPONSE_CANCEL)
1935 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1939 reply_forward_performer (gboolean canceled,
1941 GtkWindow *parent_window,
1942 TnyAccount *account,
1945 ReplyForwardHelper *rf_helper = NULL;
1946 ModestMailOperation *mail_op;
1948 rf_helper = (ReplyForwardHelper *) user_data;
1950 if (canceled || err) {
1951 free_reply_forward_helper (rf_helper);
1955 /* Retrieve the message */
1956 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1957 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1958 modest_ui_actions_disk_operations_error_handler,
1960 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1961 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1964 g_object_unref(mail_op);
1968 all_parts_retrieved (TnyMimePart *part)
1970 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1973 TnyList *pending_parts;
1974 TnyIterator *iterator;
1975 gboolean all_retrieved = TRUE;
1977 pending_parts = TNY_LIST (tny_simple_list_new ());
1978 tny_mime_part_get_parts (part, pending_parts);
1979 iterator = tny_list_create_iterator (pending_parts);
1980 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1983 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1985 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1986 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1988 all_retrieved = FALSE;
1991 g_object_unref (child);
1992 tny_iterator_next (iterator);
1994 g_object_unref (iterator);
1995 g_object_unref (pending_parts);
1996 return all_retrieved;
2001 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
2004 TnyIterator *iterator;
2006 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2007 tny_list_append (list, G_OBJECT (part));
2009 parts = TNY_LIST (tny_simple_list_new ());
2010 tny_mime_part_get_parts (part, parts);
2011 for (iterator = tny_list_create_iterator (parts);
2012 !tny_iterator_is_done (iterator);
2013 tny_iterator_next (iterator)) {
2016 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2017 forward_pending_parts_helper (child, list);
2018 g_object_unref (child);
2020 g_object_unref (iterator);
2021 g_object_unref (parts);
2025 forward_pending_parts (TnyMsg *msg)
2027 TnyList *result = TNY_LIST (tny_simple_list_new ());
2028 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2029 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2036 * Common code for the reply and forward actions
2039 reply_forward (ReplyForwardAction action, ModestWindow *win)
2041 ReplyForwardHelper *rf_helper = NULL;
2042 guint reply_forward_type;
2044 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2046 /* we check for low-mem; in that case, show a warning, and don't allow
2047 * reply/forward (because it could potentially require a lot of memory */
2048 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2052 /* we need an account when editing */
2053 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2054 if (!modest_ui_actions_run_account_setup_wizard (win))
2058 reply_forward_type =
2059 modest_conf_get_int (modest_runtime_get_conf (),
2060 (action == ACTION_FORWARD) ?
2061 MODEST_CONF_FORWARD_TYPE :
2062 MODEST_CONF_REPLY_TYPE,
2065 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2067 TnyHeader *header = NULL;
2068 /* Get header and message. Do not free them here, the
2069 reply_forward_cb must do it */
2070 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2071 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2073 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2075 rf_helper = create_reply_forward_helper (action, win,
2076 reply_forward_type, header, NULL);
2077 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2079 gboolean do_download = TRUE;
2081 if (msg && header && action == ACTION_FORWARD) {
2082 /* Not all parts retrieved. Then we have to retrieve them all before
2083 * creating the forward message */
2084 if (!tny_device_is_online (modest_runtime_get_device ())) {
2087 /* If ask for user permission to download the messages */
2088 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2089 ngettext("mcen_nc_get_msg",
2093 /* End if the user does not want to continue */
2094 if (response == GTK_RESPONSE_CANCEL)
2095 do_download = FALSE;
2099 TnyList *pending_parts;
2101 TnyAccount *account;
2104 pending_parts = forward_pending_parts (msg);
2105 rf_helper = create_reply_forward_helper (action, win,
2106 reply_forward_type, header, pending_parts);
2107 g_object_unref (pending_parts);
2109 folder = tny_header_get_folder (header);
2110 account = tny_folder_get_account (folder);
2111 modest_platform_connect_and_perform (GTK_WINDOW (win),
2113 reply_forward_performer,
2115 g_object_unref (folder);
2116 g_object_unref (account);
2120 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2125 g_object_unref (msg);
2127 g_object_unref (header);
2129 TnyHeader *header = NULL;
2131 gboolean do_retrieve = TRUE;
2132 TnyList *header_list = NULL;
2134 header_list = get_selected_headers (win);
2137 /* Check that only one message is selected for replying */
2138 if (tny_list_get_length (header_list) != 1) {
2139 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2140 NULL, _("mcen_ib_select_one_message"));
2141 g_object_unref (header_list);
2145 /* Only reply/forward to one message */
2146 iter = tny_list_create_iterator (header_list);
2147 header = TNY_HEADER (tny_iterator_get_current (iter));
2148 g_object_unref (iter);
2150 /* Retrieve messages */
2151 do_retrieve = (action == ACTION_FORWARD) ||
2152 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2155 TnyAccount *account = NULL;
2156 TnyFolder *folder = NULL;
2157 gdouble download = TRUE;
2158 guint uncached_msgs = 0;
2160 folder = tny_header_get_folder (header);
2162 goto do_retrieve_frees;
2163 account = tny_folder_get_account (folder);
2165 goto do_retrieve_frees;
2167 uncached_msgs = header_list_count_uncached_msgs (header_list);
2169 if (uncached_msgs > 0) {
2170 /* Allways download if we are online. */
2171 if (!tny_device_is_online (modest_runtime_get_device ())) {
2174 /* If ask for user permission to download the messages */
2175 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2176 ngettext("mcen_nc_get_msg",
2180 /* End if the user does not want to continue */
2181 if (response == GTK_RESPONSE_CANCEL)
2188 rf_helper = create_reply_forward_helper (action, win,
2189 reply_forward_type, header, NULL);
2190 if (uncached_msgs > 0) {
2191 modest_platform_connect_and_perform (GTK_WINDOW (win),
2193 reply_forward_performer,
2196 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2197 account, rf_helper);
2202 g_object_unref (account);
2204 g_object_unref (folder);
2206 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2209 g_object_unref (header_list);
2210 g_object_unref (header);
2215 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2217 g_return_if_fail (MODEST_IS_WINDOW(win));
2219 reply_forward (ACTION_REPLY, win);
2223 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2225 g_return_if_fail (MODEST_IS_WINDOW(win));
2227 reply_forward (ACTION_FORWARD, win);
2231 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2233 g_return_if_fail (MODEST_IS_WINDOW(win));
2235 reply_forward (ACTION_REPLY_TO_ALL, win);
2239 modest_ui_actions_on_next (GtkAction *action,
2240 ModestWindow *window)
2242 if (MODEST_IS_MAIN_WINDOW (window)) {
2243 GtkWidget *header_view;
2245 header_view = modest_main_window_get_child_widget (
2246 MODEST_MAIN_WINDOW(window),
2247 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2251 modest_header_view_select_next (
2252 MODEST_HEADER_VIEW(header_view));
2253 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2254 modest_msg_view_window_select_next_message (
2255 MODEST_MSG_VIEW_WINDOW (window));
2257 g_return_if_reached ();
2262 modest_ui_actions_on_prev (GtkAction *action,
2263 ModestWindow *window)
2265 g_return_if_fail (MODEST_IS_WINDOW(window));
2267 if (MODEST_IS_MAIN_WINDOW (window)) {
2268 GtkWidget *header_view;
2269 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2270 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2274 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2275 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2276 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2278 g_return_if_reached ();
2283 modest_ui_actions_on_sort (GtkAction *action,
2284 ModestWindow *window)
2286 GtkWidget *header_view = NULL;
2288 g_return_if_fail (MODEST_IS_WINDOW(window));
2290 if (MODEST_IS_MAIN_WINDOW (window)) {
2291 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2292 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2293 #ifdef MODEST_TOOLKIT_HILDON2
2294 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2295 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2300 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2305 /* Show sorting dialog */
2306 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2310 sync_folder_cb (ModestMailOperation *mail_op,
2314 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2316 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2317 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2319 /* We must clear first, because otherwise set_folder will ignore */
2320 /* the change as the folders are the same */
2321 modest_header_view_clear (header_view);
2322 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2324 g_object_unref (parent);
2327 g_object_unref (header_view);
2331 idle_refresh_folder (gpointer source)
2333 ModestHeaderView *header_view = NULL;
2335 /* If the window still exists */
2336 if (!GTK_IS_WIDGET (source) ||
2337 !GTK_WIDGET_VISIBLE (source))
2340 /* Refresh the current view */
2341 #ifdef MODEST_TOOLKIT_HILDON2
2342 if (MODEST_IS_HEADER_WINDOW (source))
2343 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2345 if (MODEST_IS_MAIN_WINDOW (source))
2346 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2347 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2350 TnyFolder *folder = modest_header_view_get_folder (header_view);
2352 /* Sync the folder status */
2353 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2354 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2355 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2356 g_object_unref (folder);
2357 g_object_unref (mail_op);
2365 update_account_cb (ModestMailOperation *self,
2366 TnyList *new_headers,
2370 gboolean show_visual_notifications;
2372 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2373 show_visual_notifications = (top) ? FALSE : TRUE;
2375 /* Notify new messages have been downloaded. If the
2376 send&receive was invoked by the user then do not show any
2377 visual notification, only play a sound and activate the LED
2378 (for the Maemo version) */
2379 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2381 /* We only notify about really new messages (not seen) we get */
2382 TnyList *actually_new_list;
2383 TnyIterator *iterator;
2384 actually_new_list = TNY_LIST (tny_simple_list_new ());
2385 for (iterator = tny_list_create_iterator (new_headers);
2386 !tny_iterator_is_done (iterator);
2387 tny_iterator_next (iterator)) {
2389 TnyHeaderFlags flags;
2390 header = TNY_HEADER (tny_iterator_get_current (iterator));
2391 flags = tny_header_get_flags (header);
2393 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2394 /* Messages are ordered from most
2395 recent to oldest. But we want to
2396 show notifications starting from
2397 the oldest message. That's why we
2399 tny_list_prepend (actually_new_list, G_OBJECT (header));
2401 g_object_unref (header);
2403 g_object_unref (iterator);
2405 if (tny_list_get_length (actually_new_list) > 0) {
2406 GList *new_headers_list = NULL;
2408 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2410 /* Send notifications */
2411 if (new_headers_list) {
2412 modest_platform_on_new_headers_received (new_headers_list,
2413 show_visual_notifications);
2415 modest_utils_free_notification_list (new_headers_list);
2418 g_object_unref (actually_new_list);
2422 /* Refresh the current folder in an idle. We do this
2423 in order to avoid refresh cancelations if the
2424 currently viewed folder is the inbox */
2425 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2426 idle_refresh_folder,
2433 TnyAccount *account;
2435 gchar *account_name;
2436 gboolean poke_status;
2437 gboolean interactive;
2438 ModestMailOperation *mail_op;
2442 do_send_receive_performer (gboolean canceled,
2444 GtkWindow *parent_window,
2445 TnyAccount *account,
2448 SendReceiveInfo *info;
2450 info = (SendReceiveInfo *) user_data;
2452 if (err || canceled) {
2453 /* In disk full conditions we could get this error here */
2454 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2455 (GtkWidget *) parent_window, err,
2458 if (info->mail_op) {
2459 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2465 /* Set send/receive operation in progress */
2466 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2467 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2470 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2471 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2472 G_CALLBACK (on_send_receive_finished),
2475 /* Send & receive. */
2476 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2477 update_account_cb, info->win);
2482 g_object_unref (G_OBJECT (info->mail_op));
2483 if (info->account_name)
2484 g_free (info->account_name);
2486 g_object_unref (info->win);
2488 g_object_unref (info->account);
2489 g_slice_free (SendReceiveInfo, info);
2493 * This function performs the send & receive required actions. The
2494 * window is used to create the mail operation. Typically it should
2495 * always be the main window, but we pass it as argument in order to
2499 modest_ui_actions_do_send_receive (const gchar *account_name,
2500 gboolean force_connection,
2501 gboolean poke_status,
2502 gboolean interactive,
2505 gchar *acc_name = NULL;
2506 SendReceiveInfo *info;
2507 ModestTnyAccountStore *acc_store;
2508 TnyAccount *account;
2510 /* If no account name was provided then get the current account, and if
2511 there is no current account then pick the default one: */
2512 if (!account_name) {
2514 acc_name = g_strdup (modest_window_get_active_account (win));
2516 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2518 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2522 acc_name = g_strdup (account_name);
2525 acc_store = modest_runtime_get_account_store ();
2526 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2530 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2534 /* Do not automatically refresh accounts that are flagged as
2535 NO_AUTO_UPDATE. This could be useful for accounts that
2536 handle their own update times */
2538 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2539 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2540 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2541 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2543 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2544 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2545 g_object_unref (account);
2552 /* Create the info for the connect and perform */
2553 info = g_slice_new (SendReceiveInfo);
2554 info->account_name = acc_name;
2555 info->win = (win) ? g_object_ref (win) : NULL;
2556 info->poke_status = poke_status;
2557 info->interactive = interactive;
2558 info->account = account;
2559 /* We need to create the operation here, because otherwise it
2560 could happen that the queue emits the queue-empty signal
2561 while we're trying to connect the account */
2562 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2563 modest_ui_actions_disk_operations_error_handler,
2565 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2567 /* Invoke the connect and perform */
2568 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2569 force_connection, info->account,
2570 do_send_receive_performer, info);
2575 modest_ui_actions_do_cancel_send (const gchar *account_name,
2578 TnyTransportAccount *transport_account;
2579 TnySendQueue *send_queue = NULL;
2580 GError *error = NULL;
2582 /* Get transport account */
2584 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2585 (modest_runtime_get_account_store(),
2587 TNY_ACCOUNT_TYPE_TRANSPORT));
2588 if (!transport_account) {
2589 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2594 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2595 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2596 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2597 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2598 "modest: could not find send queue for account\n");
2600 /* Cancel the current send */
2601 tny_account_cancel (TNY_ACCOUNT (transport_account));
2603 /* Suspend all pending messages */
2604 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2608 if (transport_account != NULL)
2609 g_object_unref (G_OBJECT (transport_account));
2613 modest_ui_actions_cancel_send_all (ModestWindow *win)
2615 GSList *account_names, *iter;
2617 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2620 iter = account_names;
2622 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2623 iter = g_slist_next (iter);
2626 modest_account_mgr_free_account_names (account_names);
2627 account_names = NULL;
2631 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2634 /* Check if accounts exist */
2635 gboolean accounts_exist =
2636 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2638 /* If not, allow the user to create an account before trying to send/receive. */
2639 if (!accounts_exist)
2640 modest_ui_actions_on_accounts (NULL, win);
2642 /* Cancel all sending operaitons */
2643 modest_ui_actions_cancel_send_all (win);
2647 * Refreshes all accounts. This function will be used by automatic
2651 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2652 gboolean force_connection,
2653 gboolean poke_status,
2654 gboolean interactive)
2656 GSList *account_names, *iter;
2658 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2661 iter = account_names;
2663 modest_ui_actions_do_send_receive ((const char*) iter->data,
2665 poke_status, interactive, win);
2666 iter = g_slist_next (iter);
2669 modest_account_mgr_free_account_names (account_names);
2670 account_names = NULL;
2674 * Handler of the click on Send&Receive button in the main toolbar
2677 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2679 /* Check if accounts exist */
2680 gboolean accounts_exist;
2683 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2685 /* If not, allow the user to create an account before trying to send/receive. */
2686 if (!accounts_exist)
2687 modest_ui_actions_on_accounts (NULL, win);
2689 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2690 if (MODEST_IS_MAIN_WINDOW (win)) {
2691 GtkWidget *folder_view;
2692 TnyFolderStore *folder_store;
2695 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2696 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2700 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2703 g_object_unref (folder_store);
2704 /* Refresh the active account. Force the connection if needed
2705 and poke the status of all folders */
2706 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2707 #ifdef MODEST_TOOLKIT_HILDON2
2708 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2709 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2712 const gchar *active_account;
2713 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2715 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2722 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2725 GtkWidget *header_view;
2727 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2729 header_view = modest_main_window_get_child_widget (main_window,
2730 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2734 conf = modest_runtime_get_conf ();
2736 /* what is saved/restored is depending on the style; thus; we save with
2737 * old style, then update the style, and restore for this new style
2739 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2741 if (modest_header_view_get_style
2742 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2743 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2744 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2746 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2747 MODEST_HEADER_VIEW_STYLE_DETAILS);
2749 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2750 MODEST_CONF_HEADER_VIEW_KEY);
2755 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2757 ModestMainWindow *main_window)
2759 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2760 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2762 /* in the case the folder is empty, show the empty folder message and focus
2764 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2765 if (modest_header_view_is_empty (header_view)) {
2766 TnyFolder *folder = modest_header_view_get_folder (header_view);
2767 GtkWidget *folder_view =
2768 modest_main_window_get_child_widget (main_window,
2769 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2770 if (folder != NULL) {
2771 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2772 g_object_unref (folder);
2774 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2778 /* If no header has been selected then exit */
2783 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2784 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2786 /* Update toolbar dimming state */
2787 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2788 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2792 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2795 ModestWindow *window)
2797 GtkWidget *open_widget;
2798 GtkTreeRowReference *rowref;
2800 g_return_if_fail (MODEST_IS_WINDOW(window));
2801 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2802 g_return_if_fail (TNY_IS_HEADER (header));
2804 if (modest_header_view_count_selected_headers (header_view) > 1) {
2805 /* Don't allow activation if there are more than one message selected */
2806 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2810 /* we check for low-mem; in that case, show a warning, and don't allow
2811 * activating headers
2813 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2816 if (MODEST_IS_MAIN_WINDOW (window)) {
2817 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2818 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2819 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2823 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2824 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2825 gtk_tree_row_reference_free (rowref);
2829 set_active_account_from_tny_account (TnyAccount *account,
2830 ModestWindow *window)
2832 const gchar *server_acc_name = tny_account_get_id (account);
2834 /* We need the TnyAccount provided by the
2835 account store because that is the one that
2836 knows the name of the Modest account */
2837 TnyAccount *modest_server_account =
2838 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2839 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2841 if (!modest_server_account) {
2842 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2846 /* Update active account, but only if it's not a pseudo-account */
2847 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2848 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2849 const gchar *modest_acc_name =
2850 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2851 if (modest_acc_name)
2852 modest_window_set_active_account (window, modest_acc_name);
2855 g_object_unref (modest_server_account);
2860 folder_refreshed_cb (ModestMailOperation *mail_op,
2864 ModestMainWindow *win = NULL;
2865 GtkWidget *folder_view, *header_view;
2866 const GError *error;
2868 g_return_if_fail (TNY_IS_FOLDER (folder));
2870 win = MODEST_MAIN_WINDOW (user_data);
2872 /* Check if the operation failed due to memory low conditions */
2873 error = modest_mail_operation_get_error (mail_op);
2874 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2875 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2876 modest_platform_run_information_dialog (GTK_WINDOW (win),
2877 _KR("memr_ib_operation_disabled"),
2883 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2885 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2888 TnyFolderStore *current_folder;
2890 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2891 if (current_folder) {
2892 gboolean different = ((TnyFolderStore *) folder != current_folder);
2893 g_object_unref (current_folder);
2899 /* Check if folder is empty and set headers view contents style */
2900 if ((tny_folder_get_all_count (folder) == 0) ||
2901 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2902 modest_main_window_set_contents_style (win,
2903 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2907 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2908 TnyFolderStore *folder_store,
2910 ModestMainWindow *main_window)
2912 GtkWidget *header_view;
2914 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2916 header_view = modest_main_window_get_child_widget(main_window,
2917 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2922 if (TNY_IS_ACCOUNT (folder_store)) {
2924 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2926 /* Show account details */
2927 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2930 if (TNY_IS_FOLDER (folder_store) && selected) {
2931 TnyAccount *account;
2933 /* Update the active account */
2934 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2936 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2937 g_object_unref (account);
2941 /* Set the header style by default, it could
2942 be changed later by the refresh callback to
2944 modest_main_window_set_contents_style (main_window,
2945 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2947 /* Set folder on header view. This function
2948 will call tny_folder_refresh_async so we
2949 pass a callback that will be called when
2950 finished. We use that callback to set the
2951 empty view if there are no messages */
2952 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2953 TNY_FOLDER (folder_store),
2955 MODEST_WINDOW (main_window),
2956 folder_refreshed_cb,
2959 /* Restore configuration. We need to do this
2960 *after* the set_folder because the widget
2961 memory asks the header view about its
2963 modest_widget_memory_restore (modest_runtime_get_conf (),
2964 G_OBJECT(header_view),
2965 MODEST_CONF_HEADER_VIEW_KEY);
2967 /* No need to save the header view
2968 configuration for Maemo because it only
2969 saves the sorting stuff and that it's
2970 already being done by the sort
2971 dialog. Remove it when the GNOME version
2972 has the same behaviour */
2973 #ifdef MODEST_TOOLKIT_GTK
2974 if (modest_main_window_get_contents_style (main_window) ==
2975 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2976 modest_widget_memory_save (modest_runtime_get_conf (),
2977 G_OBJECT (header_view),
2978 MODEST_CONF_HEADER_VIEW_KEY);
2980 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2984 /* Update dimming state */
2985 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2986 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2990 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2997 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2999 online = tny_device_is_online (modest_runtime_get_device());
3002 /* already online -- the item is simply not there... */
3003 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
3005 GTK_MESSAGE_WARNING,
3007 _("The %s you selected cannot be found"),
3009 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3010 gtk_dialog_run (GTK_DIALOG(dialog));
3012 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3015 _("mcen_bd_dialog_cancel"),
3016 GTK_RESPONSE_REJECT,
3017 _("mcen_bd_dialog_ok"),
3018 GTK_RESPONSE_ACCEPT,
3020 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3021 "Do you want to get online?"), item);
3022 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3023 gtk_label_new (txt), FALSE, FALSE, 0);
3024 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3027 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3028 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3029 /* TODO: Comment about why is this commented out: */
3030 /* modest_platform_connect_and_wait (); */
3033 gtk_widget_destroy (dialog);
3037 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3040 /* g_debug ("%s %s", __FUNCTION__, link); */
3045 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3048 modest_platform_activate_uri (link);
3052 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3055 modest_platform_show_uri_popup (link);
3059 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3062 /* we check for low-mem; in that case, show a warning, and don't allow
3063 * viewing attachments
3065 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3068 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3072 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3073 const gchar *address,
3076 /* g_debug ("%s %s", __FUNCTION__, address); */
3080 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3081 TnyMsg *saved_draft,
3084 ModestMsgEditWindow *edit_window;
3086 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3087 #ifndef MODEST_TOOLKIT_HILDON2
3088 ModestMainWindow *win;
3090 /* FIXME. Make the header view sensitive again. This is a
3091 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3093 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3094 modest_runtime_get_window_mgr(), FALSE));
3096 GtkWidget *hdrview = modest_main_window_get_child_widget(
3097 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3098 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3102 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3104 /* Set draft is there was no error */
3105 if (!modest_mail_operation_get_error (mail_op))
3106 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3108 g_object_unref(edit_window);
3112 enough_space_for_message (ModestMsgEditWindow *edit_window,
3115 guint64 available_disk, expected_size;
3120 available_disk = modest_utils_get_available_space (NULL);
3121 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3122 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3127 /* Double check: disk full condition or message too big */
3128 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3129 expected_size > available_disk) {
3130 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3131 modest_platform_information_banner (NULL, NULL, msg);
3138 * djcb: if we're in low-memory state, we only allow for
3139 * saving messages smaller than
3140 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3141 * should still allow for sending anything critical...
3143 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3144 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3148 * djcb: we also make sure that the attachments are smaller than the max size
3149 * this is for the case where we'd try to forward a message with attachments
3150 * bigger than our max allowed size, or sending an message from drafts which
3151 * somehow got past our checks when attaching.
3153 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3154 modest_platform_run_information_dialog (
3155 GTK_WINDOW(edit_window),
3156 _("mail_ib_error_attachment_size"),
3165 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3167 TnyTransportAccount *transport_account;
3168 ModestMailOperation *mail_operation;
3170 gchar *account_name;
3171 ModestAccountMgr *account_mgr;
3172 gboolean had_error = FALSE;
3173 ModestMainWindow *win = NULL;
3175 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3177 data = modest_msg_edit_window_get_msg_data (edit_window);
3180 if (!enough_space_for_message (edit_window, data)) {
3181 modest_msg_edit_window_free_msg_data (edit_window, data);
3185 account_name = g_strdup (data->account_name);
3186 account_mgr = modest_runtime_get_account_mgr();
3188 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3190 account_name = modest_account_mgr_get_default_account (account_mgr);
3191 if (!account_name) {
3192 g_printerr ("modest: no account found\n");
3193 modest_msg_edit_window_free_msg_data (edit_window, data);
3197 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3198 account_name = g_strdup (data->account_name);
3202 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3203 (modest_runtime_get_account_store (),
3205 TNY_ACCOUNT_TYPE_TRANSPORT));
3206 if (!transport_account) {
3207 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3208 g_free (account_name);
3209 modest_msg_edit_window_free_msg_data (edit_window, data);
3213 /* Create the mail operation */
3214 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3216 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3218 modest_mail_operation_save_to_drafts (mail_operation,
3230 data->priority_flags,
3233 on_save_to_drafts_cb,
3234 g_object_ref(edit_window));
3236 #ifdef MODEST_TOOLKIT_HILDON2
3237 /* In hildon2 we always show the information banner on saving to drafts.
3238 * It will be a system information banner in this case.
3240 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3241 modest_platform_information_banner (NULL, NULL, text);
3244 /* Use the main window as the parent of the banner, if the
3245 main window does not exist it won't be shown, if the parent
3246 window exists then it's properly shown. We don't use the
3247 editor window because it could be closed (save to drafts
3248 could happen after closing the window */
3249 win = (ModestMainWindow *)
3250 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3252 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3253 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3257 modest_msg_edit_window_set_modified (edit_window, FALSE);
3260 g_free (account_name);
3261 g_object_unref (G_OBJECT (transport_account));
3262 g_object_unref (G_OBJECT (mail_operation));
3264 modest_msg_edit_window_free_msg_data (edit_window, data);
3267 * If the drafts folder is selected then make the header view
3268 * insensitive while the message is being saved to drafts
3269 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3270 * is not very clean but it avoids letting the drafts folder
3271 * in an inconsistent state: the user could edit the message
3272 * being saved and undesirable things would happen.
3273 * In the average case the user won't notice anything at
3274 * all. In the worst case (the user is editing a really big
3275 * file from Drafts) the header view will be insensitive
3276 * during the saving process (10 or 20 seconds, depending on
3277 * the message). Anyway this is just a quick workaround: once
3278 * we find a better solution it should be removed
3279 * See NB#65125 (commend #18) for details.
3281 if (!had_error && win != NULL) {
3282 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3283 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3285 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3287 if (modest_tny_folder_is_local_folder(folder)) {
3288 TnyFolderType folder_type;
3289 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3290 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3291 GtkWidget *hdrview = modest_main_window_get_child_widget(
3292 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3293 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3297 if (folder != NULL) g_object_unref(folder);
3304 /* For instance, when clicking the Send toolbar button when editing a message: */
3306 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3308 TnyTransportAccount *transport_account = NULL;
3309 gboolean had_error = FALSE, add_to_contacts;
3311 ModestAccountMgr *account_mgr;
3312 gchar *account_name;
3313 ModestMailOperation *mail_operation;
3316 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3318 /* Check whether to automatically add new contacts to addressbook or not */
3319 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3320 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3321 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3324 data = modest_msg_edit_window_get_msg_data (edit_window);
3326 recipients = g_strconcat (data->to?data->to:"",
3327 data->cc?data->cc:"",
3328 data->bcc?data->bcc:"",
3330 if (recipients == NULL || recipients[0] == '\0') {
3331 /* Empty subject -> no send */
3332 g_free (recipients);
3333 modest_msg_edit_window_free_msg_data (edit_window, data);
3336 g_free (recipients);
3339 if (!enough_space_for_message (edit_window, data)) {
3340 modest_msg_edit_window_free_msg_data (edit_window, data);
3344 account_mgr = modest_runtime_get_account_mgr();
3345 account_name = g_strdup (data->account_name);
3347 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3350 account_name = modest_account_mgr_get_default_account (account_mgr);
3352 if (!account_name) {
3353 modest_msg_edit_window_free_msg_data (edit_window, data);
3354 /* Run account setup wizard */
3355 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3360 /* Get the currently-active transport account for this modest account: */
3361 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3363 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3364 (modest_runtime_get_account_store (),
3365 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3368 if (!transport_account) {
3369 modest_msg_edit_window_free_msg_data (edit_window, data);
3370 /* Run account setup wizard */
3371 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3376 /* Create the mail operation */
3377 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3378 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3380 modest_mail_operation_send_new_mail (mail_operation,
3394 data->priority_flags);
3396 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3397 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3399 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3400 const GError *error = modest_mail_operation_get_error (mail_operation);
3401 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3402 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3403 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3404 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3410 g_free (account_name);
3411 g_object_unref (G_OBJECT (transport_account));
3412 g_object_unref (G_OBJECT (mail_operation));
3414 modest_msg_edit_window_free_msg_data (edit_window, data);
3417 modest_msg_edit_window_set_sent (edit_window, TRUE);
3419 /* Save settings and close the window: */
3420 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3427 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3428 ModestMsgEditWindow *window)
3430 ModestMsgEditFormatState *format_state = NULL;
3432 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3433 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3435 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3438 format_state = modest_msg_edit_window_get_format_state (window);
3439 g_return_if_fail (format_state != NULL);
3441 format_state->bold = gtk_toggle_action_get_active (action);
3442 modest_msg_edit_window_set_format_state (window, format_state);
3443 g_free (format_state);
3448 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3449 ModestMsgEditWindow *window)
3451 ModestMsgEditFormatState *format_state = NULL;
3453 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3454 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3456 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3459 format_state = modest_msg_edit_window_get_format_state (window);
3460 g_return_if_fail (format_state != NULL);
3462 format_state->italics = gtk_toggle_action_get_active (action);
3463 modest_msg_edit_window_set_format_state (window, format_state);
3464 g_free (format_state);
3469 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3470 ModestMsgEditWindow *window)
3472 ModestMsgEditFormatState *format_state = NULL;
3474 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3475 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3477 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3480 format_state = modest_msg_edit_window_get_format_state (window);
3481 g_return_if_fail (format_state != NULL);
3483 format_state->bullet = gtk_toggle_action_get_active (action);
3484 modest_msg_edit_window_set_format_state (window, format_state);
3485 g_free (format_state);
3490 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3491 GtkRadioAction *selected,
3492 ModestMsgEditWindow *window)
3494 ModestMsgEditFormatState *format_state = NULL;
3495 GtkJustification value;
3497 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3499 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3502 value = gtk_radio_action_get_current_value (selected);
3504 format_state = modest_msg_edit_window_get_format_state (window);
3505 g_return_if_fail (format_state != NULL);
3507 format_state->justification = value;
3508 modest_msg_edit_window_set_format_state (window, format_state);
3509 g_free (format_state);
3513 modest_ui_actions_on_select_editor_color (GtkAction *action,
3514 ModestMsgEditWindow *window)
3516 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3517 g_return_if_fail (GTK_IS_ACTION (action));
3519 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3522 modest_msg_edit_window_select_color (window);
3526 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3527 ModestMsgEditWindow *window)
3529 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3530 g_return_if_fail (GTK_IS_ACTION (action));
3532 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3535 modest_msg_edit_window_select_background_color (window);
3539 modest_ui_actions_on_insert_image (GObject *object,
3540 ModestMsgEditWindow *window)
3542 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3545 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3548 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3551 modest_msg_edit_window_insert_image (window);
3555 modest_ui_actions_on_attach_file (GtkAction *action,
3556 ModestMsgEditWindow *window)
3558 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3559 g_return_if_fail (GTK_IS_ACTION (action));
3561 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3564 modest_msg_edit_window_offer_attach_file (window);
3568 modest_ui_actions_on_remove_attachments (GtkAction *action,
3569 ModestMsgEditWindow *window)
3571 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3573 modest_msg_edit_window_remove_attachments (window, NULL);
3577 do_create_folder_cb (ModestMailOperation *mail_op,
3578 TnyFolderStore *parent_folder,
3579 TnyFolder *new_folder,
3582 gchar *suggested_name = (gchar *) user_data;
3583 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3584 const GError *error;
3586 error = modest_mail_operation_get_error (mail_op);
3588 gboolean disk_full = FALSE;
3589 TnyAccount *account;
3590 /* Show an error. If there was some problem writing to
3591 disk, show it, otherwise show the generic folder
3592 create error. We do it here and not in an error
3593 handler because the call to do_create_folder will
3594 stop the main loop in a gtk_dialog_run and then,
3595 the message won't be shown until that dialog is
3597 account = modest_mail_operation_get_account (mail_op);
3600 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3601 (GtkWidget *) source_win,
3604 _("mail_in_ui_folder_create_error_memory"));
3605 g_object_unref (account);
3608 /* Show an error and try again if there is no
3609 full memory condition */
3610 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3611 _("mail_in_ui_folder_create_error"));
3612 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3616 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3617 * FIXME: any other? */
3618 GtkWidget *folder_view;
3620 if (MODEST_IS_MAIN_WINDOW(source_win))
3622 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3623 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3625 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3626 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3628 /* Select the newly created folder. It could happen
3629 that the widget is no longer there (i.e. the window
3630 has been destroyed, so we need to check this */
3632 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3634 g_object_unref (new_folder);
3636 /* Free. Note that the first time it'll be NULL so noop */
3637 g_free (suggested_name);
3638 g_object_unref (source_win);
3643 TnyFolderStore *parent;
3644 } CreateFolderConnect;
3647 do_create_folder_performer (gboolean canceled,
3649 GtkWindow *parent_window,
3650 TnyAccount *account,
3653 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3654 ModestMailOperation *mail_op;
3656 if (canceled || err) {
3657 /* In disk full conditions we could get this error here */
3658 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3659 (GtkWidget *) parent_window, err,
3660 NULL, _("mail_in_ui_folder_create_error_memory"));
3662 /* This happens if we have selected the outbox folder
3664 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3665 TNY_IS_MERGE_FOLDER (helper->parent)) {
3666 /* Show an error and retry */
3667 modest_platform_information_banner ((GtkWidget *) parent_window,
3669 _("mail_in_ui_folder_create_error"));
3671 do_create_folder (parent_window, helper->parent, helper->folder_name);
3677 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3678 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3680 modest_mail_operation_create_folder (mail_op,
3682 (const gchar *) helper->folder_name,
3683 do_create_folder_cb,
3684 g_strdup (helper->folder_name));
3685 g_object_unref (mail_op);
3689 g_object_unref (helper->parent);
3690 if (helper->folder_name)
3691 g_free (helper->folder_name);
3692 g_slice_free (CreateFolderConnect, helper);
3697 do_create_folder (GtkWindow *parent_window,
3698 TnyFolderStore *suggested_parent,
3699 const gchar *suggested_name)
3702 gchar *folder_name = NULL;
3703 TnyFolderStore *parent_folder = NULL;
3705 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3707 (gchar *) suggested_name,
3711 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3712 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3713 helper->folder_name = g_strdup (folder_name);
3714 helper->parent = g_object_ref (parent_folder);
3716 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3719 do_create_folder_performer,
3724 g_free (folder_name);
3726 g_object_unref (parent_folder);
3730 modest_ui_actions_create_folder(GtkWidget *parent_window,
3731 GtkWidget *folder_view,
3732 TnyFolderStore *parent_folder)
3734 if (!parent_folder) {
3735 #ifdef MODEST_TOOLKIT_HILDON2
3736 ModestTnyAccountStore *acc_store;
3738 acc_store = modest_runtime_get_account_store ();
3740 parent_folder = (TnyFolderStore *)
3741 modest_tny_account_store_get_local_folders_account (acc_store);
3743 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3747 if (parent_folder) {
3748 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3749 g_object_unref (parent_folder);
3754 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3757 g_return_if_fail (MODEST_IS_WINDOW(window));
3759 if (MODEST_IS_MAIN_WINDOW (window)) {
3760 GtkWidget *folder_view;
3762 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3763 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3767 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3768 #ifdef MODEST_TOOLKIT_HILDON2
3769 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3770 GtkWidget *folder_view;
3772 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3773 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3776 g_assert_not_reached ();
3781 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3784 const GError *error = NULL;
3785 gchar *message = NULL;
3787 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3789 /* Get error message */
3790 error = modest_mail_operation_get_error (mail_op);
3792 g_return_if_reached ();
3794 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3795 (GError *) error, account);
3797 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3798 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3799 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3800 message = _CS("ckdg_ib_folder_already_exists");
3801 } else if (error->domain == TNY_ERROR_DOMAIN &&
3802 error->code == TNY_SERVICE_ERROR_STATE) {
3803 /* This means that the folder is already in use (a
3804 message is opened for example */
3805 message = _("emev_ni_internal_error");
3807 message = _CS("ckdg_ib_unable_to_rename");
3810 /* We don't set a parent for the dialog because the dialog
3811 will be destroyed so the banner won't appear */
3812 modest_platform_information_banner (NULL, NULL, message);
3815 g_object_unref (account);
3821 TnyFolderStore *folder;
3826 on_rename_folder_cb (ModestMailOperation *mail_op,
3827 TnyFolder *new_folder,
3830 ModestFolderView *folder_view;
3832 /* If the window was closed when renaming a folder, or if
3833 * it's not a main window this will happen */
3834 if (!MODEST_IS_FOLDER_VIEW (user_data))
3837 folder_view = MODEST_FOLDER_VIEW (user_data);
3838 /* Note that if the rename fails new_folder will be NULL */
3840 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3842 modest_folder_view_select_first_inbox_or_local (folder_view);
3844 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3848 on_rename_folder_performer (gboolean canceled,
3850 GtkWindow *parent_window,
3851 TnyAccount *account,
3854 ModestMailOperation *mail_op = NULL;
3855 GtkTreeSelection *sel = NULL;
3856 GtkWidget *folder_view = NULL;
3857 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3859 if (canceled || err) {
3860 /* In disk full conditions we could get this error here */
3861 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3862 (GtkWidget *) parent_window, err,
3867 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3868 modest_ui_actions_rename_folder_error_handler,
3869 parent_window, NULL);
3871 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3874 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3876 folder_view = modest_main_window_get_child_widget (
3877 MODEST_MAIN_WINDOW (parent_window),
3878 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3880 #ifdef MODEST_TOOLKIT_HILDON2
3881 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3882 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3883 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3887 /* Clear the folders view */
3888 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3889 gtk_tree_selection_unselect_all (sel);
3891 /* Actually rename the folder */
3892 modest_mail_operation_rename_folder (mail_op,
3893 TNY_FOLDER (data->folder),
3894 (const gchar *) (data->new_name),
3895 on_rename_folder_cb,
3897 g_object_unref (mail_op);
3900 g_object_unref (data->folder);
3901 g_free (data->new_name);
3906 modest_ui_actions_on_rename_folder (GtkAction *action,
3907 ModestWindow *window)
3909 modest_ui_actions_on_edit_mode_rename_folder (window);
3913 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3915 TnyFolderStore *folder;
3916 GtkWidget *folder_view;
3917 gboolean do_rename = TRUE;
3919 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3921 if (MODEST_IS_MAIN_WINDOW (window)) {
3922 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3923 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3927 #ifdef MODEST_TOOLKIT_HILDON2
3928 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3929 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3935 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3940 if (TNY_IS_FOLDER (folder)) {
3941 gchar *folder_name = NULL;
3943 const gchar *current_name;
3944 TnyFolderStore *parent;
3946 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3947 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3948 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3949 parent, current_name,
3951 g_object_unref (parent);
3953 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3956 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3957 rename_folder_data->folder = g_object_ref (folder);
3958 rename_folder_data->new_name = folder_name;
3959 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3960 folder, on_rename_folder_performer, rename_folder_data);
3963 g_object_unref (folder);
3968 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3971 GObject *win = modest_mail_operation_get_source (mail_op);
3973 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3974 _("mail_in_ui_folder_delete_error"),
3976 g_object_unref (win);
3980 TnyFolderStore *folder;
3981 gboolean move_to_trash;
3985 on_delete_folder_cb (gboolean canceled,
3987 GtkWindow *parent_window,
3988 TnyAccount *account,
3991 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3992 GtkWidget *folder_view;
3993 ModestMailOperation *mail_op;
3994 GtkTreeSelection *sel;
3996 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3997 /* Note that the connection process can fail due to
3998 memory low conditions as it can not successfully
3999 store the summary */
4000 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4001 (GtkWidget*) parent_window, err,
4003 g_debug ("Error connecting when trying to delete a folder");
4004 g_object_unref (G_OBJECT (info->folder));
4009 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4010 folder_view = modest_main_window_get_child_widget (
4011 MODEST_MAIN_WINDOW (parent_window),
4012 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4013 #ifdef MODEST_TOOLKIT_HILDON2
4014 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4015 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4018 g_object_unref (G_OBJECT (info->folder));
4023 /* Unselect the folder before deleting it to free the headers */
4024 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4025 gtk_tree_selection_unselect_all (sel);
4027 /* Create the mail operation */
4029 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4030 modest_ui_actions_delete_folder_error_handler,
4033 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4035 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4037 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4039 g_object_unref (mail_op);
4040 g_object_unref (info->folder);
4045 delete_folder (ModestWindow *window, gboolean move_to_trash)
4047 TnyFolderStore *folder;
4048 GtkWidget *folder_view;
4052 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4054 if (MODEST_IS_MAIN_WINDOW (window)) {
4056 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4057 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4058 #ifdef MODEST_TOOLKIT_HILDON2
4059 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4060 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4068 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4073 /* Show an error if it's an account */
4074 if (!TNY_IS_FOLDER (folder)) {
4075 modest_platform_run_information_dialog (GTK_WINDOW (window),
4076 _("mail_in_ui_folder_delete_error"),
4078 g_object_unref (G_OBJECT (folder));
4083 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4084 tny_folder_get_name (TNY_FOLDER (folder)));
4085 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4086 (const gchar *) message);
4089 if (response == GTK_RESPONSE_OK) {
4090 TnyAccount *account = NULL;
4091 DeleteFolderInfo *info = NULL;
4092 info = g_new0(DeleteFolderInfo, 1);
4093 info->folder = g_object_ref (folder);
4094 info->move_to_trash = move_to_trash;
4096 account = tny_folder_get_account (TNY_FOLDER (folder));
4097 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4099 TNY_FOLDER_STORE (account),
4100 on_delete_folder_cb, info);
4101 g_object_unref (account);
4102 g_object_unref (folder);
4110 modest_ui_actions_on_delete_folder (GtkAction *action,
4111 ModestWindow *window)
4113 modest_ui_actions_on_edit_mode_delete_folder (window);
4117 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4119 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4121 return delete_folder (window, FALSE);
4125 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4127 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4129 delete_folder (MODEST_WINDOW (main_window), TRUE);
4133 typedef struct _PasswordDialogFields {
4134 GtkWidget *username;
4135 GtkWidget *password;
4137 } PasswordDialogFields;
4140 password_dialog_check_field (GtkEditable *editable,
4141 PasswordDialogFields *fields)
4144 gboolean any_value_empty = FALSE;
4146 #ifdef MODEST_TOOLKIT_HILDON2
4147 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4149 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4151 if ((value == NULL) || value[0] == '\0') {
4152 any_value_empty = TRUE;
4154 #ifdef MODEST_TOOLKIT_HILDON2
4155 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4157 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4159 if ((value == NULL) || value[0] == '\0') {
4160 any_value_empty = TRUE;
4162 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4166 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4167 const gchar* server_account_name,
4172 ModestMainWindow *main_window)
4174 g_return_if_fail(server_account_name);
4175 gboolean completed = FALSE;
4176 PasswordDialogFields *fields = NULL;
4178 /* Initalize output parameters: */
4185 #ifndef MODEST_TOOLKIT_GTK
4186 /* Maemo uses a different (awkward) button order,
4187 * It should probably just use gtk_alternative_dialog_button_order ().
4189 #ifdef MODEST_TOOLKIT_HILDON2
4191 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4194 _HL("wdgt_bd_done"),
4195 GTK_RESPONSE_ACCEPT,
4197 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4198 HILDON_MARGIN_DOUBLE);
4201 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4204 _("mcen_bd_dialog_ok"),
4205 GTK_RESPONSE_ACCEPT,
4206 _("mcen_bd_dialog_cancel"),
4207 GTK_RESPONSE_REJECT,
4209 #endif /* MODEST_TOOLKIT_HILDON2 */
4212 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4216 GTK_RESPONSE_REJECT,
4218 GTK_RESPONSE_ACCEPT,
4220 #endif /* MODEST_TOOLKIT_GTK */
4222 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4224 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4225 modest_runtime_get_account_mgr(), server_account_name);
4226 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4227 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4230 gtk_widget_destroy (dialog);
4234 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4235 GtkWidget *label = gtk_label_new (txt);
4236 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4238 g_free (server_name);
4239 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4244 gchar *initial_username = modest_account_mgr_get_server_account_username (
4245 modest_runtime_get_account_mgr(), server_account_name);
4247 #ifdef MODEST_TOOLKIT_HILDON2
4248 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4249 if (initial_username)
4250 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4252 GtkWidget *entry_username = gtk_entry_new ();
4253 if (initial_username)
4254 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4256 /* Dim this if a connection has ever succeeded with this username,
4257 * as per the UI spec: */
4258 /* const gboolean username_known = */
4259 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4260 /* modest_runtime_get_account_mgr(), server_account_name); */
4261 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4263 /* We drop the username sensitive code and disallow changing it here
4264 * as tinymail does not support really changing the username in the callback
4266 gtk_widget_set_sensitive (entry_username, FALSE);
4268 #ifndef MODEST_TOOLKIT_GTK
4269 /* Auto-capitalization is the default, so let's turn it off: */
4270 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4272 /* Create a size group to be used by all captions.
4273 * Note that HildonCaption does not create a default size group if we do not specify one.
4274 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4275 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4277 #ifdef MODEST_TOOLKIT_HILDON2
4278 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4279 _("mail_fi_username"), FALSE,
4282 GtkWidget *caption = hildon_caption_new (sizegroup,
4283 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4285 gtk_widget_show (entry_username);
4286 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4287 FALSE, FALSE, MODEST_MARGIN_HALF);
4288 gtk_widget_show (caption);
4290 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4292 #endif /* !MODEST_TOOLKIT_GTK */
4295 #ifdef MODEST_TOOLKIT_HILDON2
4296 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4298 GtkWidget *entry_password = gtk_entry_new ();
4300 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4301 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4303 #ifndef MODEST_TOOLKIT_GTK
4304 /* Auto-capitalization is the default, so let's turn it off: */
4305 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4306 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4308 #ifdef MODEST_TOOLKIT_HILDON2
4309 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4310 _("mail_fi_password"), FALSE,
4313 caption = hildon_caption_new (sizegroup,
4314 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4316 gtk_widget_show (entry_password);
4317 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4318 FALSE, FALSE, MODEST_MARGIN_HALF);
4319 gtk_widget_show (caption);
4320 g_object_unref (sizegroup);
4322 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4324 #endif /* !MODEST_TOOLKIT_GTK */
4326 if (initial_username != NULL)
4327 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4329 /* This is not in the Maemo UI spec:
4330 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4331 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4335 fields = g_slice_new0 (PasswordDialogFields);
4336 fields->username = entry_username;
4337 fields->password = entry_password;
4338 fields->dialog = dialog;
4340 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4341 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4342 password_dialog_check_field (NULL, fields);
4344 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4346 while (!completed) {
4348 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4350 #ifdef MODEST_TOOLKIT_HILDON2
4351 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4353 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4356 /* Note that an empty field becomes the "" string */
4357 if (*username && strlen (*username) > 0) {
4358 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4359 server_account_name,
4363 const gboolean username_was_changed =
4364 (strcmp (*username, initial_username) != 0);
4365 if (username_was_changed) {
4366 g_warning ("%s: tinymail does not yet support changing the "
4367 "username in the get_password() callback.\n", __FUNCTION__);
4373 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4374 _("mcen_ib_username_pw_incorrect"));
4380 #ifdef MODEST_TOOLKIT_HILDON2
4381 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4383 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4386 /* We do not save the password in the configuration,
4387 * because this function is only called for passwords that should
4388 * not be remembered:
4389 modest_server_account_set_password (
4390 modest_runtime_get_account_mgr(), server_account_name,
4397 #ifndef MODEST_TOOLKIT_HILDON2
4398 /* Set parent to NULL or the banner will disappear with its parent dialog */
4399 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4411 /* This is not in the Maemo UI spec:
4412 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4418 g_free (initial_username);
4419 gtk_widget_destroy (dialog);
4420 g_slice_free (PasswordDialogFields, fields);
4422 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4426 modest_ui_actions_on_cut (GtkAction *action,
4427 ModestWindow *window)
4429 GtkWidget *focused_widget;
4430 GtkClipboard *clipboard;
4432 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4433 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4434 if (GTK_IS_EDITABLE (focused_widget)) {
4435 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4436 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4437 gtk_clipboard_store (clipboard);
4438 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4439 GtkTextBuffer *buffer;
4441 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4442 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4443 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4444 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4445 gtk_clipboard_store (clipboard);
4447 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4448 TnyList *header_list = modest_header_view_get_selected_headers (
4449 MODEST_HEADER_VIEW (focused_widget));
4450 gboolean continue_download = FALSE;
4451 gint num_of_unc_msgs;
4453 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4455 if (num_of_unc_msgs) {
4456 TnyAccount *account = get_account_from_header_list (header_list);
4458 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4459 g_object_unref (account);
4463 if (num_of_unc_msgs == 0 || continue_download) {
4464 /* modest_platform_information_banner (
4465 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4466 modest_header_view_cut_selection (
4467 MODEST_HEADER_VIEW (focused_widget));
4470 g_object_unref (header_list);
4471 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4472 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4477 modest_ui_actions_on_copy (GtkAction *action,
4478 ModestWindow *window)
4480 GtkClipboard *clipboard;
4481 GtkWidget *focused_widget;
4482 gboolean copied = TRUE;
4484 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4485 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4487 if (GTK_IS_LABEL (focused_widget)) {
4489 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4490 gtk_clipboard_set_text (clipboard, selection, -1);
4492 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4493 gtk_clipboard_store (clipboard);
4494 } else if (GTK_IS_EDITABLE (focused_widget)) {
4495 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4496 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4497 gtk_clipboard_store (clipboard);
4498 } else if (GTK_IS_HTML (focused_widget)) {
4501 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4502 if ((sel == NULL) || (sel[0] == '\0')) {
4505 gtk_html_copy (GTK_HTML (focused_widget));
4506 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4507 gtk_clipboard_store (clipboard);
4509 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4510 GtkTextBuffer *buffer;
4511 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4512 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4513 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4514 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4515 gtk_clipboard_store (clipboard);
4517 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4518 TnyList *header_list = modest_header_view_get_selected_headers (
4519 MODEST_HEADER_VIEW (focused_widget));
4520 gboolean continue_download = FALSE;
4521 gint num_of_unc_msgs;
4523 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4525 if (num_of_unc_msgs) {
4526 TnyAccount *account = get_account_from_header_list (header_list);
4528 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4529 g_object_unref (account);
4533 if (num_of_unc_msgs == 0 || continue_download) {
4534 modest_platform_information_banner (
4535 NULL, NULL, _CS("mcen_ib_getting_items"));
4536 modest_header_view_copy_selection (
4537 MODEST_HEADER_VIEW (focused_widget));
4541 g_object_unref (header_list);
4543 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4544 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4547 /* Show information banner if there was a copy to clipboard */
4549 modest_platform_information_banner (
4550 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4554 modest_ui_actions_on_undo (GtkAction *action,
4555 ModestWindow *window)
4557 ModestEmailClipboard *clipboard = NULL;
4559 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4560 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4561 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4562 /* Clear clipboard source */
4563 clipboard = modest_runtime_get_email_clipboard ();
4564 modest_email_clipboard_clear (clipboard);
4567 g_return_if_reached ();
4572 modest_ui_actions_on_redo (GtkAction *action,
4573 ModestWindow *window)
4575 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4576 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4579 g_return_if_reached ();
4585 destroy_information_note (ModestMailOperation *mail_op,
4588 /* destroy information note */
4589 gtk_widget_destroy (GTK_WIDGET(user_data));
4593 destroy_folder_information_note (ModestMailOperation *mail_op,
4594 TnyFolder *new_folder,
4597 /* destroy information note */
4598 gtk_widget_destroy (GTK_WIDGET(user_data));
4603 paste_as_attachment_free (gpointer data)
4605 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4607 if (helper->banner) {
4608 gtk_widget_destroy (helper->banner);
4609 g_object_unref (helper->banner);
4615 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4620 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4621 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4626 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4631 modest_ui_actions_on_paste (GtkAction *action,
4632 ModestWindow *window)
4634 GtkWidget *focused_widget = NULL;
4635 GtkWidget *inf_note = NULL;
4636 ModestMailOperation *mail_op = NULL;
4638 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4639 if (GTK_IS_EDITABLE (focused_widget)) {
4640 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4641 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4642 ModestEmailClipboard *e_clipboard = NULL;
4643 e_clipboard = modest_runtime_get_email_clipboard ();
4644 if (modest_email_clipboard_cleared (e_clipboard)) {
4645 GtkTextBuffer *buffer;
4646 GtkClipboard *clipboard;
4648 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4649 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4650 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4651 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4652 ModestMailOperation *mail_op;
4653 TnyFolder *src_folder = NULL;
4654 TnyList *data = NULL;
4656 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4657 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4658 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4659 _CS("ckct_nw_pasting"));
4660 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4661 mail_op = modest_mail_operation_new (G_OBJECT (window));
4662 if (helper->banner != NULL) {
4663 g_object_ref (G_OBJECT (helper->banner));
4664 gtk_widget_show (GTK_WIDGET (helper->banner));
4668 modest_mail_operation_get_msgs_full (mail_op,
4670 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4672 paste_as_attachment_free);
4676 g_object_unref (data);
4678 g_object_unref (src_folder);
4681 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4682 ModestEmailClipboard *clipboard = NULL;
4683 TnyFolder *src_folder = NULL;
4684 TnyFolderStore *folder_store = NULL;
4685 TnyList *data = NULL;
4686 gboolean delete = FALSE;
4688 /* Check clipboard source */
4689 clipboard = modest_runtime_get_email_clipboard ();
4690 if (modest_email_clipboard_cleared (clipboard))
4693 /* Get elements to paste */
4694 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4696 /* Create a new mail operation */
4697 mail_op = modest_mail_operation_new (G_OBJECT(window));
4699 /* Get destination folder */
4700 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4702 /* transfer messages */
4706 /* Ask for user confirmation */
4708 modest_ui_actions_msgs_move_to_confirmation (window,
4709 TNY_FOLDER (folder_store),
4713 if (response == GTK_RESPONSE_OK) {
4714 /* Launch notification */
4715 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4716 _CS("ckct_nw_pasting"));
4717 if (inf_note != NULL) {
4718 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4719 gtk_widget_show (GTK_WIDGET(inf_note));
4722 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4723 modest_mail_operation_xfer_msgs (mail_op,
4725 TNY_FOLDER (folder_store),
4727 destroy_information_note,
4730 g_object_unref (mail_op);
4733 } else if (src_folder != NULL) {
4734 /* Launch notification */
4735 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4736 _CS("ckct_nw_pasting"));
4737 if (inf_note != NULL) {
4738 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4739 gtk_widget_show (GTK_WIDGET(inf_note));
4742 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4743 modest_mail_operation_xfer_folder (mail_op,
4747 destroy_folder_information_note,
4753 g_object_unref (data);
4754 if (src_folder != NULL)
4755 g_object_unref (src_folder);
4756 if (folder_store != NULL)
4757 g_object_unref (folder_store);
4763 modest_ui_actions_on_select_all (GtkAction *action,
4764 ModestWindow *window)
4766 GtkWidget *focused_widget;
4768 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4769 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4770 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4771 } else if (GTK_IS_LABEL (focused_widget)) {
4772 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4773 } else if (GTK_IS_EDITABLE (focused_widget)) {
4774 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4775 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4776 GtkTextBuffer *buffer;
4777 GtkTextIter start, end;
4779 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4780 gtk_text_buffer_get_start_iter (buffer, &start);
4781 gtk_text_buffer_get_end_iter (buffer, &end);
4782 gtk_text_buffer_select_range (buffer, &start, &end);
4783 } else if (GTK_IS_HTML (focused_widget)) {
4784 gtk_html_select_all (GTK_HTML (focused_widget));
4785 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4786 GtkWidget *header_view = focused_widget;
4787 GtkTreeSelection *selection = NULL;
4789 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4790 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4791 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4794 /* Disable window dimming management */
4795 modest_window_disable_dimming (MODEST_WINDOW(window));
4797 /* Select all messages */
4798 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4799 gtk_tree_selection_select_all (selection);
4801 /* Set focuse on header view */
4802 gtk_widget_grab_focus (header_view);
4804 /* Enable window dimming management */
4805 modest_window_enable_dimming (MODEST_WINDOW(window));
4806 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4807 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4813 modest_ui_actions_on_mark_as_read (GtkAction *action,
4814 ModestWindow *window)
4816 g_return_if_fail (MODEST_IS_WINDOW(window));
4818 /* Mark each header as read */
4819 do_headers_action (window, headers_action_mark_as_read, NULL);
4823 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4824 ModestWindow *window)
4826 g_return_if_fail (MODEST_IS_WINDOW(window));
4828 /* Mark each header as read */
4829 do_headers_action (window, headers_action_mark_as_unread, NULL);
4833 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4834 GtkRadioAction *selected,
4835 ModestWindow *window)
4839 value = gtk_radio_action_get_current_value (selected);
4840 if (MODEST_IS_WINDOW (window)) {
4841 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4846 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4847 GtkRadioAction *selected,
4848 ModestWindow *window)
4850 TnyHeaderFlags flags;
4851 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4853 flags = gtk_radio_action_get_current_value (selected);
4854 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4858 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4859 GtkRadioAction *selected,
4860 ModestWindow *window)
4864 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4866 file_format = gtk_radio_action_get_current_value (selected);
4867 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4872 modest_ui_actions_on_zoom_plus (GtkAction *action,
4873 ModestWindow *window)
4875 g_return_if_fail (MODEST_IS_WINDOW (window));
4877 modest_window_zoom_plus (MODEST_WINDOW (window));
4881 modest_ui_actions_on_zoom_minus (GtkAction *action,
4882 ModestWindow *window)
4884 g_return_if_fail (MODEST_IS_WINDOW (window));
4886 modest_window_zoom_minus (MODEST_WINDOW (window));
4890 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4891 ModestWindow *window)
4893 ModestWindowMgr *mgr;
4894 gboolean fullscreen, active;
4895 g_return_if_fail (MODEST_IS_WINDOW (window));
4897 mgr = modest_runtime_get_window_mgr ();
4899 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4900 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4902 if (active != fullscreen) {
4903 modest_window_mgr_set_fullscreen_mode (mgr, active);
4904 #ifndef MODEST_TOOLKIT_HILDON2
4905 gtk_window_present (GTK_WINDOW (window));
4911 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4912 ModestWindow *window)
4914 ModestWindowMgr *mgr;
4915 gboolean fullscreen;
4917 g_return_if_fail (MODEST_IS_WINDOW (window));
4919 mgr = modest_runtime_get_window_mgr ();
4920 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4921 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4923 #ifndef MODEST_TOOLKIT_HILDON2
4924 gtk_window_present (GTK_WINDOW (window));
4929 * Used by modest_ui_actions_on_details to call do_headers_action
4932 headers_action_show_details (TnyHeader *header,
4933 ModestWindow *window,
4937 gboolean async_retrieval;
4940 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4941 async_retrieval = TRUE;
4942 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4943 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4945 async_retrieval = FALSE;
4947 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4949 g_object_unref (msg);
4953 * Show the header details in a ModestDetailsDialog widget
4956 modest_ui_actions_on_details (GtkAction *action,
4959 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4963 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4967 header = tny_msg_get_header (msg);
4969 headers_action_show_details (header, win, NULL);
4970 g_object_unref (header);
4972 g_object_unref (msg);
4974 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4975 GtkWidget *folder_view, *header_view;
4977 /* Check which widget has the focus */
4978 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4979 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4980 if (gtk_widget_is_focus (folder_view)) {
4981 TnyFolderStore *folder_store
4982 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4983 if (!folder_store) {
4984 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4987 /* Show only when it's a folder */
4988 /* This function should not be called for account items,
4989 * because we dim the menu item for them. */
4990 if (TNY_IS_FOLDER (folder_store)) {
4991 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4992 TNY_FOLDER (folder_store));
4995 g_object_unref (folder_store);
4998 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4999 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5000 /* Show details of each header */
5001 do_headers_action (win, headers_action_show_details, header_view);
5003 #ifdef MODEST_TOOLKIT_HILDON2
5004 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5006 GtkWidget *header_view;
5008 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5009 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5011 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5013 g_object_unref (folder);
5020 modest_ui_actions_on_limit_error (GtkAction *action,
5023 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5025 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5030 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5031 ModestMsgEditWindow *window)
5033 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5035 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5039 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5040 ModestMsgEditWindow *window)
5042 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5044 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5048 modest_ui_actions_toggle_folders_view (GtkAction *action,
5049 ModestMainWindow *main_window)
5051 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5053 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5054 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5056 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5060 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5061 ModestWindow *window)
5063 gboolean active, fullscreen = FALSE;
5064 ModestWindowMgr *mgr;
5066 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5068 /* Check if we want to toggle the toolbar view in fullscreen
5070 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5071 "ViewShowToolbarFullScreen")) {
5075 /* Toggle toolbar */
5076 mgr = modest_runtime_get_window_mgr ();
5077 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5081 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5082 ModestMsgEditWindow *window)
5084 modest_msg_edit_window_select_font (window);
5089 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5090 const gchar *display_name,
5093 /* don't update the display name if it was already set;
5094 * updating the display name apparently is expensive */
5095 const gchar* old_name = gtk_window_get_title (window);
5097 if (display_name == NULL)
5100 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5101 return; /* don't do anything */
5103 /* This is usually used to change the title of the main window, which
5104 * is the one that holds the folder view. Note that this change can
5105 * happen even when the widget doesn't have the focus. */
5106 gtk_window_set_title (window, display_name);
5111 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5113 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5114 modest_msg_edit_window_select_contacts (window);
5118 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5120 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5121 modest_msg_edit_window_check_names (window, FALSE);
5124 #ifndef MODEST_TOOLKIT_HILDON2
5126 * This function is used to track changes in the selection of the
5127 * folder view that is inside the "move to" dialog to enable/disable
5128 * the OK button because we do not want the user to select a disallowed
5129 * destination for a folder.
5130 * The user also not desired to be able to use NEW button on items where
5131 * folder creation is not possibel.
5134 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5135 TnyFolderStore *folder_store,
5139 GtkWidget *dialog = NULL;
5140 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5141 gboolean moving_folder = FALSE;
5142 gboolean is_local_account = TRUE;
5143 GtkWidget *folder_view = NULL;
5144 ModestTnyFolderRules rules;
5146 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5151 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5155 /* check if folder_store is an remote account */
5156 if (TNY_IS_ACCOUNT (folder_store)) {
5157 TnyAccount *local_account = NULL;
5158 TnyAccount *mmc_account = NULL;
5159 ModestTnyAccountStore *account_store = NULL;
5161 account_store = modest_runtime_get_account_store ();
5162 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5163 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5165 if ((gpointer) local_account != (gpointer) folder_store &&
5166 (gpointer) mmc_account != (gpointer) folder_store) {
5167 ModestProtocolType proto;
5168 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5169 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5170 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5172 is_local_account = FALSE;
5173 /* New button should be dimmed on remote
5175 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5177 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5179 g_object_unref (local_account);
5181 /* It could not exist */
5183 g_object_unref (mmc_account);
5186 /* Check the target folder rules */
5187 if (TNY_IS_FOLDER (folder_store)) {
5188 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5189 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5190 ok_sensitive = FALSE;
5191 new_sensitive = FALSE;
5196 /* Check if we're moving a folder */
5197 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5198 /* Get the widgets */
5199 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5200 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5201 if (gtk_widget_is_focus (folder_view))
5202 moving_folder = TRUE;
5205 if (moving_folder) {
5206 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5208 /* Get the folder to move */
5209 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5211 /* Check that we're not moving to the same folder */
5212 if (TNY_IS_FOLDER (moved_folder)) {
5213 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5214 if (parent == folder_store)
5215 ok_sensitive = FALSE;
5216 g_object_unref (parent);
5219 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5220 /* Do not allow to move to an account unless it's the
5221 local folders account */
5222 if (!is_local_account)
5223 ok_sensitive = FALSE;
5226 if (ok_sensitive && (moved_folder == folder_store)) {
5227 /* Do not allow to move to itself */
5228 ok_sensitive = FALSE;
5230 g_object_unref (moved_folder);
5232 TnyFolder *src_folder = NULL;
5234 /* Moving a message */
5235 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5237 TnyHeader *header = NULL;
5238 header = modest_msg_view_window_get_header
5239 (MODEST_MSG_VIEW_WINDOW (user_data));
5240 if (!TNY_IS_HEADER(header))
5241 g_warning ("%s: could not get source header", __FUNCTION__);
5243 src_folder = tny_header_get_folder (header);
5246 g_object_unref (header);
5249 TNY_FOLDER (modest_folder_view_get_selected
5250 (MODEST_FOLDER_VIEW (folder_view)));
5253 if (TNY_IS_FOLDER(src_folder)) {
5254 /* Do not allow to move the msg to the same folder */
5255 /* Do not allow to move the msg to an account */
5256 if ((gpointer) src_folder == (gpointer) folder_store ||
5257 TNY_IS_ACCOUNT (folder_store))
5258 ok_sensitive = FALSE;
5259 g_object_unref (src_folder);
5261 g_warning ("%s: could not get source folder", __FUNCTION__);
5265 /* Set sensitivity of the OK and NEW button */
5266 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5267 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5272 on_move_to_dialog_response (GtkDialog *dialog,
5276 GtkWidget *parent_win;
5277 MoveToInfo *helper = NULL;
5278 ModestFolderView *folder_view;
5279 gboolean unset_edit_mode = FALSE;
5281 helper = (MoveToInfo *) user_data;
5283 parent_win = (GtkWidget *) helper->win;
5284 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5285 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5287 TnyFolderStore *dst_folder;
5288 TnyFolderStore *selected;
5290 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5291 selected = modest_folder_view_get_selected (folder_view);
5292 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5293 g_object_unref (selected);
5295 case GTK_RESPONSE_NONE:
5296 case GTK_RESPONSE_CANCEL:
5297 case GTK_RESPONSE_DELETE_EVENT:
5299 case GTK_RESPONSE_OK:
5300 dst_folder = modest_folder_view_get_selected (folder_view);
5302 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5303 /* Clean list to move used for filtering */
5304 modest_folder_view_set_list_to_move (folder_view, NULL);
5306 modest_ui_actions_on_main_window_move_to (NULL,
5307 GTK_WIDGET (folder_view),
5309 MODEST_MAIN_WINDOW (parent_win));
5310 #ifdef MODEST_TOOLKIT_HILDON2
5311 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5312 /* Clean list to move used for filtering */
5313 modest_folder_view_set_list_to_move (folder_view, NULL);
5315 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5318 GTK_WINDOW (parent_win));
5321 /* if the user selected a root folder
5322 (account) then do not perform any action */
5323 if (TNY_IS_ACCOUNT (dst_folder)) {
5324 g_signal_stop_emission_by_name (dialog, "response");
5328 /* Clean list to move used for filtering */
5329 modest_folder_view_set_list_to_move (folder_view, NULL);
5331 /* Moving from headers window in edit mode */
5332 modest_ui_actions_on_window_move_to (NULL, helper->list,
5334 MODEST_WINDOW (parent_win));
5338 g_object_unref (dst_folder);
5340 unset_edit_mode = TRUE;
5343 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5346 /* Free the helper and exit */
5348 g_object_unref (helper->list);
5349 if (unset_edit_mode) {
5350 #ifdef MODEST_TOOLKIT_HILDON2
5351 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5354 g_slice_free (MoveToInfo, helper);
5355 gtk_widget_destroy (GTK_WIDGET (dialog));
5359 create_move_to_dialog (GtkWindow *win,
5360 GtkWidget *folder_view,
5361 TnyList *list_to_move)
5363 GtkWidget *dialog, *tree_view = NULL;
5365 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5367 #ifndef MODEST_TOOLKIT_HILDON2
5368 /* Track changes in the selection to
5369 * disable the OK button whenever "Move to" is not possible
5370 * disbale NEW button whenever New is not possible */
5371 g_signal_connect (tree_view,
5372 "folder_selection_changed",
5373 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5377 /* It could happen that we're trying to move a message from a
5378 window (msg window for example) after the main window was
5379 closed, so we can not just get the model of the folder
5381 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5382 const gchar *visible_id = NULL;
5384 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5385 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5386 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5387 MODEST_FOLDER_VIEW(tree_view));
5390 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5392 /* Show the same account than the one that is shown in the main window */
5393 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5396 const gchar *active_account_name = NULL;
5397 ModestAccountMgr *mgr = NULL;
5398 ModestAccountSettings *settings = NULL;
5399 ModestServerAccountSettings *store_settings = NULL;
5401 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5402 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5404 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5405 mgr = modest_runtime_get_account_mgr ();
5406 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5409 const gchar *store_account_name;
5410 store_settings = modest_account_settings_get_store_settings (settings);
5411 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5413 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5414 store_account_name);
5415 g_object_unref (store_settings);
5416 g_object_unref (settings);
5420 /* we keep a pointer to the embedded folder view, so we can
5421 * retrieve it with get_folder_view_from_move_to_dialog (see
5422 * above) later (needed for focus handling)
5424 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5426 /* Hide special folders */
5427 #ifndef MODEST_TOOLKIT_HILDON2
5428 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5431 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5432 #ifndef MODEST_TOOLKIT_HILDON2
5433 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5436 gtk_widget_show (GTK_WIDGET (tree_view));
5442 * Shows a confirmation dialog to the user when we're moving messages
5443 * from a remote server to the local storage. Returns the dialog
5444 * response. If it's other kind of movement then it always returns
5447 * This one is used by the next functions:
5448 * modest_ui_actions_on_paste - commented out
5449 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5452 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5453 TnyFolder *dest_folder,
5457 gint response = GTK_RESPONSE_OK;
5458 TnyAccount *account = NULL;
5459 TnyFolder *src_folder = NULL;
5460 TnyIterator *iter = NULL;
5461 TnyHeader *header = NULL;
5463 /* return with OK if the destination is a remote folder */
5464 if (modest_tny_folder_is_remote_folder (dest_folder))
5465 return GTK_RESPONSE_OK;
5467 /* Get source folder */
5468 iter = tny_list_create_iterator (headers);
5469 header = TNY_HEADER (tny_iterator_get_current (iter));
5471 src_folder = tny_header_get_folder (header);
5472 g_object_unref (header);
5474 g_object_unref (iter);
5476 /* if no src_folder, message may be an attahcment */
5477 if (src_folder == NULL)
5478 return GTK_RESPONSE_CANCEL;
5480 /* If the source is a local or MMC folder */
5481 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5482 g_object_unref (src_folder);
5483 return GTK_RESPONSE_OK;
5486 /* Get the account */
5487 account = tny_folder_get_account (src_folder);
5489 /* now if offline we ask the user */
5490 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5491 response = GTK_RESPONSE_OK;
5493 response = GTK_RESPONSE_CANCEL;
5496 g_object_unref (src_folder);
5497 g_object_unref (account);
5503 move_to_helper_destroyer (gpointer user_data)
5505 MoveToHelper *helper = (MoveToHelper *) user_data;
5507 /* Close the "Pasting" information banner */
5508 if (helper->banner) {
5509 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5510 g_object_unref (helper->banner);
5512 if (gtk_tree_row_reference_valid (helper->reference)) {
5513 gtk_tree_row_reference_free (helper->reference);
5514 helper->reference = NULL;
5520 move_to_cb (ModestMailOperation *mail_op,
5523 MoveToHelper *helper = (MoveToHelper *) user_data;
5524 GObject *object = modest_mail_operation_get_source (mail_op);
5526 /* Note that the operation could have failed, in that case do
5528 if (modest_mail_operation_get_status (mail_op) !=
5529 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5532 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5533 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5535 if (!modest_msg_view_window_select_next_message (self) &&
5536 !modest_msg_view_window_select_previous_message (self)) {
5537 /* No more messages to view, so close this window */
5538 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5540 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5541 gtk_tree_row_reference_valid (helper->reference)) {
5542 GtkWidget *header_view;
5544 GtkTreeSelection *sel;
5546 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5547 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5548 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5549 path = gtk_tree_row_reference_get_path (helper->reference);
5550 /* We need to unselect the previous one
5551 because we could be copying instead of
5553 gtk_tree_selection_unselect_all (sel);
5554 gtk_tree_selection_select_path (sel, path);
5555 gtk_tree_path_free (path);
5557 g_object_unref (object);
5560 /* Destroy the helper */
5561 move_to_helper_destroyer (helper);
5565 folder_move_to_cb (ModestMailOperation *mail_op,
5566 TnyFolder *new_folder,
5569 GtkWidget *folder_view;
5572 object = modest_mail_operation_get_source (mail_op);
5573 if (MODEST_IS_MAIN_WINDOW (object)) {
5574 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5575 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5576 g_object_ref (folder_view);
5577 g_object_unref (object);
5578 move_to_cb (mail_op, user_data);
5579 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5580 g_object_unref (folder_view);
5582 move_to_cb (mail_op, user_data);
5587 msgs_move_to_cb (ModestMailOperation *mail_op,
5590 move_to_cb (mail_op, user_data);
5594 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5597 GObject *win = NULL;
5598 const GError *error;
5599 TnyAccount *account = NULL;
5601 #ifndef MODEST_TOOLKIT_HILDON2
5602 ModestWindow *main_window = NULL;
5604 /* Disable next automatic folder selection */
5605 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5606 FALSE); /* don't create */
5608 /* Show notification dialog only if the main window exists */
5610 GtkWidget *folder_view = NULL;
5612 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5613 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5614 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5616 if (user_data && TNY_IS_FOLDER (user_data)) {
5617 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5618 TNY_FOLDER (user_data), FALSE);
5622 win = modest_mail_operation_get_source (mail_op);
5623 error = modest_mail_operation_get_error (mail_op);
5625 if (TNY_IS_FOLDER (user_data))
5626 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5627 else if (TNY_IS_ACCOUNT (user_data))
5628 account = g_object_ref (user_data);
5630 /* If it's not a disk full error then show a generic error */
5631 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5632 (GtkWidget *) win, (GError *) error,
5634 modest_platform_run_information_dialog ((GtkWindow *) win,
5635 _("mail_in_ui_folder_move_target_error"),
5638 g_object_unref (account);
5640 g_object_unref (win);
5644 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5653 gint pending_purges = 0;
5654 gboolean some_purged = FALSE;
5655 ModestWindow *win = MODEST_WINDOW (user_data);
5656 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5658 /* If there was any error */
5659 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5660 modest_window_mgr_unregister_header (mgr, header);
5664 /* Once the message has been retrieved for purging, we check if
5665 * it's all ok for purging */
5667 parts = tny_simple_list_new ();
5668 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5669 iter = tny_list_create_iterator (parts);
5671 while (!tny_iterator_is_done (iter)) {
5673 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5674 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5675 if (tny_mime_part_is_purged (part))
5682 g_object_unref (part);
5684 tny_iterator_next (iter);
5686 g_object_unref (iter);
5689 if (pending_purges>0) {
5691 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5693 if (response == GTK_RESPONSE_OK) {
5696 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5697 iter = tny_list_create_iterator (parts);
5698 while (!tny_iterator_is_done (iter)) {
5701 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5702 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5703 tny_mime_part_set_purged (part);
5706 g_object_unref (part);
5708 tny_iterator_next (iter);
5710 g_object_unref (iter);
5712 tny_msg_rewrite_cache (msg);
5714 gtk_widget_destroy (info);
5718 modest_window_mgr_unregister_header (mgr, header);
5720 g_object_unref (parts);
5724 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5725 ModestMainWindow *win)
5727 GtkWidget *header_view;
5728 TnyList *header_list;
5730 TnyHeaderFlags flags;
5731 ModestWindow *msg_view_window = NULL;
5734 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5736 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5737 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5739 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5741 g_warning ("%s: no header selected", __FUNCTION__);
5745 if (tny_list_get_length (header_list) == 1) {
5746 TnyIterator *iter = tny_list_create_iterator (header_list);
5747 header = TNY_HEADER (tny_iterator_get_current (iter));
5748 g_object_unref (iter);
5752 if (!header || !TNY_IS_HEADER(header)) {
5753 g_warning ("%s: header is not valid", __FUNCTION__);
5757 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5758 header, &msg_view_window);
5759 flags = tny_header_get_flags (header);
5760 if (!(flags & TNY_HEADER_FLAG_CACHED))
5763 if (msg_view_window != NULL)
5764 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5766 /* do nothing; uid was registered before, so window is probably on it's way */
5767 g_debug ("header %p has already been registered", header);
5770 ModestMailOperation *mail_op = NULL;
5771 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5772 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5773 modest_ui_actions_disk_operations_error_handler,
5775 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5776 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5778 g_object_unref (mail_op);
5781 g_object_unref (header);
5783 g_object_unref (header_list);
5787 * Checks if we need a connection to do the transfer and if the user
5788 * wants to connect to complete it
5791 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5792 TnyFolderStore *src_folder,
5794 TnyFolder *dst_folder,
5795 gboolean delete_originals,
5796 gboolean *need_connection,
5799 TnyAccount *src_account;
5800 gint uncached_msgs = 0;
5802 /* We don't need any further check if
5804 * 1- the source folder is local OR
5805 * 2- the device is already online
5807 if (!modest_tny_folder_store_is_remote (src_folder) ||
5808 tny_device_is_online (modest_runtime_get_device())) {
5809 *need_connection = FALSE;
5814 /* We must ask for a connection when
5816 * - the message(s) is not already cached OR
5817 * - the message(s) is cached but the leave_on_server setting
5818 * is FALSE (because we need to sync the source folder to
5819 * delete the message from the server (for IMAP we could do it
5820 * offline, it'll take place the next time we get a
5823 uncached_msgs = header_list_count_uncached_msgs (headers);
5824 src_account = get_account_from_folder_store (src_folder);
5825 if (uncached_msgs > 0) {
5829 *need_connection = TRUE;
5830 num_headers = tny_list_get_length (headers);
5831 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5833 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5834 GTK_RESPONSE_CANCEL) {
5840 /* The transfer is possible and the user wants to */
5843 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5844 const gchar *account_name;
5845 gboolean leave_on_server;
5847 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5848 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5851 if (leave_on_server == TRUE) {
5852 *need_connection = FALSE;
5854 *need_connection = TRUE;
5857 *need_connection = FALSE;
5862 g_object_unref (src_account);
5866 xfer_messages_error_handler (ModestMailOperation *mail_op,
5870 const GError *error;
5871 TnyAccount *account;
5873 win = modest_mail_operation_get_source (mail_op);
5874 error = modest_mail_operation_get_error (mail_op);
5876 /* We cannot get the account from the mail op as that is the
5877 source account and for checking memory full conditions we
5878 need the destination one */
5879 account = TNY_ACCOUNT (user_data);
5882 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5883 (GtkWidget *) win, (GError*) error,
5884 account, _KR("cerm_memory_card_full"))) {
5885 modest_platform_run_information_dialog ((GtkWindow *) win,
5886 _("mail_in_ui_folder_move_target_error"),
5890 g_object_unref (win);
5894 TnyFolderStore *dst_folder;
5899 * Utility function that transfer messages from both the main window
5900 * and the msg view window when using the "Move to" dialog
5903 xfer_messages_performer (gboolean canceled,
5905 GtkWindow *parent_window,
5906 TnyAccount *account,
5909 ModestWindow *win = MODEST_WINDOW (parent_window);
5910 TnyAccount *dst_account = NULL;
5911 gboolean dst_forbids_message_add = FALSE;
5912 XferMsgsHelper *helper;
5913 MoveToHelper *movehelper;
5914 ModestMailOperation *mail_op;
5916 helper = (XferMsgsHelper *) user_data;
5918 if (canceled || err) {
5919 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5920 (GtkWidget *) parent_window, err,
5922 /* Show the proper error message */
5923 modest_ui_actions_on_account_connection_error (parent_window, account);
5928 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5930 /* tinymail will return NULL for local folders it seems */
5931 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5932 modest_tny_account_get_protocol_type (dst_account),
5933 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5935 if (dst_forbids_message_add) {
5936 modest_platform_information_banner (GTK_WIDGET (win),
5938 ngettext("mail_in_ui_folder_move_target_error",
5939 "mail_in_ui_folder_move_targets_error",
5940 tny_list_get_length (helper->headers)));
5944 movehelper = g_new0 (MoveToHelper, 1);
5946 #ifndef MODEST_TOOLKIT_HILDON2
5947 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5948 _CS("ckct_nw_pasting"));
5949 if (movehelper->banner != NULL) {
5950 g_object_ref (movehelper->banner);
5951 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5955 if (MODEST_IS_MAIN_WINDOW (win)) {
5956 GtkWidget *header_view =
5957 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5958 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5959 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5962 /* Perform the mail operation */
5963 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5964 xfer_messages_error_handler,
5965 g_object_ref (dst_account),
5967 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5970 modest_mail_operation_xfer_msgs (mail_op,
5972 TNY_FOLDER (helper->dst_folder),
5977 g_object_unref (G_OBJECT (mail_op));
5980 g_object_unref (dst_account);
5981 g_object_unref (helper->dst_folder);
5982 g_object_unref (helper->headers);
5983 g_slice_free (XferMsgsHelper, helper);
5987 TnyFolder *src_folder;
5988 TnyFolderStore *dst_folder;
5989 gboolean delete_original;
5990 GtkWidget *folder_view;
5994 on_move_folder_cb (gboolean canceled,
5996 GtkWindow *parent_window,
5997 TnyAccount *account,
6000 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
6001 GtkTreeSelection *sel;
6002 ModestMailOperation *mail_op = NULL;
6004 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6005 /* Note that the connection process can fail due to
6006 memory low conditions as it can not successfully
6007 store the summary */
6008 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6009 (GtkWidget*) parent_window, err,
6011 g_debug ("Error connecting when trying to move a folder");
6013 g_object_unref (G_OBJECT (info->src_folder));
6014 g_object_unref (G_OBJECT (info->dst_folder));
6019 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6020 #ifndef MODEST_TOOLKIT_HILDON2
6021 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6022 _CS("ckct_nw_pasting"));
6023 if (helper->banner != NULL) {
6024 g_object_ref (helper->banner);
6025 gtk_widget_show (GTK_WIDGET(helper->banner));
6028 /* Clean folder on header view before moving it */
6029 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6030 gtk_tree_selection_unselect_all (sel);
6032 /* Let gtk events run. We need that the folder
6033 view frees its reference to the source
6034 folder *before* issuing the mail operation
6035 so we need the signal handler of selection
6036 changed to happen before the mail
6038 while (gtk_events_pending ())
6039 gtk_main_iteration (); */
6042 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6043 modest_ui_actions_move_folder_error_handler,
6044 g_object_ref (info->dst_folder), g_object_unref);
6045 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6048 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6049 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6050 TNY_FOLDER (info->dst_folder), TRUE);
6052 modest_mail_operation_xfer_folder (mail_op,
6053 TNY_FOLDER (info->src_folder),
6055 info->delete_original,
6058 g_object_unref (G_OBJECT (info->src_folder));
6060 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6063 /* Unref mail operation */
6064 g_object_unref (G_OBJECT (mail_op));
6065 g_object_unref (G_OBJECT (info->dst_folder));
6070 get_account_from_folder_store (TnyFolderStore *folder_store)
6072 if (TNY_IS_ACCOUNT (folder_store))
6073 return g_object_ref (folder_store);
6075 return tny_folder_get_account (TNY_FOLDER (folder_store));
6079 * UI handler for the "Move to" action when invoked from the
6083 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6084 GtkWidget *folder_view,
6085 TnyFolderStore *dst_folder,
6086 ModestMainWindow *win)
6088 ModestHeaderView *header_view = NULL;
6089 TnyFolderStore *src_folder = NULL;
6091 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6093 /* Get the source folder */
6094 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6096 /* Get header view */
6097 header_view = (ModestHeaderView *)
6098 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6100 /* Get folder or messages to transfer */
6101 if (gtk_widget_is_focus (folder_view)) {
6102 gboolean do_xfer = TRUE;
6104 /* Allow only to transfer folders to the local root folder */
6105 if (TNY_IS_ACCOUNT (dst_folder) &&
6106 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6107 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6109 } else if (!TNY_IS_FOLDER (src_folder)) {
6110 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6115 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6116 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6118 info->src_folder = g_object_ref (src_folder);
6119 info->dst_folder = g_object_ref (dst_folder);
6120 info->delete_original = TRUE;
6121 info->folder_view = folder_view;
6123 connect_info->callback = on_move_folder_cb;
6124 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6125 connect_info->data = info;
6127 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6128 TNY_FOLDER_STORE (src_folder),
6131 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6134 headers = modest_header_view_get_selected_headers(header_view);
6136 /* Transfer the messages */
6137 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6138 headers, TNY_FOLDER (dst_folder));
6140 g_object_unref (headers);
6144 g_object_unref (src_folder);
6147 #ifdef MODEST_TOOLKIT_HILDON2
6149 * UI handler for the "Move to" action when invoked from the
6150 * ModestFolderWindow
6153 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6154 TnyFolderStore *dst_folder,
6158 TnyFolderStore *src_folder = NULL;
6159 TnyIterator *iterator;
6161 if (tny_list_get_length (selection) != 1)
6164 iterator = tny_list_create_iterator (selection);
6165 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6166 g_object_unref (iterator);
6169 gboolean do_xfer = TRUE;
6171 /* Allow only to transfer folders to the local root folder */
6172 if (TNY_IS_ACCOUNT (dst_folder) &&
6173 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6174 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6177 modest_platform_run_information_dialog (win,
6178 _("mail_in_ui_folder_move_target_error"),
6180 } else if (!TNY_IS_FOLDER (src_folder)) {
6181 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6186 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6187 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6189 info->src_folder = g_object_ref (src_folder);
6190 info->dst_folder = g_object_ref (dst_folder);
6191 info->delete_original = TRUE;
6192 info->folder_view = folder_view;
6194 connect_info->callback = on_move_folder_cb;
6195 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6196 connect_info->data = info;
6198 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6199 TNY_FOLDER_STORE (src_folder),
6204 g_object_unref (src_folder);
6210 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6211 TnyFolder *src_folder,
6213 TnyFolder *dst_folder)
6215 gboolean need_connection = TRUE;
6216 gboolean do_xfer = TRUE;
6217 XferMsgsHelper *helper;
6219 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6220 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6221 g_return_if_fail (TNY_IS_LIST (headers));
6223 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6224 headers, TNY_FOLDER (dst_folder),
6225 TRUE, &need_connection,
6228 /* If we don't want to transfer just return */
6232 /* Create the helper */
6233 helper = g_slice_new (XferMsgsHelper);
6234 helper->dst_folder = g_object_ref (dst_folder);
6235 helper->headers = g_object_ref (headers);
6237 if (need_connection) {
6238 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6239 connect_info->callback = xfer_messages_performer;
6240 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6241 connect_info->data = helper;
6243 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6244 TNY_FOLDER_STORE (src_folder),
6247 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6248 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6249 src_account, helper);
6250 g_object_unref (src_account);
6255 * UI handler for the "Move to" action when invoked from the
6256 * ModestMsgViewWindow
6259 modest_ui_actions_on_window_move_to (GtkAction *action,
6261 TnyFolderStore *dst_folder,
6264 TnyFolder *src_folder = NULL;
6266 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6269 TnyHeader *header = NULL;
6272 iter = tny_list_create_iterator (headers);
6273 header = (TnyHeader *) tny_iterator_get_current (iter);
6274 src_folder = tny_header_get_folder (header);
6276 /* Transfer the messages */
6277 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6279 TNY_FOLDER (dst_folder));
6282 g_object_unref (header);
6283 g_object_unref (iter);
6284 g_object_unref (src_folder);
6289 modest_ui_actions_on_move_to (GtkAction *action,
6292 modest_ui_actions_on_edit_mode_move_to (win);
6296 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6298 GtkWidget *dialog = NULL;
6299 MoveToInfo *helper = NULL;
6300 TnyList *list_to_move;
6302 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6304 #ifndef MODEST_TOOLKIT_HILDON2
6305 /* Get the main window if exists */
6306 ModestMainWindow *main_window;
6307 if (MODEST_IS_MAIN_WINDOW (win))
6308 main_window = MODEST_MAIN_WINDOW (win);
6311 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6312 FALSE)); /* don't create */
6315 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6320 if (tny_list_get_length (list_to_move) < 1) {
6321 g_object_unref (list_to_move);
6325 /* Create and run the dialog */
6326 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6327 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6328 GTK_WINDOW (dialog),
6332 helper = g_slice_new0 (MoveToInfo);
6333 helper->list = list_to_move;
6336 /* Listen to response signal */
6337 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6339 /* Show the dialog */
6340 gtk_widget_show (dialog);
6346 * Calls #HeadersFunc for each header already selected in the main
6347 * window or the message currently being shown in the msg view window
6350 do_headers_action (ModestWindow *win,
6354 TnyList *headers_list = NULL;
6355 TnyIterator *iter = NULL;
6356 TnyHeader *header = NULL;
6357 TnyFolder *folder = NULL;
6360 headers_list = get_selected_headers (win);
6364 /* Get the folder */
6365 iter = tny_list_create_iterator (headers_list);
6366 header = TNY_HEADER (tny_iterator_get_current (iter));
6368 folder = tny_header_get_folder (header);
6369 g_object_unref (header);
6372 /* Call the function for each header */
6373 while (!tny_iterator_is_done (iter)) {
6374 header = TNY_HEADER (tny_iterator_get_current (iter));
6375 func (header, win, user_data);
6376 g_object_unref (header);
6377 tny_iterator_next (iter);
6380 /* Trick: do a poke status in order to speed up the signaling
6383 tny_folder_poke_status (folder);
6384 g_object_unref (folder);
6388 g_object_unref (iter);
6389 g_object_unref (headers_list);
6393 modest_ui_actions_view_attachment (GtkAction *action,
6394 ModestWindow *window)
6396 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6397 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6399 /* not supported window for this action */
6400 g_return_if_reached ();
6405 modest_ui_actions_save_attachments (GtkAction *action,
6406 ModestWindow *window)
6408 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6410 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6413 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6415 /* not supported window for this action */
6416 g_return_if_reached ();
6421 modest_ui_actions_remove_attachments (GtkAction *action,
6422 ModestWindow *window)
6424 if (MODEST_IS_MAIN_WINDOW (window)) {
6425 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6426 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6427 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6429 /* not supported window for this action */
6430 g_return_if_reached ();
6435 modest_ui_actions_on_settings (GtkAction *action,
6440 dialog = modest_platform_get_global_settings_dialog ();
6441 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6442 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6443 gtk_widget_show_all (dialog);
6445 gtk_dialog_run (GTK_DIALOG (dialog));
6447 gtk_widget_destroy (dialog);
6451 modest_ui_actions_on_help (GtkAction *action,
6454 /* Help app is not available at all in fremantle */
6455 #ifndef MODEST_TOOLKIT_HILDON2
6456 const gchar *help_id;
6458 g_return_if_fail (win && GTK_IS_WINDOW(win));
6460 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6463 modest_platform_show_help (GTK_WINDOW (win), help_id);
6468 modest_ui_actions_on_csm_help (GtkAction *action,
6471 /* Help app is not available at all in fremantle */
6472 #ifndef MODEST_TOOLKIT_HILDON2
6474 const gchar* help_id = NULL;
6475 GtkWidget *folder_view;
6476 TnyFolderStore *folder_store;
6478 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6480 /* Get selected folder */
6481 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6482 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6483 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6485 /* Switch help_id */
6486 if (folder_store && TNY_IS_FOLDER (folder_store))
6487 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6490 g_object_unref (folder_store);
6493 modest_platform_show_help (GTK_WINDOW (win), help_id);
6495 modest_ui_actions_on_help (action, win);
6500 retrieve_contents_cb (ModestMailOperation *mail_op,
6507 /* We only need this callback to show an error in case of
6508 memory low condition */
6509 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6510 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6515 retrieve_msg_contents_performer (gboolean canceled,
6517 GtkWindow *parent_window,
6518 TnyAccount *account,
6521 ModestMailOperation *mail_op;
6522 TnyList *headers = TNY_LIST (user_data);
6524 if (err || canceled) {
6525 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6526 (GtkWidget *) parent_window, err,
6531 /* Create mail operation */
6532 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6533 modest_ui_actions_disk_operations_error_handler,
6535 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6536 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6539 g_object_unref (mail_op);
6541 g_object_unref (headers);
6542 g_object_unref (account);
6546 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6547 ModestWindow *window)
6549 TnyList *headers = NULL;
6550 TnyAccount *account = NULL;
6551 TnyIterator *iter = NULL;
6552 TnyHeader *header = NULL;
6553 TnyFolder *folder = NULL;
6556 headers = get_selected_headers (window);
6560 /* Pick the account */
6561 iter = tny_list_create_iterator (headers);
6562 header = TNY_HEADER (tny_iterator_get_current (iter));
6563 folder = tny_header_get_folder (header);
6564 account = tny_folder_get_account (folder);
6565 g_object_unref (folder);
6566 g_object_unref (header);
6567 g_object_unref (iter);
6569 /* Connect and perform the message retrieval */
6570 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6571 g_object_ref (account),
6572 retrieve_msg_contents_performer,
6573 g_object_ref (headers));
6576 g_object_unref (account);
6577 g_object_unref (headers);
6581 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6583 g_return_if_fail (MODEST_IS_WINDOW (window));
6586 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6590 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6592 g_return_if_fail (MODEST_IS_WINDOW (window));
6595 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6599 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6600 ModestWindow *window)
6602 g_return_if_fail (MODEST_IS_WINDOW (window));
6605 modest_ui_actions_check_menu_dimming_rules (window);
6609 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6610 ModestWindow *window)
6612 g_return_if_fail (MODEST_IS_WINDOW (window));
6615 modest_ui_actions_check_menu_dimming_rules (window);
6619 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6620 ModestWindow *window)
6622 g_return_if_fail (MODEST_IS_WINDOW (window));
6625 modest_ui_actions_check_menu_dimming_rules (window);
6629 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6630 ModestWindow *window)
6632 g_return_if_fail (MODEST_IS_WINDOW (window));
6635 modest_ui_actions_check_menu_dimming_rules (window);
6639 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6640 ModestWindow *window)
6642 g_return_if_fail (MODEST_IS_WINDOW (window));
6645 modest_ui_actions_check_menu_dimming_rules (window);
6649 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6650 ModestWindow *window)
6652 g_return_if_fail (MODEST_IS_WINDOW (window));
6655 modest_ui_actions_check_menu_dimming_rules (window);
6659 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6660 ModestWindow *window)
6662 g_return_if_fail (MODEST_IS_WINDOW (window));
6665 modest_ui_actions_check_menu_dimming_rules (window);
6669 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6670 ModestWindow *window)
6672 g_return_if_fail (MODEST_IS_WINDOW (window));
6675 modest_ui_actions_check_menu_dimming_rules (window);
6679 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6680 ModestWindow *window)
6682 g_return_if_fail (MODEST_IS_WINDOW (window));
6685 modest_ui_actions_check_menu_dimming_rules (window);
6689 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6691 g_return_if_fail (MODEST_IS_WINDOW (window));
6693 /* we check for low-mem; in that case, show a warning, and don't allow
6696 if (modest_platform_check_memory_low (window, TRUE))
6699 modest_platform_show_search_messages (GTK_WINDOW (window));
6703 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6705 g_return_if_fail (MODEST_IS_WINDOW (win));
6708 /* we check for low-mem; in that case, show a warning, and don't allow
6709 * for the addressbook
6711 if (modest_platform_check_memory_low (win, TRUE))
6715 modest_platform_show_addressbook (GTK_WINDOW (win));
6720 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6721 ModestWindow *window)
6724 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6726 if (GTK_IS_TOGGLE_ACTION (action))
6727 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6731 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6736 on_send_receive_finished (ModestMailOperation *mail_op,
6739 GtkWidget *header_view, *folder_view;
6740 TnyFolderStore *folder_store;
6741 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6743 /* Set send/receive operation finished */
6744 modest_main_window_notify_send_receive_completed (main_win);
6746 /* Don't refresh the current folder if there were any errors */
6747 if (modest_mail_operation_get_status (mail_op) !=
6748 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6751 /* Refresh the current folder if we're viewing a window. We do
6752 this because the user won't be able to see the new mails in
6753 the selected folder after a Send&Receive because it only
6754 performs a poke_status, i.e, only the number of read/unread
6755 messages is updated, but the new headers are not
6757 folder_view = modest_main_window_get_child_widget (main_win,
6758 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6762 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6764 /* Do not need to refresh INBOX again because the
6765 update_account does it always automatically */
6766 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6767 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6768 ModestMailOperation *refresh_op;
6770 header_view = modest_main_window_get_child_widget (main_win,
6771 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6773 /* We do not need to set the contents style
6774 because it hasn't changed. We also do not
6775 need to save the widget status. Just force
6777 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6778 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6779 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6780 folder_refreshed_cb, main_win);
6781 g_object_unref (refresh_op);
6785 g_object_unref (folder_store);
6790 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6796 const gchar* server_name = NULL;
6797 TnyTransportAccount *transport;
6798 gchar *message = NULL;
6799 ModestProtocol *protocol;
6801 /* Don't show anything if the user cancelled something or the
6802 * send receive request is not interactive. Authentication
6803 * errors are managed by the account store so no need to show
6804 * a dialog here again */
6805 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6806 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6807 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6811 /* Get the server name. Note that we could be using a
6812 connection specific transport account */
6813 transport = (TnyTransportAccount *)
6814 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6816 ModestTnyAccountStore *acc_store;
6817 const gchar *acc_name;
6818 TnyTransportAccount *conn_specific;
6820 acc_store = modest_runtime_get_account_store();
6821 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6822 conn_specific = (TnyTransportAccount *)
6823 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6824 if (conn_specific) {
6825 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6826 g_object_unref (conn_specific);
6828 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6830 g_object_unref (transport);
6834 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6835 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6836 tny_account_get_proto (TNY_ACCOUNT (transport)));
6838 g_warning ("%s: Account with no proto", __FUNCTION__);
6842 /* Show the appropriate message text for the GError: */
6843 switch (err->code) {
6844 case TNY_SERVICE_ERROR_CONNECT:
6845 message = modest_protocol_get_translation (protocol,
6846 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6849 case TNY_SERVICE_ERROR_SEND:
6850 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6852 case TNY_SERVICE_ERROR_UNAVAILABLE:
6853 message = modest_protocol_get_translation (protocol,
6854 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6858 g_warning ("%s: unexpected ERROR %d",
6859 __FUNCTION__, err->code);
6860 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6864 modest_platform_run_information_dialog (NULL, message, FALSE);
6869 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6874 ModestWindow *top_window = NULL;
6875 ModestWindowMgr *mgr = NULL;
6876 GtkWidget *header_view = NULL;
6877 TnyFolder *selected_folder = NULL;
6878 TnyFolderType folder_type;
6880 mgr = modest_runtime_get_window_mgr ();
6881 top_window = modest_window_mgr_get_current_top (mgr);
6886 #ifndef MODEST_TOOLKIT_HILDON2
6887 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6888 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6889 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6892 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6893 header_view = (GtkWidget *)
6894 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6898 /* Get selected folder */
6900 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6901 if (!selected_folder)
6904 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6905 #if GTK_CHECK_VERSION(2, 8, 0)
6906 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6907 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6908 GtkTreeViewColumn *tree_column;
6910 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6911 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6913 gtk_tree_view_column_queue_resize (tree_column);
6915 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6916 gtk_widget_queue_draw (header_view);
6919 #ifndef MODEST_TOOLKIT_HILDON2
6920 /* Rerun dimming rules, because the message could become deletable for example */
6921 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6922 MODEST_DIMMING_RULES_TOOLBAR);
6923 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6924 MODEST_DIMMING_RULES_MENU);
6928 g_object_unref (selected_folder);
6932 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6933 TnyAccount *account)
6935 ModestProtocolType protocol_type;
6936 ModestProtocol *protocol;
6937 gchar *error_note = NULL;
6939 protocol_type = modest_tny_account_get_protocol_type (account);
6940 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6943 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6944 if (error_note == NULL) {
6945 g_warning ("%s: This should not be reached", __FUNCTION__);
6947 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6948 g_free (error_note);
6953 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6957 TnyFolderStore *folder = NULL;
6958 TnyAccount *account = NULL;
6959 ModestProtocolType proto;
6960 ModestProtocol *protocol;
6961 TnyHeader *header = NULL;
6963 if (MODEST_IS_MAIN_WINDOW (win)) {
6964 GtkWidget *header_view;
6965 TnyList* headers = NULL;
6967 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6968 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6969 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6970 if (!headers || tny_list_get_length (headers) == 0) {
6972 g_object_unref (headers);
6975 iter = tny_list_create_iterator (headers);
6976 header = TNY_HEADER (tny_iterator_get_current (iter));
6977 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6978 g_object_unref (iter);
6979 g_object_unref (headers);
6980 #ifdef MODEST_TOOLKIT_HILDON2
6981 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6982 GtkWidget *header_view;
6983 TnyList* headers = NULL;
6985 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6986 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6987 if (!headers || tny_list_get_length (headers) == 0) {
6989 g_object_unref (headers);
6992 iter = tny_list_create_iterator (headers);
6993 header = TNY_HEADER (tny_iterator_get_current (iter));
6995 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6997 g_warning ("List should contain headers");
6999 g_object_unref (iter);
7000 g_object_unref (headers);
7002 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7003 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7005 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7008 if (!header || !folder)
7011 /* Get the account type */
7012 account = tny_folder_get_account (TNY_FOLDER (folder));
7013 proto = modest_tny_account_get_protocol_type (account);
7014 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7017 subject = tny_header_dup_subject (header);
7018 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7022 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7028 g_object_unref (account);
7030 g_object_unref (folder);
7032 g_object_unref (header);
7038 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7039 const gchar *account_name,
7040 const gchar *account_title)
7042 ModestAccountMgr *account_mgr;
7045 ModestProtocol *protocol;
7046 gboolean removed = FALSE;
7048 g_return_val_if_fail (account_name, FALSE);
7049 g_return_val_if_fail (account_title, FALSE);
7051 account_mgr = modest_runtime_get_account_mgr();
7053 /* The warning text depends on the account type: */
7054 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7055 modest_account_mgr_get_store_protocol (account_mgr,
7057 txt = modest_protocol_get_translation (protocol,
7058 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7061 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7063 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7067 if (response == GTK_RESPONSE_OK) {
7068 /* Remove account. If it succeeds then it also removes
7069 the account from the ModestAccountView: */
7070 gboolean is_default = FALSE;
7071 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7072 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7074 g_free (default_account_name);
7076 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7078 #ifdef MODEST_TOOLKIT_HILDON2
7079 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7081 /* Close all email notifications, we cannot
7082 distinguish if the notification belongs to
7083 this account or not, so for safety reasons
7084 we remove them all */
7085 modest_platform_remove_new_mail_notifications (FALSE);
7087 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7094 on_fetch_images_performer (gboolean canceled,
7096 GtkWindow *parent_window,
7097 TnyAccount *account,
7100 if (err || canceled) {
7101 /* Show an unable to retrieve images ??? */
7105 /* Note that the user could have closed the window while connecting */
7106 if (GTK_WIDGET_VISIBLE (parent_window))
7107 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7108 g_object_unref ((GObject *) user_data);
7112 modest_ui_actions_on_fetch_images (GtkAction *action,
7113 ModestWindow *window)
7115 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7117 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7119 on_fetch_images_performer,
7120 g_object_ref (window));
7124 modest_ui_actions_on_reload_message (const gchar *msg_id)
7126 ModestWindow *window = NULL;
7128 g_return_if_fail (msg_id && msg_id[0] != '\0');
7129 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7135 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7138 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7141 /** Check whether any connections are active, and cancel them if
7143 * Returns TRUE is there was no problem,
7144 * or if an operation was cancelled so we can continue.
7145 * Returns FALSE if the user chose to cancel his request instead.
7149 modest_ui_actions_check_for_active_account (ModestWindow *self,
7150 const gchar* account_name)
7152 ModestTnySendQueue *send_queue;
7153 ModestTnyAccountStore *acc_store;
7154 ModestMailOperationQueue* queue;
7155 TnyConnectionStatus store_conn_status;
7156 TnyAccount *store_account = NULL, *transport_account = NULL;
7157 gboolean retval = TRUE, sending = FALSE;
7159 acc_store = modest_runtime_get_account_store ();
7160 queue = modest_runtime_get_mail_operation_queue ();
7163 modest_tny_account_store_get_server_account (acc_store,
7165 TNY_ACCOUNT_TYPE_STORE);
7167 /* This could happen if the account was deleted before the
7168 call to this function */
7173 modest_tny_account_store_get_server_account (acc_store,
7175 TNY_ACCOUNT_TYPE_TRANSPORT);
7177 /* This could happen if the account was deleted before the
7178 call to this function */
7179 if (!transport_account) {
7180 g_object_unref (store_account);
7184 /* If the transport account was not used yet, then the send
7185 queue could not exist (it's created on demand) */
7186 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7187 if (TNY_IS_SEND_QUEUE (send_queue))
7188 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7190 store_conn_status = tny_account_get_connection_status (store_account);
7191 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7194 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7195 _("emev_nc_disconnect_account"));
7196 if (response == GTK_RESPONSE_OK) {
7205 /* FIXME: We should only cancel those of this account */
7206 modest_mail_operation_queue_cancel_all (queue);
7208 /* Also disconnect the account */
7209 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7210 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7211 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7215 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7221 g_object_unref (store_account);
7222 g_object_unref (transport_account);