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 (gtk_style_lookup_color (GTK_WIDGET (win)->style, "SecondaryTextColor", &color))
911 gray_color_markup = modest_text_utils_get_color_string (&color);
912 if (!gray_color_markup)
913 gray_color_markup = g_strdup ("#999999");
915 color_begin = g_strdup_printf ("<font color=\"%s\">", gray_color_markup);
916 color_end = "</font>";
918 body = use_signature ? g_strconcat("<br/>\n", color_begin,
919 MODEST_TEXT_UTILS_SIGNATURE_MARKER, "<br/>\n",
920 signature, color_end, NULL) : g_strdup("");
922 g_free (gray_color_markup);
923 g_free (color_begin);
926 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
927 NULL, NULL, body, NULL, NULL, NULL, NULL, NULL);
929 g_printerr ("modest: failed to create new msg\n");
933 /* Create and register edit window */
934 /* This is destroyed by TODO. */
936 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
937 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
939 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
940 gtk_widget_destroy (GTK_WIDGET (msg_win));
943 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
944 gtk_widget_show_all (GTK_WIDGET (msg_win));
946 while (attachments) {
947 GnomeVFSFileSize att_size;
949 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
950 attachments->data, allowed_size);
951 total_size += att_size;
953 if (att_size > allowed_size) {
954 g_debug ("%s: total size: %u",
955 __FUNCTION__, (unsigned int)total_size);
958 allowed_size -= att_size;
960 attachments = g_slist_next(attachments);
967 g_free (account_name);
969 g_object_unref (G_OBJECT(account));
971 g_object_unref (G_OBJECT(folder));
973 g_object_unref (G_OBJECT(msg));
977 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
979 /* if there are no accounts yet, just show the wizard */
980 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
981 if (!modest_ui_actions_run_account_setup_wizard (win))
984 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
989 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
993 ModestMailOperationStatus status;
995 /* If there is no message or the operation was not successful */
996 status = modest_mail_operation_get_status (mail_op);
997 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
1000 /* If it's a memory low issue, then show a banner */
1001 error = modest_mail_operation_get_error (mail_op);
1002 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
1003 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
1004 GObject *source = modest_mail_operation_get_source (mail_op);
1005 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
1006 _KR("memr_ib_operation_disabled"),
1008 g_object_unref (source);
1011 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
1012 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
1013 gchar *subject, *msg, *format = NULL;
1014 TnyAccount *account;
1016 subject = (header) ? tny_header_dup_subject (header) : NULL;
1018 subject = g_strdup (_("mail_va_no_subject"));
1020 account = modest_mail_operation_get_account (mail_op);
1022 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1023 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1026 if (tny_account_get_connection_status (account) ==
1027 TNY_CONNECTION_STATUS_CONNECTED) {
1029 format = modest_protocol_get_translation (protocol,
1030 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1033 format = modest_protocol_get_translation (protocol,
1034 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1037 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1038 tny_account_get_hostname (account));
1041 g_object_unref (account);
1046 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1048 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1052 msg = g_strdup_printf (format, subject);
1053 modest_platform_run_information_dialog (NULL, msg, FALSE);
1059 /* Remove the header from the preregistered uids */
1060 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1073 } OpenMsgBannerInfo;
1076 GtkTreeModel *model;
1078 ModestWindow *caller_window;
1079 OpenMsgBannerInfo *banner_info;
1080 GtkTreeRowReference *rowref;
1084 open_msg_banner_idle (gpointer userdata)
1086 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1088 gdk_threads_enter ();
1089 banner_info->idle_handler = 0;
1090 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1091 if (banner_info->banner)
1092 g_object_ref (banner_info->banner);
1094 gdk_threads_leave ();
1100 get_header_view_from_window (ModestWindow *window)
1102 GtkWidget *header_view;
1104 if (MODEST_IS_MAIN_WINDOW (window)) {
1105 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1106 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1107 #ifdef MODEST_TOOLKIT_HILDON2
1108 } else if (MODEST_IS_HEADER_WINDOW (window)){
1109 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1119 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1122 gchar *account = NULL;
1123 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1128 folder = tny_header_get_folder (header);
1129 /* Gets folder type (OUTBOX headers will be opened in edit window */
1130 if (modest_tny_folder_is_local_folder (folder)) {
1131 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1132 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1133 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1136 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1137 TnyTransportAccount *traccount = NULL;
1138 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1139 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1141 ModestTnySendQueue *send_queue = NULL;
1142 ModestTnySendQueueStatus status;
1144 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1145 TNY_ACCOUNT(traccount)));
1146 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1147 if (TNY_IS_SEND_QUEUE (send_queue)) {
1148 msg_id = modest_tny_send_queue_get_msg_id (header);
1149 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1151 /* Only open messages in outbox with the editor if they are in Failed state */
1152 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1155 #ifdef MODEST_TOOLKIT_HILDON2
1157 /* In Fremantle we can not
1158 open any message from
1159 outbox which is not in
1165 g_object_unref(traccount);
1167 g_warning("Cannot get transport account for message in outbox!!");
1169 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1170 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1174 TnyAccount *acc = tny_folder_get_account (folder);
1177 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1178 g_object_unref (acc);
1182 g_object_unref (folder);
1188 open_msg_cb (ModestMailOperation *mail_op,
1195 ModestWindowMgr *mgr = NULL;
1196 ModestWindow *parent_win = NULL;
1197 ModestWindow *win = NULL;
1198 gchar *account = NULL;
1199 gboolean open_in_editor = FALSE;
1201 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1203 /* Do nothing if there was any problem with the mail
1204 operation. The error will be shown by the error_handler of
1205 the mail operation */
1206 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1209 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1211 /* Mark header as read */
1212 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1214 account = get_info_from_header (header, &open_in_editor, &can_open);
1218 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1220 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1222 if (open_in_editor) {
1223 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1224 gchar *from_header = NULL, *acc_name;
1225 gchar *mailbox = NULL;
1227 from_header = tny_header_dup_from (header);
1229 /* we cannot edit without a valid account... */
1230 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1231 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1232 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1234 g_free (from_header);
1239 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1240 g_free (from_header);
1246 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1250 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1251 const gchar *mailbox = NULL;
1253 if (parent_win && MODEST_IS_WINDOW (parent_win))
1254 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1256 if (helper->rowref && helper->model) {
1257 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1258 helper->model, helper->rowref);
1260 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1265 /* Register and show new window */
1267 mgr = modest_runtime_get_window_mgr ();
1268 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1269 gtk_widget_destroy (GTK_WIDGET (win));
1272 gtk_widget_show_all (GTK_WIDGET(win));
1275 /* Update toolbar dimming state */
1276 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1277 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1283 g_object_unref (parent_win);
1287 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1290 const GError *error;
1291 GObject *win = NULL;
1292 ModestMailOperationStatus status;
1294 win = modest_mail_operation_get_source (mail_op);
1295 error = modest_mail_operation_get_error (mail_op);
1296 status = modest_mail_operation_get_status (mail_op);
1298 /* If the mail op has been cancelled then it's not an error:
1299 don't show any message */
1300 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1301 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1302 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1303 (GError *) error, account)) {
1304 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1305 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1307 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1308 modest_platform_information_banner ((GtkWidget *) win,
1309 NULL, _("emev_ui_imap_inbox_select_error"));
1310 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1311 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1312 modest_platform_information_banner ((GtkWidget *) win,
1313 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1314 } else if (user_data) {
1315 modest_platform_information_banner ((GtkWidget *) win,
1319 g_object_unref (account);
1323 g_object_unref (win);
1327 * Returns the account a list of headers belongs to. It returns a
1328 * *new* reference so don't forget to unref it
1331 get_account_from_header_list (TnyList *headers)
1333 TnyAccount *account = NULL;
1335 if (tny_list_get_length (headers) > 0) {
1336 TnyIterator *iter = tny_list_create_iterator (headers);
1337 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1338 TnyFolder *folder = tny_header_get_folder (header);
1341 g_object_unref (header);
1343 while (!tny_iterator_is_done (iter)) {
1344 header = TNY_HEADER (tny_iterator_get_current (iter));
1345 folder = tny_header_get_folder (header);
1348 g_object_unref (header);
1350 tny_iterator_next (iter);
1355 account = tny_folder_get_account (folder);
1356 g_object_unref (folder);
1360 g_object_unref (header);
1362 g_object_unref (iter);
1368 get_account_from_header (TnyHeader *header)
1370 TnyAccount *account = NULL;
1373 folder = tny_header_get_folder (header);
1376 account = tny_folder_get_account (folder);
1377 g_object_unref (folder);
1383 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1385 if (helper->caller_window)
1386 helper->caller_window = NULL;
1390 open_msg_helper_destroyer (gpointer user_data)
1392 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1394 if (helper->caller_window) {
1395 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1396 helper->caller_window = NULL;
1399 if (helper->banner_info) {
1400 g_free (helper->banner_info->message);
1401 if (helper->banner_info->idle_handler > 0) {
1402 g_source_remove (helper->banner_info->idle_handler);
1403 helper->banner_info->idle_handler = 0;
1405 if (helper->banner_info->banner != NULL) {
1406 gtk_widget_destroy (helper->banner_info->banner);
1407 g_object_unref (helper->banner_info->banner);
1408 helper->banner_info->banner = NULL;
1410 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1411 helper->banner_info = NULL;
1413 g_object_unref (helper->model);
1414 g_object_unref (helper->header);
1415 gtk_tree_row_reference_free (helper->rowref);
1416 g_slice_free (OpenMsgHelper, helper);
1420 open_msg_performer(gboolean canceled,
1422 GtkWindow *parent_window,
1423 TnyAccount *account,
1426 ModestMailOperation *mail_op = NULL;
1427 gchar *error_msg = NULL;
1428 ModestProtocolType proto;
1429 TnyConnectionStatus status;
1430 OpenMsgHelper *helper = NULL;
1431 ModestProtocol *protocol;
1432 ModestProtocolRegistry *protocol_registry;
1435 helper = (OpenMsgHelper *) user_data;
1437 status = tny_account_get_connection_status (account);
1438 if (err || canceled || helper->caller_window == NULL) {
1439 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1440 /* Free the helper */
1441 open_msg_helper_destroyer (helper);
1443 /* In disk full conditions we could get this error here */
1444 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1445 (GtkWidget *) parent_window, err,
1451 /* Get the error message depending on the protocol */
1452 proto = modest_tny_account_get_protocol_type (account);
1453 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1454 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1457 protocol_registry = modest_runtime_get_protocol_registry ();
1458 subject = tny_header_dup_subject (helper->header);
1460 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1461 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1465 if (error_msg == NULL) {
1466 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1469 #ifndef MODEST_TOOLKIT_HILDON2
1470 gboolean show_open_draft = FALSE;
1471 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1473 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1475 TnyFolderType folder_type;
1477 folder = tny_header_get_folder (helper->header);
1478 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1479 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1480 g_object_unref (folder);
1484 #ifdef MODEST_TOOLKIT_HILDON2
1487 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1490 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1491 g_free (account_name);
1492 open_msg_helper_destroyer (helper);
1497 ModestWindow *window;
1498 GtkWidget *header_view;
1501 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1502 uid = modest_tny_folder_get_header_unique_id (helper->header);
1504 const gchar *mailbox = NULL;
1505 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1506 window = modest_msg_view_window_new_from_header_view
1507 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1508 if (window != NULL) {
1509 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1511 gtk_widget_destroy (GTK_WIDGET (window));
1513 gtk_widget_show_all (GTK_WIDGET(window));
1517 g_free (account_name);
1519 open_msg_helper_destroyer (helper);
1522 g_free (account_name);
1524 /* Create the mail operation */
1526 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1527 modest_ui_actions_disk_operations_error_handler,
1528 g_strdup (error_msg), g_free);
1529 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1533 #ifndef MODEST_TOOLKIT_HILDON2
1534 if (show_open_draft) {
1535 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1536 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1537 helper->banner_info->banner = NULL;
1538 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1539 helper->banner_info);
1545 headers = TNY_LIST (tny_simple_list_new ());
1546 tny_list_prepend (headers, G_OBJECT (helper->header));
1547 modest_mail_operation_get_msgs_full (mail_op,
1551 open_msg_helper_destroyer);
1552 g_object_unref (headers);
1559 g_object_unref (mail_op);
1560 g_object_unref (account);
1564 * This function is used by both modest_ui_actions_on_open and
1565 * modest_ui_actions_on_header_activated. This way we always do the
1566 * same when trying to open messages.
1569 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1571 ModestWindowMgr *mgr = NULL;
1572 TnyAccount *account;
1573 gboolean cached = FALSE;
1575 GtkWidget *header_view = NULL;
1576 OpenMsgHelper *helper;
1577 ModestWindow *window;
1579 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1581 mgr = modest_runtime_get_window_mgr ();
1584 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1585 if (header_view == NULL)
1588 /* Get the account */
1589 account = get_account_from_header (header);
1594 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1596 /* Do not open again the message and present the
1597 window to the user */
1600 #ifndef MODEST_TOOLKIT_HILDON2
1601 gtk_window_present (GTK_WINDOW (window));
1604 /* the header has been registered already, we don't do
1605 * anything but wait for the window to come up*/
1606 g_debug ("header %p already registered, waiting for window", header);
1611 /* Open each message */
1612 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1614 /* Allways download if we are online. */
1615 if (!tny_device_is_online (modest_runtime_get_device ())) {
1618 /* If ask for user permission to download the messages */
1619 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1620 _("mcen_nc_get_msg"));
1622 /* End if the user does not want to continue */
1623 if (response == GTK_RESPONSE_CANCEL) {
1629 /* We register the window for opening */
1630 modest_window_mgr_register_header (mgr, header, NULL);
1632 /* Create the helper. We need to get a reference to the model
1633 here because it could change while the message is readed
1634 (the user could switch between folders) */
1635 helper = g_slice_new (OpenMsgHelper);
1636 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1637 helper->caller_window = win;
1638 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1639 helper->header = g_object_ref (header);
1640 helper->rowref = gtk_tree_row_reference_copy (rowref);
1641 helper->banner_info = NULL;
1643 /* Connect to the account and perform */
1645 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1646 open_msg_performer, helper);
1648 /* Call directly the performer, do not need to connect */
1649 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1650 g_object_ref (account), helper);
1655 g_object_unref (account);
1659 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1666 /* we check for low-mem; in that case, show a warning, and don't allow
1669 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1673 headers = get_selected_headers (win);
1677 headers_count = tny_list_get_length (headers);
1678 if (headers_count != 1) {
1679 if (headers_count > 1) {
1680 /* Don't allow activation if there are more than one message selected */
1681 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1684 g_object_unref (headers);
1688 iter = tny_list_create_iterator (headers);
1689 header = TNY_HEADER (tny_iterator_get_current (iter));
1690 g_object_unref (iter);
1694 open_msg_from_header (header, NULL, win);
1695 g_object_unref (header);
1698 g_object_unref(headers);
1702 rf_helper_window_closed (gpointer data,
1705 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1707 helper->parent_window = NULL;
1710 static ReplyForwardHelper*
1711 create_reply_forward_helper (ReplyForwardAction action,
1713 guint reply_forward_type,
1717 ReplyForwardHelper *rf_helper = NULL;
1718 const gchar *active_acc = modest_window_get_active_account (win);
1719 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1721 rf_helper = g_slice_new0 (ReplyForwardHelper);
1722 rf_helper->reply_forward_type = reply_forward_type;
1723 rf_helper->action = action;
1724 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1725 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1726 rf_helper->account_name = (active_acc) ?
1727 g_strdup (active_acc) :
1728 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1729 rf_helper->mailbox = g_strdup (active_mailbox);
1731 rf_helper->parts = g_object_ref (parts);
1733 rf_helper->parts = NULL;
1735 /* Note that window could be destroyed just AFTER calling
1736 register_window so we must ensure that this pointer does
1737 not hold invalid references */
1738 if (rf_helper->parent_window)
1739 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1740 rf_helper_window_closed, rf_helper);
1746 free_reply_forward_helper (gpointer data)
1748 ReplyForwardHelper *helper;
1750 helper = (ReplyForwardHelper *) data;
1751 g_free (helper->account_name);
1752 g_free (helper->mailbox);
1754 g_object_unref (helper->header);
1756 g_object_unref (helper->parts);
1757 if (helper->parent_window)
1758 g_object_weak_unref (G_OBJECT (helper->parent_window),
1759 rf_helper_window_closed, helper);
1760 g_slice_free (ReplyForwardHelper, helper);
1764 reply_forward_cb (ModestMailOperation *mail_op,
1771 TnyMsg *new_msg = NULL;
1772 ReplyForwardHelper *rf_helper;
1773 ModestWindow *msg_win = NULL;
1774 ModestEditType edit_type;
1776 TnyAccount *account = NULL;
1777 ModestWindowMgr *mgr = NULL;
1778 gchar *signature = NULL;
1779 gboolean use_signature;
1782 /* If there was any error. The mail operation could be NULL,
1783 this means that we already have the message downloaded and
1784 that we didn't do a mail operation to retrieve it */
1785 rf_helper = (ReplyForwardHelper *) user_data;
1786 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1789 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1790 rf_helper->account_name, rf_helper->mailbox);
1791 recipient = modest_text_utils_get_email_address (from);
1792 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1797 /* Create reply mail */
1798 switch (rf_helper->action) {
1799 /* Use the msg_header to ensure that we have all the
1800 information. The summary can lack some data */
1801 TnyHeader *msg_header;
1803 msg_header = tny_msg_get_header (msg);
1805 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1806 (use_signature) ? signature : NULL,
1807 rf_helper->reply_forward_type,
1808 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1809 g_object_unref (msg_header);
1811 case ACTION_REPLY_TO_ALL:
1812 msg_header = tny_msg_get_header (msg);
1814 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1815 (use_signature) ? signature : NULL,
1816 rf_helper->reply_forward_type,
1817 MODEST_TNY_MSG_REPLY_MODE_ALL);
1818 edit_type = MODEST_EDIT_TYPE_REPLY;
1819 g_object_unref (msg_header);
1821 case ACTION_FORWARD:
1823 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1824 rf_helper->reply_forward_type);
1825 edit_type = MODEST_EDIT_TYPE_FORWARD;
1828 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1830 g_return_if_reached ();
1838 g_warning ("%s: failed to create message\n", __FUNCTION__);
1842 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1843 rf_helper->account_name,
1844 TNY_ACCOUNT_TYPE_STORE);
1846 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1850 /* Create and register the windows */
1851 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1852 mgr = modest_runtime_get_window_mgr ();
1853 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1855 /* Note that register_window could have deleted the account */
1856 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1857 gdouble parent_zoom;
1859 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1860 modest_window_set_zoom (msg_win, parent_zoom);
1863 /* Show edit window */
1864 gtk_widget_show_all (GTK_WIDGET (msg_win));
1867 /* We always unregister the header because the message is
1868 forwarded or replied so the original one is no longer
1870 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1873 g_object_unref (G_OBJECT (new_msg));
1875 g_object_unref (G_OBJECT (account));
1876 free_reply_forward_helper (rf_helper);
1879 /* Checks a list of headers. If any of them are not currently
1880 * downloaded (CACHED) then returns TRUE else returns FALSE.
1883 header_list_count_uncached_msgs (TnyList *header_list)
1886 gint uncached_messages = 0;
1888 iter = tny_list_create_iterator (header_list);
1889 while (!tny_iterator_is_done (iter)) {
1892 header = TNY_HEADER (tny_iterator_get_current (iter));
1894 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1895 uncached_messages ++;
1896 g_object_unref (header);
1899 tny_iterator_next (iter);
1901 g_object_unref (iter);
1903 return uncached_messages;
1906 /* Returns FALSE if the user does not want to download the
1907 * messages. Returns TRUE if the user allowed the download.
1910 connect_to_get_msg (ModestWindow *win,
1911 gint num_of_uncached_msgs,
1912 TnyAccount *account)
1914 GtkResponseType response;
1916 /* Allways download if we are online. */
1917 if (tny_device_is_online (modest_runtime_get_device ()))
1920 /* If offline, then ask for user permission to download the messages */
1921 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1922 ngettext("mcen_nc_get_msg",
1924 num_of_uncached_msgs));
1926 if (response == GTK_RESPONSE_CANCEL)
1929 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1933 reply_forward_performer (gboolean canceled,
1935 GtkWindow *parent_window,
1936 TnyAccount *account,
1939 ReplyForwardHelper *rf_helper = NULL;
1940 ModestMailOperation *mail_op;
1942 rf_helper = (ReplyForwardHelper *) user_data;
1944 if (canceled || err) {
1945 free_reply_forward_helper (rf_helper);
1949 /* Retrieve the message */
1950 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1951 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1952 modest_ui_actions_disk_operations_error_handler,
1954 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1955 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1958 g_object_unref(mail_op);
1962 all_parts_retrieved (TnyMimePart *part)
1964 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1967 TnyList *pending_parts;
1968 TnyIterator *iterator;
1969 gboolean all_retrieved = TRUE;
1971 pending_parts = TNY_LIST (tny_simple_list_new ());
1972 tny_mime_part_get_parts (part, pending_parts);
1973 iterator = tny_list_create_iterator (pending_parts);
1974 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1977 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1979 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1980 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1982 all_retrieved = FALSE;
1985 g_object_unref (child);
1986 tny_iterator_next (iterator);
1988 g_object_unref (iterator);
1989 g_object_unref (pending_parts);
1990 return all_retrieved;
1995 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1998 TnyIterator *iterator;
2000 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2001 tny_list_append (list, G_OBJECT (part));
2003 parts = TNY_LIST (tny_simple_list_new ());
2004 tny_mime_part_get_parts (part, parts);
2005 for (iterator = tny_list_create_iterator (parts);
2006 !tny_iterator_is_done (iterator);
2007 tny_iterator_next (iterator)) {
2010 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2011 forward_pending_parts_helper (child, list);
2012 g_object_unref (child);
2014 g_object_unref (iterator);
2015 g_object_unref (parts);
2019 forward_pending_parts (TnyMsg *msg)
2021 TnyList *result = TNY_LIST (tny_simple_list_new ());
2022 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2023 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2030 * Common code for the reply and forward actions
2033 reply_forward (ReplyForwardAction action, ModestWindow *win)
2035 ReplyForwardHelper *rf_helper = NULL;
2036 guint reply_forward_type;
2038 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2040 /* we check for low-mem; in that case, show a warning, and don't allow
2041 * reply/forward (because it could potentially require a lot of memory */
2042 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2046 /* we need an account when editing */
2047 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2048 if (!modest_ui_actions_run_account_setup_wizard (win))
2052 reply_forward_type =
2053 modest_conf_get_int (modest_runtime_get_conf (),
2054 (action == ACTION_FORWARD) ?
2055 MODEST_CONF_FORWARD_TYPE :
2056 MODEST_CONF_REPLY_TYPE,
2059 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2061 TnyHeader *header = NULL;
2062 /* Get header and message. Do not free them here, the
2063 reply_forward_cb must do it */
2064 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2065 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2067 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2069 rf_helper = create_reply_forward_helper (action, win,
2070 reply_forward_type, header, NULL);
2071 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2073 gboolean do_download = TRUE;
2075 if (msg && header && action == ACTION_FORWARD) {
2076 /* Not all parts retrieved. Then we have to retrieve them all before
2077 * creating the forward message */
2078 if (!tny_device_is_online (modest_runtime_get_device ())) {
2081 /* If ask for user permission to download the messages */
2082 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2083 ngettext("mcen_nc_get_msg",
2087 /* End if the user does not want to continue */
2088 if (response == GTK_RESPONSE_CANCEL)
2089 do_download = FALSE;
2093 TnyList *pending_parts;
2095 TnyAccount *account;
2098 pending_parts = forward_pending_parts (msg);
2099 rf_helper = create_reply_forward_helper (action, win,
2100 reply_forward_type, header, pending_parts);
2101 g_object_unref (pending_parts);
2103 folder = tny_header_get_folder (header);
2104 account = tny_folder_get_account (folder);
2105 modest_platform_connect_and_perform (GTK_WINDOW (win),
2107 reply_forward_performer,
2109 g_object_unref (folder);
2110 g_object_unref (account);
2114 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2119 g_object_unref (msg);
2121 g_object_unref (header);
2123 TnyHeader *header = NULL;
2125 gboolean do_retrieve = TRUE;
2126 TnyList *header_list = NULL;
2128 header_list = get_selected_headers (win);
2131 /* Check that only one message is selected for replying */
2132 if (tny_list_get_length (header_list) != 1) {
2133 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2134 NULL, _("mcen_ib_select_one_message"));
2135 g_object_unref (header_list);
2139 /* Only reply/forward to one message */
2140 iter = tny_list_create_iterator (header_list);
2141 header = TNY_HEADER (tny_iterator_get_current (iter));
2142 g_object_unref (iter);
2144 /* Retrieve messages */
2145 do_retrieve = (action == ACTION_FORWARD) ||
2146 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2149 TnyAccount *account = NULL;
2150 TnyFolder *folder = NULL;
2151 gdouble download = TRUE;
2152 guint uncached_msgs = 0;
2154 folder = tny_header_get_folder (header);
2156 goto do_retrieve_frees;
2157 account = tny_folder_get_account (folder);
2159 goto do_retrieve_frees;
2161 uncached_msgs = header_list_count_uncached_msgs (header_list);
2163 if (uncached_msgs > 0) {
2164 /* Allways download if we are online. */
2165 if (!tny_device_is_online (modest_runtime_get_device ())) {
2168 /* If ask for user permission to download the messages */
2169 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2170 ngettext("mcen_nc_get_msg",
2174 /* End if the user does not want to continue */
2175 if (response == GTK_RESPONSE_CANCEL)
2182 rf_helper = create_reply_forward_helper (action, win,
2183 reply_forward_type, header, NULL);
2184 if (uncached_msgs > 0) {
2185 modest_platform_connect_and_perform (GTK_WINDOW (win),
2187 reply_forward_performer,
2190 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2191 account, rf_helper);
2196 g_object_unref (account);
2198 g_object_unref (folder);
2200 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2203 g_object_unref (header_list);
2204 g_object_unref (header);
2209 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2211 g_return_if_fail (MODEST_IS_WINDOW(win));
2213 reply_forward (ACTION_REPLY, win);
2217 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2219 g_return_if_fail (MODEST_IS_WINDOW(win));
2221 reply_forward (ACTION_FORWARD, win);
2225 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2227 g_return_if_fail (MODEST_IS_WINDOW(win));
2229 reply_forward (ACTION_REPLY_TO_ALL, win);
2233 modest_ui_actions_on_next (GtkAction *action,
2234 ModestWindow *window)
2236 if (MODEST_IS_MAIN_WINDOW (window)) {
2237 GtkWidget *header_view;
2239 header_view = modest_main_window_get_child_widget (
2240 MODEST_MAIN_WINDOW(window),
2241 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2245 modest_header_view_select_next (
2246 MODEST_HEADER_VIEW(header_view));
2247 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2248 modest_msg_view_window_select_next_message (
2249 MODEST_MSG_VIEW_WINDOW (window));
2251 g_return_if_reached ();
2256 modest_ui_actions_on_prev (GtkAction *action,
2257 ModestWindow *window)
2259 g_return_if_fail (MODEST_IS_WINDOW(window));
2261 if (MODEST_IS_MAIN_WINDOW (window)) {
2262 GtkWidget *header_view;
2263 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2264 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2268 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2269 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2270 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2272 g_return_if_reached ();
2277 modest_ui_actions_on_sort (GtkAction *action,
2278 ModestWindow *window)
2280 GtkWidget *header_view = NULL;
2282 g_return_if_fail (MODEST_IS_WINDOW(window));
2284 if (MODEST_IS_MAIN_WINDOW (window)) {
2285 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2286 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2287 #ifdef MODEST_TOOLKIT_HILDON2
2288 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2289 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2294 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2299 /* Show sorting dialog */
2300 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2304 sync_folder_cb (ModestMailOperation *mail_op,
2308 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2310 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2311 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2313 /* We must clear first, because otherwise set_folder will ignore */
2314 /* the change as the folders are the same */
2315 modest_header_view_clear (header_view);
2316 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2318 g_object_unref (parent);
2321 g_object_unref (header_view);
2325 idle_refresh_folder (gpointer source)
2327 ModestHeaderView *header_view = NULL;
2329 /* If the window still exists */
2330 if (!GTK_IS_WIDGET (source) ||
2331 !GTK_WIDGET_VISIBLE (source))
2334 /* Refresh the current view */
2335 #ifdef MODEST_TOOLKIT_HILDON2
2336 if (MODEST_IS_HEADER_WINDOW (source))
2337 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2339 if (MODEST_IS_MAIN_WINDOW (source))
2340 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2341 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2344 TnyFolder *folder = modest_header_view_get_folder (header_view);
2346 /* Sync the folder status */
2347 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2348 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2349 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2350 g_object_unref (folder);
2351 g_object_unref (mail_op);
2359 update_account_cb (ModestMailOperation *self,
2360 TnyList *new_headers,
2364 gboolean show_visual_notifications;
2366 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2367 show_visual_notifications = (top) ? FALSE : TRUE;
2369 /* Notify new messages have been downloaded. If the
2370 send&receive was invoked by the user then do not show any
2371 visual notification, only play a sound and activate the LED
2372 (for the Maemo version) */
2373 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2375 /* We only notify about really new messages (not seen) we get */
2376 TnyList *actually_new_list;
2377 TnyIterator *iterator;
2378 actually_new_list = TNY_LIST (tny_simple_list_new ());
2379 for (iterator = tny_list_create_iterator (new_headers);
2380 !tny_iterator_is_done (iterator);
2381 tny_iterator_next (iterator)) {
2383 TnyHeaderFlags flags;
2384 header = TNY_HEADER (tny_iterator_get_current (iterator));
2385 flags = tny_header_get_flags (header);
2387 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2388 /* Messages are ordered from most
2389 recent to oldest. But we want to
2390 show notifications starting from
2391 the oldest message. That's why we
2393 tny_list_prepend (actually_new_list, G_OBJECT (header));
2395 g_object_unref (header);
2397 g_object_unref (iterator);
2399 if (tny_list_get_length (actually_new_list) > 0) {
2400 GList *new_headers_list = NULL;
2402 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2404 /* Send notifications */
2405 if (new_headers_list) {
2406 modest_platform_on_new_headers_received (new_headers_list,
2407 show_visual_notifications);
2409 modest_utils_free_notification_list (new_headers_list);
2412 g_object_unref (actually_new_list);
2416 /* Refresh the current folder in an idle. We do this
2417 in order to avoid refresh cancelations if the
2418 currently viewed folder is the inbox */
2419 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2420 idle_refresh_folder,
2427 TnyAccount *account;
2429 gchar *account_name;
2430 gboolean poke_status;
2431 gboolean interactive;
2432 ModestMailOperation *mail_op;
2436 do_send_receive_performer (gboolean canceled,
2438 GtkWindow *parent_window,
2439 TnyAccount *account,
2442 SendReceiveInfo *info;
2444 info = (SendReceiveInfo *) user_data;
2446 if (err || canceled) {
2447 /* In disk full conditions we could get this error here */
2448 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2449 (GtkWidget *) parent_window, err,
2452 if (info->mail_op) {
2453 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2459 /* Set send/receive operation in progress */
2460 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2461 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2464 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2465 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2466 G_CALLBACK (on_send_receive_finished),
2469 /* Send & receive. */
2470 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2471 update_account_cb, info->win);
2476 g_object_unref (G_OBJECT (info->mail_op));
2477 if (info->account_name)
2478 g_free (info->account_name);
2480 g_object_unref (info->win);
2482 g_object_unref (info->account);
2483 g_slice_free (SendReceiveInfo, info);
2487 * This function performs the send & receive required actions. The
2488 * window is used to create the mail operation. Typically it should
2489 * always be the main window, but we pass it as argument in order to
2493 modest_ui_actions_do_send_receive (const gchar *account_name,
2494 gboolean force_connection,
2495 gboolean poke_status,
2496 gboolean interactive,
2499 gchar *acc_name = NULL;
2500 SendReceiveInfo *info;
2501 ModestTnyAccountStore *acc_store;
2502 TnyAccount *account;
2504 /* If no account name was provided then get the current account, and if
2505 there is no current account then pick the default one: */
2506 if (!account_name) {
2508 acc_name = g_strdup (modest_window_get_active_account (win));
2510 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2512 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2516 acc_name = g_strdup (account_name);
2519 acc_store = modest_runtime_get_account_store ();
2520 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2524 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2528 /* Do not automatically refresh accounts that are flagged as
2529 NO_AUTO_UPDATE. This could be useful for accounts that
2530 handle their own update times */
2532 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2533 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2534 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2535 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2537 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2538 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2539 g_object_unref (account);
2546 /* Create the info for the connect and perform */
2547 info = g_slice_new (SendReceiveInfo);
2548 info->account_name = acc_name;
2549 info->win = (win) ? g_object_ref (win) : NULL;
2550 info->poke_status = poke_status;
2551 info->interactive = interactive;
2552 info->account = account;
2553 /* We need to create the operation here, because otherwise it
2554 could happen that the queue emits the queue-empty signal
2555 while we're trying to connect the account */
2556 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2557 modest_ui_actions_disk_operations_error_handler,
2559 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2561 /* Invoke the connect and perform */
2562 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2563 force_connection, info->account,
2564 do_send_receive_performer, info);
2569 modest_ui_actions_do_cancel_send (const gchar *account_name,
2572 TnyTransportAccount *transport_account;
2573 TnySendQueue *send_queue = NULL;
2574 GError *error = NULL;
2576 /* Get transport account */
2578 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2579 (modest_runtime_get_account_store(),
2581 TNY_ACCOUNT_TYPE_TRANSPORT));
2582 if (!transport_account) {
2583 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2588 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2589 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2590 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2591 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2592 "modest: could not find send queue for account\n");
2594 /* Cancel the current send */
2595 tny_account_cancel (TNY_ACCOUNT (transport_account));
2597 /* Suspend all pending messages */
2598 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2602 if (transport_account != NULL)
2603 g_object_unref (G_OBJECT (transport_account));
2607 modest_ui_actions_cancel_send_all (ModestWindow *win)
2609 GSList *account_names, *iter;
2611 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2614 iter = account_names;
2616 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2617 iter = g_slist_next (iter);
2620 modest_account_mgr_free_account_names (account_names);
2621 account_names = NULL;
2625 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2628 /* Check if accounts exist */
2629 gboolean accounts_exist =
2630 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2632 /* If not, allow the user to create an account before trying to send/receive. */
2633 if (!accounts_exist)
2634 modest_ui_actions_on_accounts (NULL, win);
2636 /* Cancel all sending operaitons */
2637 modest_ui_actions_cancel_send_all (win);
2641 * Refreshes all accounts. This function will be used by automatic
2645 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2646 gboolean force_connection,
2647 gboolean poke_status,
2648 gboolean interactive)
2650 GSList *account_names, *iter;
2652 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2655 iter = account_names;
2657 modest_ui_actions_do_send_receive ((const char*) iter->data,
2659 poke_status, interactive, win);
2660 iter = g_slist_next (iter);
2663 modest_account_mgr_free_account_names (account_names);
2664 account_names = NULL;
2668 * Handler of the click on Send&Receive button in the main toolbar
2671 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2673 /* Check if accounts exist */
2674 gboolean accounts_exist;
2677 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2679 /* If not, allow the user to create an account before trying to send/receive. */
2680 if (!accounts_exist)
2681 modest_ui_actions_on_accounts (NULL, win);
2683 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2684 if (MODEST_IS_MAIN_WINDOW (win)) {
2685 GtkWidget *folder_view;
2686 TnyFolderStore *folder_store;
2689 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2690 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2694 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2697 g_object_unref (folder_store);
2698 /* Refresh the active account. Force the connection if needed
2699 and poke the status of all folders */
2700 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2701 #ifdef MODEST_TOOLKIT_HILDON2
2702 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2703 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2706 const gchar *active_account;
2707 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2709 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2716 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2719 GtkWidget *header_view;
2721 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2723 header_view = modest_main_window_get_child_widget (main_window,
2724 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2728 conf = modest_runtime_get_conf ();
2730 /* what is saved/restored is depending on the style; thus; we save with
2731 * old style, then update the style, and restore for this new style
2733 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2735 if (modest_header_view_get_style
2736 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2737 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2738 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2740 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2741 MODEST_HEADER_VIEW_STYLE_DETAILS);
2743 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2744 MODEST_CONF_HEADER_VIEW_KEY);
2749 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2751 ModestMainWindow *main_window)
2753 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2754 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2756 /* in the case the folder is empty, show the empty folder message and focus
2758 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2759 if (modest_header_view_is_empty (header_view)) {
2760 TnyFolder *folder = modest_header_view_get_folder (header_view);
2761 GtkWidget *folder_view =
2762 modest_main_window_get_child_widget (main_window,
2763 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2764 if (folder != NULL) {
2765 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2766 g_object_unref (folder);
2768 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2772 /* If no header has been selected then exit */
2777 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2778 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2780 /* Update toolbar dimming state */
2781 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2782 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2786 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2789 ModestWindow *window)
2791 GtkWidget *open_widget;
2792 GtkTreeRowReference *rowref;
2794 g_return_if_fail (MODEST_IS_WINDOW(window));
2795 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2796 g_return_if_fail (TNY_IS_HEADER (header));
2798 if (modest_header_view_count_selected_headers (header_view) > 1) {
2799 /* Don't allow activation if there are more than one message selected */
2800 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2804 /* we check for low-mem; in that case, show a warning, and don't allow
2805 * activating headers
2807 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2810 if (MODEST_IS_MAIN_WINDOW (window)) {
2811 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2812 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2813 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2817 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2818 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2819 gtk_tree_row_reference_free (rowref);
2823 set_active_account_from_tny_account (TnyAccount *account,
2824 ModestWindow *window)
2826 const gchar *server_acc_name = tny_account_get_id (account);
2828 /* We need the TnyAccount provided by the
2829 account store because that is the one that
2830 knows the name of the Modest account */
2831 TnyAccount *modest_server_account =
2832 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2833 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2835 if (!modest_server_account) {
2836 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2840 /* Update active account, but only if it's not a pseudo-account */
2841 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2842 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2843 const gchar *modest_acc_name =
2844 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2845 if (modest_acc_name)
2846 modest_window_set_active_account (window, modest_acc_name);
2849 g_object_unref (modest_server_account);
2854 folder_refreshed_cb (ModestMailOperation *mail_op,
2858 ModestMainWindow *win = NULL;
2859 GtkWidget *folder_view, *header_view;
2860 const GError *error;
2862 g_return_if_fail (TNY_IS_FOLDER (folder));
2864 win = MODEST_MAIN_WINDOW (user_data);
2866 /* Check if the operation failed due to memory low conditions */
2867 error = modest_mail_operation_get_error (mail_op);
2868 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2869 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2870 modest_platform_run_information_dialog (GTK_WINDOW (win),
2871 _KR("memr_ib_operation_disabled"),
2877 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2879 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2882 TnyFolderStore *current_folder;
2884 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2885 if (current_folder) {
2886 gboolean different = ((TnyFolderStore *) folder != current_folder);
2887 g_object_unref (current_folder);
2893 /* Check if folder is empty and set headers view contents style */
2894 if ((tny_folder_get_all_count (folder) == 0) ||
2895 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2896 modest_main_window_set_contents_style (win,
2897 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2901 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2902 TnyFolderStore *folder_store,
2904 ModestMainWindow *main_window)
2906 GtkWidget *header_view;
2908 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2910 header_view = modest_main_window_get_child_widget(main_window,
2911 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2916 if (TNY_IS_ACCOUNT (folder_store)) {
2918 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2920 /* Show account details */
2921 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2924 if (TNY_IS_FOLDER (folder_store) && selected) {
2925 TnyAccount *account;
2927 /* Update the active account */
2928 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2930 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2931 g_object_unref (account);
2935 /* Set the header style by default, it could
2936 be changed later by the refresh callback to
2938 modest_main_window_set_contents_style (main_window,
2939 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2941 /* Set folder on header view. This function
2942 will call tny_folder_refresh_async so we
2943 pass a callback that will be called when
2944 finished. We use that callback to set the
2945 empty view if there are no messages */
2946 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2947 TNY_FOLDER (folder_store),
2949 MODEST_WINDOW (main_window),
2950 folder_refreshed_cb,
2953 /* Restore configuration. We need to do this
2954 *after* the set_folder because the widget
2955 memory asks the header view about its
2957 modest_widget_memory_restore (modest_runtime_get_conf (),
2958 G_OBJECT(header_view),
2959 MODEST_CONF_HEADER_VIEW_KEY);
2961 /* No need to save the header view
2962 configuration for Maemo because it only
2963 saves the sorting stuff and that it's
2964 already being done by the sort
2965 dialog. Remove it when the GNOME version
2966 has the same behaviour */
2967 #ifdef MODEST_TOOLKIT_GTK
2968 if (modest_main_window_get_contents_style (main_window) ==
2969 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2970 modest_widget_memory_save (modest_runtime_get_conf (),
2971 G_OBJECT (header_view),
2972 MODEST_CONF_HEADER_VIEW_KEY);
2974 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2978 /* Update dimming state */
2979 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2980 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2984 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2991 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2993 online = tny_device_is_online (modest_runtime_get_device());
2996 /* already online -- the item is simply not there... */
2997 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2999 GTK_MESSAGE_WARNING,
3001 _("The %s you selected cannot be found"),
3003 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3004 gtk_dialog_run (GTK_DIALOG(dialog));
3006 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3009 _("mcen_bd_dialog_cancel"),
3010 GTK_RESPONSE_REJECT,
3011 _("mcen_bd_dialog_ok"),
3012 GTK_RESPONSE_ACCEPT,
3014 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3015 "Do you want to get online?"), item);
3016 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3017 gtk_label_new (txt), FALSE, FALSE, 0);
3018 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3021 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3022 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3023 /* TODO: Comment about why is this commented out: */
3024 /* modest_platform_connect_and_wait (); */
3027 gtk_widget_destroy (dialog);
3031 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3034 /* g_debug ("%s %s", __FUNCTION__, link); */
3039 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3042 modest_platform_activate_uri (link);
3046 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3049 modest_platform_show_uri_popup (link);
3053 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3056 /* we check for low-mem; in that case, show a warning, and don't allow
3057 * viewing attachments
3059 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3062 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3066 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3067 const gchar *address,
3070 /* g_debug ("%s %s", __FUNCTION__, address); */
3074 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3075 TnyMsg *saved_draft,
3078 ModestMsgEditWindow *edit_window;
3080 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3081 #ifndef MODEST_TOOLKIT_HILDON2
3082 ModestMainWindow *win;
3084 /* FIXME. Make the header view sensitive again. This is a
3085 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3087 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3088 modest_runtime_get_window_mgr(), FALSE));
3090 GtkWidget *hdrview = modest_main_window_get_child_widget(
3091 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3092 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3096 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3098 /* Set draft is there was no error */
3099 if (!modest_mail_operation_get_error (mail_op))
3100 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3102 g_object_unref(edit_window);
3106 enough_space_for_message (ModestMsgEditWindow *edit_window,
3109 guint64 available_disk, expected_size;
3114 available_disk = modest_utils_get_available_space (NULL);
3115 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3116 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3121 /* Double check: disk full condition or message too big */
3122 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3123 expected_size > available_disk) {
3124 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3125 modest_platform_information_banner (NULL, NULL, msg);
3132 * djcb: if we're in low-memory state, we only allow for
3133 * saving messages smaller than
3134 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3135 * should still allow for sending anything critical...
3137 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3138 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3142 * djcb: we also make sure that the attachments are smaller than the max size
3143 * this is for the case where we'd try to forward a message with attachments
3144 * bigger than our max allowed size, or sending an message from drafts which
3145 * somehow got past our checks when attaching.
3147 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3148 modest_platform_run_information_dialog (
3149 GTK_WINDOW(edit_window),
3150 _("mail_ib_error_attachment_size"),
3159 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3161 TnyTransportAccount *transport_account;
3162 ModestMailOperation *mail_operation;
3164 gchar *account_name;
3165 ModestAccountMgr *account_mgr;
3166 gboolean had_error = FALSE;
3167 ModestMainWindow *win = NULL;
3169 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3171 data = modest_msg_edit_window_get_msg_data (edit_window);
3174 if (!enough_space_for_message (edit_window, data)) {
3175 modest_msg_edit_window_free_msg_data (edit_window, data);
3179 account_name = g_strdup (data->account_name);
3180 account_mgr = modest_runtime_get_account_mgr();
3182 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3184 account_name = modest_account_mgr_get_default_account (account_mgr);
3185 if (!account_name) {
3186 g_printerr ("modest: no account found\n");
3187 modest_msg_edit_window_free_msg_data (edit_window, data);
3191 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3192 account_name = g_strdup (data->account_name);
3196 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3197 (modest_runtime_get_account_store (),
3199 TNY_ACCOUNT_TYPE_TRANSPORT));
3200 if (!transport_account) {
3201 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3202 g_free (account_name);
3203 modest_msg_edit_window_free_msg_data (edit_window, data);
3207 /* Create the mail operation */
3208 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3210 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3212 modest_mail_operation_save_to_drafts (mail_operation,
3224 data->priority_flags,
3227 on_save_to_drafts_cb,
3228 g_object_ref(edit_window));
3230 #ifdef MODEST_TOOLKIT_HILDON2
3231 /* In hildon2 we always show the information banner on saving to drafts.
3232 * It will be a system information banner in this case.
3234 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3235 modest_platform_information_banner (NULL, NULL, text);
3238 /* Use the main window as the parent of the banner, if the
3239 main window does not exist it won't be shown, if the parent
3240 window exists then it's properly shown. We don't use the
3241 editor window because it could be closed (save to drafts
3242 could happen after closing the window */
3243 win = (ModestMainWindow *)
3244 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3246 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3247 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3251 modest_msg_edit_window_set_modified (edit_window, FALSE);
3254 g_free (account_name);
3255 g_object_unref (G_OBJECT (transport_account));
3256 g_object_unref (G_OBJECT (mail_operation));
3258 modest_msg_edit_window_free_msg_data (edit_window, data);
3261 * If the drafts folder is selected then make the header view
3262 * insensitive while the message is being saved to drafts
3263 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3264 * is not very clean but it avoids letting the drafts folder
3265 * in an inconsistent state: the user could edit the message
3266 * being saved and undesirable things would happen.
3267 * In the average case the user won't notice anything at
3268 * all. In the worst case (the user is editing a really big
3269 * file from Drafts) the header view will be insensitive
3270 * during the saving process (10 or 20 seconds, depending on
3271 * the message). Anyway this is just a quick workaround: once
3272 * we find a better solution it should be removed
3273 * See NB#65125 (commend #18) for details.
3275 if (!had_error && win != NULL) {
3276 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3277 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3279 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3281 if (modest_tny_folder_is_local_folder(folder)) {
3282 TnyFolderType folder_type;
3283 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3284 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3285 GtkWidget *hdrview = modest_main_window_get_child_widget(
3286 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3287 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3291 if (folder != NULL) g_object_unref(folder);
3298 /* For instance, when clicking the Send toolbar button when editing a message: */
3300 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3302 TnyTransportAccount *transport_account = NULL;
3303 gboolean had_error = FALSE, add_to_contacts;
3305 ModestAccountMgr *account_mgr;
3306 gchar *account_name;
3307 ModestMailOperation *mail_operation;
3310 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3312 /* Check whether to automatically add new contacts to addressbook or not */
3313 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3314 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3315 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3318 data = modest_msg_edit_window_get_msg_data (edit_window);
3320 recipients = g_strconcat (data->to?data->to:"",
3321 data->cc?data->cc:"",
3322 data->bcc?data->bcc:"",
3324 if (recipients == NULL || recipients[0] == '\0') {
3325 /* Empty subject -> no send */
3326 g_free (recipients);
3327 modest_msg_edit_window_free_msg_data (edit_window, data);
3330 g_free (recipients);
3333 if (!enough_space_for_message (edit_window, data)) {
3334 modest_msg_edit_window_free_msg_data (edit_window, data);
3338 account_mgr = modest_runtime_get_account_mgr();
3339 account_name = g_strdup (data->account_name);
3341 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3344 account_name = modest_account_mgr_get_default_account (account_mgr);
3346 if (!account_name) {
3347 modest_msg_edit_window_free_msg_data (edit_window, data);
3348 /* Run account setup wizard */
3349 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3354 /* Get the currently-active transport account for this modest account: */
3355 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3357 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3358 (modest_runtime_get_account_store (),
3359 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3362 if (!transport_account) {
3363 modest_msg_edit_window_free_msg_data (edit_window, data);
3364 /* Run account setup wizard */
3365 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3370 /* Create the mail operation */
3371 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3372 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3374 modest_mail_operation_send_new_mail (mail_operation,
3388 data->priority_flags);
3390 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3391 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3393 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3394 const GError *error = modest_mail_operation_get_error (mail_operation);
3395 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3396 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3397 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3398 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3404 g_free (account_name);
3405 g_object_unref (G_OBJECT (transport_account));
3406 g_object_unref (G_OBJECT (mail_operation));
3408 modest_msg_edit_window_free_msg_data (edit_window, data);
3411 modest_msg_edit_window_set_sent (edit_window, TRUE);
3413 /* Save settings and close the window: */
3414 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3421 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3422 ModestMsgEditWindow *window)
3424 ModestMsgEditFormatState *format_state = NULL;
3426 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3427 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3429 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3432 format_state = modest_msg_edit_window_get_format_state (window);
3433 g_return_if_fail (format_state != NULL);
3435 format_state->bold = gtk_toggle_action_get_active (action);
3436 modest_msg_edit_window_set_format_state (window, format_state);
3437 g_free (format_state);
3442 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3443 ModestMsgEditWindow *window)
3445 ModestMsgEditFormatState *format_state = NULL;
3447 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3448 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3450 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3453 format_state = modest_msg_edit_window_get_format_state (window);
3454 g_return_if_fail (format_state != NULL);
3456 format_state->italics = gtk_toggle_action_get_active (action);
3457 modest_msg_edit_window_set_format_state (window, format_state);
3458 g_free (format_state);
3463 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3464 ModestMsgEditWindow *window)
3466 ModestMsgEditFormatState *format_state = NULL;
3468 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3469 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3471 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3474 format_state = modest_msg_edit_window_get_format_state (window);
3475 g_return_if_fail (format_state != NULL);
3477 format_state->bullet = gtk_toggle_action_get_active (action);
3478 modest_msg_edit_window_set_format_state (window, format_state);
3479 g_free (format_state);
3484 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3485 GtkRadioAction *selected,
3486 ModestMsgEditWindow *window)
3488 ModestMsgEditFormatState *format_state = NULL;
3489 GtkJustification value;
3491 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3493 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3496 value = gtk_radio_action_get_current_value (selected);
3498 format_state = modest_msg_edit_window_get_format_state (window);
3499 g_return_if_fail (format_state != NULL);
3501 format_state->justification = value;
3502 modest_msg_edit_window_set_format_state (window, format_state);
3503 g_free (format_state);
3507 modest_ui_actions_on_select_editor_color (GtkAction *action,
3508 ModestMsgEditWindow *window)
3510 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3511 g_return_if_fail (GTK_IS_ACTION (action));
3513 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3516 modest_msg_edit_window_select_color (window);
3520 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3521 ModestMsgEditWindow *window)
3523 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3524 g_return_if_fail (GTK_IS_ACTION (action));
3526 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3529 modest_msg_edit_window_select_background_color (window);
3533 modest_ui_actions_on_insert_image (GObject *object,
3534 ModestMsgEditWindow *window)
3536 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3539 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3542 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3545 modest_msg_edit_window_insert_image (window);
3549 modest_ui_actions_on_attach_file (GtkAction *action,
3550 ModestMsgEditWindow *window)
3552 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3553 g_return_if_fail (GTK_IS_ACTION (action));
3555 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3558 modest_msg_edit_window_offer_attach_file (window);
3562 modest_ui_actions_on_remove_attachments (GtkAction *action,
3563 ModestMsgEditWindow *window)
3565 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3567 modest_msg_edit_window_remove_attachments (window, NULL);
3571 do_create_folder_cb (ModestMailOperation *mail_op,
3572 TnyFolderStore *parent_folder,
3573 TnyFolder *new_folder,
3576 gchar *suggested_name = (gchar *) user_data;
3577 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3578 const GError *error;
3580 error = modest_mail_operation_get_error (mail_op);
3582 gboolean disk_full = FALSE;
3583 TnyAccount *account;
3584 /* Show an error. If there was some problem writing to
3585 disk, show it, otherwise show the generic folder
3586 create error. We do it here and not in an error
3587 handler because the call to do_create_folder will
3588 stop the main loop in a gtk_dialog_run and then,
3589 the message won't be shown until that dialog is
3591 account = modest_mail_operation_get_account (mail_op);
3594 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3595 (GtkWidget *) source_win,
3598 _("mail_in_ui_folder_create_error_memory"));
3599 g_object_unref (account);
3602 /* Show an error and try again if there is no
3603 full memory condition */
3604 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3605 _("mail_in_ui_folder_create_error"));
3606 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3610 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3611 * FIXME: any other? */
3612 GtkWidget *folder_view;
3614 if (MODEST_IS_MAIN_WINDOW(source_win))
3616 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3617 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3619 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3620 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3622 /* Select the newly created folder. It could happen
3623 that the widget is no longer there (i.e. the window
3624 has been destroyed, so we need to check this */
3626 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3628 g_object_unref (new_folder);
3630 /* Free. Note that the first time it'll be NULL so noop */
3631 g_free (suggested_name);
3632 g_object_unref (source_win);
3637 TnyFolderStore *parent;
3638 } CreateFolderConnect;
3641 do_create_folder_performer (gboolean canceled,
3643 GtkWindow *parent_window,
3644 TnyAccount *account,
3647 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3648 ModestMailOperation *mail_op;
3650 if (canceled || err) {
3651 /* In disk full conditions we could get this error here */
3652 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3653 (GtkWidget *) parent_window, err,
3654 NULL, _("mail_in_ui_folder_create_error_memory"));
3656 /* This happens if we have selected the outbox folder
3658 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3659 TNY_IS_MERGE_FOLDER (helper->parent)) {
3660 /* Show an error and retry */
3661 modest_platform_information_banner ((GtkWidget *) parent_window,
3663 _("mail_in_ui_folder_create_error"));
3665 do_create_folder (parent_window, helper->parent, helper->folder_name);
3671 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3672 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3674 modest_mail_operation_create_folder (mail_op,
3676 (const gchar *) helper->folder_name,
3677 do_create_folder_cb,
3678 g_strdup (helper->folder_name));
3679 g_object_unref (mail_op);
3683 g_object_unref (helper->parent);
3684 if (helper->folder_name)
3685 g_free (helper->folder_name);
3686 g_slice_free (CreateFolderConnect, helper);
3691 do_create_folder (GtkWindow *parent_window,
3692 TnyFolderStore *suggested_parent,
3693 const gchar *suggested_name)
3696 gchar *folder_name = NULL;
3697 TnyFolderStore *parent_folder = NULL;
3699 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3701 (gchar *) suggested_name,
3705 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3706 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3707 helper->folder_name = g_strdup (folder_name);
3708 helper->parent = g_object_ref (parent_folder);
3710 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3713 do_create_folder_performer,
3718 g_free (folder_name);
3720 g_object_unref (parent_folder);
3724 modest_ui_actions_create_folder(GtkWidget *parent_window,
3725 GtkWidget *folder_view,
3726 TnyFolderStore *parent_folder)
3728 if (!parent_folder) {
3729 #ifdef MODEST_TOOLKIT_HILDON2
3730 ModestTnyAccountStore *acc_store;
3732 acc_store = modest_runtime_get_account_store ();
3734 parent_folder = (TnyFolderStore *)
3735 modest_tny_account_store_get_local_folders_account (acc_store);
3737 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3741 if (parent_folder) {
3742 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3743 g_object_unref (parent_folder);
3748 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3751 g_return_if_fail (MODEST_IS_WINDOW(window));
3753 if (MODEST_IS_MAIN_WINDOW (window)) {
3754 GtkWidget *folder_view;
3756 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3757 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3761 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3762 #ifdef MODEST_TOOLKIT_HILDON2
3763 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3764 GtkWidget *folder_view;
3766 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3767 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3770 g_assert_not_reached ();
3775 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3778 const GError *error = NULL;
3779 gchar *message = NULL;
3781 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3783 /* Get error message */
3784 error = modest_mail_operation_get_error (mail_op);
3786 g_return_if_reached ();
3788 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3789 (GError *) error, account);
3791 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3792 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3793 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3794 message = _CS("ckdg_ib_folder_already_exists");
3795 } else if (error->domain == TNY_ERROR_DOMAIN &&
3796 error->code == TNY_SERVICE_ERROR_STATE) {
3797 /* This means that the folder is already in use (a
3798 message is opened for example */
3799 message = _("emev_ni_internal_error");
3801 message = _CS("ckdg_ib_unable_to_rename");
3804 /* We don't set a parent for the dialog because the dialog
3805 will be destroyed so the banner won't appear */
3806 modest_platform_information_banner (NULL, NULL, message);
3809 g_object_unref (account);
3815 TnyFolderStore *folder;
3820 on_rename_folder_cb (ModestMailOperation *mail_op,
3821 TnyFolder *new_folder,
3824 ModestFolderView *folder_view;
3826 /* If the window was closed when renaming a folder, or if
3827 * it's not a main window this will happen */
3828 if (!MODEST_IS_FOLDER_VIEW (user_data))
3831 folder_view = MODEST_FOLDER_VIEW (user_data);
3832 /* Note that if the rename fails new_folder will be NULL */
3834 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3836 modest_folder_view_select_first_inbox_or_local (folder_view);
3838 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3842 on_rename_folder_performer (gboolean canceled,
3844 GtkWindow *parent_window,
3845 TnyAccount *account,
3848 ModestMailOperation *mail_op = NULL;
3849 GtkTreeSelection *sel = NULL;
3850 GtkWidget *folder_view = NULL;
3851 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3853 if (canceled || err) {
3854 /* In disk full conditions we could get this error here */
3855 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3856 (GtkWidget *) parent_window, err,
3861 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3862 modest_ui_actions_rename_folder_error_handler,
3863 parent_window, NULL);
3865 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3868 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3870 folder_view = modest_main_window_get_child_widget (
3871 MODEST_MAIN_WINDOW (parent_window),
3872 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3874 #ifdef MODEST_TOOLKIT_HILDON2
3875 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3876 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3877 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3881 /* Clear the folders view */
3882 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3883 gtk_tree_selection_unselect_all (sel);
3885 /* Actually rename the folder */
3886 modest_mail_operation_rename_folder (mail_op,
3887 TNY_FOLDER (data->folder),
3888 (const gchar *) (data->new_name),
3889 on_rename_folder_cb,
3891 g_object_unref (mail_op);
3894 g_object_unref (data->folder);
3895 g_free (data->new_name);
3900 modest_ui_actions_on_rename_folder (GtkAction *action,
3901 ModestWindow *window)
3903 modest_ui_actions_on_edit_mode_rename_folder (window);
3907 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3909 TnyFolderStore *folder;
3910 GtkWidget *folder_view;
3911 gboolean do_rename = TRUE;
3913 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3915 if (MODEST_IS_MAIN_WINDOW (window)) {
3916 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3917 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3921 #ifdef MODEST_TOOLKIT_HILDON2
3922 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3923 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3929 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3934 if (TNY_IS_FOLDER (folder)) {
3935 gchar *folder_name = NULL;
3937 const gchar *current_name;
3938 TnyFolderStore *parent;
3940 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3941 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3942 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3943 parent, current_name,
3945 g_object_unref (parent);
3947 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3950 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3951 rename_folder_data->folder = g_object_ref (folder);
3952 rename_folder_data->new_name = folder_name;
3953 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3954 folder, on_rename_folder_performer, rename_folder_data);
3957 g_object_unref (folder);
3962 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3965 GObject *win = modest_mail_operation_get_source (mail_op);
3967 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3968 _("mail_in_ui_folder_delete_error"),
3970 g_object_unref (win);
3974 TnyFolderStore *folder;
3975 gboolean move_to_trash;
3979 on_delete_folder_cb (gboolean canceled,
3981 GtkWindow *parent_window,
3982 TnyAccount *account,
3985 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3986 GtkWidget *folder_view;
3987 ModestMailOperation *mail_op;
3988 GtkTreeSelection *sel;
3990 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3991 /* Note that the connection process can fail due to
3992 memory low conditions as it can not successfully
3993 store the summary */
3994 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3995 (GtkWidget*) parent_window, err,
3997 g_debug ("Error connecting when trying to delete a folder");
3998 g_object_unref (G_OBJECT (info->folder));
4003 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4004 folder_view = modest_main_window_get_child_widget (
4005 MODEST_MAIN_WINDOW (parent_window),
4006 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4007 #ifdef MODEST_TOOLKIT_HILDON2
4008 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4009 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4012 g_object_unref (G_OBJECT (info->folder));
4017 /* Unselect the folder before deleting it to free the headers */
4018 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4019 gtk_tree_selection_unselect_all (sel);
4021 /* Create the mail operation */
4023 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4024 modest_ui_actions_delete_folder_error_handler,
4027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4029 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4031 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4033 g_object_unref (mail_op);
4034 g_object_unref (info->folder);
4039 delete_folder (ModestWindow *window, gboolean move_to_trash)
4041 TnyFolderStore *folder;
4042 GtkWidget *folder_view;
4046 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4048 if (MODEST_IS_MAIN_WINDOW (window)) {
4050 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4051 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4052 #ifdef MODEST_TOOLKIT_HILDON2
4053 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4054 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4062 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4067 /* Show an error if it's an account */
4068 if (!TNY_IS_FOLDER (folder)) {
4069 modest_platform_run_information_dialog (GTK_WINDOW (window),
4070 _("mail_in_ui_folder_delete_error"),
4072 g_object_unref (G_OBJECT (folder));
4077 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4078 tny_folder_get_name (TNY_FOLDER (folder)));
4079 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4080 (const gchar *) message);
4083 if (response == GTK_RESPONSE_OK) {
4084 TnyAccount *account = NULL;
4085 DeleteFolderInfo *info = NULL;
4086 info = g_new0(DeleteFolderInfo, 1);
4087 info->folder = g_object_ref (folder);
4088 info->move_to_trash = move_to_trash;
4090 account = tny_folder_get_account (TNY_FOLDER (folder));
4091 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4093 TNY_FOLDER_STORE (account),
4094 on_delete_folder_cb, info);
4095 g_object_unref (account);
4096 g_object_unref (folder);
4104 modest_ui_actions_on_delete_folder (GtkAction *action,
4105 ModestWindow *window)
4107 modest_ui_actions_on_edit_mode_delete_folder (window);
4111 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4113 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4115 return delete_folder (window, FALSE);
4119 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4121 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4123 delete_folder (MODEST_WINDOW (main_window), TRUE);
4127 typedef struct _PasswordDialogFields {
4128 GtkWidget *username;
4129 GtkWidget *password;
4131 } PasswordDialogFields;
4134 password_dialog_check_field (GtkEditable *editable,
4135 PasswordDialogFields *fields)
4138 gboolean any_value_empty = FALSE;
4140 #ifdef MODEST_TOOLKIT_HILDON2
4141 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4143 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4145 if ((value == NULL) || value[0] == '\0') {
4146 any_value_empty = TRUE;
4148 #ifdef MODEST_TOOLKIT_HILDON2
4149 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4151 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4153 if ((value == NULL) || value[0] == '\0') {
4154 any_value_empty = TRUE;
4156 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4160 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4161 const gchar* server_account_name,
4166 ModestMainWindow *main_window)
4168 g_return_if_fail(server_account_name);
4169 gboolean completed = FALSE;
4170 PasswordDialogFields *fields = NULL;
4172 /* Initalize output parameters: */
4179 #ifndef MODEST_TOOLKIT_GTK
4180 /* Maemo uses a different (awkward) button order,
4181 * It should probably just use gtk_alternative_dialog_button_order ().
4183 #ifdef MODEST_TOOLKIT_HILDON2
4185 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4188 _HL("wdgt_bd_done"),
4189 GTK_RESPONSE_ACCEPT,
4191 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4192 HILDON_MARGIN_DOUBLE);
4195 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4198 _("mcen_bd_dialog_ok"),
4199 GTK_RESPONSE_ACCEPT,
4200 _("mcen_bd_dialog_cancel"),
4201 GTK_RESPONSE_REJECT,
4203 #endif /* MODEST_TOOLKIT_HILDON2 */
4206 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4210 GTK_RESPONSE_REJECT,
4212 GTK_RESPONSE_ACCEPT,
4214 #endif /* MODEST_TOOLKIT_GTK */
4216 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4218 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4219 modest_runtime_get_account_mgr(), server_account_name);
4220 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4221 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4224 gtk_widget_destroy (dialog);
4228 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4229 GtkWidget *label = gtk_label_new (txt);
4230 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4232 g_free (server_name);
4233 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4238 gchar *initial_username = modest_account_mgr_get_server_account_username (
4239 modest_runtime_get_account_mgr(), server_account_name);
4241 #ifdef MODEST_TOOLKIT_HILDON2
4242 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4243 if (initial_username)
4244 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4246 GtkWidget *entry_username = gtk_entry_new ();
4247 if (initial_username)
4248 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4250 /* Dim this if a connection has ever succeeded with this username,
4251 * as per the UI spec: */
4252 /* const gboolean username_known = */
4253 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4254 /* modest_runtime_get_account_mgr(), server_account_name); */
4255 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4257 /* We drop the username sensitive code and disallow changing it here
4258 * as tinymail does not support really changing the username in the callback
4260 gtk_widget_set_sensitive (entry_username, FALSE);
4262 #ifndef MODEST_TOOLKIT_GTK
4263 /* Auto-capitalization is the default, so let's turn it off: */
4264 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4266 /* Create a size group to be used by all captions.
4267 * Note that HildonCaption does not create a default size group if we do not specify one.
4268 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4269 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4271 #ifdef MODEST_TOOLKIT_HILDON2
4272 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4273 _("mail_fi_username"), FALSE,
4276 GtkWidget *caption = hildon_caption_new (sizegroup,
4277 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4279 gtk_widget_show (entry_username);
4280 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4281 FALSE, FALSE, MODEST_MARGIN_HALF);
4282 gtk_widget_show (caption);
4284 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4286 #endif /* !MODEST_TOOLKIT_GTK */
4289 #ifdef MODEST_TOOLKIT_HILDON2
4290 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4292 GtkWidget *entry_password = gtk_entry_new ();
4294 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4295 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4297 #ifndef MODEST_TOOLKIT_GTK
4298 /* Auto-capitalization is the default, so let's turn it off: */
4299 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4300 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4302 #ifdef MODEST_TOOLKIT_HILDON2
4303 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4304 _("mail_fi_password"), FALSE,
4307 caption = hildon_caption_new (sizegroup,
4308 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4310 gtk_widget_show (entry_password);
4311 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4312 FALSE, FALSE, MODEST_MARGIN_HALF);
4313 gtk_widget_show (caption);
4314 g_object_unref (sizegroup);
4316 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4318 #endif /* !MODEST_TOOLKIT_GTK */
4320 if (initial_username != NULL)
4321 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4323 /* This is not in the Maemo UI spec:
4324 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4325 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4329 fields = g_slice_new0 (PasswordDialogFields);
4330 fields->username = entry_username;
4331 fields->password = entry_password;
4332 fields->dialog = dialog;
4334 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4335 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4336 password_dialog_check_field (NULL, fields);
4338 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4340 while (!completed) {
4342 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4344 #ifdef MODEST_TOOLKIT_HILDON2
4345 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4347 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4350 /* Note that an empty field becomes the "" string */
4351 if (*username && strlen (*username) > 0) {
4352 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4353 server_account_name,
4357 const gboolean username_was_changed =
4358 (strcmp (*username, initial_username) != 0);
4359 if (username_was_changed) {
4360 g_warning ("%s: tinymail does not yet support changing the "
4361 "username in the get_password() callback.\n", __FUNCTION__);
4367 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4368 _("mcen_ib_username_pw_incorrect"));
4374 #ifdef MODEST_TOOLKIT_HILDON2
4375 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4377 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4380 /* We do not save the password in the configuration,
4381 * because this function is only called for passwords that should
4382 * not be remembered:
4383 modest_server_account_set_password (
4384 modest_runtime_get_account_mgr(), server_account_name,
4391 #ifndef MODEST_TOOLKIT_HILDON2
4392 /* Set parent to NULL or the banner will disappear with its parent dialog */
4393 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4405 /* This is not in the Maemo UI spec:
4406 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4412 g_free (initial_username);
4413 gtk_widget_destroy (dialog);
4414 g_slice_free (PasswordDialogFields, fields);
4416 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4420 modest_ui_actions_on_cut (GtkAction *action,
4421 ModestWindow *window)
4423 GtkWidget *focused_widget;
4424 GtkClipboard *clipboard;
4426 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4427 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4428 if (GTK_IS_EDITABLE (focused_widget)) {
4429 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4430 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4431 gtk_clipboard_store (clipboard);
4432 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4433 GtkTextBuffer *buffer;
4435 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4436 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4437 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4438 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4439 gtk_clipboard_store (clipboard);
4441 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4442 TnyList *header_list = modest_header_view_get_selected_headers (
4443 MODEST_HEADER_VIEW (focused_widget));
4444 gboolean continue_download = FALSE;
4445 gint num_of_unc_msgs;
4447 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4449 if (num_of_unc_msgs) {
4450 TnyAccount *account = get_account_from_header_list (header_list);
4452 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4453 g_object_unref (account);
4457 if (num_of_unc_msgs == 0 || continue_download) {
4458 /* modest_platform_information_banner (
4459 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4460 modest_header_view_cut_selection (
4461 MODEST_HEADER_VIEW (focused_widget));
4464 g_object_unref (header_list);
4465 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4466 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4471 modest_ui_actions_on_copy (GtkAction *action,
4472 ModestWindow *window)
4474 GtkClipboard *clipboard;
4475 GtkWidget *focused_widget;
4476 gboolean copied = TRUE;
4478 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4479 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4481 if (GTK_IS_LABEL (focused_widget)) {
4483 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4484 gtk_clipboard_set_text (clipboard, selection, -1);
4486 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4487 gtk_clipboard_store (clipboard);
4488 } else if (GTK_IS_EDITABLE (focused_widget)) {
4489 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4490 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4491 gtk_clipboard_store (clipboard);
4492 } else if (GTK_IS_HTML (focused_widget)) {
4495 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4496 if ((sel == NULL) || (sel[0] == '\0')) {
4499 gtk_html_copy (GTK_HTML (focused_widget));
4500 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4501 gtk_clipboard_store (clipboard);
4503 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4504 GtkTextBuffer *buffer;
4505 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4506 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4507 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4508 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4509 gtk_clipboard_store (clipboard);
4511 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4512 TnyList *header_list = modest_header_view_get_selected_headers (
4513 MODEST_HEADER_VIEW (focused_widget));
4514 gboolean continue_download = FALSE;
4515 gint num_of_unc_msgs;
4517 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4519 if (num_of_unc_msgs) {
4520 TnyAccount *account = get_account_from_header_list (header_list);
4522 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4523 g_object_unref (account);
4527 if (num_of_unc_msgs == 0 || continue_download) {
4528 modest_platform_information_banner (
4529 NULL, NULL, _CS("mcen_ib_getting_items"));
4530 modest_header_view_copy_selection (
4531 MODEST_HEADER_VIEW (focused_widget));
4535 g_object_unref (header_list);
4537 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4538 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4541 /* Show information banner if there was a copy to clipboard */
4543 modest_platform_information_banner (
4544 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4548 modest_ui_actions_on_undo (GtkAction *action,
4549 ModestWindow *window)
4551 ModestEmailClipboard *clipboard = NULL;
4553 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4554 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4555 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4556 /* Clear clipboard source */
4557 clipboard = modest_runtime_get_email_clipboard ();
4558 modest_email_clipboard_clear (clipboard);
4561 g_return_if_reached ();
4566 modest_ui_actions_on_redo (GtkAction *action,
4567 ModestWindow *window)
4569 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4570 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4573 g_return_if_reached ();
4579 destroy_information_note (ModestMailOperation *mail_op,
4582 /* destroy information note */
4583 gtk_widget_destroy (GTK_WIDGET(user_data));
4587 destroy_folder_information_note (ModestMailOperation *mail_op,
4588 TnyFolder *new_folder,
4591 /* destroy information note */
4592 gtk_widget_destroy (GTK_WIDGET(user_data));
4597 paste_as_attachment_free (gpointer data)
4599 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4601 if (helper->banner) {
4602 gtk_widget_destroy (helper->banner);
4603 g_object_unref (helper->banner);
4609 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4614 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4615 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4620 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4625 modest_ui_actions_on_paste (GtkAction *action,
4626 ModestWindow *window)
4628 GtkWidget *focused_widget = NULL;
4629 GtkWidget *inf_note = NULL;
4630 ModestMailOperation *mail_op = NULL;
4632 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4633 if (GTK_IS_EDITABLE (focused_widget)) {
4634 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4635 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4636 ModestEmailClipboard *e_clipboard = NULL;
4637 e_clipboard = modest_runtime_get_email_clipboard ();
4638 if (modest_email_clipboard_cleared (e_clipboard)) {
4639 GtkTextBuffer *buffer;
4640 GtkClipboard *clipboard;
4642 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4643 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4644 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4645 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4646 ModestMailOperation *mail_op;
4647 TnyFolder *src_folder = NULL;
4648 TnyList *data = NULL;
4650 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4651 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4652 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4653 _CS("ckct_nw_pasting"));
4654 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4655 mail_op = modest_mail_operation_new (G_OBJECT (window));
4656 if (helper->banner != NULL) {
4657 g_object_ref (G_OBJECT (helper->banner));
4658 gtk_widget_show (GTK_WIDGET (helper->banner));
4662 modest_mail_operation_get_msgs_full (mail_op,
4664 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4666 paste_as_attachment_free);
4670 g_object_unref (data);
4672 g_object_unref (src_folder);
4675 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4676 ModestEmailClipboard *clipboard = NULL;
4677 TnyFolder *src_folder = NULL;
4678 TnyFolderStore *folder_store = NULL;
4679 TnyList *data = NULL;
4680 gboolean delete = FALSE;
4682 /* Check clipboard source */
4683 clipboard = modest_runtime_get_email_clipboard ();
4684 if (modest_email_clipboard_cleared (clipboard))
4687 /* Get elements to paste */
4688 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4690 /* Create a new mail operation */
4691 mail_op = modest_mail_operation_new (G_OBJECT(window));
4693 /* Get destination folder */
4694 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4696 /* transfer messages */
4700 /* Ask for user confirmation */
4702 modest_ui_actions_msgs_move_to_confirmation (window,
4703 TNY_FOLDER (folder_store),
4707 if (response == GTK_RESPONSE_OK) {
4708 /* Launch notification */
4709 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4710 _CS("ckct_nw_pasting"));
4711 if (inf_note != NULL) {
4712 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4713 gtk_widget_show (GTK_WIDGET(inf_note));
4716 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4717 modest_mail_operation_xfer_msgs (mail_op,
4719 TNY_FOLDER (folder_store),
4721 destroy_information_note,
4724 g_object_unref (mail_op);
4727 } else if (src_folder != NULL) {
4728 /* Launch notification */
4729 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4730 _CS("ckct_nw_pasting"));
4731 if (inf_note != NULL) {
4732 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4733 gtk_widget_show (GTK_WIDGET(inf_note));
4736 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4737 modest_mail_operation_xfer_folder (mail_op,
4741 destroy_folder_information_note,
4747 g_object_unref (data);
4748 if (src_folder != NULL)
4749 g_object_unref (src_folder);
4750 if (folder_store != NULL)
4751 g_object_unref (folder_store);
4757 modest_ui_actions_on_select_all (GtkAction *action,
4758 ModestWindow *window)
4760 GtkWidget *focused_widget;
4762 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4763 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4764 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4765 } else if (GTK_IS_LABEL (focused_widget)) {
4766 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4767 } else if (GTK_IS_EDITABLE (focused_widget)) {
4768 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4769 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4770 GtkTextBuffer *buffer;
4771 GtkTextIter start, end;
4773 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4774 gtk_text_buffer_get_start_iter (buffer, &start);
4775 gtk_text_buffer_get_end_iter (buffer, &end);
4776 gtk_text_buffer_select_range (buffer, &start, &end);
4777 } else if (GTK_IS_HTML (focused_widget)) {
4778 gtk_html_select_all (GTK_HTML (focused_widget));
4779 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4780 GtkWidget *header_view = focused_widget;
4781 GtkTreeSelection *selection = NULL;
4783 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4784 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4785 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4788 /* Disable window dimming management */
4789 modest_window_disable_dimming (MODEST_WINDOW(window));
4791 /* Select all messages */
4792 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4793 gtk_tree_selection_select_all (selection);
4795 /* Set focuse on header view */
4796 gtk_widget_grab_focus (header_view);
4798 /* Enable window dimming management */
4799 modest_window_enable_dimming (MODEST_WINDOW(window));
4800 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4801 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4807 modest_ui_actions_on_mark_as_read (GtkAction *action,
4808 ModestWindow *window)
4810 g_return_if_fail (MODEST_IS_WINDOW(window));
4812 /* Mark each header as read */
4813 do_headers_action (window, headers_action_mark_as_read, NULL);
4817 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4818 ModestWindow *window)
4820 g_return_if_fail (MODEST_IS_WINDOW(window));
4822 /* Mark each header as read */
4823 do_headers_action (window, headers_action_mark_as_unread, NULL);
4827 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4828 GtkRadioAction *selected,
4829 ModestWindow *window)
4833 value = gtk_radio_action_get_current_value (selected);
4834 if (MODEST_IS_WINDOW (window)) {
4835 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4840 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4841 GtkRadioAction *selected,
4842 ModestWindow *window)
4844 TnyHeaderFlags flags;
4845 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4847 flags = gtk_radio_action_get_current_value (selected);
4848 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4852 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4853 GtkRadioAction *selected,
4854 ModestWindow *window)
4858 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4860 file_format = gtk_radio_action_get_current_value (selected);
4861 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4866 modest_ui_actions_on_zoom_plus (GtkAction *action,
4867 ModestWindow *window)
4869 g_return_if_fail (MODEST_IS_WINDOW (window));
4871 modest_window_zoom_plus (MODEST_WINDOW (window));
4875 modest_ui_actions_on_zoom_minus (GtkAction *action,
4876 ModestWindow *window)
4878 g_return_if_fail (MODEST_IS_WINDOW (window));
4880 modest_window_zoom_minus (MODEST_WINDOW (window));
4884 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4885 ModestWindow *window)
4887 ModestWindowMgr *mgr;
4888 gboolean fullscreen, active;
4889 g_return_if_fail (MODEST_IS_WINDOW (window));
4891 mgr = modest_runtime_get_window_mgr ();
4893 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4894 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4896 if (active != fullscreen) {
4897 modest_window_mgr_set_fullscreen_mode (mgr, active);
4898 #ifndef MODEST_TOOLKIT_HILDON2
4899 gtk_window_present (GTK_WINDOW (window));
4905 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4906 ModestWindow *window)
4908 ModestWindowMgr *mgr;
4909 gboolean fullscreen;
4911 g_return_if_fail (MODEST_IS_WINDOW (window));
4913 mgr = modest_runtime_get_window_mgr ();
4914 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4915 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4917 #ifndef MODEST_TOOLKIT_HILDON2
4918 gtk_window_present (GTK_WINDOW (window));
4923 * Used by modest_ui_actions_on_details to call do_headers_action
4926 headers_action_show_details (TnyHeader *header,
4927 ModestWindow *window,
4931 gboolean async_retrieval;
4934 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4935 async_retrieval = TRUE;
4936 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4937 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4939 async_retrieval = FALSE;
4941 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4943 g_object_unref (msg);
4947 * Show the header details in a ModestDetailsDialog widget
4950 modest_ui_actions_on_details (GtkAction *action,
4953 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4957 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4961 header = tny_msg_get_header (msg);
4963 headers_action_show_details (header, win, NULL);
4964 g_object_unref (header);
4966 g_object_unref (msg);
4968 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4969 GtkWidget *folder_view, *header_view;
4971 /* Check which widget has the focus */
4972 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4973 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4974 if (gtk_widget_is_focus (folder_view)) {
4975 TnyFolderStore *folder_store
4976 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4977 if (!folder_store) {
4978 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4981 /* Show only when it's a folder */
4982 /* This function should not be called for account items,
4983 * because we dim the menu item for them. */
4984 if (TNY_IS_FOLDER (folder_store)) {
4985 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4986 TNY_FOLDER (folder_store));
4989 g_object_unref (folder_store);
4992 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4993 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4994 /* Show details of each header */
4995 do_headers_action (win, headers_action_show_details, header_view);
4997 #ifdef MODEST_TOOLKIT_HILDON2
4998 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5000 GtkWidget *header_view;
5002 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5003 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5005 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5007 g_object_unref (folder);
5014 modest_ui_actions_on_limit_error (GtkAction *action,
5017 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5019 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5024 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5025 ModestMsgEditWindow *window)
5027 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5029 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5033 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5034 ModestMsgEditWindow *window)
5036 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5038 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5042 modest_ui_actions_toggle_folders_view (GtkAction *action,
5043 ModestMainWindow *main_window)
5045 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5047 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5048 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5050 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5054 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5055 ModestWindow *window)
5057 gboolean active, fullscreen = FALSE;
5058 ModestWindowMgr *mgr;
5060 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5062 /* Check if we want to toggle the toolbar view in fullscreen
5064 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5065 "ViewShowToolbarFullScreen")) {
5069 /* Toggle toolbar */
5070 mgr = modest_runtime_get_window_mgr ();
5071 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5075 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5076 ModestMsgEditWindow *window)
5078 modest_msg_edit_window_select_font (window);
5083 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5084 const gchar *display_name,
5087 /* don't update the display name if it was already set;
5088 * updating the display name apparently is expensive */
5089 const gchar* old_name = gtk_window_get_title (window);
5091 if (display_name == NULL)
5094 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5095 return; /* don't do anything */
5097 /* This is usually used to change the title of the main window, which
5098 * is the one that holds the folder view. Note that this change can
5099 * happen even when the widget doesn't have the focus. */
5100 gtk_window_set_title (window, display_name);
5105 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5107 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5108 modest_msg_edit_window_select_contacts (window);
5112 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5115 modest_msg_edit_window_check_names (window, FALSE);
5118 #ifndef MODEST_TOOLKIT_HILDON2
5120 * This function is used to track changes in the selection of the
5121 * folder view that is inside the "move to" dialog to enable/disable
5122 * the OK button because we do not want the user to select a disallowed
5123 * destination for a folder.
5124 * The user also not desired to be able to use NEW button on items where
5125 * folder creation is not possibel.
5128 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5129 TnyFolderStore *folder_store,
5133 GtkWidget *dialog = NULL;
5134 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5135 gboolean moving_folder = FALSE;
5136 gboolean is_local_account = TRUE;
5137 GtkWidget *folder_view = NULL;
5138 ModestTnyFolderRules rules;
5140 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5145 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5149 /* check if folder_store is an remote account */
5150 if (TNY_IS_ACCOUNT (folder_store)) {
5151 TnyAccount *local_account = NULL;
5152 TnyAccount *mmc_account = NULL;
5153 ModestTnyAccountStore *account_store = NULL;
5155 account_store = modest_runtime_get_account_store ();
5156 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5157 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5159 if ((gpointer) local_account != (gpointer) folder_store &&
5160 (gpointer) mmc_account != (gpointer) folder_store) {
5161 ModestProtocolType proto;
5162 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5163 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5164 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5166 is_local_account = FALSE;
5167 /* New button should be dimmed on remote
5169 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5171 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5173 g_object_unref (local_account);
5175 /* It could not exist */
5177 g_object_unref (mmc_account);
5180 /* Check the target folder rules */
5181 if (TNY_IS_FOLDER (folder_store)) {
5182 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5183 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5184 ok_sensitive = FALSE;
5185 new_sensitive = FALSE;
5190 /* Check if we're moving a folder */
5191 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5192 /* Get the widgets */
5193 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5194 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5195 if (gtk_widget_is_focus (folder_view))
5196 moving_folder = TRUE;
5199 if (moving_folder) {
5200 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5202 /* Get the folder to move */
5203 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5205 /* Check that we're not moving to the same folder */
5206 if (TNY_IS_FOLDER (moved_folder)) {
5207 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5208 if (parent == folder_store)
5209 ok_sensitive = FALSE;
5210 g_object_unref (parent);
5213 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5214 /* Do not allow to move to an account unless it's the
5215 local folders account */
5216 if (!is_local_account)
5217 ok_sensitive = FALSE;
5220 if (ok_sensitive && (moved_folder == folder_store)) {
5221 /* Do not allow to move to itself */
5222 ok_sensitive = FALSE;
5224 g_object_unref (moved_folder);
5226 TnyFolder *src_folder = NULL;
5228 /* Moving a message */
5229 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5231 TnyHeader *header = NULL;
5232 header = modest_msg_view_window_get_header
5233 (MODEST_MSG_VIEW_WINDOW (user_data));
5234 if (!TNY_IS_HEADER(header))
5235 g_warning ("%s: could not get source header", __FUNCTION__);
5237 src_folder = tny_header_get_folder (header);
5240 g_object_unref (header);
5243 TNY_FOLDER (modest_folder_view_get_selected
5244 (MODEST_FOLDER_VIEW (folder_view)));
5247 if (TNY_IS_FOLDER(src_folder)) {
5248 /* Do not allow to move the msg to the same folder */
5249 /* Do not allow to move the msg to an account */
5250 if ((gpointer) src_folder == (gpointer) folder_store ||
5251 TNY_IS_ACCOUNT (folder_store))
5252 ok_sensitive = FALSE;
5253 g_object_unref (src_folder);
5255 g_warning ("%s: could not get source folder", __FUNCTION__);
5259 /* Set sensitivity of the OK and NEW button */
5260 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5261 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5266 on_move_to_dialog_response (GtkDialog *dialog,
5270 GtkWidget *parent_win;
5271 MoveToInfo *helper = NULL;
5272 ModestFolderView *folder_view;
5273 gboolean unset_edit_mode = FALSE;
5275 helper = (MoveToInfo *) user_data;
5277 parent_win = (GtkWidget *) helper->win;
5278 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5279 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5281 TnyFolderStore *dst_folder;
5282 TnyFolderStore *selected;
5284 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5285 selected = modest_folder_view_get_selected (folder_view);
5286 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5287 g_object_unref (selected);
5289 case GTK_RESPONSE_NONE:
5290 case GTK_RESPONSE_CANCEL:
5291 case GTK_RESPONSE_DELETE_EVENT:
5293 case GTK_RESPONSE_OK:
5294 dst_folder = modest_folder_view_get_selected (folder_view);
5296 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5297 /* Clean list to move used for filtering */
5298 modest_folder_view_set_list_to_move (folder_view, NULL);
5300 modest_ui_actions_on_main_window_move_to (NULL,
5301 GTK_WIDGET (folder_view),
5303 MODEST_MAIN_WINDOW (parent_win));
5304 #ifdef MODEST_TOOLKIT_HILDON2
5305 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5306 /* Clean list to move used for filtering */
5307 modest_folder_view_set_list_to_move (folder_view, NULL);
5309 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5312 GTK_WINDOW (parent_win));
5315 /* if the user selected a root folder
5316 (account) then do not perform any action */
5317 if (TNY_IS_ACCOUNT (dst_folder)) {
5318 g_signal_stop_emission_by_name (dialog, "response");
5322 /* Clean list to move used for filtering */
5323 modest_folder_view_set_list_to_move (folder_view, NULL);
5325 /* Moving from headers window in edit mode */
5326 modest_ui_actions_on_window_move_to (NULL, helper->list,
5328 MODEST_WINDOW (parent_win));
5332 g_object_unref (dst_folder);
5334 unset_edit_mode = TRUE;
5337 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5340 /* Free the helper and exit */
5342 g_object_unref (helper->list);
5343 if (unset_edit_mode) {
5344 #ifdef MODEST_TOOLKIT_HILDON2
5345 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5348 g_slice_free (MoveToInfo, helper);
5349 gtk_widget_destroy (GTK_WIDGET (dialog));
5353 create_move_to_dialog (GtkWindow *win,
5354 GtkWidget *folder_view,
5355 TnyList *list_to_move)
5357 GtkWidget *dialog, *tree_view = NULL;
5359 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5361 #ifndef MODEST_TOOLKIT_HILDON2
5362 /* Track changes in the selection to
5363 * disable the OK button whenever "Move to" is not possible
5364 * disbale NEW button whenever New is not possible */
5365 g_signal_connect (tree_view,
5366 "folder_selection_changed",
5367 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5371 /* It could happen that we're trying to move a message from a
5372 window (msg window for example) after the main window was
5373 closed, so we can not just get the model of the folder
5375 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5376 const gchar *visible_id = NULL;
5378 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5379 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5380 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5381 MODEST_FOLDER_VIEW(tree_view));
5384 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5386 /* Show the same account than the one that is shown in the main window */
5387 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5390 const gchar *active_account_name = NULL;
5391 ModestAccountMgr *mgr = NULL;
5392 ModestAccountSettings *settings = NULL;
5393 ModestServerAccountSettings *store_settings = NULL;
5395 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5396 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5397 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5398 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5400 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5401 mgr = modest_runtime_get_account_mgr ();
5402 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5405 const gchar *store_account_name;
5406 store_settings = modest_account_settings_get_store_settings (settings);
5407 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5409 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5410 store_account_name);
5411 g_object_unref (store_settings);
5412 g_object_unref (settings);
5416 /* we keep a pointer to the embedded folder view, so we can
5417 * retrieve it with get_folder_view_from_move_to_dialog (see
5418 * above) later (needed for focus handling)
5420 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5422 /* Hide special folders */
5423 #ifndef MODEST_TOOLKIT_HILDON2
5424 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5427 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5428 #ifndef MODEST_TOOLKIT_HILDON2
5429 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5432 gtk_widget_show (GTK_WIDGET (tree_view));
5438 * Shows a confirmation dialog to the user when we're moving messages
5439 * from a remote server to the local storage. Returns the dialog
5440 * response. If it's other kind of movement then it always returns
5443 * This one is used by the next functions:
5444 * modest_ui_actions_on_paste - commented out
5445 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5448 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5449 TnyFolder *dest_folder,
5453 gint response = GTK_RESPONSE_OK;
5454 TnyAccount *account = NULL;
5455 TnyFolder *src_folder = NULL;
5456 TnyIterator *iter = NULL;
5457 TnyHeader *header = NULL;
5459 /* return with OK if the destination is a remote folder */
5460 if (modest_tny_folder_is_remote_folder (dest_folder))
5461 return GTK_RESPONSE_OK;
5463 /* Get source folder */
5464 iter = tny_list_create_iterator (headers);
5465 header = TNY_HEADER (tny_iterator_get_current (iter));
5467 src_folder = tny_header_get_folder (header);
5468 g_object_unref (header);
5470 g_object_unref (iter);
5472 /* if no src_folder, message may be an attahcment */
5473 if (src_folder == NULL)
5474 return GTK_RESPONSE_CANCEL;
5476 /* If the source is a local or MMC folder */
5477 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5478 g_object_unref (src_folder);
5479 return GTK_RESPONSE_OK;
5482 /* Get the account */
5483 account = tny_folder_get_account (src_folder);
5485 /* now if offline we ask the user */
5486 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5487 response = GTK_RESPONSE_OK;
5489 response = GTK_RESPONSE_CANCEL;
5492 g_object_unref (src_folder);
5493 g_object_unref (account);
5499 move_to_helper_destroyer (gpointer user_data)
5501 MoveToHelper *helper = (MoveToHelper *) user_data;
5503 /* Close the "Pasting" information banner */
5504 if (helper->banner) {
5505 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5506 g_object_unref (helper->banner);
5508 if (gtk_tree_row_reference_valid (helper->reference)) {
5509 gtk_tree_row_reference_free (helper->reference);
5510 helper->reference = NULL;
5516 move_to_cb (ModestMailOperation *mail_op,
5519 MoveToHelper *helper = (MoveToHelper *) user_data;
5520 GObject *object = modest_mail_operation_get_source (mail_op);
5522 /* Note that the operation could have failed, in that case do
5524 if (modest_mail_operation_get_status (mail_op) !=
5525 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5528 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5529 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5531 if (!modest_msg_view_window_select_next_message (self) &&
5532 !modest_msg_view_window_select_previous_message (self)) {
5533 /* No more messages to view, so close this window */
5534 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5536 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5537 gtk_tree_row_reference_valid (helper->reference)) {
5538 GtkWidget *header_view;
5540 GtkTreeSelection *sel;
5542 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5543 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5544 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5545 path = gtk_tree_row_reference_get_path (helper->reference);
5546 /* We need to unselect the previous one
5547 because we could be copying instead of
5549 gtk_tree_selection_unselect_all (sel);
5550 gtk_tree_selection_select_path (sel, path);
5551 gtk_tree_path_free (path);
5553 g_object_unref (object);
5556 /* Destroy the helper */
5557 move_to_helper_destroyer (helper);
5561 folder_move_to_cb (ModestMailOperation *mail_op,
5562 TnyFolder *new_folder,
5565 GtkWidget *folder_view;
5568 object = modest_mail_operation_get_source (mail_op);
5569 if (MODEST_IS_MAIN_WINDOW (object)) {
5570 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5571 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5572 g_object_ref (folder_view);
5573 g_object_unref (object);
5574 move_to_cb (mail_op, user_data);
5575 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5576 g_object_unref (folder_view);
5578 move_to_cb (mail_op, user_data);
5583 msgs_move_to_cb (ModestMailOperation *mail_op,
5586 move_to_cb (mail_op, user_data);
5590 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5593 GObject *win = NULL;
5594 const GError *error;
5595 TnyAccount *account = NULL;
5597 #ifndef MODEST_TOOLKIT_HILDON2
5598 ModestWindow *main_window = NULL;
5600 /* Disable next automatic folder selection */
5601 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5602 FALSE); /* don't create */
5604 /* Show notification dialog only if the main window exists */
5606 GtkWidget *folder_view = NULL;
5608 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5609 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5610 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5612 if (user_data && TNY_IS_FOLDER (user_data)) {
5613 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5614 TNY_FOLDER (user_data), FALSE);
5618 win = modest_mail_operation_get_source (mail_op);
5619 error = modest_mail_operation_get_error (mail_op);
5621 if (TNY_IS_FOLDER (user_data))
5622 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5623 else if (TNY_IS_ACCOUNT (user_data))
5624 account = g_object_ref (user_data);
5626 /* If it's not a disk full error then show a generic error */
5627 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5628 (GtkWidget *) win, (GError *) error,
5630 modest_platform_run_information_dialog ((GtkWindow *) win,
5631 _("mail_in_ui_folder_move_target_error"),
5634 g_object_unref (account);
5636 g_object_unref (win);
5640 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5649 gint pending_purges = 0;
5650 gboolean some_purged = FALSE;
5651 ModestWindow *win = MODEST_WINDOW (user_data);
5652 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5654 /* If there was any error */
5655 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5656 modest_window_mgr_unregister_header (mgr, header);
5660 /* Once the message has been retrieved for purging, we check if
5661 * it's all ok for purging */
5663 parts = tny_simple_list_new ();
5664 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5665 iter = tny_list_create_iterator (parts);
5667 while (!tny_iterator_is_done (iter)) {
5669 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5670 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5671 if (tny_mime_part_is_purged (part))
5678 g_object_unref (part);
5680 tny_iterator_next (iter);
5682 g_object_unref (iter);
5685 if (pending_purges>0) {
5687 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5689 if (response == GTK_RESPONSE_OK) {
5692 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5693 iter = tny_list_create_iterator (parts);
5694 while (!tny_iterator_is_done (iter)) {
5697 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5698 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5699 tny_mime_part_set_purged (part);
5702 g_object_unref (part);
5704 tny_iterator_next (iter);
5706 g_object_unref (iter);
5708 tny_msg_rewrite_cache (msg);
5710 gtk_widget_destroy (info);
5714 modest_window_mgr_unregister_header (mgr, header);
5716 g_object_unref (parts);
5720 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5721 ModestMainWindow *win)
5723 GtkWidget *header_view;
5724 TnyList *header_list;
5726 TnyHeaderFlags flags;
5727 ModestWindow *msg_view_window = NULL;
5730 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5732 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5733 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5735 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5737 g_warning ("%s: no header selected", __FUNCTION__);
5741 if (tny_list_get_length (header_list) == 1) {
5742 TnyIterator *iter = tny_list_create_iterator (header_list);
5743 header = TNY_HEADER (tny_iterator_get_current (iter));
5744 g_object_unref (iter);
5748 if (!header || !TNY_IS_HEADER(header)) {
5749 g_warning ("%s: header is not valid", __FUNCTION__);
5753 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5754 header, &msg_view_window);
5755 flags = tny_header_get_flags (header);
5756 if (!(flags & TNY_HEADER_FLAG_CACHED))
5759 if (msg_view_window != NULL)
5760 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5762 /* do nothing; uid was registered before, so window is probably on it's way */
5763 g_debug ("header %p has already been registered", header);
5766 ModestMailOperation *mail_op = NULL;
5767 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5768 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5769 modest_ui_actions_disk_operations_error_handler,
5771 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5772 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5774 g_object_unref (mail_op);
5777 g_object_unref (header);
5779 g_object_unref (header_list);
5783 * Checks if we need a connection to do the transfer and if the user
5784 * wants to connect to complete it
5787 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5788 TnyFolderStore *src_folder,
5790 TnyFolder *dst_folder,
5791 gboolean delete_originals,
5792 gboolean *need_connection,
5795 TnyAccount *src_account;
5796 gint uncached_msgs = 0;
5798 /* We don't need any further check if
5800 * 1- the source folder is local OR
5801 * 2- the device is already online
5803 if (!modest_tny_folder_store_is_remote (src_folder) ||
5804 tny_device_is_online (modest_runtime_get_device())) {
5805 *need_connection = FALSE;
5810 /* We must ask for a connection when
5812 * - the message(s) is not already cached OR
5813 * - the message(s) is cached but the leave_on_server setting
5814 * is FALSE (because we need to sync the source folder to
5815 * delete the message from the server (for IMAP we could do it
5816 * offline, it'll take place the next time we get a
5819 uncached_msgs = header_list_count_uncached_msgs (headers);
5820 src_account = get_account_from_folder_store (src_folder);
5821 if (uncached_msgs > 0) {
5825 *need_connection = TRUE;
5826 num_headers = tny_list_get_length (headers);
5827 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5829 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5830 GTK_RESPONSE_CANCEL) {
5836 /* The transfer is possible and the user wants to */
5839 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5840 const gchar *account_name;
5841 gboolean leave_on_server;
5843 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5844 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5847 if (leave_on_server == TRUE) {
5848 *need_connection = FALSE;
5850 *need_connection = TRUE;
5853 *need_connection = FALSE;
5858 g_object_unref (src_account);
5862 xfer_messages_error_handler (ModestMailOperation *mail_op,
5866 const GError *error;
5867 TnyAccount *account;
5869 win = modest_mail_operation_get_source (mail_op);
5870 error = modest_mail_operation_get_error (mail_op);
5872 /* We cannot get the account from the mail op as that is the
5873 source account and for checking memory full conditions we
5874 need the destination one */
5875 account = TNY_ACCOUNT (user_data);
5878 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5879 (GtkWidget *) win, (GError*) error,
5880 account, _KR("cerm_memory_card_full"))) {
5881 modest_platform_run_information_dialog ((GtkWindow *) win,
5882 _("mail_in_ui_folder_move_target_error"),
5886 g_object_unref (win);
5890 TnyFolderStore *dst_folder;
5895 * Utility function that transfer messages from both the main window
5896 * and the msg view window when using the "Move to" dialog
5899 xfer_messages_performer (gboolean canceled,
5901 GtkWindow *parent_window,
5902 TnyAccount *account,
5905 ModestWindow *win = MODEST_WINDOW (parent_window);
5906 TnyAccount *dst_account = NULL;
5907 gboolean dst_forbids_message_add = FALSE;
5908 XferMsgsHelper *helper;
5909 MoveToHelper *movehelper;
5910 ModestMailOperation *mail_op;
5912 helper = (XferMsgsHelper *) user_data;
5914 if (canceled || err) {
5915 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5916 (GtkWidget *) parent_window, err,
5918 /* Show the proper error message */
5919 modest_ui_actions_on_account_connection_error (parent_window, account);
5924 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5926 /* tinymail will return NULL for local folders it seems */
5927 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5928 modest_tny_account_get_protocol_type (dst_account),
5929 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5931 if (dst_forbids_message_add) {
5932 modest_platform_information_banner (GTK_WIDGET (win),
5934 ngettext("mail_in_ui_folder_move_target_error",
5935 "mail_in_ui_folder_move_targets_error",
5936 tny_list_get_length (helper->headers)));
5940 movehelper = g_new0 (MoveToHelper, 1);
5942 #ifndef MODEST_TOOLKIT_HILDON2
5943 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5944 _CS("ckct_nw_pasting"));
5945 if (movehelper->banner != NULL) {
5946 g_object_ref (movehelper->banner);
5947 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5951 if (MODEST_IS_MAIN_WINDOW (win)) {
5952 GtkWidget *header_view =
5953 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5954 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5955 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5958 /* Perform the mail operation */
5959 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5960 xfer_messages_error_handler,
5961 g_object_ref (dst_account),
5963 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5966 modest_mail_operation_xfer_msgs (mail_op,
5968 TNY_FOLDER (helper->dst_folder),
5973 g_object_unref (G_OBJECT (mail_op));
5976 g_object_unref (dst_account);
5977 g_object_unref (helper->dst_folder);
5978 g_object_unref (helper->headers);
5979 g_slice_free (XferMsgsHelper, helper);
5983 TnyFolder *src_folder;
5984 TnyFolderStore *dst_folder;
5985 gboolean delete_original;
5986 GtkWidget *folder_view;
5990 on_move_folder_cb (gboolean canceled,
5992 GtkWindow *parent_window,
5993 TnyAccount *account,
5996 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5997 GtkTreeSelection *sel;
5998 ModestMailOperation *mail_op = NULL;
6000 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6001 /* Note that the connection process can fail due to
6002 memory low conditions as it can not successfully
6003 store the summary */
6004 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6005 (GtkWidget*) parent_window, err,
6007 g_debug ("Error connecting when trying to move a folder");
6009 g_object_unref (G_OBJECT (info->src_folder));
6010 g_object_unref (G_OBJECT (info->dst_folder));
6015 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6016 #ifndef MODEST_TOOLKIT_HILDON2
6017 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6018 _CS("ckct_nw_pasting"));
6019 if (helper->banner != NULL) {
6020 g_object_ref (helper->banner);
6021 gtk_widget_show (GTK_WIDGET(helper->banner));
6024 /* Clean folder on header view before moving it */
6025 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6026 gtk_tree_selection_unselect_all (sel);
6028 /* Let gtk events run. We need that the folder
6029 view frees its reference to the source
6030 folder *before* issuing the mail operation
6031 so we need the signal handler of selection
6032 changed to happen before the mail
6034 while (gtk_events_pending ())
6035 gtk_main_iteration (); */
6038 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6039 modest_ui_actions_move_folder_error_handler,
6040 g_object_ref (info->dst_folder), g_object_unref);
6041 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6044 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6045 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6046 TNY_FOLDER (info->dst_folder), TRUE);
6048 modest_mail_operation_xfer_folder (mail_op,
6049 TNY_FOLDER (info->src_folder),
6051 info->delete_original,
6054 g_object_unref (G_OBJECT (info->src_folder));
6056 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6059 /* Unref mail operation */
6060 g_object_unref (G_OBJECT (mail_op));
6061 g_object_unref (G_OBJECT (info->dst_folder));
6066 get_account_from_folder_store (TnyFolderStore *folder_store)
6068 if (TNY_IS_ACCOUNT (folder_store))
6069 return g_object_ref (folder_store);
6071 return tny_folder_get_account (TNY_FOLDER (folder_store));
6075 * UI handler for the "Move to" action when invoked from the
6079 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6080 GtkWidget *folder_view,
6081 TnyFolderStore *dst_folder,
6082 ModestMainWindow *win)
6084 ModestHeaderView *header_view = NULL;
6085 TnyFolderStore *src_folder = NULL;
6087 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6089 /* Get the source folder */
6090 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6092 /* Get header view */
6093 header_view = (ModestHeaderView *)
6094 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6096 /* Get folder or messages to transfer */
6097 if (gtk_widget_is_focus (folder_view)) {
6098 gboolean do_xfer = TRUE;
6100 /* Allow only to transfer folders to the local root folder */
6101 if (TNY_IS_ACCOUNT (dst_folder) &&
6102 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6103 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6105 } else if (!TNY_IS_FOLDER (src_folder)) {
6106 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6111 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6112 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6114 info->src_folder = g_object_ref (src_folder);
6115 info->dst_folder = g_object_ref (dst_folder);
6116 info->delete_original = TRUE;
6117 info->folder_view = folder_view;
6119 connect_info->callback = on_move_folder_cb;
6120 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6121 connect_info->data = info;
6123 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6124 TNY_FOLDER_STORE (src_folder),
6127 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6130 headers = modest_header_view_get_selected_headers(header_view);
6132 /* Transfer the messages */
6133 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6134 headers, TNY_FOLDER (dst_folder));
6136 g_object_unref (headers);
6140 g_object_unref (src_folder);
6143 #ifdef MODEST_TOOLKIT_HILDON2
6145 * UI handler for the "Move to" action when invoked from the
6146 * ModestFolderWindow
6149 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6150 TnyFolderStore *dst_folder,
6154 TnyFolderStore *src_folder = NULL;
6155 TnyIterator *iterator;
6157 if (tny_list_get_length (selection) != 1)
6160 iterator = tny_list_create_iterator (selection);
6161 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6162 g_object_unref (iterator);
6165 gboolean do_xfer = TRUE;
6167 /* Allow only to transfer folders to the local root folder */
6168 if (TNY_IS_ACCOUNT (dst_folder) &&
6169 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6170 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6173 modest_platform_run_information_dialog (win,
6174 _("mail_in_ui_folder_move_target_error"),
6176 } else if (!TNY_IS_FOLDER (src_folder)) {
6177 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6182 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6183 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6185 info->src_folder = g_object_ref (src_folder);
6186 info->dst_folder = g_object_ref (dst_folder);
6187 info->delete_original = TRUE;
6188 info->folder_view = folder_view;
6190 connect_info->callback = on_move_folder_cb;
6191 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6192 connect_info->data = info;
6194 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6195 TNY_FOLDER_STORE (src_folder),
6200 g_object_unref (src_folder);
6206 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6207 TnyFolder *src_folder,
6209 TnyFolder *dst_folder)
6211 gboolean need_connection = TRUE;
6212 gboolean do_xfer = TRUE;
6213 XferMsgsHelper *helper;
6215 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6216 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6217 g_return_if_fail (TNY_IS_LIST (headers));
6219 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6220 headers, TNY_FOLDER (dst_folder),
6221 TRUE, &need_connection,
6224 /* If we don't want to transfer just return */
6228 /* Create the helper */
6229 helper = g_slice_new (XferMsgsHelper);
6230 helper->dst_folder = g_object_ref (dst_folder);
6231 helper->headers = g_object_ref (headers);
6233 if (need_connection) {
6234 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6235 connect_info->callback = xfer_messages_performer;
6236 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6237 connect_info->data = helper;
6239 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6240 TNY_FOLDER_STORE (src_folder),
6243 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6244 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6245 src_account, helper);
6246 g_object_unref (src_account);
6251 * UI handler for the "Move to" action when invoked from the
6252 * ModestMsgViewWindow
6255 modest_ui_actions_on_window_move_to (GtkAction *action,
6257 TnyFolderStore *dst_folder,
6260 TnyFolder *src_folder = NULL;
6262 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6265 TnyHeader *header = NULL;
6268 iter = tny_list_create_iterator (headers);
6269 header = (TnyHeader *) tny_iterator_get_current (iter);
6270 src_folder = tny_header_get_folder (header);
6272 /* Transfer the messages */
6273 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6275 TNY_FOLDER (dst_folder));
6278 g_object_unref (header);
6279 g_object_unref (iter);
6280 g_object_unref (src_folder);
6285 modest_ui_actions_on_move_to (GtkAction *action,
6288 modest_ui_actions_on_edit_mode_move_to (win);
6292 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6294 GtkWidget *dialog = NULL;
6295 MoveToInfo *helper = NULL;
6296 TnyList *list_to_move;
6298 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6300 #ifndef MODEST_TOOLKIT_HILDON2
6301 /* Get the main window if exists */
6302 ModestMainWindow *main_window;
6303 if (MODEST_IS_MAIN_WINDOW (win))
6304 main_window = MODEST_MAIN_WINDOW (win);
6307 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6308 FALSE)); /* don't create */
6311 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6316 if (tny_list_get_length (list_to_move) < 1) {
6317 g_object_unref (list_to_move);
6321 /* Create and run the dialog */
6322 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6323 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6324 GTK_WINDOW (dialog),
6328 helper = g_slice_new0 (MoveToInfo);
6329 helper->list = list_to_move;
6332 /* Listen to response signal */
6333 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6335 /* Show the dialog */
6336 gtk_widget_show (dialog);
6342 * Calls #HeadersFunc for each header already selected in the main
6343 * window or the message currently being shown in the msg view window
6346 do_headers_action (ModestWindow *win,
6350 TnyList *headers_list = NULL;
6351 TnyIterator *iter = NULL;
6352 TnyHeader *header = NULL;
6353 TnyFolder *folder = NULL;
6356 headers_list = get_selected_headers (win);
6360 /* Get the folder */
6361 iter = tny_list_create_iterator (headers_list);
6362 header = TNY_HEADER (tny_iterator_get_current (iter));
6364 folder = tny_header_get_folder (header);
6365 g_object_unref (header);
6368 /* Call the function for each header */
6369 while (!tny_iterator_is_done (iter)) {
6370 header = TNY_HEADER (tny_iterator_get_current (iter));
6371 func (header, win, user_data);
6372 g_object_unref (header);
6373 tny_iterator_next (iter);
6376 /* Trick: do a poke status in order to speed up the signaling
6379 tny_folder_poke_status (folder);
6380 g_object_unref (folder);
6384 g_object_unref (iter);
6385 g_object_unref (headers_list);
6389 modest_ui_actions_view_attachment (GtkAction *action,
6390 ModestWindow *window)
6392 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6393 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6395 /* not supported window for this action */
6396 g_return_if_reached ();
6401 modest_ui_actions_save_attachments (GtkAction *action,
6402 ModestWindow *window)
6404 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6406 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6409 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6411 /* not supported window for this action */
6412 g_return_if_reached ();
6417 modest_ui_actions_remove_attachments (GtkAction *action,
6418 ModestWindow *window)
6420 if (MODEST_IS_MAIN_WINDOW (window)) {
6421 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6422 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6423 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6425 /* not supported window for this action */
6426 g_return_if_reached ();
6431 modest_ui_actions_on_settings (GtkAction *action,
6436 dialog = modest_platform_get_global_settings_dialog ();
6437 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6438 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6439 gtk_widget_show_all (dialog);
6441 gtk_dialog_run (GTK_DIALOG (dialog));
6443 gtk_widget_destroy (dialog);
6447 modest_ui_actions_on_help (GtkAction *action,
6450 /* Help app is not available at all in fremantle */
6451 #ifndef MODEST_TOOLKIT_HILDON2
6452 const gchar *help_id;
6454 g_return_if_fail (win && GTK_IS_WINDOW(win));
6456 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6459 modest_platform_show_help (GTK_WINDOW (win), help_id);
6464 modest_ui_actions_on_csm_help (GtkAction *action,
6467 /* Help app is not available at all in fremantle */
6468 #ifndef MODEST_TOOLKIT_HILDON2
6470 const gchar* help_id = NULL;
6471 GtkWidget *folder_view;
6472 TnyFolderStore *folder_store;
6474 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6476 /* Get selected folder */
6477 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6478 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6479 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6481 /* Switch help_id */
6482 if (folder_store && TNY_IS_FOLDER (folder_store))
6483 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6486 g_object_unref (folder_store);
6489 modest_platform_show_help (GTK_WINDOW (win), help_id);
6491 modest_ui_actions_on_help (action, win);
6496 retrieve_contents_cb (ModestMailOperation *mail_op,
6503 /* We only need this callback to show an error in case of
6504 memory low condition */
6505 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6506 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6511 retrieve_msg_contents_performer (gboolean canceled,
6513 GtkWindow *parent_window,
6514 TnyAccount *account,
6517 ModestMailOperation *mail_op;
6518 TnyList *headers = TNY_LIST (user_data);
6520 if (err || canceled) {
6521 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6522 (GtkWidget *) parent_window, err,
6527 /* Create mail operation */
6528 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6529 modest_ui_actions_disk_operations_error_handler,
6531 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6532 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6535 g_object_unref (mail_op);
6537 g_object_unref (headers);
6538 g_object_unref (account);
6542 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6543 ModestWindow *window)
6545 TnyList *headers = NULL;
6546 TnyAccount *account = NULL;
6547 TnyIterator *iter = NULL;
6548 TnyHeader *header = NULL;
6549 TnyFolder *folder = NULL;
6552 headers = get_selected_headers (window);
6556 /* Pick the account */
6557 iter = tny_list_create_iterator (headers);
6558 header = TNY_HEADER (tny_iterator_get_current (iter));
6559 folder = tny_header_get_folder (header);
6560 account = tny_folder_get_account (folder);
6561 g_object_unref (folder);
6562 g_object_unref (header);
6563 g_object_unref (iter);
6565 /* Connect and perform the message retrieval */
6566 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6567 g_object_ref (account),
6568 retrieve_msg_contents_performer,
6569 g_object_ref (headers));
6572 g_object_unref (account);
6573 g_object_unref (headers);
6577 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6579 g_return_if_fail (MODEST_IS_WINDOW (window));
6582 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6586 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6588 g_return_if_fail (MODEST_IS_WINDOW (window));
6591 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6595 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6596 ModestWindow *window)
6598 g_return_if_fail (MODEST_IS_WINDOW (window));
6601 modest_ui_actions_check_menu_dimming_rules (window);
6605 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6606 ModestWindow *window)
6608 g_return_if_fail (MODEST_IS_WINDOW (window));
6611 modest_ui_actions_check_menu_dimming_rules (window);
6615 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6616 ModestWindow *window)
6618 g_return_if_fail (MODEST_IS_WINDOW (window));
6621 modest_ui_actions_check_menu_dimming_rules (window);
6625 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6626 ModestWindow *window)
6628 g_return_if_fail (MODEST_IS_WINDOW (window));
6631 modest_ui_actions_check_menu_dimming_rules (window);
6635 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6636 ModestWindow *window)
6638 g_return_if_fail (MODEST_IS_WINDOW (window));
6641 modest_ui_actions_check_menu_dimming_rules (window);
6645 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6646 ModestWindow *window)
6648 g_return_if_fail (MODEST_IS_WINDOW (window));
6651 modest_ui_actions_check_menu_dimming_rules (window);
6655 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6656 ModestWindow *window)
6658 g_return_if_fail (MODEST_IS_WINDOW (window));
6661 modest_ui_actions_check_menu_dimming_rules (window);
6665 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6666 ModestWindow *window)
6668 g_return_if_fail (MODEST_IS_WINDOW (window));
6671 modest_ui_actions_check_menu_dimming_rules (window);
6675 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6676 ModestWindow *window)
6678 g_return_if_fail (MODEST_IS_WINDOW (window));
6681 modest_ui_actions_check_menu_dimming_rules (window);
6685 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6687 g_return_if_fail (MODEST_IS_WINDOW (window));
6689 /* we check for low-mem; in that case, show a warning, and don't allow
6692 if (modest_platform_check_memory_low (window, TRUE))
6695 modest_platform_show_search_messages (GTK_WINDOW (window));
6699 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6701 g_return_if_fail (MODEST_IS_WINDOW (win));
6704 /* we check for low-mem; in that case, show a warning, and don't allow
6705 * for the addressbook
6707 if (modest_platform_check_memory_low (win, TRUE))
6711 modest_platform_show_addressbook (GTK_WINDOW (win));
6716 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6717 ModestWindow *window)
6720 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6722 if (GTK_IS_TOGGLE_ACTION (action))
6723 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6727 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6732 on_send_receive_finished (ModestMailOperation *mail_op,
6735 GtkWidget *header_view, *folder_view;
6736 TnyFolderStore *folder_store;
6737 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6739 /* Set send/receive operation finished */
6740 modest_main_window_notify_send_receive_completed (main_win);
6742 /* Don't refresh the current folder if there were any errors */
6743 if (modest_mail_operation_get_status (mail_op) !=
6744 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6747 /* Refresh the current folder if we're viewing a window. We do
6748 this because the user won't be able to see the new mails in
6749 the selected folder after a Send&Receive because it only
6750 performs a poke_status, i.e, only the number of read/unread
6751 messages is updated, but the new headers are not
6753 folder_view = modest_main_window_get_child_widget (main_win,
6754 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6758 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6760 /* Do not need to refresh INBOX again because the
6761 update_account does it always automatically */
6762 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6763 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6764 ModestMailOperation *refresh_op;
6766 header_view = modest_main_window_get_child_widget (main_win,
6767 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6769 /* We do not need to set the contents style
6770 because it hasn't changed. We also do not
6771 need to save the widget status. Just force
6773 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6774 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6775 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6776 folder_refreshed_cb, main_win);
6777 g_object_unref (refresh_op);
6781 g_object_unref (folder_store);
6786 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6792 const gchar* server_name = NULL;
6793 TnyTransportAccount *transport;
6794 gchar *message = NULL;
6795 ModestProtocol *protocol;
6797 /* Don't show anything if the user cancelled something or the
6798 * send receive request is not interactive. Authentication
6799 * errors are managed by the account store so no need to show
6800 * a dialog here again */
6801 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6802 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6803 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6807 /* Get the server name. Note that we could be using a
6808 connection specific transport account */
6809 transport = (TnyTransportAccount *)
6810 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6812 ModestTnyAccountStore *acc_store;
6813 const gchar *acc_name;
6814 TnyTransportAccount *conn_specific;
6816 acc_store = modest_runtime_get_account_store();
6817 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6818 conn_specific = (TnyTransportAccount *)
6819 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6820 if (conn_specific) {
6821 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6822 g_object_unref (conn_specific);
6824 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6826 g_object_unref (transport);
6830 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6831 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6832 tny_account_get_proto (TNY_ACCOUNT (transport)));
6834 g_warning ("%s: Account with no proto", __FUNCTION__);
6838 /* Show the appropriate message text for the GError: */
6839 switch (err->code) {
6840 case TNY_SERVICE_ERROR_CONNECT:
6841 message = modest_protocol_get_translation (protocol,
6842 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6845 case TNY_SERVICE_ERROR_SEND:
6846 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6848 case TNY_SERVICE_ERROR_UNAVAILABLE:
6849 message = modest_protocol_get_translation (protocol,
6850 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6854 g_warning ("%s: unexpected ERROR %d",
6855 __FUNCTION__, err->code);
6856 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6860 modest_platform_run_information_dialog (NULL, message, FALSE);
6865 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6870 ModestWindow *top_window = NULL;
6871 ModestWindowMgr *mgr = NULL;
6872 GtkWidget *header_view = NULL;
6873 TnyFolder *selected_folder = NULL;
6874 TnyFolderType folder_type;
6876 mgr = modest_runtime_get_window_mgr ();
6877 top_window = modest_window_mgr_get_current_top (mgr);
6882 #ifndef MODEST_TOOLKIT_HILDON2
6883 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6884 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6885 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6888 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6889 header_view = (GtkWidget *)
6890 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6894 /* Get selected folder */
6896 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6897 if (!selected_folder)
6900 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6901 #if GTK_CHECK_VERSION(2, 8, 0)
6902 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6903 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6904 GtkTreeViewColumn *tree_column;
6906 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6907 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6909 gtk_tree_view_column_queue_resize (tree_column);
6911 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6912 gtk_widget_queue_draw (header_view);
6915 #ifndef MODEST_TOOLKIT_HILDON2
6916 /* Rerun dimming rules, because the message could become deletable for example */
6917 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6918 MODEST_DIMMING_RULES_TOOLBAR);
6919 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6920 MODEST_DIMMING_RULES_MENU);
6924 g_object_unref (selected_folder);
6928 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6929 TnyAccount *account)
6931 ModestProtocolType protocol_type;
6932 ModestProtocol *protocol;
6933 gchar *error_note = NULL;
6935 protocol_type = modest_tny_account_get_protocol_type (account);
6936 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6939 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6940 if (error_note == NULL) {
6941 g_warning ("%s: This should not be reached", __FUNCTION__);
6943 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6944 g_free (error_note);
6949 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6953 TnyFolderStore *folder = NULL;
6954 TnyAccount *account = NULL;
6955 ModestProtocolType proto;
6956 ModestProtocol *protocol;
6957 TnyHeader *header = NULL;
6959 if (MODEST_IS_MAIN_WINDOW (win)) {
6960 GtkWidget *header_view;
6961 TnyList* headers = NULL;
6963 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6964 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6965 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6966 if (!headers || tny_list_get_length (headers) == 0) {
6968 g_object_unref (headers);
6971 iter = tny_list_create_iterator (headers);
6972 header = TNY_HEADER (tny_iterator_get_current (iter));
6973 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6974 g_object_unref (iter);
6975 g_object_unref (headers);
6976 #ifdef MODEST_TOOLKIT_HILDON2
6977 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6978 GtkWidget *header_view;
6979 TnyList* headers = NULL;
6981 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6982 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6983 if (!headers || tny_list_get_length (headers) == 0) {
6985 g_object_unref (headers);
6988 iter = tny_list_create_iterator (headers);
6989 header = TNY_HEADER (tny_iterator_get_current (iter));
6991 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6993 g_warning ("List should contain headers");
6995 g_object_unref (iter);
6996 g_object_unref (headers);
6998 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6999 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7001 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7004 if (!header || !folder)
7007 /* Get the account type */
7008 account = tny_folder_get_account (TNY_FOLDER (folder));
7009 proto = modest_tny_account_get_protocol_type (account);
7010 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7013 subject = tny_header_dup_subject (header);
7014 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7018 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7024 g_object_unref (account);
7026 g_object_unref (folder);
7028 g_object_unref (header);
7034 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7035 const gchar *account_name,
7036 const gchar *account_title)
7038 ModestAccountMgr *account_mgr;
7041 ModestProtocol *protocol;
7042 gboolean removed = FALSE;
7044 g_return_val_if_fail (account_name, FALSE);
7045 g_return_val_if_fail (account_title, FALSE);
7047 account_mgr = modest_runtime_get_account_mgr();
7049 /* The warning text depends on the account type: */
7050 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7051 modest_account_mgr_get_store_protocol (account_mgr,
7053 txt = modest_protocol_get_translation (protocol,
7054 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7057 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7059 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7063 if (response == GTK_RESPONSE_OK) {
7064 /* Remove account. If it succeeds then it also removes
7065 the account from the ModestAccountView: */
7066 gboolean is_default = FALSE;
7067 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7068 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7070 g_free (default_account_name);
7072 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7074 #ifdef MODEST_TOOLKIT_HILDON2
7075 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7077 /* Close all email notifications, we cannot
7078 distinguish if the notification belongs to
7079 this account or not, so for safety reasons
7080 we remove them all */
7081 modest_platform_remove_new_mail_notifications (FALSE);
7083 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7090 on_fetch_images_performer (gboolean canceled,
7092 GtkWindow *parent_window,
7093 TnyAccount *account,
7096 if (err || canceled) {
7097 /* Show an unable to retrieve images ??? */
7101 /* Note that the user could have closed the window while connecting */
7102 if (GTK_WIDGET_VISIBLE (parent_window))
7103 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7104 g_object_unref ((GObject *) user_data);
7108 modest_ui_actions_on_fetch_images (GtkAction *action,
7109 ModestWindow *window)
7111 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7113 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7115 on_fetch_images_performer,
7116 g_object_ref (window));
7120 modest_ui_actions_on_reload_message (const gchar *msg_id)
7122 ModestWindow *window = NULL;
7124 g_return_if_fail (msg_id && msg_id[0] != '\0');
7125 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7131 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7134 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7137 /** Check whether any connections are active, and cancel them if
7139 * Returns TRUE is there was no problem,
7140 * or if an operation was cancelled so we can continue.
7141 * Returns FALSE if the user chose to cancel his request instead.
7145 modest_ui_actions_check_for_active_account (ModestWindow *self,
7146 const gchar* account_name)
7148 ModestTnySendQueue *send_queue;
7149 ModestTnyAccountStore *acc_store;
7150 ModestMailOperationQueue* queue;
7151 TnyConnectionStatus store_conn_status;
7152 TnyAccount *store_account = NULL, *transport_account = NULL;
7153 gboolean retval = TRUE, sending = FALSE;
7155 acc_store = modest_runtime_get_account_store ();
7156 queue = modest_runtime_get_mail_operation_queue ();
7159 modest_tny_account_store_get_server_account (acc_store,
7161 TNY_ACCOUNT_TYPE_STORE);
7163 /* This could happen if the account was deleted before the
7164 call to this function */
7169 modest_tny_account_store_get_server_account (acc_store,
7171 TNY_ACCOUNT_TYPE_TRANSPORT);
7173 /* This could happen if the account was deleted before the
7174 call to this function */
7175 if (!transport_account) {
7176 g_object_unref (store_account);
7180 /* If the transport account was not used yet, then the send
7181 queue could not exist (it's created on demand) */
7182 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7183 if (TNY_IS_SEND_QUEUE (send_queue))
7184 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7186 store_conn_status = tny_account_get_connection_status (store_account);
7187 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7190 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7191 _("emev_nc_disconnect_account"));
7192 if (response == GTK_RESPONSE_OK) {
7201 /* FIXME: We should only cancel those of this account */
7202 modest_mail_operation_queue_cancel_all (queue);
7204 /* Also disconnect the account */
7205 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7206 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7207 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7211 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7217 g_object_unref (store_account);
7218 g_object_unref (transport_account);