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);
1491 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1492 g_free (account_name);
1493 open_msg_helper_destroyer (helper);
1498 ModestWindow *window;
1499 GtkWidget *header_view;
1502 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1503 uid = modest_tny_folder_get_header_unique_id (helper->header);
1505 const gchar *mailbox = NULL;
1506 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1507 window = modest_msg_view_window_new_from_header_view
1508 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1509 if (window != NULL) {
1510 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1512 gtk_widget_destroy (GTK_WIDGET (window));
1514 gtk_widget_show_all (GTK_WIDGET(window));
1518 g_free (account_name);
1520 open_msg_helper_destroyer (helper);
1523 g_free (account_name);
1525 /* Create the mail operation */
1527 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1528 modest_ui_actions_disk_operations_error_handler,
1529 g_strdup (error_msg), g_free);
1530 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1534 #ifndef MODEST_TOOLKIT_HILDON2
1535 if (show_open_draft) {
1536 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1537 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1538 helper->banner_info->banner = NULL;
1539 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1540 helper->banner_info);
1546 headers = TNY_LIST (tny_simple_list_new ());
1547 tny_list_prepend (headers, G_OBJECT (helper->header));
1548 modest_mail_operation_get_msgs_full (mail_op,
1552 open_msg_helper_destroyer);
1553 g_object_unref (headers);
1560 g_object_unref (mail_op);
1561 g_object_unref (account);
1565 * This function is used by both modest_ui_actions_on_open and
1566 * modest_ui_actions_on_header_activated. This way we always do the
1567 * same when trying to open messages.
1570 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1572 ModestWindowMgr *mgr = NULL;
1573 TnyAccount *account;
1574 gboolean cached = FALSE;
1576 GtkWidget *header_view = NULL;
1577 OpenMsgHelper *helper;
1578 ModestWindow *window;
1580 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1582 mgr = modest_runtime_get_window_mgr ();
1585 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1586 if (header_view == NULL)
1589 /* Get the account */
1590 account = get_account_from_header (header);
1595 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1597 /* Do not open again the message and present the
1598 window to the user */
1601 #ifndef MODEST_TOOLKIT_HILDON2
1602 gtk_window_present (GTK_WINDOW (window));
1605 /* the header has been registered already, we don't do
1606 * anything but wait for the window to come up*/
1607 g_debug ("header %p already registered, waiting for window", header);
1612 /* Open each message */
1613 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1615 /* Allways download if we are online. */
1616 if (!tny_device_is_online (modest_runtime_get_device ())) {
1619 /* If ask for user permission to download the messages */
1620 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1621 _("mcen_nc_get_msg"));
1623 /* End if the user does not want to continue */
1624 if (response == GTK_RESPONSE_CANCEL) {
1630 /* We register the window for opening */
1631 modest_window_mgr_register_header (mgr, header, NULL);
1633 /* Create the helper. We need to get a reference to the model
1634 here because it could change while the message is readed
1635 (the user could switch between folders) */
1636 helper = g_slice_new (OpenMsgHelper);
1637 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1638 helper->caller_window = win;
1639 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1640 helper->header = g_object_ref (header);
1641 helper->rowref = gtk_tree_row_reference_copy (rowref);
1642 helper->banner_info = NULL;
1644 /* Connect to the account and perform */
1646 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1647 open_msg_performer, helper);
1649 /* Call directly the performer, do not need to connect */
1650 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1651 g_object_ref (account), helper);
1656 g_object_unref (account);
1660 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1667 /* we check for low-mem; in that case, show a warning, and don't allow
1670 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1674 headers = get_selected_headers (win);
1678 headers_count = tny_list_get_length (headers);
1679 if (headers_count != 1) {
1680 if (headers_count > 1) {
1681 /* Don't allow activation if there are more than one message selected */
1682 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1685 g_object_unref (headers);
1689 iter = tny_list_create_iterator (headers);
1690 header = TNY_HEADER (tny_iterator_get_current (iter));
1691 g_object_unref (iter);
1695 open_msg_from_header (header, NULL, win);
1696 g_object_unref (header);
1699 g_object_unref(headers);
1703 rf_helper_window_closed (gpointer data,
1706 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1708 helper->parent_window = NULL;
1711 static ReplyForwardHelper*
1712 create_reply_forward_helper (ReplyForwardAction action,
1714 guint reply_forward_type,
1718 ReplyForwardHelper *rf_helper = NULL;
1719 const gchar *active_acc = modest_window_get_active_account (win);
1720 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1722 rf_helper = g_slice_new0 (ReplyForwardHelper);
1723 rf_helper->reply_forward_type = reply_forward_type;
1724 rf_helper->action = action;
1725 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1726 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1727 rf_helper->account_name = (active_acc) ?
1728 g_strdup (active_acc) :
1729 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1730 rf_helper->mailbox = g_strdup (active_mailbox);
1732 rf_helper->parts = g_object_ref (parts);
1734 rf_helper->parts = NULL;
1736 /* Note that window could be destroyed just AFTER calling
1737 register_window so we must ensure that this pointer does
1738 not hold invalid references */
1739 if (rf_helper->parent_window)
1740 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1741 rf_helper_window_closed, rf_helper);
1747 free_reply_forward_helper (gpointer data)
1749 ReplyForwardHelper *helper;
1751 helper = (ReplyForwardHelper *) data;
1752 g_free (helper->account_name);
1753 g_free (helper->mailbox);
1755 g_object_unref (helper->header);
1757 g_object_unref (helper->parts);
1758 if (helper->parent_window)
1759 g_object_weak_unref (G_OBJECT (helper->parent_window),
1760 rf_helper_window_closed, helper);
1761 g_slice_free (ReplyForwardHelper, helper);
1765 reply_forward_cb (ModestMailOperation *mail_op,
1772 TnyMsg *new_msg = NULL;
1773 ReplyForwardHelper *rf_helper;
1774 ModestWindow *msg_win = NULL;
1775 ModestEditType edit_type;
1777 TnyAccount *account = NULL;
1778 ModestWindowMgr *mgr = NULL;
1779 gchar *signature = NULL;
1780 gboolean use_signature;
1783 /* If there was any error. The mail operation could be NULL,
1784 this means that we already have the message downloaded and
1785 that we didn't do a mail operation to retrieve it */
1786 rf_helper = (ReplyForwardHelper *) user_data;
1787 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1790 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1791 rf_helper->account_name, rf_helper->mailbox);
1792 recipient = modest_text_utils_get_email_address (from);
1793 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1798 /* Create reply mail */
1799 switch (rf_helper->action) {
1800 /* Use the msg_header to ensure that we have all the
1801 information. The summary can lack some data */
1802 TnyHeader *msg_header;
1804 msg_header = tny_msg_get_header (msg);
1806 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1807 (use_signature) ? signature : NULL,
1808 rf_helper->reply_forward_type,
1809 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1810 g_object_unref (msg_header);
1812 case ACTION_REPLY_TO_ALL:
1813 msg_header = tny_msg_get_header (msg);
1815 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1816 (use_signature) ? signature : NULL,
1817 rf_helper->reply_forward_type,
1818 MODEST_TNY_MSG_REPLY_MODE_ALL);
1819 edit_type = MODEST_EDIT_TYPE_REPLY;
1820 g_object_unref (msg_header);
1822 case ACTION_FORWARD:
1824 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1825 rf_helper->reply_forward_type);
1826 edit_type = MODEST_EDIT_TYPE_FORWARD;
1829 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1831 g_return_if_reached ();
1839 g_warning ("%s: failed to create message\n", __FUNCTION__);
1843 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1844 rf_helper->account_name,
1845 TNY_ACCOUNT_TYPE_STORE);
1847 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1851 /* Create and register the windows */
1852 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1853 mgr = modest_runtime_get_window_mgr ();
1854 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1856 /* Note that register_window could have deleted the account */
1857 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1858 gdouble parent_zoom;
1860 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1861 modest_window_set_zoom (msg_win, parent_zoom);
1864 /* Show edit window */
1865 gtk_widget_show_all (GTK_WIDGET (msg_win));
1868 /* We always unregister the header because the message is
1869 forwarded or replied so the original one is no longer
1871 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1874 g_object_unref (G_OBJECT (new_msg));
1876 g_object_unref (G_OBJECT (account));
1877 free_reply_forward_helper (rf_helper);
1880 /* Checks a list of headers. If any of them are not currently
1881 * downloaded (CACHED) then returns TRUE else returns FALSE.
1884 header_list_count_uncached_msgs (TnyList *header_list)
1887 gint uncached_messages = 0;
1889 iter = tny_list_create_iterator (header_list);
1890 while (!tny_iterator_is_done (iter)) {
1893 header = TNY_HEADER (tny_iterator_get_current (iter));
1895 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1896 uncached_messages ++;
1897 g_object_unref (header);
1900 tny_iterator_next (iter);
1902 g_object_unref (iter);
1904 return uncached_messages;
1907 /* Returns FALSE if the user does not want to download the
1908 * messages. Returns TRUE if the user allowed the download.
1911 connect_to_get_msg (ModestWindow *win,
1912 gint num_of_uncached_msgs,
1913 TnyAccount *account)
1915 GtkResponseType response;
1917 /* Allways download if we are online. */
1918 if (tny_device_is_online (modest_runtime_get_device ()))
1921 /* If offline, then ask for user permission to download the messages */
1922 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1923 ngettext("mcen_nc_get_msg",
1925 num_of_uncached_msgs));
1927 if (response == GTK_RESPONSE_CANCEL)
1930 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1934 reply_forward_performer (gboolean canceled,
1936 GtkWindow *parent_window,
1937 TnyAccount *account,
1940 ReplyForwardHelper *rf_helper = NULL;
1941 ModestMailOperation *mail_op;
1943 rf_helper = (ReplyForwardHelper *) user_data;
1945 if (canceled || err) {
1946 free_reply_forward_helper (rf_helper);
1950 /* Retrieve the message */
1951 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1952 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1953 modest_ui_actions_disk_operations_error_handler,
1955 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1956 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1959 g_object_unref(mail_op);
1963 all_parts_retrieved (TnyMimePart *part)
1965 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1968 TnyList *pending_parts;
1969 TnyIterator *iterator;
1970 gboolean all_retrieved = TRUE;
1972 pending_parts = TNY_LIST (tny_simple_list_new ());
1973 tny_mime_part_get_parts (part, pending_parts);
1974 iterator = tny_list_create_iterator (pending_parts);
1975 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1978 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1980 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1981 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1983 all_retrieved = FALSE;
1986 g_object_unref (child);
1987 tny_iterator_next (iterator);
1989 g_object_unref (iterator);
1990 g_object_unref (pending_parts);
1991 return all_retrieved;
1996 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1999 TnyIterator *iterator;
2001 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2002 tny_list_append (list, G_OBJECT (part));
2004 parts = TNY_LIST (tny_simple_list_new ());
2005 tny_mime_part_get_parts (part, parts);
2006 for (iterator = tny_list_create_iterator (parts);
2007 !tny_iterator_is_done (iterator);
2008 tny_iterator_next (iterator)) {
2011 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2012 forward_pending_parts_helper (child, list);
2013 g_object_unref (child);
2015 g_object_unref (iterator);
2016 g_object_unref (parts);
2020 forward_pending_parts (TnyMsg *msg)
2022 TnyList *result = TNY_LIST (tny_simple_list_new ());
2023 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2024 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2031 * Common code for the reply and forward actions
2034 reply_forward (ReplyForwardAction action, ModestWindow *win)
2036 ReplyForwardHelper *rf_helper = NULL;
2037 guint reply_forward_type;
2039 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2041 /* we check for low-mem; in that case, show a warning, and don't allow
2042 * reply/forward (because it could potentially require a lot of memory */
2043 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2047 /* we need an account when editing */
2048 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2049 if (!modest_ui_actions_run_account_setup_wizard (win))
2053 reply_forward_type =
2054 modest_conf_get_int (modest_runtime_get_conf (),
2055 (action == ACTION_FORWARD) ?
2056 MODEST_CONF_FORWARD_TYPE :
2057 MODEST_CONF_REPLY_TYPE,
2060 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2062 TnyHeader *header = NULL;
2063 /* Get header and message. Do not free them here, the
2064 reply_forward_cb must do it */
2065 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2066 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2068 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2070 rf_helper = create_reply_forward_helper (action, win,
2071 reply_forward_type, header, NULL);
2072 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2074 gboolean do_download = TRUE;
2076 if (msg && header && action == ACTION_FORWARD) {
2077 /* Not all parts retrieved. Then we have to retrieve them all before
2078 * creating the forward message */
2079 if (!tny_device_is_online (modest_runtime_get_device ())) {
2082 /* If ask for user permission to download the messages */
2083 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2084 ngettext("mcen_nc_get_msg",
2088 /* End if the user does not want to continue */
2089 if (response == GTK_RESPONSE_CANCEL)
2090 do_download = FALSE;
2094 TnyList *pending_parts;
2096 TnyAccount *account;
2099 pending_parts = forward_pending_parts (msg);
2100 rf_helper = create_reply_forward_helper (action, win,
2101 reply_forward_type, header, pending_parts);
2102 g_object_unref (pending_parts);
2104 folder = tny_header_get_folder (header);
2105 account = tny_folder_get_account (folder);
2106 modest_platform_connect_and_perform (GTK_WINDOW (win),
2108 reply_forward_performer,
2110 g_object_unref (folder);
2111 g_object_unref (account);
2115 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2120 g_object_unref (msg);
2122 g_object_unref (header);
2124 TnyHeader *header = NULL;
2126 gboolean do_retrieve = TRUE;
2127 TnyList *header_list = NULL;
2129 header_list = get_selected_headers (win);
2132 /* Check that only one message is selected for replying */
2133 if (tny_list_get_length (header_list) != 1) {
2134 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2135 NULL, _("mcen_ib_select_one_message"));
2136 g_object_unref (header_list);
2140 /* Only reply/forward to one message */
2141 iter = tny_list_create_iterator (header_list);
2142 header = TNY_HEADER (tny_iterator_get_current (iter));
2143 g_object_unref (iter);
2145 /* Retrieve messages */
2146 do_retrieve = (action == ACTION_FORWARD) ||
2147 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2150 TnyAccount *account = NULL;
2151 TnyFolder *folder = NULL;
2152 gdouble download = TRUE;
2153 guint uncached_msgs = 0;
2155 folder = tny_header_get_folder (header);
2157 goto do_retrieve_frees;
2158 account = tny_folder_get_account (folder);
2160 goto do_retrieve_frees;
2162 uncached_msgs = header_list_count_uncached_msgs (header_list);
2164 if (uncached_msgs > 0) {
2165 /* Allways download if we are online. */
2166 if (!tny_device_is_online (modest_runtime_get_device ())) {
2169 /* If ask for user permission to download the messages */
2170 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2171 ngettext("mcen_nc_get_msg",
2175 /* End if the user does not want to continue */
2176 if (response == GTK_RESPONSE_CANCEL)
2183 rf_helper = create_reply_forward_helper (action, win,
2184 reply_forward_type, header, NULL);
2185 if (uncached_msgs > 0) {
2186 modest_platform_connect_and_perform (GTK_WINDOW (win),
2188 reply_forward_performer,
2191 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2192 account, rf_helper);
2197 g_object_unref (account);
2199 g_object_unref (folder);
2201 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2204 g_object_unref (header_list);
2205 g_object_unref (header);
2210 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2212 g_return_if_fail (MODEST_IS_WINDOW(win));
2214 reply_forward (ACTION_REPLY, win);
2218 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2220 g_return_if_fail (MODEST_IS_WINDOW(win));
2222 reply_forward (ACTION_FORWARD, win);
2226 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2228 g_return_if_fail (MODEST_IS_WINDOW(win));
2230 reply_forward (ACTION_REPLY_TO_ALL, win);
2234 modest_ui_actions_on_next (GtkAction *action,
2235 ModestWindow *window)
2237 if (MODEST_IS_MAIN_WINDOW (window)) {
2238 GtkWidget *header_view;
2240 header_view = modest_main_window_get_child_widget (
2241 MODEST_MAIN_WINDOW(window),
2242 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2246 modest_header_view_select_next (
2247 MODEST_HEADER_VIEW(header_view));
2248 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2249 modest_msg_view_window_select_next_message (
2250 MODEST_MSG_VIEW_WINDOW (window));
2252 g_return_if_reached ();
2257 modest_ui_actions_on_prev (GtkAction *action,
2258 ModestWindow *window)
2260 g_return_if_fail (MODEST_IS_WINDOW(window));
2262 if (MODEST_IS_MAIN_WINDOW (window)) {
2263 GtkWidget *header_view;
2264 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2265 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2269 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2270 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2271 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2273 g_return_if_reached ();
2278 modest_ui_actions_on_sort (GtkAction *action,
2279 ModestWindow *window)
2281 GtkWidget *header_view = NULL;
2283 g_return_if_fail (MODEST_IS_WINDOW(window));
2285 if (MODEST_IS_MAIN_WINDOW (window)) {
2286 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2287 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2288 #ifdef MODEST_TOOLKIT_HILDON2
2289 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2290 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2295 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2300 /* Show sorting dialog */
2301 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2305 sync_folder_cb (ModestMailOperation *mail_op,
2309 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2311 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2312 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2314 /* We must clear first, because otherwise set_folder will ignore */
2315 /* the change as the folders are the same */
2316 modest_header_view_clear (header_view);
2317 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2319 g_object_unref (parent);
2322 g_object_unref (header_view);
2326 idle_refresh_folder (gpointer source)
2328 ModestHeaderView *header_view = NULL;
2330 /* If the window still exists */
2331 if (!GTK_IS_WIDGET (source) ||
2332 !GTK_WIDGET_VISIBLE (source))
2335 /* Refresh the current view */
2336 #ifdef MODEST_TOOLKIT_HILDON2
2337 if (MODEST_IS_HEADER_WINDOW (source))
2338 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2340 if (MODEST_IS_MAIN_WINDOW (source))
2341 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2342 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2345 TnyFolder *folder = modest_header_view_get_folder (header_view);
2347 /* Sync the folder status */
2348 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2349 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2350 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2351 g_object_unref (folder);
2352 g_object_unref (mail_op);
2360 update_account_cb (ModestMailOperation *self,
2361 TnyList *new_headers,
2365 gboolean show_visual_notifications;
2367 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2368 show_visual_notifications = (top) ? FALSE : TRUE;
2370 /* Notify new messages have been downloaded. If the
2371 send&receive was invoked by the user then do not show any
2372 visual notification, only play a sound and activate the LED
2373 (for the Maemo version) */
2374 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2376 /* We only notify about really new messages (not seen) we get */
2377 TnyList *actually_new_list;
2378 TnyIterator *iterator;
2379 actually_new_list = TNY_LIST (tny_simple_list_new ());
2380 for (iterator = tny_list_create_iterator (new_headers);
2381 !tny_iterator_is_done (iterator);
2382 tny_iterator_next (iterator)) {
2384 TnyHeaderFlags flags;
2385 header = TNY_HEADER (tny_iterator_get_current (iterator));
2386 flags = tny_header_get_flags (header);
2388 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2389 /* Messages are ordered from most
2390 recent to oldest. But we want to
2391 show notifications starting from
2392 the oldest message. That's why we
2394 tny_list_prepend (actually_new_list, G_OBJECT (header));
2396 g_object_unref (header);
2398 g_object_unref (iterator);
2400 if (tny_list_get_length (actually_new_list) > 0) {
2401 GList *new_headers_list = NULL;
2403 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2405 /* Send notifications */
2406 if (new_headers_list) {
2407 modest_platform_on_new_headers_received (new_headers_list,
2408 show_visual_notifications);
2410 modest_utils_free_notification_list (new_headers_list);
2413 g_object_unref (actually_new_list);
2417 /* Refresh the current folder in an idle. We do this
2418 in order to avoid refresh cancelations if the
2419 currently viewed folder is the inbox */
2420 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2421 idle_refresh_folder,
2428 TnyAccount *account;
2430 gchar *account_name;
2431 gboolean poke_status;
2432 gboolean interactive;
2433 ModestMailOperation *mail_op;
2437 do_send_receive_performer (gboolean canceled,
2439 GtkWindow *parent_window,
2440 TnyAccount *account,
2443 SendReceiveInfo *info;
2445 info = (SendReceiveInfo *) user_data;
2447 if (err || canceled) {
2448 /* In disk full conditions we could get this error here */
2449 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2450 (GtkWidget *) parent_window, err,
2453 if (info->mail_op) {
2454 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2460 /* Set send/receive operation in progress */
2461 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2462 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2465 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2466 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2467 G_CALLBACK (on_send_receive_finished),
2470 /* Send & receive. */
2471 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2472 update_account_cb, info->win);
2477 g_object_unref (G_OBJECT (info->mail_op));
2478 if (info->account_name)
2479 g_free (info->account_name);
2481 g_object_unref (info->win);
2483 g_object_unref (info->account);
2484 g_slice_free (SendReceiveInfo, info);
2488 * This function performs the send & receive required actions. The
2489 * window is used to create the mail operation. Typically it should
2490 * always be the main window, but we pass it as argument in order to
2494 modest_ui_actions_do_send_receive (const gchar *account_name,
2495 gboolean force_connection,
2496 gboolean poke_status,
2497 gboolean interactive,
2500 gchar *acc_name = NULL;
2501 SendReceiveInfo *info;
2502 ModestTnyAccountStore *acc_store;
2503 TnyAccount *account;
2505 /* If no account name was provided then get the current account, and if
2506 there is no current account then pick the default one: */
2507 if (!account_name) {
2509 acc_name = g_strdup (modest_window_get_active_account (win));
2511 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2513 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2517 acc_name = g_strdup (account_name);
2520 acc_store = modest_runtime_get_account_store ();
2521 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2525 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2529 /* Do not automatically refresh accounts that are flagged as
2530 NO_AUTO_UPDATE. This could be useful for accounts that
2531 handle their own update times */
2533 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2534 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2535 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2536 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2538 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2539 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2540 g_object_unref (account);
2547 /* Create the info for the connect and perform */
2548 info = g_slice_new (SendReceiveInfo);
2549 info->account_name = acc_name;
2550 info->win = (win) ? g_object_ref (win) : NULL;
2551 info->poke_status = poke_status;
2552 info->interactive = interactive;
2553 info->account = account;
2554 /* We need to create the operation here, because otherwise it
2555 could happen that the queue emits the queue-empty signal
2556 while we're trying to connect the account */
2557 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2558 modest_ui_actions_disk_operations_error_handler,
2560 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2562 /* Invoke the connect and perform */
2563 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2564 force_connection, info->account,
2565 do_send_receive_performer, info);
2570 modest_ui_actions_do_cancel_send (const gchar *account_name,
2573 TnyTransportAccount *transport_account;
2574 TnySendQueue *send_queue = NULL;
2575 GError *error = NULL;
2577 /* Get transport account */
2579 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2580 (modest_runtime_get_account_store(),
2582 TNY_ACCOUNT_TYPE_TRANSPORT));
2583 if (!transport_account) {
2584 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2589 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2590 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2591 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2592 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2593 "modest: could not find send queue for account\n");
2595 /* Cancel the current send */
2596 tny_account_cancel (TNY_ACCOUNT (transport_account));
2598 /* Suspend all pending messages */
2599 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2603 if (transport_account != NULL)
2604 g_object_unref (G_OBJECT (transport_account));
2608 modest_ui_actions_cancel_send_all (ModestWindow *win)
2610 GSList *account_names, *iter;
2612 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2615 iter = account_names;
2617 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2618 iter = g_slist_next (iter);
2621 modest_account_mgr_free_account_names (account_names);
2622 account_names = NULL;
2626 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2629 /* Check if accounts exist */
2630 gboolean accounts_exist =
2631 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2633 /* If not, allow the user to create an account before trying to send/receive. */
2634 if (!accounts_exist)
2635 modest_ui_actions_on_accounts (NULL, win);
2637 /* Cancel all sending operaitons */
2638 modest_ui_actions_cancel_send_all (win);
2642 * Refreshes all accounts. This function will be used by automatic
2646 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2647 gboolean force_connection,
2648 gboolean poke_status,
2649 gboolean interactive)
2651 GSList *account_names, *iter;
2653 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2656 iter = account_names;
2658 modest_ui_actions_do_send_receive ((const char*) iter->data,
2660 poke_status, interactive, win);
2661 iter = g_slist_next (iter);
2664 modest_account_mgr_free_account_names (account_names);
2665 account_names = NULL;
2669 * Handler of the click on Send&Receive button in the main toolbar
2672 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2674 /* Check if accounts exist */
2675 gboolean accounts_exist;
2678 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2680 /* If not, allow the user to create an account before trying to send/receive. */
2681 if (!accounts_exist)
2682 modest_ui_actions_on_accounts (NULL, win);
2684 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2685 if (MODEST_IS_MAIN_WINDOW (win)) {
2686 GtkWidget *folder_view;
2687 TnyFolderStore *folder_store;
2690 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2691 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2695 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2698 g_object_unref (folder_store);
2699 /* Refresh the active account. Force the connection if needed
2700 and poke the status of all folders */
2701 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2702 #ifdef MODEST_TOOLKIT_HILDON2
2703 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2704 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2707 const gchar *active_account;
2708 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2710 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2717 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2720 GtkWidget *header_view;
2722 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2724 header_view = modest_main_window_get_child_widget (main_window,
2725 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2729 conf = modest_runtime_get_conf ();
2731 /* what is saved/restored is depending on the style; thus; we save with
2732 * old style, then update the style, and restore for this new style
2734 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2736 if (modest_header_view_get_style
2737 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2738 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2739 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2741 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2742 MODEST_HEADER_VIEW_STYLE_DETAILS);
2744 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2745 MODEST_CONF_HEADER_VIEW_KEY);
2750 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2752 ModestMainWindow *main_window)
2754 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2755 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2757 /* in the case the folder is empty, show the empty folder message and focus
2759 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2760 if (modest_header_view_is_empty (header_view)) {
2761 TnyFolder *folder = modest_header_view_get_folder (header_view);
2762 GtkWidget *folder_view =
2763 modest_main_window_get_child_widget (main_window,
2764 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2765 if (folder != NULL) {
2766 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2767 g_object_unref (folder);
2769 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2773 /* If no header has been selected then exit */
2778 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2779 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2781 /* Update toolbar dimming state */
2782 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2783 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2787 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2790 ModestWindow *window)
2792 GtkWidget *open_widget;
2793 GtkTreeRowReference *rowref;
2795 g_return_if_fail (MODEST_IS_WINDOW(window));
2796 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2797 g_return_if_fail (TNY_IS_HEADER (header));
2799 if (modest_header_view_count_selected_headers (header_view) > 1) {
2800 /* Don't allow activation if there are more than one message selected */
2801 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2805 /* we check for low-mem; in that case, show a warning, and don't allow
2806 * activating headers
2808 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2811 if (MODEST_IS_MAIN_WINDOW (window)) {
2812 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2813 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2814 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2818 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2819 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2820 gtk_tree_row_reference_free (rowref);
2824 set_active_account_from_tny_account (TnyAccount *account,
2825 ModestWindow *window)
2827 const gchar *server_acc_name = tny_account_get_id (account);
2829 /* We need the TnyAccount provided by the
2830 account store because that is the one that
2831 knows the name of the Modest account */
2832 TnyAccount *modest_server_account =
2833 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2834 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2836 if (!modest_server_account) {
2837 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2841 /* Update active account, but only if it's not a pseudo-account */
2842 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2843 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2844 const gchar *modest_acc_name =
2845 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2846 if (modest_acc_name)
2847 modest_window_set_active_account (window, modest_acc_name);
2850 g_object_unref (modest_server_account);
2855 folder_refreshed_cb (ModestMailOperation *mail_op,
2859 ModestMainWindow *win = NULL;
2860 GtkWidget *folder_view, *header_view;
2861 const GError *error;
2863 g_return_if_fail (TNY_IS_FOLDER (folder));
2865 win = MODEST_MAIN_WINDOW (user_data);
2867 /* Check if the operation failed due to memory low conditions */
2868 error = modest_mail_operation_get_error (mail_op);
2869 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2870 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2871 modest_platform_run_information_dialog (GTK_WINDOW (win),
2872 _KR("memr_ib_operation_disabled"),
2878 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2880 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2883 TnyFolderStore *current_folder;
2885 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2886 if (current_folder) {
2887 gboolean different = ((TnyFolderStore *) folder != current_folder);
2888 g_object_unref (current_folder);
2894 /* Check if folder is empty and set headers view contents style */
2895 if ((tny_folder_get_all_count (folder) == 0) ||
2896 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2897 modest_main_window_set_contents_style (win,
2898 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2902 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2903 TnyFolderStore *folder_store,
2905 ModestMainWindow *main_window)
2907 GtkWidget *header_view;
2909 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2911 header_view = modest_main_window_get_child_widget(main_window,
2912 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2917 if (TNY_IS_ACCOUNT (folder_store)) {
2919 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2921 /* Show account details */
2922 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2925 if (TNY_IS_FOLDER (folder_store) && selected) {
2926 TnyAccount *account;
2928 /* Update the active account */
2929 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2931 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2932 g_object_unref (account);
2936 /* Set the header style by default, it could
2937 be changed later by the refresh callback to
2939 modest_main_window_set_contents_style (main_window,
2940 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2942 /* Set folder on header view. This function
2943 will call tny_folder_refresh_async so we
2944 pass a callback that will be called when
2945 finished. We use that callback to set the
2946 empty view if there are no messages */
2947 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2948 TNY_FOLDER (folder_store),
2950 MODEST_WINDOW (main_window),
2951 folder_refreshed_cb,
2954 /* Restore configuration. We need to do this
2955 *after* the set_folder because the widget
2956 memory asks the header view about its
2958 modest_widget_memory_restore (modest_runtime_get_conf (),
2959 G_OBJECT(header_view),
2960 MODEST_CONF_HEADER_VIEW_KEY);
2962 /* No need to save the header view
2963 configuration for Maemo because it only
2964 saves the sorting stuff and that it's
2965 already being done by the sort
2966 dialog. Remove it when the GNOME version
2967 has the same behaviour */
2968 #ifdef MODEST_TOOLKIT_GTK
2969 if (modest_main_window_get_contents_style (main_window) ==
2970 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2971 modest_widget_memory_save (modest_runtime_get_conf (),
2972 G_OBJECT (header_view),
2973 MODEST_CONF_HEADER_VIEW_KEY);
2975 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2979 /* Update dimming state */
2980 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2981 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2985 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2992 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2994 online = tny_device_is_online (modest_runtime_get_device());
2997 /* already online -- the item is simply not there... */
2998 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
3000 GTK_MESSAGE_WARNING,
3002 _("The %s you selected cannot be found"),
3004 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3005 gtk_dialog_run (GTK_DIALOG(dialog));
3007 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3010 _("mcen_bd_dialog_cancel"),
3011 GTK_RESPONSE_REJECT,
3012 _("mcen_bd_dialog_ok"),
3013 GTK_RESPONSE_ACCEPT,
3015 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3016 "Do you want to get online?"), item);
3017 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3018 gtk_label_new (txt), FALSE, FALSE, 0);
3019 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3022 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3023 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3024 /* TODO: Comment about why is this commented out: */
3025 /* modest_platform_connect_and_wait (); */
3028 gtk_widget_destroy (dialog);
3032 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3035 /* g_debug ("%s %s", __FUNCTION__, link); */
3040 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3043 modest_platform_activate_uri (link);
3047 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3050 modest_platform_show_uri_popup (link);
3054 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3057 /* we check for low-mem; in that case, show a warning, and don't allow
3058 * viewing attachments
3060 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3063 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3067 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3068 const gchar *address,
3071 /* g_debug ("%s %s", __FUNCTION__, address); */
3075 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3076 TnyMsg *saved_draft,
3079 ModestMsgEditWindow *edit_window;
3081 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3082 #ifndef MODEST_TOOLKIT_HILDON2
3083 ModestMainWindow *win;
3085 /* FIXME. Make the header view sensitive again. This is a
3086 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3088 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3089 modest_runtime_get_window_mgr(), FALSE));
3091 GtkWidget *hdrview = modest_main_window_get_child_widget(
3092 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3093 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3097 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3099 /* Set draft is there was no error */
3100 if (!modest_mail_operation_get_error (mail_op))
3101 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3103 g_object_unref(edit_window);
3107 enough_space_for_message (ModestMsgEditWindow *edit_window,
3110 guint64 available_disk, expected_size;
3115 available_disk = modest_utils_get_available_space (NULL);
3116 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3117 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3122 /* Double check: disk full condition or message too big */
3123 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3124 expected_size > available_disk) {
3125 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3126 modest_platform_information_banner (NULL, NULL, msg);
3133 * djcb: if we're in low-memory state, we only allow for
3134 * saving messages smaller than
3135 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3136 * should still allow for sending anything critical...
3138 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3139 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3143 * djcb: we also make sure that the attachments are smaller than the max size
3144 * this is for the case where we'd try to forward a message with attachments
3145 * bigger than our max allowed size, or sending an message from drafts which
3146 * somehow got past our checks when attaching.
3148 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3149 modest_platform_run_information_dialog (
3150 GTK_WINDOW(edit_window),
3151 _("mail_ib_error_attachment_size"),
3160 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3162 TnyTransportAccount *transport_account;
3163 ModestMailOperation *mail_operation;
3165 gchar *account_name;
3166 ModestAccountMgr *account_mgr;
3167 gboolean had_error = FALSE;
3168 ModestMainWindow *win = NULL;
3170 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3172 data = modest_msg_edit_window_get_msg_data (edit_window);
3175 if (!enough_space_for_message (edit_window, data)) {
3176 modest_msg_edit_window_free_msg_data (edit_window, data);
3180 account_name = g_strdup (data->account_name);
3181 account_mgr = modest_runtime_get_account_mgr();
3183 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3185 account_name = modest_account_mgr_get_default_account (account_mgr);
3186 if (!account_name) {
3187 g_printerr ("modest: no account found\n");
3188 modest_msg_edit_window_free_msg_data (edit_window, data);
3192 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3193 account_name = g_strdup (data->account_name);
3197 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3198 (modest_runtime_get_account_store (),
3200 TNY_ACCOUNT_TYPE_TRANSPORT));
3201 if (!transport_account) {
3202 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3203 g_free (account_name);
3204 modest_msg_edit_window_free_msg_data (edit_window, data);
3208 /* Create the mail operation */
3209 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3211 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3213 modest_mail_operation_save_to_drafts (mail_operation,
3225 data->priority_flags,
3228 on_save_to_drafts_cb,
3229 g_object_ref(edit_window));
3231 #ifdef MODEST_TOOLKIT_HILDON2
3232 /* In hildon2 we always show the information banner on saving to drafts.
3233 * It will be a system information banner in this case.
3235 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3236 modest_platform_information_banner (NULL, NULL, text);
3239 /* Use the main window as the parent of the banner, if the
3240 main window does not exist it won't be shown, if the parent
3241 window exists then it's properly shown. We don't use the
3242 editor window because it could be closed (save to drafts
3243 could happen after closing the window */
3244 win = (ModestMainWindow *)
3245 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3247 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3248 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3252 modest_msg_edit_window_set_modified (edit_window, FALSE);
3255 g_free (account_name);
3256 g_object_unref (G_OBJECT (transport_account));
3257 g_object_unref (G_OBJECT (mail_operation));
3259 modest_msg_edit_window_free_msg_data (edit_window, data);
3262 * If the drafts folder is selected then make the header view
3263 * insensitive while the message is being saved to drafts
3264 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3265 * is not very clean but it avoids letting the drafts folder
3266 * in an inconsistent state: the user could edit the message
3267 * being saved and undesirable things would happen.
3268 * In the average case the user won't notice anything at
3269 * all. In the worst case (the user is editing a really big
3270 * file from Drafts) the header view will be insensitive
3271 * during the saving process (10 or 20 seconds, depending on
3272 * the message). Anyway this is just a quick workaround: once
3273 * we find a better solution it should be removed
3274 * See NB#65125 (commend #18) for details.
3276 if (!had_error && win != NULL) {
3277 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3278 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3280 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3282 if (modest_tny_folder_is_local_folder(folder)) {
3283 TnyFolderType folder_type;
3284 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3285 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3286 GtkWidget *hdrview = modest_main_window_get_child_widget(
3287 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3288 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3292 if (folder != NULL) g_object_unref(folder);
3299 /* For instance, when clicking the Send toolbar button when editing a message: */
3301 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3303 TnyTransportAccount *transport_account = NULL;
3304 gboolean had_error = FALSE, add_to_contacts;
3306 ModestAccountMgr *account_mgr;
3307 gchar *account_name;
3308 ModestMailOperation *mail_operation;
3311 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3313 /* Check whether to automatically add new contacts to addressbook or not */
3314 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3315 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3316 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3319 data = modest_msg_edit_window_get_msg_data (edit_window);
3321 recipients = g_strconcat (data->to?data->to:"",
3322 data->cc?data->cc:"",
3323 data->bcc?data->bcc:"",
3325 if (recipients == NULL || recipients[0] == '\0') {
3326 /* Empty subject -> no send */
3327 g_free (recipients);
3328 modest_msg_edit_window_free_msg_data (edit_window, data);
3331 g_free (recipients);
3334 if (!enough_space_for_message (edit_window, data)) {
3335 modest_msg_edit_window_free_msg_data (edit_window, data);
3339 account_mgr = modest_runtime_get_account_mgr();
3340 account_name = g_strdup (data->account_name);
3342 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3345 account_name = modest_account_mgr_get_default_account (account_mgr);
3347 if (!account_name) {
3348 modest_msg_edit_window_free_msg_data (edit_window, data);
3349 /* Run account setup wizard */
3350 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3355 /* Get the currently-active transport account for this modest account: */
3356 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3358 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3359 (modest_runtime_get_account_store (),
3360 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3363 if (!transport_account) {
3364 modest_msg_edit_window_free_msg_data (edit_window, data);
3365 /* Run account setup wizard */
3366 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3371 /* Create the mail operation */
3372 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3373 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3375 modest_mail_operation_send_new_mail (mail_operation,
3389 data->priority_flags);
3391 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3392 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3394 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3395 const GError *error = modest_mail_operation_get_error (mail_operation);
3396 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3397 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3398 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3399 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3405 g_free (account_name);
3406 g_object_unref (G_OBJECT (transport_account));
3407 g_object_unref (G_OBJECT (mail_operation));
3409 modest_msg_edit_window_free_msg_data (edit_window, data);
3412 modest_msg_edit_window_set_sent (edit_window, TRUE);
3414 /* Save settings and close the window: */
3415 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3422 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3423 ModestMsgEditWindow *window)
3425 ModestMsgEditFormatState *format_state = NULL;
3427 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3428 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3430 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3433 format_state = modest_msg_edit_window_get_format_state (window);
3434 g_return_if_fail (format_state != NULL);
3436 format_state->bold = gtk_toggle_action_get_active (action);
3437 modest_msg_edit_window_set_format_state (window, format_state);
3438 g_free (format_state);
3443 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3444 ModestMsgEditWindow *window)
3446 ModestMsgEditFormatState *format_state = NULL;
3448 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3449 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3451 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3454 format_state = modest_msg_edit_window_get_format_state (window);
3455 g_return_if_fail (format_state != NULL);
3457 format_state->italics = gtk_toggle_action_get_active (action);
3458 modest_msg_edit_window_set_format_state (window, format_state);
3459 g_free (format_state);
3464 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3465 ModestMsgEditWindow *window)
3467 ModestMsgEditFormatState *format_state = NULL;
3469 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3470 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3472 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3475 format_state = modest_msg_edit_window_get_format_state (window);
3476 g_return_if_fail (format_state != NULL);
3478 format_state->bullet = gtk_toggle_action_get_active (action);
3479 modest_msg_edit_window_set_format_state (window, format_state);
3480 g_free (format_state);
3485 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3486 GtkRadioAction *selected,
3487 ModestMsgEditWindow *window)
3489 ModestMsgEditFormatState *format_state = NULL;
3490 GtkJustification value;
3492 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3494 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3497 value = gtk_radio_action_get_current_value (selected);
3499 format_state = modest_msg_edit_window_get_format_state (window);
3500 g_return_if_fail (format_state != NULL);
3502 format_state->justification = value;
3503 modest_msg_edit_window_set_format_state (window, format_state);
3504 g_free (format_state);
3508 modest_ui_actions_on_select_editor_color (GtkAction *action,
3509 ModestMsgEditWindow *window)
3511 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3512 g_return_if_fail (GTK_IS_ACTION (action));
3514 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3517 modest_msg_edit_window_select_color (window);
3521 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3522 ModestMsgEditWindow *window)
3524 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3525 g_return_if_fail (GTK_IS_ACTION (action));
3527 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3530 modest_msg_edit_window_select_background_color (window);
3534 modest_ui_actions_on_insert_image (GObject *object,
3535 ModestMsgEditWindow *window)
3537 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3540 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3543 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3546 modest_msg_edit_window_insert_image (window);
3550 modest_ui_actions_on_attach_file (GtkAction *action,
3551 ModestMsgEditWindow *window)
3553 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3554 g_return_if_fail (GTK_IS_ACTION (action));
3556 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3559 modest_msg_edit_window_offer_attach_file (window);
3563 modest_ui_actions_on_remove_attachments (GtkAction *action,
3564 ModestMsgEditWindow *window)
3566 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3568 modest_msg_edit_window_remove_attachments (window, NULL);
3572 do_create_folder_cb (ModestMailOperation *mail_op,
3573 TnyFolderStore *parent_folder,
3574 TnyFolder *new_folder,
3577 gchar *suggested_name = (gchar *) user_data;
3578 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3579 const GError *error;
3581 error = modest_mail_operation_get_error (mail_op);
3583 gboolean disk_full = FALSE;
3584 TnyAccount *account;
3585 /* Show an error. If there was some problem writing to
3586 disk, show it, otherwise show the generic folder
3587 create error. We do it here and not in an error
3588 handler because the call to do_create_folder will
3589 stop the main loop in a gtk_dialog_run and then,
3590 the message won't be shown until that dialog is
3592 account = modest_mail_operation_get_account (mail_op);
3595 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3596 (GtkWidget *) source_win,
3599 _("mail_in_ui_folder_create_error_memory"));
3600 g_object_unref (account);
3603 /* Show an error and try again if there is no
3604 full memory condition */
3605 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3606 _("mail_in_ui_folder_create_error"));
3607 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3611 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3612 * FIXME: any other? */
3613 GtkWidget *folder_view;
3615 if (MODEST_IS_MAIN_WINDOW(source_win))
3617 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3618 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3620 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3621 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3623 /* Select the newly created folder. It could happen
3624 that the widget is no longer there (i.e. the window
3625 has been destroyed, so we need to check this */
3627 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3629 g_object_unref (new_folder);
3631 /* Free. Note that the first time it'll be NULL so noop */
3632 g_free (suggested_name);
3633 g_object_unref (source_win);
3638 TnyFolderStore *parent;
3639 } CreateFolderConnect;
3642 do_create_folder_performer (gboolean canceled,
3644 GtkWindow *parent_window,
3645 TnyAccount *account,
3648 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3649 ModestMailOperation *mail_op;
3651 if (canceled || err) {
3652 /* In disk full conditions we could get this error here */
3653 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3654 (GtkWidget *) parent_window, err,
3655 NULL, _("mail_in_ui_folder_create_error_memory"));
3657 /* This happens if we have selected the outbox folder
3659 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3660 TNY_IS_MERGE_FOLDER (helper->parent)) {
3661 /* Show an error and retry */
3662 modest_platform_information_banner ((GtkWidget *) parent_window,
3664 _("mail_in_ui_folder_create_error"));
3666 do_create_folder (parent_window, helper->parent, helper->folder_name);
3672 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3673 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3675 modest_mail_operation_create_folder (mail_op,
3677 (const gchar *) helper->folder_name,
3678 do_create_folder_cb,
3679 g_strdup (helper->folder_name));
3680 g_object_unref (mail_op);
3684 g_object_unref (helper->parent);
3685 if (helper->folder_name)
3686 g_free (helper->folder_name);
3687 g_slice_free (CreateFolderConnect, helper);
3692 do_create_folder (GtkWindow *parent_window,
3693 TnyFolderStore *suggested_parent,
3694 const gchar *suggested_name)
3697 gchar *folder_name = NULL;
3698 TnyFolderStore *parent_folder = NULL;
3700 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3702 (gchar *) suggested_name,
3706 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3707 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3708 helper->folder_name = g_strdup (folder_name);
3709 helper->parent = g_object_ref (parent_folder);
3711 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3714 do_create_folder_performer,
3719 g_free (folder_name);
3721 g_object_unref (parent_folder);
3725 modest_ui_actions_create_folder(GtkWidget *parent_window,
3726 GtkWidget *folder_view,
3727 TnyFolderStore *parent_folder)
3729 if (!parent_folder) {
3730 #ifdef MODEST_TOOLKIT_HILDON2
3731 ModestTnyAccountStore *acc_store;
3733 acc_store = modest_runtime_get_account_store ();
3735 parent_folder = (TnyFolderStore *)
3736 modest_tny_account_store_get_local_folders_account (acc_store);
3738 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3742 if (parent_folder) {
3743 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3744 g_object_unref (parent_folder);
3749 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3752 g_return_if_fail (MODEST_IS_WINDOW(window));
3754 if (MODEST_IS_MAIN_WINDOW (window)) {
3755 GtkWidget *folder_view;
3757 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3758 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3762 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3763 #ifdef MODEST_TOOLKIT_HILDON2
3764 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3765 GtkWidget *folder_view;
3767 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3768 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3771 g_assert_not_reached ();
3776 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3779 const GError *error = NULL;
3780 gchar *message = NULL;
3782 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3784 /* Get error message */
3785 error = modest_mail_operation_get_error (mail_op);
3787 g_return_if_reached ();
3789 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3790 (GError *) error, account);
3792 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3793 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3794 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3795 message = _CS("ckdg_ib_folder_already_exists");
3796 } else if (error->domain == TNY_ERROR_DOMAIN &&
3797 error->code == TNY_SERVICE_ERROR_STATE) {
3798 /* This means that the folder is already in use (a
3799 message is opened for example */
3800 message = _("emev_ni_internal_error");
3802 message = _CS("ckdg_ib_unable_to_rename");
3805 /* We don't set a parent for the dialog because the dialog
3806 will be destroyed so the banner won't appear */
3807 modest_platform_information_banner (NULL, NULL, message);
3810 g_object_unref (account);
3816 TnyFolderStore *folder;
3821 on_rename_folder_cb (ModestMailOperation *mail_op,
3822 TnyFolder *new_folder,
3825 ModestFolderView *folder_view;
3827 /* If the window was closed when renaming a folder, or if
3828 * it's not a main window this will happen */
3829 if (!MODEST_IS_FOLDER_VIEW (user_data))
3832 folder_view = MODEST_FOLDER_VIEW (user_data);
3833 /* Note that if the rename fails new_folder will be NULL */
3835 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3837 modest_folder_view_select_first_inbox_or_local (folder_view);
3839 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3843 on_rename_folder_performer (gboolean canceled,
3845 GtkWindow *parent_window,
3846 TnyAccount *account,
3849 ModestMailOperation *mail_op = NULL;
3850 GtkTreeSelection *sel = NULL;
3851 GtkWidget *folder_view = NULL;
3852 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3854 if (canceled || err) {
3855 /* In disk full conditions we could get this error here */
3856 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3857 (GtkWidget *) parent_window, err,
3862 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3863 modest_ui_actions_rename_folder_error_handler,
3864 parent_window, NULL);
3866 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3869 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3871 folder_view = modest_main_window_get_child_widget (
3872 MODEST_MAIN_WINDOW (parent_window),
3873 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3875 #ifdef MODEST_TOOLKIT_HILDON2
3876 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3877 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3878 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3882 /* Clear the folders view */
3883 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3884 gtk_tree_selection_unselect_all (sel);
3886 /* Actually rename the folder */
3887 modest_mail_operation_rename_folder (mail_op,
3888 TNY_FOLDER (data->folder),
3889 (const gchar *) (data->new_name),
3890 on_rename_folder_cb,
3892 g_object_unref (mail_op);
3895 g_object_unref (data->folder);
3896 g_free (data->new_name);
3901 modest_ui_actions_on_rename_folder (GtkAction *action,
3902 ModestWindow *window)
3904 modest_ui_actions_on_edit_mode_rename_folder (window);
3908 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3910 TnyFolderStore *folder;
3911 GtkWidget *folder_view;
3912 gboolean do_rename = TRUE;
3914 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3916 if (MODEST_IS_MAIN_WINDOW (window)) {
3917 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3918 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3922 #ifdef MODEST_TOOLKIT_HILDON2
3923 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3924 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3930 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3935 if (TNY_IS_FOLDER (folder)) {
3936 gchar *folder_name = NULL;
3938 const gchar *current_name;
3939 TnyFolderStore *parent;
3941 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3942 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3943 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3944 parent, current_name,
3946 g_object_unref (parent);
3948 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3951 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3952 rename_folder_data->folder = g_object_ref (folder);
3953 rename_folder_data->new_name = folder_name;
3954 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3955 folder, on_rename_folder_performer, rename_folder_data);
3958 g_object_unref (folder);
3963 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3966 GObject *win = modest_mail_operation_get_source (mail_op);
3968 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3969 _("mail_in_ui_folder_delete_error"),
3971 g_object_unref (win);
3975 TnyFolderStore *folder;
3976 gboolean move_to_trash;
3980 on_delete_folder_cb (gboolean canceled,
3982 GtkWindow *parent_window,
3983 TnyAccount *account,
3986 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3987 GtkWidget *folder_view;
3988 ModestMailOperation *mail_op;
3989 GtkTreeSelection *sel;
3991 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3992 /* Note that the connection process can fail due to
3993 memory low conditions as it can not successfully
3994 store the summary */
3995 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3996 (GtkWidget*) parent_window, err,
3998 g_debug ("Error connecting when trying to delete a folder");
3999 g_object_unref (G_OBJECT (info->folder));
4004 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4005 folder_view = modest_main_window_get_child_widget (
4006 MODEST_MAIN_WINDOW (parent_window),
4007 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4008 #ifdef MODEST_TOOLKIT_HILDON2
4009 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4010 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4013 g_object_unref (G_OBJECT (info->folder));
4018 /* Unselect the folder before deleting it to free the headers */
4019 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4020 gtk_tree_selection_unselect_all (sel);
4022 /* Create the mail operation */
4024 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4025 modest_ui_actions_delete_folder_error_handler,
4028 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4030 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4032 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4034 g_object_unref (mail_op);
4035 g_object_unref (info->folder);
4040 delete_folder (ModestWindow *window, gboolean move_to_trash)
4042 TnyFolderStore *folder;
4043 GtkWidget *folder_view;
4047 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4049 if (MODEST_IS_MAIN_WINDOW (window)) {
4051 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4052 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4053 #ifdef MODEST_TOOLKIT_HILDON2
4054 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4055 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4063 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4068 /* Show an error if it's an account */
4069 if (!TNY_IS_FOLDER (folder)) {
4070 modest_platform_run_information_dialog (GTK_WINDOW (window),
4071 _("mail_in_ui_folder_delete_error"),
4073 g_object_unref (G_OBJECT (folder));
4078 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4079 tny_folder_get_name (TNY_FOLDER (folder)));
4080 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4081 (const gchar *) message);
4084 if (response == GTK_RESPONSE_OK) {
4085 TnyAccount *account = NULL;
4086 DeleteFolderInfo *info = NULL;
4087 info = g_new0(DeleteFolderInfo, 1);
4088 info->folder = g_object_ref (folder);
4089 info->move_to_trash = move_to_trash;
4091 account = tny_folder_get_account (TNY_FOLDER (folder));
4092 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4094 TNY_FOLDER_STORE (account),
4095 on_delete_folder_cb, info);
4096 g_object_unref (account);
4097 g_object_unref (folder);
4105 modest_ui_actions_on_delete_folder (GtkAction *action,
4106 ModestWindow *window)
4108 modest_ui_actions_on_edit_mode_delete_folder (window);
4112 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4114 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4116 return delete_folder (window, FALSE);
4120 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4122 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4124 delete_folder (MODEST_WINDOW (main_window), TRUE);
4128 typedef struct _PasswordDialogFields {
4129 GtkWidget *username;
4130 GtkWidget *password;
4132 } PasswordDialogFields;
4135 password_dialog_check_field (GtkEditable *editable,
4136 PasswordDialogFields *fields)
4139 gboolean any_value_empty = FALSE;
4141 #ifdef MODEST_TOOLKIT_HILDON2
4142 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4144 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4146 if ((value == NULL) || value[0] == '\0') {
4147 any_value_empty = TRUE;
4149 #ifdef MODEST_TOOLKIT_HILDON2
4150 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4152 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4154 if ((value == NULL) || value[0] == '\0') {
4155 any_value_empty = TRUE;
4157 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4161 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4162 const gchar* server_account_name,
4167 ModestMainWindow *main_window)
4169 g_return_if_fail(server_account_name);
4170 gboolean completed = FALSE;
4171 PasswordDialogFields *fields = NULL;
4173 /* Initalize output parameters: */
4180 #ifndef MODEST_TOOLKIT_GTK
4181 /* Maemo uses a different (awkward) button order,
4182 * It should probably just use gtk_alternative_dialog_button_order ().
4184 #ifdef MODEST_TOOLKIT_HILDON2
4186 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4189 _HL("wdgt_bd_done"),
4190 GTK_RESPONSE_ACCEPT,
4192 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4193 HILDON_MARGIN_DOUBLE);
4196 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4199 _("mcen_bd_dialog_ok"),
4200 GTK_RESPONSE_ACCEPT,
4201 _("mcen_bd_dialog_cancel"),
4202 GTK_RESPONSE_REJECT,
4204 #endif /* MODEST_TOOLKIT_HILDON2 */
4207 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4211 GTK_RESPONSE_REJECT,
4213 GTK_RESPONSE_ACCEPT,
4215 #endif /* MODEST_TOOLKIT_GTK */
4217 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4219 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4220 modest_runtime_get_account_mgr(), server_account_name);
4221 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4222 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4225 gtk_widget_destroy (dialog);
4229 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4230 GtkWidget *label = gtk_label_new (txt);
4231 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4233 g_free (server_name);
4234 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4239 gchar *initial_username = modest_account_mgr_get_server_account_username (
4240 modest_runtime_get_account_mgr(), server_account_name);
4242 #ifdef MODEST_TOOLKIT_HILDON2
4243 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4244 if (initial_username)
4245 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4247 GtkWidget *entry_username = gtk_entry_new ();
4248 if (initial_username)
4249 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4251 /* Dim this if a connection has ever succeeded with this username,
4252 * as per the UI spec: */
4253 /* const gboolean username_known = */
4254 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4255 /* modest_runtime_get_account_mgr(), server_account_name); */
4256 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4258 /* We drop the username sensitive code and disallow changing it here
4259 * as tinymail does not support really changing the username in the callback
4261 gtk_widget_set_sensitive (entry_username, FALSE);
4263 #ifndef MODEST_TOOLKIT_GTK
4264 /* Auto-capitalization is the default, so let's turn it off: */
4265 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4267 /* Create a size group to be used by all captions.
4268 * Note that HildonCaption does not create a default size group if we do not specify one.
4269 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4270 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4272 #ifdef MODEST_TOOLKIT_HILDON2
4273 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4274 _("mail_fi_username"), FALSE,
4277 GtkWidget *caption = hildon_caption_new (sizegroup,
4278 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4280 gtk_widget_show (entry_username);
4281 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4282 FALSE, FALSE, MODEST_MARGIN_HALF);
4283 gtk_widget_show (caption);
4285 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4287 #endif /* !MODEST_TOOLKIT_GTK */
4290 #ifdef MODEST_TOOLKIT_HILDON2
4291 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4293 GtkWidget *entry_password = gtk_entry_new ();
4295 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4296 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4298 #ifndef MODEST_TOOLKIT_GTK
4299 /* Auto-capitalization is the default, so let's turn it off: */
4300 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4301 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4303 #ifdef MODEST_TOOLKIT_HILDON2
4304 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4305 _("mail_fi_password"), FALSE,
4308 caption = hildon_caption_new (sizegroup,
4309 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4311 gtk_widget_show (entry_password);
4312 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4313 FALSE, FALSE, MODEST_MARGIN_HALF);
4314 gtk_widget_show (caption);
4315 g_object_unref (sizegroup);
4317 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4319 #endif /* !MODEST_TOOLKIT_GTK */
4321 if (initial_username != NULL)
4322 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4324 /* This is not in the Maemo UI spec:
4325 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4326 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4330 fields = g_slice_new0 (PasswordDialogFields);
4331 fields->username = entry_username;
4332 fields->password = entry_password;
4333 fields->dialog = dialog;
4335 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4336 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4337 password_dialog_check_field (NULL, fields);
4339 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4341 while (!completed) {
4343 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4345 #ifdef MODEST_TOOLKIT_HILDON2
4346 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4348 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4351 /* Note that an empty field becomes the "" string */
4352 if (*username && strlen (*username) > 0) {
4353 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4354 server_account_name,
4358 const gboolean username_was_changed =
4359 (strcmp (*username, initial_username) != 0);
4360 if (username_was_changed) {
4361 g_warning ("%s: tinymail does not yet support changing the "
4362 "username in the get_password() callback.\n", __FUNCTION__);
4368 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4369 _("mcen_ib_username_pw_incorrect"));
4375 #ifdef MODEST_TOOLKIT_HILDON2
4376 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4378 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4381 /* We do not save the password in the configuration,
4382 * because this function is only called for passwords that should
4383 * not be remembered:
4384 modest_server_account_set_password (
4385 modest_runtime_get_account_mgr(), server_account_name,
4392 #ifndef MODEST_TOOLKIT_HILDON2
4393 /* Set parent to NULL or the banner will disappear with its parent dialog */
4394 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4406 /* This is not in the Maemo UI spec:
4407 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4413 g_free (initial_username);
4414 gtk_widget_destroy (dialog);
4415 g_slice_free (PasswordDialogFields, fields);
4417 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4421 modest_ui_actions_on_cut (GtkAction *action,
4422 ModestWindow *window)
4424 GtkWidget *focused_widget;
4425 GtkClipboard *clipboard;
4427 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4428 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4429 if (GTK_IS_EDITABLE (focused_widget)) {
4430 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4431 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4432 gtk_clipboard_store (clipboard);
4433 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4434 GtkTextBuffer *buffer;
4436 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4437 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4438 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4439 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4440 gtk_clipboard_store (clipboard);
4442 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4443 TnyList *header_list = modest_header_view_get_selected_headers (
4444 MODEST_HEADER_VIEW (focused_widget));
4445 gboolean continue_download = FALSE;
4446 gint num_of_unc_msgs;
4448 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4450 if (num_of_unc_msgs) {
4451 TnyAccount *account = get_account_from_header_list (header_list);
4453 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4454 g_object_unref (account);
4458 if (num_of_unc_msgs == 0 || continue_download) {
4459 /* modest_platform_information_banner (
4460 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4461 modest_header_view_cut_selection (
4462 MODEST_HEADER_VIEW (focused_widget));
4465 g_object_unref (header_list);
4466 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4467 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4472 modest_ui_actions_on_copy (GtkAction *action,
4473 ModestWindow *window)
4475 GtkClipboard *clipboard;
4476 GtkWidget *focused_widget;
4477 gboolean copied = TRUE;
4479 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4480 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4482 if (GTK_IS_LABEL (focused_widget)) {
4484 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4485 gtk_clipboard_set_text (clipboard, selection, -1);
4487 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4488 gtk_clipboard_store (clipboard);
4489 } else if (GTK_IS_EDITABLE (focused_widget)) {
4490 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4491 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4492 gtk_clipboard_store (clipboard);
4493 } else if (GTK_IS_HTML (focused_widget)) {
4496 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4497 if ((sel == NULL) || (sel[0] == '\0')) {
4500 gtk_html_copy (GTK_HTML (focused_widget));
4501 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4502 gtk_clipboard_store (clipboard);
4504 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4505 GtkTextBuffer *buffer;
4506 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4507 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4508 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4509 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4510 gtk_clipboard_store (clipboard);
4512 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4513 TnyList *header_list = modest_header_view_get_selected_headers (
4514 MODEST_HEADER_VIEW (focused_widget));
4515 gboolean continue_download = FALSE;
4516 gint num_of_unc_msgs;
4518 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4520 if (num_of_unc_msgs) {
4521 TnyAccount *account = get_account_from_header_list (header_list);
4523 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4524 g_object_unref (account);
4528 if (num_of_unc_msgs == 0 || continue_download) {
4529 modest_platform_information_banner (
4530 NULL, NULL, _CS("mcen_ib_getting_items"));
4531 modest_header_view_copy_selection (
4532 MODEST_HEADER_VIEW (focused_widget));
4536 g_object_unref (header_list);
4538 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4539 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4542 /* Show information banner if there was a copy to clipboard */
4544 modest_platform_information_banner (
4545 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4549 modest_ui_actions_on_undo (GtkAction *action,
4550 ModestWindow *window)
4552 ModestEmailClipboard *clipboard = NULL;
4554 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4555 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4556 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4557 /* Clear clipboard source */
4558 clipboard = modest_runtime_get_email_clipboard ();
4559 modest_email_clipboard_clear (clipboard);
4562 g_return_if_reached ();
4567 modest_ui_actions_on_redo (GtkAction *action,
4568 ModestWindow *window)
4570 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4571 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4574 g_return_if_reached ();
4580 destroy_information_note (ModestMailOperation *mail_op,
4583 /* destroy information note */
4584 gtk_widget_destroy (GTK_WIDGET(user_data));
4588 destroy_folder_information_note (ModestMailOperation *mail_op,
4589 TnyFolder *new_folder,
4592 /* destroy information note */
4593 gtk_widget_destroy (GTK_WIDGET(user_data));
4598 paste_as_attachment_free (gpointer data)
4600 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4602 if (helper->banner) {
4603 gtk_widget_destroy (helper->banner);
4604 g_object_unref (helper->banner);
4610 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4615 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4616 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4621 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4626 modest_ui_actions_on_paste (GtkAction *action,
4627 ModestWindow *window)
4629 GtkWidget *focused_widget = NULL;
4630 GtkWidget *inf_note = NULL;
4631 ModestMailOperation *mail_op = NULL;
4633 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4634 if (GTK_IS_EDITABLE (focused_widget)) {
4635 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4636 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4637 ModestEmailClipboard *e_clipboard = NULL;
4638 e_clipboard = modest_runtime_get_email_clipboard ();
4639 if (modest_email_clipboard_cleared (e_clipboard)) {
4640 GtkTextBuffer *buffer;
4641 GtkClipboard *clipboard;
4643 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4644 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4645 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4646 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4647 ModestMailOperation *mail_op;
4648 TnyFolder *src_folder = NULL;
4649 TnyList *data = NULL;
4651 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4652 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4653 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4654 _CS("ckct_nw_pasting"));
4655 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4656 mail_op = modest_mail_operation_new (G_OBJECT (window));
4657 if (helper->banner != NULL) {
4658 g_object_ref (G_OBJECT (helper->banner));
4659 gtk_widget_show (GTK_WIDGET (helper->banner));
4663 modest_mail_operation_get_msgs_full (mail_op,
4665 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4667 paste_as_attachment_free);
4671 g_object_unref (data);
4673 g_object_unref (src_folder);
4676 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4677 ModestEmailClipboard *clipboard = NULL;
4678 TnyFolder *src_folder = NULL;
4679 TnyFolderStore *folder_store = NULL;
4680 TnyList *data = NULL;
4681 gboolean delete = FALSE;
4683 /* Check clipboard source */
4684 clipboard = modest_runtime_get_email_clipboard ();
4685 if (modest_email_clipboard_cleared (clipboard))
4688 /* Get elements to paste */
4689 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4691 /* Create a new mail operation */
4692 mail_op = modest_mail_operation_new (G_OBJECT(window));
4694 /* Get destination folder */
4695 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4697 /* transfer messages */
4701 /* Ask for user confirmation */
4703 modest_ui_actions_msgs_move_to_confirmation (window,
4704 TNY_FOLDER (folder_store),
4708 if (response == GTK_RESPONSE_OK) {
4709 /* Launch notification */
4710 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4711 _CS("ckct_nw_pasting"));
4712 if (inf_note != NULL) {
4713 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4714 gtk_widget_show (GTK_WIDGET(inf_note));
4717 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4718 modest_mail_operation_xfer_msgs (mail_op,
4720 TNY_FOLDER (folder_store),
4722 destroy_information_note,
4725 g_object_unref (mail_op);
4728 } else if (src_folder != NULL) {
4729 /* Launch notification */
4730 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4731 _CS("ckct_nw_pasting"));
4732 if (inf_note != NULL) {
4733 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4734 gtk_widget_show (GTK_WIDGET(inf_note));
4737 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4738 modest_mail_operation_xfer_folder (mail_op,
4742 destroy_folder_information_note,
4748 g_object_unref (data);
4749 if (src_folder != NULL)
4750 g_object_unref (src_folder);
4751 if (folder_store != NULL)
4752 g_object_unref (folder_store);
4758 modest_ui_actions_on_select_all (GtkAction *action,
4759 ModestWindow *window)
4761 GtkWidget *focused_widget;
4763 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4764 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4765 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4766 } else if (GTK_IS_LABEL (focused_widget)) {
4767 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4768 } else if (GTK_IS_EDITABLE (focused_widget)) {
4769 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4770 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4771 GtkTextBuffer *buffer;
4772 GtkTextIter start, end;
4774 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4775 gtk_text_buffer_get_start_iter (buffer, &start);
4776 gtk_text_buffer_get_end_iter (buffer, &end);
4777 gtk_text_buffer_select_range (buffer, &start, &end);
4778 } else if (GTK_IS_HTML (focused_widget)) {
4779 gtk_html_select_all (GTK_HTML (focused_widget));
4780 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4781 GtkWidget *header_view = focused_widget;
4782 GtkTreeSelection *selection = NULL;
4784 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4785 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4786 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4789 /* Disable window dimming management */
4790 modest_window_disable_dimming (MODEST_WINDOW(window));
4792 /* Select all messages */
4793 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4794 gtk_tree_selection_select_all (selection);
4796 /* Set focuse on header view */
4797 gtk_widget_grab_focus (header_view);
4799 /* Enable window dimming management */
4800 modest_window_enable_dimming (MODEST_WINDOW(window));
4801 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4802 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4808 modest_ui_actions_on_mark_as_read (GtkAction *action,
4809 ModestWindow *window)
4811 g_return_if_fail (MODEST_IS_WINDOW(window));
4813 /* Mark each header as read */
4814 do_headers_action (window, headers_action_mark_as_read, NULL);
4818 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4819 ModestWindow *window)
4821 g_return_if_fail (MODEST_IS_WINDOW(window));
4823 /* Mark each header as read */
4824 do_headers_action (window, headers_action_mark_as_unread, NULL);
4828 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4829 GtkRadioAction *selected,
4830 ModestWindow *window)
4834 value = gtk_radio_action_get_current_value (selected);
4835 if (MODEST_IS_WINDOW (window)) {
4836 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4841 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4842 GtkRadioAction *selected,
4843 ModestWindow *window)
4845 TnyHeaderFlags flags;
4846 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4848 flags = gtk_radio_action_get_current_value (selected);
4849 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4853 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4854 GtkRadioAction *selected,
4855 ModestWindow *window)
4859 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4861 file_format = gtk_radio_action_get_current_value (selected);
4862 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4867 modest_ui_actions_on_zoom_plus (GtkAction *action,
4868 ModestWindow *window)
4870 g_return_if_fail (MODEST_IS_WINDOW (window));
4872 modest_window_zoom_plus (MODEST_WINDOW (window));
4876 modest_ui_actions_on_zoom_minus (GtkAction *action,
4877 ModestWindow *window)
4879 g_return_if_fail (MODEST_IS_WINDOW (window));
4881 modest_window_zoom_minus (MODEST_WINDOW (window));
4885 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4886 ModestWindow *window)
4888 ModestWindowMgr *mgr;
4889 gboolean fullscreen, active;
4890 g_return_if_fail (MODEST_IS_WINDOW (window));
4892 mgr = modest_runtime_get_window_mgr ();
4894 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4895 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4897 if (active != fullscreen) {
4898 modest_window_mgr_set_fullscreen_mode (mgr, active);
4899 #ifndef MODEST_TOOLKIT_HILDON2
4900 gtk_window_present (GTK_WINDOW (window));
4906 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4907 ModestWindow *window)
4909 ModestWindowMgr *mgr;
4910 gboolean fullscreen;
4912 g_return_if_fail (MODEST_IS_WINDOW (window));
4914 mgr = modest_runtime_get_window_mgr ();
4915 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4916 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4918 #ifndef MODEST_TOOLKIT_HILDON2
4919 gtk_window_present (GTK_WINDOW (window));
4924 * Used by modest_ui_actions_on_details to call do_headers_action
4927 headers_action_show_details (TnyHeader *header,
4928 ModestWindow *window,
4932 gboolean async_retrieval;
4935 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4936 async_retrieval = TRUE;
4937 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4938 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4940 async_retrieval = FALSE;
4942 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4944 g_object_unref (msg);
4948 * Show the header details in a ModestDetailsDialog widget
4951 modest_ui_actions_on_details (GtkAction *action,
4954 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4958 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4962 header = tny_msg_get_header (msg);
4964 headers_action_show_details (header, win, NULL);
4965 g_object_unref (header);
4967 g_object_unref (msg);
4969 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4970 GtkWidget *folder_view, *header_view;
4972 /* Check which widget has the focus */
4973 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4974 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4975 if (gtk_widget_is_focus (folder_view)) {
4976 TnyFolderStore *folder_store
4977 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4978 if (!folder_store) {
4979 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4982 /* Show only when it's a folder */
4983 /* This function should not be called for account items,
4984 * because we dim the menu item for them. */
4985 if (TNY_IS_FOLDER (folder_store)) {
4986 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4987 TNY_FOLDER (folder_store));
4990 g_object_unref (folder_store);
4993 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4994 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4995 /* Show details of each header */
4996 do_headers_action (win, headers_action_show_details, header_view);
4998 #ifdef MODEST_TOOLKIT_HILDON2
4999 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5001 GtkWidget *header_view;
5003 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5004 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5006 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5008 g_object_unref (folder);
5015 modest_ui_actions_on_limit_error (GtkAction *action,
5018 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5020 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5025 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5026 ModestMsgEditWindow *window)
5028 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5030 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5034 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5035 ModestMsgEditWindow *window)
5037 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5039 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5043 modest_ui_actions_toggle_folders_view (GtkAction *action,
5044 ModestMainWindow *main_window)
5046 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5048 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5049 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5051 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5055 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5056 ModestWindow *window)
5058 gboolean active, fullscreen = FALSE;
5059 ModestWindowMgr *mgr;
5061 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5063 /* Check if we want to toggle the toolbar view in fullscreen
5065 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5066 "ViewShowToolbarFullScreen")) {
5070 /* Toggle toolbar */
5071 mgr = modest_runtime_get_window_mgr ();
5072 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5076 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5077 ModestMsgEditWindow *window)
5079 modest_msg_edit_window_select_font (window);
5084 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5085 const gchar *display_name,
5088 /* don't update the display name if it was already set;
5089 * updating the display name apparently is expensive */
5090 const gchar* old_name = gtk_window_get_title (window);
5092 if (display_name == NULL)
5095 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5096 return; /* don't do anything */
5098 /* This is usually used to change the title of the main window, which
5099 * is the one that holds the folder view. Note that this change can
5100 * happen even when the widget doesn't have the focus. */
5101 gtk_window_set_title (window, display_name);
5106 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5108 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5109 modest_msg_edit_window_select_contacts (window);
5113 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5115 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5116 modest_msg_edit_window_check_names (window, FALSE);
5119 #ifndef MODEST_TOOLKIT_HILDON2
5121 * This function is used to track changes in the selection of the
5122 * folder view that is inside the "move to" dialog to enable/disable
5123 * the OK button because we do not want the user to select a disallowed
5124 * destination for a folder.
5125 * The user also not desired to be able to use NEW button on items where
5126 * folder creation is not possibel.
5129 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5130 TnyFolderStore *folder_store,
5134 GtkWidget *dialog = NULL;
5135 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5136 gboolean moving_folder = FALSE;
5137 gboolean is_local_account = TRUE;
5138 GtkWidget *folder_view = NULL;
5139 ModestTnyFolderRules rules;
5141 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5146 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5150 /* check if folder_store is an remote account */
5151 if (TNY_IS_ACCOUNT (folder_store)) {
5152 TnyAccount *local_account = NULL;
5153 TnyAccount *mmc_account = NULL;
5154 ModestTnyAccountStore *account_store = NULL;
5156 account_store = modest_runtime_get_account_store ();
5157 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5158 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5160 if ((gpointer) local_account != (gpointer) folder_store &&
5161 (gpointer) mmc_account != (gpointer) folder_store) {
5162 ModestProtocolType proto;
5163 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5164 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5165 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5167 is_local_account = FALSE;
5168 /* New button should be dimmed on remote
5170 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5172 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5174 g_object_unref (local_account);
5176 /* It could not exist */
5178 g_object_unref (mmc_account);
5181 /* Check the target folder rules */
5182 if (TNY_IS_FOLDER (folder_store)) {
5183 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5184 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5185 ok_sensitive = FALSE;
5186 new_sensitive = FALSE;
5191 /* Check if we're moving a folder */
5192 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5193 /* Get the widgets */
5194 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5195 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5196 if (gtk_widget_is_focus (folder_view))
5197 moving_folder = TRUE;
5200 if (moving_folder) {
5201 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5203 /* Get the folder to move */
5204 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5206 /* Check that we're not moving to the same folder */
5207 if (TNY_IS_FOLDER (moved_folder)) {
5208 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5209 if (parent == folder_store)
5210 ok_sensitive = FALSE;
5211 g_object_unref (parent);
5214 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5215 /* Do not allow to move to an account unless it's the
5216 local folders account */
5217 if (!is_local_account)
5218 ok_sensitive = FALSE;
5221 if (ok_sensitive && (moved_folder == folder_store)) {
5222 /* Do not allow to move to itself */
5223 ok_sensitive = FALSE;
5225 g_object_unref (moved_folder);
5227 TnyFolder *src_folder = NULL;
5229 /* Moving a message */
5230 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5232 TnyHeader *header = NULL;
5233 header = modest_msg_view_window_get_header
5234 (MODEST_MSG_VIEW_WINDOW (user_data));
5235 if (!TNY_IS_HEADER(header))
5236 g_warning ("%s: could not get source header", __FUNCTION__);
5238 src_folder = tny_header_get_folder (header);
5241 g_object_unref (header);
5244 TNY_FOLDER (modest_folder_view_get_selected
5245 (MODEST_FOLDER_VIEW (folder_view)));
5248 if (TNY_IS_FOLDER(src_folder)) {
5249 /* Do not allow to move the msg to the same folder */
5250 /* Do not allow to move the msg to an account */
5251 if ((gpointer) src_folder == (gpointer) folder_store ||
5252 TNY_IS_ACCOUNT (folder_store))
5253 ok_sensitive = FALSE;
5254 g_object_unref (src_folder);
5256 g_warning ("%s: could not get source folder", __FUNCTION__);
5260 /* Set sensitivity of the OK and NEW button */
5261 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5262 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5267 on_move_to_dialog_response (GtkDialog *dialog,
5271 GtkWidget *parent_win;
5272 MoveToInfo *helper = NULL;
5273 ModestFolderView *folder_view;
5274 gboolean unset_edit_mode = FALSE;
5276 helper = (MoveToInfo *) user_data;
5278 parent_win = (GtkWidget *) helper->win;
5279 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5280 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5282 TnyFolderStore *dst_folder;
5283 TnyFolderStore *selected;
5285 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5286 selected = modest_folder_view_get_selected (folder_view);
5287 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5288 g_object_unref (selected);
5290 case GTK_RESPONSE_NONE:
5291 case GTK_RESPONSE_CANCEL:
5292 case GTK_RESPONSE_DELETE_EVENT:
5294 case GTK_RESPONSE_OK:
5295 dst_folder = modest_folder_view_get_selected (folder_view);
5297 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5298 /* Clean list to move used for filtering */
5299 modest_folder_view_set_list_to_move (folder_view, NULL);
5301 modest_ui_actions_on_main_window_move_to (NULL,
5302 GTK_WIDGET (folder_view),
5304 MODEST_MAIN_WINDOW (parent_win));
5305 #ifdef MODEST_TOOLKIT_HILDON2
5306 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5307 /* Clean list to move used for filtering */
5308 modest_folder_view_set_list_to_move (folder_view, NULL);
5310 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5313 GTK_WINDOW (parent_win));
5316 /* if the user selected a root folder
5317 (account) then do not perform any action */
5318 if (TNY_IS_ACCOUNT (dst_folder)) {
5319 g_signal_stop_emission_by_name (dialog, "response");
5323 /* Clean list to move used for filtering */
5324 modest_folder_view_set_list_to_move (folder_view, NULL);
5326 /* Moving from headers window in edit mode */
5327 modest_ui_actions_on_window_move_to (NULL, helper->list,
5329 MODEST_WINDOW (parent_win));
5333 g_object_unref (dst_folder);
5335 unset_edit_mode = TRUE;
5338 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5341 /* Free the helper and exit */
5343 g_object_unref (helper->list);
5344 if (unset_edit_mode) {
5345 #ifdef MODEST_TOOLKIT_HILDON2
5346 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5349 g_slice_free (MoveToInfo, helper);
5350 gtk_widget_destroy (GTK_WIDGET (dialog));
5354 create_move_to_dialog (GtkWindow *win,
5355 GtkWidget *folder_view,
5356 TnyList *list_to_move)
5358 GtkWidget *dialog, *tree_view = NULL;
5360 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5362 #ifndef MODEST_TOOLKIT_HILDON2
5363 /* Track changes in the selection to
5364 * disable the OK button whenever "Move to" is not possible
5365 * disbale NEW button whenever New is not possible */
5366 g_signal_connect (tree_view,
5367 "folder_selection_changed",
5368 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5372 /* It could happen that we're trying to move a message from a
5373 window (msg window for example) after the main window was
5374 closed, so we can not just get the model of the folder
5376 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5377 const gchar *visible_id = NULL;
5379 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5380 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5381 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5382 MODEST_FOLDER_VIEW(tree_view));
5385 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5387 /* Show the same account than the one that is shown in the main window */
5388 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5391 const gchar *active_account_name = NULL;
5392 ModestAccountMgr *mgr = NULL;
5393 ModestAccountSettings *settings = NULL;
5394 ModestServerAccountSettings *store_settings = NULL;
5396 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5397 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5398 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5399 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5401 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5402 mgr = modest_runtime_get_account_mgr ();
5403 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5406 const gchar *store_account_name;
5407 store_settings = modest_account_settings_get_store_settings (settings);
5408 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5410 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5411 store_account_name);
5412 g_object_unref (store_settings);
5413 g_object_unref (settings);
5417 /* we keep a pointer to the embedded folder view, so we can
5418 * retrieve it with get_folder_view_from_move_to_dialog (see
5419 * above) later (needed for focus handling)
5421 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5423 /* Hide special folders */
5424 #ifndef MODEST_TOOLKIT_HILDON2
5425 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5428 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5429 #ifndef MODEST_TOOLKIT_HILDON2
5430 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5433 gtk_widget_show (GTK_WIDGET (tree_view));
5439 * Shows a confirmation dialog to the user when we're moving messages
5440 * from a remote server to the local storage. Returns the dialog
5441 * response. If it's other kind of movement then it always returns
5444 * This one is used by the next functions:
5445 * modest_ui_actions_on_paste - commented out
5446 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5449 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5450 TnyFolder *dest_folder,
5454 gint response = GTK_RESPONSE_OK;
5455 TnyAccount *account = NULL;
5456 TnyFolder *src_folder = NULL;
5457 TnyIterator *iter = NULL;
5458 TnyHeader *header = NULL;
5460 /* return with OK if the destination is a remote folder */
5461 if (modest_tny_folder_is_remote_folder (dest_folder))
5462 return GTK_RESPONSE_OK;
5464 /* Get source folder */
5465 iter = tny_list_create_iterator (headers);
5466 header = TNY_HEADER (tny_iterator_get_current (iter));
5468 src_folder = tny_header_get_folder (header);
5469 g_object_unref (header);
5471 g_object_unref (iter);
5473 /* if no src_folder, message may be an attahcment */
5474 if (src_folder == NULL)
5475 return GTK_RESPONSE_CANCEL;
5477 /* If the source is a local or MMC folder */
5478 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5479 g_object_unref (src_folder);
5480 return GTK_RESPONSE_OK;
5483 /* Get the account */
5484 account = tny_folder_get_account (src_folder);
5486 /* now if offline we ask the user */
5487 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5488 response = GTK_RESPONSE_OK;
5490 response = GTK_RESPONSE_CANCEL;
5493 g_object_unref (src_folder);
5494 g_object_unref (account);
5500 move_to_helper_destroyer (gpointer user_data)
5502 MoveToHelper *helper = (MoveToHelper *) user_data;
5504 /* Close the "Pasting" information banner */
5505 if (helper->banner) {
5506 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5507 g_object_unref (helper->banner);
5509 if (gtk_tree_row_reference_valid (helper->reference)) {
5510 gtk_tree_row_reference_free (helper->reference);
5511 helper->reference = NULL;
5517 move_to_cb (ModestMailOperation *mail_op,
5520 MoveToHelper *helper = (MoveToHelper *) user_data;
5521 GObject *object = modest_mail_operation_get_source (mail_op);
5523 /* Note that the operation could have failed, in that case do
5525 if (modest_mail_operation_get_status (mail_op) !=
5526 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5529 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5530 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5532 if (!modest_msg_view_window_select_next_message (self) &&
5533 !modest_msg_view_window_select_previous_message (self)) {
5534 /* No more messages to view, so close this window */
5535 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5537 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5538 gtk_tree_row_reference_valid (helper->reference)) {
5539 GtkWidget *header_view;
5541 GtkTreeSelection *sel;
5543 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5544 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5545 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5546 path = gtk_tree_row_reference_get_path (helper->reference);
5547 /* We need to unselect the previous one
5548 because we could be copying instead of
5550 gtk_tree_selection_unselect_all (sel);
5551 gtk_tree_selection_select_path (sel, path);
5552 gtk_tree_path_free (path);
5554 g_object_unref (object);
5557 /* Destroy the helper */
5558 move_to_helper_destroyer (helper);
5562 folder_move_to_cb (ModestMailOperation *mail_op,
5563 TnyFolder *new_folder,
5566 GtkWidget *folder_view;
5569 object = modest_mail_operation_get_source (mail_op);
5570 if (MODEST_IS_MAIN_WINDOW (object)) {
5571 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5572 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5573 g_object_ref (folder_view);
5574 g_object_unref (object);
5575 move_to_cb (mail_op, user_data);
5576 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5577 g_object_unref (folder_view);
5579 move_to_cb (mail_op, user_data);
5584 msgs_move_to_cb (ModestMailOperation *mail_op,
5587 move_to_cb (mail_op, user_data);
5591 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5594 GObject *win = NULL;
5595 const GError *error;
5596 TnyAccount *account = NULL;
5598 #ifndef MODEST_TOOLKIT_HILDON2
5599 ModestWindow *main_window = NULL;
5601 /* Disable next automatic folder selection */
5602 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5603 FALSE); /* don't create */
5605 /* Show notification dialog only if the main window exists */
5607 GtkWidget *folder_view = NULL;
5609 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5610 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5611 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5613 if (user_data && TNY_IS_FOLDER (user_data)) {
5614 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5615 TNY_FOLDER (user_data), FALSE);
5619 win = modest_mail_operation_get_source (mail_op);
5620 error = modest_mail_operation_get_error (mail_op);
5622 if (TNY_IS_FOLDER (user_data))
5623 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5624 else if (TNY_IS_ACCOUNT (user_data))
5625 account = g_object_ref (user_data);
5627 /* If it's not a disk full error then show a generic error */
5628 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5629 (GtkWidget *) win, (GError *) error,
5631 modest_platform_run_information_dialog ((GtkWindow *) win,
5632 _("mail_in_ui_folder_move_target_error"),
5635 g_object_unref (account);
5637 g_object_unref (win);
5641 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5650 gint pending_purges = 0;
5651 gboolean some_purged = FALSE;
5652 ModestWindow *win = MODEST_WINDOW (user_data);
5653 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5655 /* If there was any error */
5656 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5657 modest_window_mgr_unregister_header (mgr, header);
5661 /* Once the message has been retrieved for purging, we check if
5662 * it's all ok for purging */
5664 parts = tny_simple_list_new ();
5665 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5666 iter = tny_list_create_iterator (parts);
5668 while (!tny_iterator_is_done (iter)) {
5670 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5671 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5672 if (tny_mime_part_is_purged (part))
5679 g_object_unref (part);
5681 tny_iterator_next (iter);
5683 g_object_unref (iter);
5686 if (pending_purges>0) {
5688 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5690 if (response == GTK_RESPONSE_OK) {
5693 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5694 iter = tny_list_create_iterator (parts);
5695 while (!tny_iterator_is_done (iter)) {
5698 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5699 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5700 tny_mime_part_set_purged (part);
5703 g_object_unref (part);
5705 tny_iterator_next (iter);
5707 g_object_unref (iter);
5709 tny_msg_rewrite_cache (msg);
5711 gtk_widget_destroy (info);
5715 modest_window_mgr_unregister_header (mgr, header);
5717 g_object_unref (parts);
5721 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5722 ModestMainWindow *win)
5724 GtkWidget *header_view;
5725 TnyList *header_list;
5727 TnyHeaderFlags flags;
5728 ModestWindow *msg_view_window = NULL;
5731 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5733 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5734 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5736 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5738 g_warning ("%s: no header selected", __FUNCTION__);
5742 if (tny_list_get_length (header_list) == 1) {
5743 TnyIterator *iter = tny_list_create_iterator (header_list);
5744 header = TNY_HEADER (tny_iterator_get_current (iter));
5745 g_object_unref (iter);
5749 if (!header || !TNY_IS_HEADER(header)) {
5750 g_warning ("%s: header is not valid", __FUNCTION__);
5754 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5755 header, &msg_view_window);
5756 flags = tny_header_get_flags (header);
5757 if (!(flags & TNY_HEADER_FLAG_CACHED))
5760 if (msg_view_window != NULL)
5761 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5763 /* do nothing; uid was registered before, so window is probably on it's way */
5764 g_debug ("header %p has already been registered", header);
5767 ModestMailOperation *mail_op = NULL;
5768 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5769 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5770 modest_ui_actions_disk_operations_error_handler,
5772 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5773 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5775 g_object_unref (mail_op);
5778 g_object_unref (header);
5780 g_object_unref (header_list);
5784 * Checks if we need a connection to do the transfer and if the user
5785 * wants to connect to complete it
5788 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5789 TnyFolderStore *src_folder,
5791 TnyFolder *dst_folder,
5792 gboolean delete_originals,
5793 gboolean *need_connection,
5796 TnyAccount *src_account;
5797 gint uncached_msgs = 0;
5799 /* We don't need any further check if
5801 * 1- the source folder is local OR
5802 * 2- the device is already online
5804 if (!modest_tny_folder_store_is_remote (src_folder) ||
5805 tny_device_is_online (modest_runtime_get_device())) {
5806 *need_connection = FALSE;
5811 /* We must ask for a connection when
5813 * - the message(s) is not already cached OR
5814 * - the message(s) is cached but the leave_on_server setting
5815 * is FALSE (because we need to sync the source folder to
5816 * delete the message from the server (for IMAP we could do it
5817 * offline, it'll take place the next time we get a
5820 uncached_msgs = header_list_count_uncached_msgs (headers);
5821 src_account = get_account_from_folder_store (src_folder);
5822 if (uncached_msgs > 0) {
5826 *need_connection = TRUE;
5827 num_headers = tny_list_get_length (headers);
5828 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5830 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5831 GTK_RESPONSE_CANCEL) {
5837 /* The transfer is possible and the user wants to */
5840 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5841 const gchar *account_name;
5842 gboolean leave_on_server;
5844 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5845 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5848 if (leave_on_server == TRUE) {
5849 *need_connection = FALSE;
5851 *need_connection = TRUE;
5854 *need_connection = FALSE;
5859 g_object_unref (src_account);
5863 xfer_messages_error_handler (ModestMailOperation *mail_op,
5867 const GError *error;
5868 TnyAccount *account;
5870 win = modest_mail_operation_get_source (mail_op);
5871 error = modest_mail_operation_get_error (mail_op);
5873 /* We cannot get the account from the mail op as that is the
5874 source account and for checking memory full conditions we
5875 need the destination one */
5876 account = TNY_ACCOUNT (user_data);
5879 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5880 (GtkWidget *) win, (GError*) error,
5881 account, _KR("cerm_memory_card_full"))) {
5882 modest_platform_run_information_dialog ((GtkWindow *) win,
5883 _("mail_in_ui_folder_move_target_error"),
5887 g_object_unref (win);
5891 TnyFolderStore *dst_folder;
5896 * Utility function that transfer messages from both the main window
5897 * and the msg view window when using the "Move to" dialog
5900 xfer_messages_performer (gboolean canceled,
5902 GtkWindow *parent_window,
5903 TnyAccount *account,
5906 ModestWindow *win = MODEST_WINDOW (parent_window);
5907 TnyAccount *dst_account = NULL;
5908 gboolean dst_forbids_message_add = FALSE;
5909 XferMsgsHelper *helper;
5910 MoveToHelper *movehelper;
5911 ModestMailOperation *mail_op;
5913 helper = (XferMsgsHelper *) user_data;
5915 if (canceled || err) {
5916 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5917 (GtkWidget *) parent_window, err,
5919 /* Show the proper error message */
5920 modest_ui_actions_on_account_connection_error (parent_window, account);
5925 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5927 /* tinymail will return NULL for local folders it seems */
5928 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5929 modest_tny_account_get_protocol_type (dst_account),
5930 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5932 if (dst_forbids_message_add) {
5933 modest_platform_information_banner (GTK_WIDGET (win),
5935 ngettext("mail_in_ui_folder_move_target_error",
5936 "mail_in_ui_folder_move_targets_error",
5937 tny_list_get_length (helper->headers)));
5941 movehelper = g_new0 (MoveToHelper, 1);
5943 #ifndef MODEST_TOOLKIT_HILDON2
5944 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5945 _CS("ckct_nw_pasting"));
5946 if (movehelper->banner != NULL) {
5947 g_object_ref (movehelper->banner);
5948 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5952 if (MODEST_IS_MAIN_WINDOW (win)) {
5953 GtkWidget *header_view =
5954 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5955 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5956 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5959 /* Perform the mail operation */
5960 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5961 xfer_messages_error_handler,
5962 g_object_ref (dst_account),
5964 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5967 modest_mail_operation_xfer_msgs (mail_op,
5969 TNY_FOLDER (helper->dst_folder),
5974 g_object_unref (G_OBJECT (mail_op));
5977 g_object_unref (dst_account);
5978 g_object_unref (helper->dst_folder);
5979 g_object_unref (helper->headers);
5980 g_slice_free (XferMsgsHelper, helper);
5984 TnyFolder *src_folder;
5985 TnyFolderStore *dst_folder;
5986 gboolean delete_original;
5987 GtkWidget *folder_view;
5991 on_move_folder_cb (gboolean canceled,
5993 GtkWindow *parent_window,
5994 TnyAccount *account,
5997 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5998 GtkTreeSelection *sel;
5999 ModestMailOperation *mail_op = NULL;
6001 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6002 /* Note that the connection process can fail due to
6003 memory low conditions as it can not successfully
6004 store the summary */
6005 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6006 (GtkWidget*) parent_window, err,
6008 g_debug ("Error connecting when trying to move a folder");
6010 g_object_unref (G_OBJECT (info->src_folder));
6011 g_object_unref (G_OBJECT (info->dst_folder));
6016 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6017 #ifndef MODEST_TOOLKIT_HILDON2
6018 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6019 _CS("ckct_nw_pasting"));
6020 if (helper->banner != NULL) {
6021 g_object_ref (helper->banner);
6022 gtk_widget_show (GTK_WIDGET(helper->banner));
6025 /* Clean folder on header view before moving it */
6026 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6027 gtk_tree_selection_unselect_all (sel);
6029 /* Let gtk events run. We need that the folder
6030 view frees its reference to the source
6031 folder *before* issuing the mail operation
6032 so we need the signal handler of selection
6033 changed to happen before the mail
6035 while (gtk_events_pending ())
6036 gtk_main_iteration (); */
6039 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6040 modest_ui_actions_move_folder_error_handler,
6041 g_object_ref (info->dst_folder), g_object_unref);
6042 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6045 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6046 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6047 TNY_FOLDER (info->dst_folder), TRUE);
6049 modest_mail_operation_xfer_folder (mail_op,
6050 TNY_FOLDER (info->src_folder),
6052 info->delete_original,
6055 g_object_unref (G_OBJECT (info->src_folder));
6057 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6060 /* Unref mail operation */
6061 g_object_unref (G_OBJECT (mail_op));
6062 g_object_unref (G_OBJECT (info->dst_folder));
6067 get_account_from_folder_store (TnyFolderStore *folder_store)
6069 if (TNY_IS_ACCOUNT (folder_store))
6070 return g_object_ref (folder_store);
6072 return tny_folder_get_account (TNY_FOLDER (folder_store));
6076 * UI handler for the "Move to" action when invoked from the
6080 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6081 GtkWidget *folder_view,
6082 TnyFolderStore *dst_folder,
6083 ModestMainWindow *win)
6085 ModestHeaderView *header_view = NULL;
6086 TnyFolderStore *src_folder = NULL;
6088 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6090 /* Get the source folder */
6091 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6093 /* Get header view */
6094 header_view = (ModestHeaderView *)
6095 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6097 /* Get folder or messages to transfer */
6098 if (gtk_widget_is_focus (folder_view)) {
6099 gboolean do_xfer = TRUE;
6101 /* Allow only to transfer folders to the local root folder */
6102 if (TNY_IS_ACCOUNT (dst_folder) &&
6103 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6104 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6106 } else if (!TNY_IS_FOLDER (src_folder)) {
6107 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6112 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6113 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6115 info->src_folder = g_object_ref (src_folder);
6116 info->dst_folder = g_object_ref (dst_folder);
6117 info->delete_original = TRUE;
6118 info->folder_view = folder_view;
6120 connect_info->callback = on_move_folder_cb;
6121 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6122 connect_info->data = info;
6124 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6125 TNY_FOLDER_STORE (src_folder),
6128 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6131 headers = modest_header_view_get_selected_headers(header_view);
6133 /* Transfer the messages */
6134 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6135 headers, TNY_FOLDER (dst_folder));
6137 g_object_unref (headers);
6141 g_object_unref (src_folder);
6144 #ifdef MODEST_TOOLKIT_HILDON2
6146 * UI handler for the "Move to" action when invoked from the
6147 * ModestFolderWindow
6150 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6151 TnyFolderStore *dst_folder,
6155 TnyFolderStore *src_folder = NULL;
6156 TnyIterator *iterator;
6158 if (tny_list_get_length (selection) != 1)
6161 iterator = tny_list_create_iterator (selection);
6162 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6163 g_object_unref (iterator);
6166 gboolean do_xfer = TRUE;
6168 /* Allow only to transfer folders to the local root folder */
6169 if (TNY_IS_ACCOUNT (dst_folder) &&
6170 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6171 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6174 modest_platform_run_information_dialog (win,
6175 _("mail_in_ui_folder_move_target_error"),
6177 } else if (!TNY_IS_FOLDER (src_folder)) {
6178 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6183 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6184 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6186 info->src_folder = g_object_ref (src_folder);
6187 info->dst_folder = g_object_ref (dst_folder);
6188 info->delete_original = TRUE;
6189 info->folder_view = folder_view;
6191 connect_info->callback = on_move_folder_cb;
6192 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6193 connect_info->data = info;
6195 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6196 TNY_FOLDER_STORE (src_folder),
6201 g_object_unref (src_folder);
6207 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6208 TnyFolder *src_folder,
6210 TnyFolder *dst_folder)
6212 gboolean need_connection = TRUE;
6213 gboolean do_xfer = TRUE;
6214 XferMsgsHelper *helper;
6216 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6217 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6218 g_return_if_fail (TNY_IS_LIST (headers));
6220 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6221 headers, TNY_FOLDER (dst_folder),
6222 TRUE, &need_connection,
6225 /* If we don't want to transfer just return */
6229 /* Create the helper */
6230 helper = g_slice_new (XferMsgsHelper);
6231 helper->dst_folder = g_object_ref (dst_folder);
6232 helper->headers = g_object_ref (headers);
6234 if (need_connection) {
6235 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6236 connect_info->callback = xfer_messages_performer;
6237 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6238 connect_info->data = helper;
6240 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6241 TNY_FOLDER_STORE (src_folder),
6244 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6245 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6246 src_account, helper);
6247 g_object_unref (src_account);
6252 * UI handler for the "Move to" action when invoked from the
6253 * ModestMsgViewWindow
6256 modest_ui_actions_on_window_move_to (GtkAction *action,
6258 TnyFolderStore *dst_folder,
6261 TnyFolder *src_folder = NULL;
6263 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6266 TnyHeader *header = NULL;
6269 iter = tny_list_create_iterator (headers);
6270 header = (TnyHeader *) tny_iterator_get_current (iter);
6271 src_folder = tny_header_get_folder (header);
6273 /* Transfer the messages */
6274 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6276 TNY_FOLDER (dst_folder));
6279 g_object_unref (header);
6280 g_object_unref (iter);
6281 g_object_unref (src_folder);
6286 modest_ui_actions_on_move_to (GtkAction *action,
6289 modest_ui_actions_on_edit_mode_move_to (win);
6293 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6295 GtkWidget *dialog = NULL;
6296 MoveToInfo *helper = NULL;
6297 TnyList *list_to_move;
6299 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6301 #ifndef MODEST_TOOLKIT_HILDON2
6302 /* Get the main window if exists */
6303 ModestMainWindow *main_window;
6304 if (MODEST_IS_MAIN_WINDOW (win))
6305 main_window = MODEST_MAIN_WINDOW (win);
6308 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6309 FALSE)); /* don't create */
6312 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6317 if (tny_list_get_length (list_to_move) < 1) {
6318 g_object_unref (list_to_move);
6322 /* Create and run the dialog */
6323 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6324 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6325 GTK_WINDOW (dialog),
6329 helper = g_slice_new0 (MoveToInfo);
6330 helper->list = list_to_move;
6333 /* Listen to response signal */
6334 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6336 /* Show the dialog */
6337 gtk_widget_show (dialog);
6343 * Calls #HeadersFunc for each header already selected in the main
6344 * window or the message currently being shown in the msg view window
6347 do_headers_action (ModestWindow *win,
6351 TnyList *headers_list = NULL;
6352 TnyIterator *iter = NULL;
6353 TnyHeader *header = NULL;
6354 TnyFolder *folder = NULL;
6357 headers_list = get_selected_headers (win);
6361 /* Get the folder */
6362 iter = tny_list_create_iterator (headers_list);
6363 header = TNY_HEADER (tny_iterator_get_current (iter));
6365 folder = tny_header_get_folder (header);
6366 g_object_unref (header);
6369 /* Call the function for each header */
6370 while (!tny_iterator_is_done (iter)) {
6371 header = TNY_HEADER (tny_iterator_get_current (iter));
6372 func (header, win, user_data);
6373 g_object_unref (header);
6374 tny_iterator_next (iter);
6377 /* Trick: do a poke status in order to speed up the signaling
6380 tny_folder_poke_status (folder);
6381 g_object_unref (folder);
6385 g_object_unref (iter);
6386 g_object_unref (headers_list);
6390 modest_ui_actions_view_attachment (GtkAction *action,
6391 ModestWindow *window)
6393 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6394 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6396 /* not supported window for this action */
6397 g_return_if_reached ();
6402 modest_ui_actions_save_attachments (GtkAction *action,
6403 ModestWindow *window)
6405 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6407 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6410 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6412 /* not supported window for this action */
6413 g_return_if_reached ();
6418 modest_ui_actions_remove_attachments (GtkAction *action,
6419 ModestWindow *window)
6421 if (MODEST_IS_MAIN_WINDOW (window)) {
6422 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6423 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6424 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6426 /* not supported window for this action */
6427 g_return_if_reached ();
6432 modest_ui_actions_on_settings (GtkAction *action,
6437 dialog = modest_platform_get_global_settings_dialog ();
6438 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6439 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6440 gtk_widget_show_all (dialog);
6442 gtk_dialog_run (GTK_DIALOG (dialog));
6444 gtk_widget_destroy (dialog);
6448 modest_ui_actions_on_help (GtkAction *action,
6451 /* Help app is not available at all in fremantle */
6452 #ifndef MODEST_TOOLKIT_HILDON2
6453 const gchar *help_id;
6455 g_return_if_fail (win && GTK_IS_WINDOW(win));
6457 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6460 modest_platform_show_help (GTK_WINDOW (win), help_id);
6465 modest_ui_actions_on_csm_help (GtkAction *action,
6468 /* Help app is not available at all in fremantle */
6469 #ifndef MODEST_TOOLKIT_HILDON2
6471 const gchar* help_id = NULL;
6472 GtkWidget *folder_view;
6473 TnyFolderStore *folder_store;
6475 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6477 /* Get selected folder */
6478 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6479 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6480 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6482 /* Switch help_id */
6483 if (folder_store && TNY_IS_FOLDER (folder_store))
6484 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6487 g_object_unref (folder_store);
6490 modest_platform_show_help (GTK_WINDOW (win), help_id);
6492 modest_ui_actions_on_help (action, win);
6497 retrieve_contents_cb (ModestMailOperation *mail_op,
6504 /* We only need this callback to show an error in case of
6505 memory low condition */
6506 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6507 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6512 retrieve_msg_contents_performer (gboolean canceled,
6514 GtkWindow *parent_window,
6515 TnyAccount *account,
6518 ModestMailOperation *mail_op;
6519 TnyList *headers = TNY_LIST (user_data);
6521 if (err || canceled) {
6522 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6523 (GtkWidget *) parent_window, err,
6528 /* Create mail operation */
6529 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6530 modest_ui_actions_disk_operations_error_handler,
6532 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6533 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6536 g_object_unref (mail_op);
6538 g_object_unref (headers);
6539 g_object_unref (account);
6543 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6544 ModestWindow *window)
6546 TnyList *headers = NULL;
6547 TnyAccount *account = NULL;
6548 TnyIterator *iter = NULL;
6549 TnyHeader *header = NULL;
6550 TnyFolder *folder = NULL;
6553 headers = get_selected_headers (window);
6557 /* Pick the account */
6558 iter = tny_list_create_iterator (headers);
6559 header = TNY_HEADER (tny_iterator_get_current (iter));
6560 folder = tny_header_get_folder (header);
6561 account = tny_folder_get_account (folder);
6562 g_object_unref (folder);
6563 g_object_unref (header);
6564 g_object_unref (iter);
6566 /* Connect and perform the message retrieval */
6567 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6568 g_object_ref (account),
6569 retrieve_msg_contents_performer,
6570 g_object_ref (headers));
6573 g_object_unref (account);
6574 g_object_unref (headers);
6578 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6580 g_return_if_fail (MODEST_IS_WINDOW (window));
6583 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6587 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6589 g_return_if_fail (MODEST_IS_WINDOW (window));
6592 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6596 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6597 ModestWindow *window)
6599 g_return_if_fail (MODEST_IS_WINDOW (window));
6602 modest_ui_actions_check_menu_dimming_rules (window);
6606 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6607 ModestWindow *window)
6609 g_return_if_fail (MODEST_IS_WINDOW (window));
6612 modest_ui_actions_check_menu_dimming_rules (window);
6616 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6617 ModestWindow *window)
6619 g_return_if_fail (MODEST_IS_WINDOW (window));
6622 modest_ui_actions_check_menu_dimming_rules (window);
6626 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6627 ModestWindow *window)
6629 g_return_if_fail (MODEST_IS_WINDOW (window));
6632 modest_ui_actions_check_menu_dimming_rules (window);
6636 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6637 ModestWindow *window)
6639 g_return_if_fail (MODEST_IS_WINDOW (window));
6642 modest_ui_actions_check_menu_dimming_rules (window);
6646 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6647 ModestWindow *window)
6649 g_return_if_fail (MODEST_IS_WINDOW (window));
6652 modest_ui_actions_check_menu_dimming_rules (window);
6656 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6657 ModestWindow *window)
6659 g_return_if_fail (MODEST_IS_WINDOW (window));
6662 modest_ui_actions_check_menu_dimming_rules (window);
6666 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6667 ModestWindow *window)
6669 g_return_if_fail (MODEST_IS_WINDOW (window));
6672 modest_ui_actions_check_menu_dimming_rules (window);
6676 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6677 ModestWindow *window)
6679 g_return_if_fail (MODEST_IS_WINDOW (window));
6682 modest_ui_actions_check_menu_dimming_rules (window);
6686 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6688 g_return_if_fail (MODEST_IS_WINDOW (window));
6690 /* we check for low-mem; in that case, show a warning, and don't allow
6693 if (modest_platform_check_memory_low (window, TRUE))
6696 modest_platform_show_search_messages (GTK_WINDOW (window));
6700 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6702 g_return_if_fail (MODEST_IS_WINDOW (win));
6705 /* we check for low-mem; in that case, show a warning, and don't allow
6706 * for the addressbook
6708 if (modest_platform_check_memory_low (win, TRUE))
6712 modest_platform_show_addressbook (GTK_WINDOW (win));
6717 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6718 ModestWindow *window)
6721 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6723 if (GTK_IS_TOGGLE_ACTION (action))
6724 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6728 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6733 on_send_receive_finished (ModestMailOperation *mail_op,
6736 GtkWidget *header_view, *folder_view;
6737 TnyFolderStore *folder_store;
6738 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6740 /* Set send/receive operation finished */
6741 modest_main_window_notify_send_receive_completed (main_win);
6743 /* Don't refresh the current folder if there were any errors */
6744 if (modest_mail_operation_get_status (mail_op) !=
6745 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6748 /* Refresh the current folder if we're viewing a window. We do
6749 this because the user won't be able to see the new mails in
6750 the selected folder after a Send&Receive because it only
6751 performs a poke_status, i.e, only the number of read/unread
6752 messages is updated, but the new headers are not
6754 folder_view = modest_main_window_get_child_widget (main_win,
6755 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6759 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6761 /* Do not need to refresh INBOX again because the
6762 update_account does it always automatically */
6763 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6764 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6765 ModestMailOperation *refresh_op;
6767 header_view = modest_main_window_get_child_widget (main_win,
6768 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6770 /* We do not need to set the contents style
6771 because it hasn't changed. We also do not
6772 need to save the widget status. Just force
6774 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6775 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6776 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6777 folder_refreshed_cb, main_win);
6778 g_object_unref (refresh_op);
6782 g_object_unref (folder_store);
6787 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6793 const gchar* server_name = NULL;
6794 TnyTransportAccount *transport;
6795 gchar *message = NULL;
6796 ModestProtocol *protocol;
6798 /* Don't show anything if the user cancelled something or the
6799 * send receive request is not interactive. Authentication
6800 * errors are managed by the account store so no need to show
6801 * a dialog here again */
6802 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6803 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6804 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6808 /* Get the server name. Note that we could be using a
6809 connection specific transport account */
6810 transport = (TnyTransportAccount *)
6811 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6813 ModestTnyAccountStore *acc_store;
6814 const gchar *acc_name;
6815 TnyTransportAccount *conn_specific;
6817 acc_store = modest_runtime_get_account_store();
6818 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6819 conn_specific = (TnyTransportAccount *)
6820 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6821 if (conn_specific) {
6822 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6823 g_object_unref (conn_specific);
6825 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6827 g_object_unref (transport);
6831 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6832 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6833 tny_account_get_proto (TNY_ACCOUNT (transport)));
6835 g_warning ("%s: Account with no proto", __FUNCTION__);
6839 /* Show the appropriate message text for the GError: */
6840 switch (err->code) {
6841 case TNY_SERVICE_ERROR_CONNECT:
6842 message = modest_protocol_get_translation (protocol,
6843 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6846 case TNY_SERVICE_ERROR_SEND:
6847 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6849 case TNY_SERVICE_ERROR_UNAVAILABLE:
6850 message = modest_protocol_get_translation (protocol,
6851 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6855 g_warning ("%s: unexpected ERROR %d",
6856 __FUNCTION__, err->code);
6857 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6861 modest_platform_run_information_dialog (NULL, message, FALSE);
6866 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6871 ModestWindow *top_window = NULL;
6872 ModestWindowMgr *mgr = NULL;
6873 GtkWidget *header_view = NULL;
6874 TnyFolder *selected_folder = NULL;
6875 TnyFolderType folder_type;
6877 mgr = modest_runtime_get_window_mgr ();
6878 top_window = modest_window_mgr_get_current_top (mgr);
6883 #ifndef MODEST_TOOLKIT_HILDON2
6884 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6885 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6886 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6889 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6890 header_view = (GtkWidget *)
6891 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6895 /* Get selected folder */
6897 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6898 if (!selected_folder)
6901 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6902 #if GTK_CHECK_VERSION(2, 8, 0)
6903 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6904 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6905 GtkTreeViewColumn *tree_column;
6907 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6908 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6910 gtk_tree_view_column_queue_resize (tree_column);
6912 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6913 gtk_widget_queue_draw (header_view);
6916 #ifndef MODEST_TOOLKIT_HILDON2
6917 /* Rerun dimming rules, because the message could become deletable for example */
6918 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6919 MODEST_DIMMING_RULES_TOOLBAR);
6920 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6921 MODEST_DIMMING_RULES_MENU);
6925 g_object_unref (selected_folder);
6929 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6930 TnyAccount *account)
6932 ModestProtocolType protocol_type;
6933 ModestProtocol *protocol;
6934 gchar *error_note = NULL;
6936 protocol_type = modest_tny_account_get_protocol_type (account);
6937 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6940 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6941 if (error_note == NULL) {
6942 g_warning ("%s: This should not be reached", __FUNCTION__);
6944 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6945 g_free (error_note);
6950 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6954 TnyFolderStore *folder = NULL;
6955 TnyAccount *account = NULL;
6956 ModestProtocolType proto;
6957 ModestProtocol *protocol;
6958 TnyHeader *header = NULL;
6960 if (MODEST_IS_MAIN_WINDOW (win)) {
6961 GtkWidget *header_view;
6962 TnyList* headers = NULL;
6964 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6965 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6966 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6967 if (!headers || tny_list_get_length (headers) == 0) {
6969 g_object_unref (headers);
6972 iter = tny_list_create_iterator (headers);
6973 header = TNY_HEADER (tny_iterator_get_current (iter));
6974 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6975 g_object_unref (iter);
6976 g_object_unref (headers);
6977 #ifdef MODEST_TOOLKIT_HILDON2
6978 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6979 GtkWidget *header_view;
6980 TnyList* headers = NULL;
6982 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6983 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6984 if (!headers || tny_list_get_length (headers) == 0) {
6986 g_object_unref (headers);
6989 iter = tny_list_create_iterator (headers);
6990 header = TNY_HEADER (tny_iterator_get_current (iter));
6992 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6994 g_warning ("List should contain headers");
6996 g_object_unref (iter);
6997 g_object_unref (headers);
6999 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7000 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7002 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7005 if (!header || !folder)
7008 /* Get the account type */
7009 account = tny_folder_get_account (TNY_FOLDER (folder));
7010 proto = modest_tny_account_get_protocol_type (account);
7011 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7014 subject = tny_header_dup_subject (header);
7015 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7019 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7025 g_object_unref (account);
7027 g_object_unref (folder);
7029 g_object_unref (header);
7035 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7036 const gchar *account_name,
7037 const gchar *account_title)
7039 ModestAccountMgr *account_mgr;
7042 ModestProtocol *protocol;
7043 gboolean removed = FALSE;
7045 g_return_val_if_fail (account_name, FALSE);
7046 g_return_val_if_fail (account_title, FALSE);
7048 account_mgr = modest_runtime_get_account_mgr();
7050 /* The warning text depends on the account type: */
7051 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7052 modest_account_mgr_get_store_protocol (account_mgr,
7054 txt = modest_protocol_get_translation (protocol,
7055 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7058 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7060 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7064 if (response == GTK_RESPONSE_OK) {
7065 /* Remove account. If it succeeds then it also removes
7066 the account from the ModestAccountView: */
7067 gboolean is_default = FALSE;
7068 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7069 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7071 g_free (default_account_name);
7073 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7075 #ifdef MODEST_TOOLKIT_HILDON2
7076 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7078 /* Close all email notifications, we cannot
7079 distinguish if the notification belongs to
7080 this account or not, so for safety reasons
7081 we remove them all */
7082 modest_platform_remove_new_mail_notifications (FALSE);
7084 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7091 on_fetch_images_performer (gboolean canceled,
7093 GtkWindow *parent_window,
7094 TnyAccount *account,
7097 if (err || canceled) {
7098 /* Show an unable to retrieve images ??? */
7102 /* Note that the user could have closed the window while connecting */
7103 if (GTK_WIDGET_VISIBLE (parent_window))
7104 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7105 g_object_unref ((GObject *) user_data);
7109 modest_ui_actions_on_fetch_images (GtkAction *action,
7110 ModestWindow *window)
7112 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7114 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7116 on_fetch_images_performer,
7117 g_object_ref (window));
7121 modest_ui_actions_on_reload_message (const gchar *msg_id)
7123 ModestWindow *window = NULL;
7125 g_return_if_fail (msg_id && msg_id[0] != '\0');
7126 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7132 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7135 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7138 /** Check whether any connections are active, and cancel them if
7140 * Returns TRUE is there was no problem,
7141 * or if an operation was cancelled so we can continue.
7142 * Returns FALSE if the user chose to cancel his request instead.
7146 modest_ui_actions_check_for_active_account (ModestWindow *self,
7147 const gchar* account_name)
7149 ModestTnySendQueue *send_queue;
7150 ModestTnyAccountStore *acc_store;
7151 ModestMailOperationQueue* queue;
7152 TnyConnectionStatus store_conn_status;
7153 TnyAccount *store_account = NULL, *transport_account = NULL;
7154 gboolean retval = TRUE, sending = FALSE;
7156 acc_store = modest_runtime_get_account_store ();
7157 queue = modest_runtime_get_mail_operation_queue ();
7160 modest_tny_account_store_get_server_account (acc_store,
7162 TNY_ACCOUNT_TYPE_STORE);
7164 /* This could happen if the account was deleted before the
7165 call to this function */
7170 modest_tny_account_store_get_server_account (acc_store,
7172 TNY_ACCOUNT_TYPE_TRANSPORT);
7174 /* This could happen if the account was deleted before the
7175 call to this function */
7176 if (!transport_account) {
7177 g_object_unref (store_account);
7181 /* If the transport account was not used yet, then the send
7182 queue could not exist (it's created on demand) */
7183 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7184 if (TNY_IS_SEND_QUEUE (send_queue))
7185 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7187 store_conn_status = tny_account_get_connection_status (store_account);
7188 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7191 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7192 _("emev_nc_disconnect_account"));
7193 if (response == GTK_RESPONSE_OK) {
7202 /* FIXME: We should only cancel those of this account */
7203 modest_mail_operation_queue_cancel_all (queue);
7205 /* Also disconnect the account */
7206 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7207 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7208 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7212 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7218 g_object_unref (store_account);
7219 g_object_unref (transport_account);