1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #ifdef MODEST_PLATFORM_MAEMO
63 #include "maemo/modest-osso-state-saving.h"
64 #endif /* MODEST_PLATFORM_MAEMO */
65 #ifndef MODEST_TOOLKIT_GTK
66 #include "maemo/modest-hildon-includes.h"
67 #include "maemo/modest-connection-specific-smtp-window.h"
68 #endif /* !MODEST_TOOLKIT_GTK */
70 #include <modest-utils.h>
71 #include "widgets/modest-ui-constants.h"
72 #include <widgets/modest-main-window.h>
73 #include <widgets/modest-msg-view-window.h>
74 #include <widgets/modest-account-view-window.h>
75 #include <widgets/modest-details-dialog.h>
76 #include <widgets/modest-attachments-view.h>
77 #include "widgets/modest-folder-view.h"
78 #include "widgets/modest-global-settings-dialog.h"
79 #include "modest-account-mgr-helpers.h"
80 #include "modest-mail-operation.h"
81 #include "modest-text-utils.h"
82 #include <modest-widget-memory.h>
83 #include <tny-error.h>
84 #include <tny-simple-list.h>
85 #include <tny-msg-view.h>
86 #include <tny-device.h>
87 #include <tny-merge-folder.h>
89 #include <gtkhtml/gtkhtml.h>
91 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
93 typedef struct _GetMsgAsyncHelper {
95 ModestMailOperation *mail_op;
102 typedef enum _ReplyForwardAction {
106 } ReplyForwardAction;
108 typedef struct _ReplyForwardHelper {
109 guint reply_forward_type;
110 ReplyForwardAction action;
113 GtkWidget *parent_window;
115 } ReplyForwardHelper;
117 typedef struct _MoveToHelper {
118 GtkTreeRowReference *reference;
122 typedef struct _PasteAsAttachmentHelper {
123 ModestMsgEditWindow *window;
125 } PasteAsAttachmentHelper;
133 * The do_headers_action uses this kind of functions to perform some
134 * action to each member of a list of headers
136 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
138 static void do_headers_action (ModestWindow *win,
142 static void open_msg_cb (ModestMailOperation *mail_op,
149 static void reply_forward_cb (ModestMailOperation *mail_op,
156 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
158 static void folder_refreshed_cb (ModestMailOperation *mail_op,
162 static void on_send_receive_finished (ModestMailOperation *mail_op,
165 static gint header_list_count_uncached_msgs (TnyList *header_list);
167 static gboolean connect_to_get_msg (ModestWindow *win,
168 gint num_of_uncached_msgs,
169 TnyAccount *account);
171 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
173 static void do_create_folder (GtkWindow *window,
174 TnyFolderStore *parent_folder,
175 const gchar *suggested_name);
177 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
179 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
180 GtkWidget *folder_view,
181 TnyFolderStore *dst_folder,
182 ModestMainWindow *win);
183 #ifdef MODEST_TOOLKIT_HILDON2
184 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
185 TnyFolderStore *dst_folder,
190 static void modest_ui_actions_on_window_move_to (GtkAction *action,
191 TnyList *list_to_move,
192 TnyFolderStore *dst_folder,
196 * This function checks whether a TnyFolderStore is a pop account
199 remote_folder_has_leave_on_server (TnyFolderStore *folder)
204 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
206 account = get_account_from_folder_store (folder);
207 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
208 modest_tny_account_get_protocol_type (account)));
209 g_object_unref (account);
214 /* FIXME: this should be merged with the similar code in modest-account-view-window */
215 /* Show the account creation wizard dialog.
216 * returns: TRUE if an account was created. FALSE if the user cancelled.
219 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
221 gboolean result = FALSE;
223 gint dialog_response;
225 /* there is no such wizard yet */
226 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
227 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
229 #ifndef MODEST_TOOLKIT_HILDON2
230 /* always present a main window in the background
231 * we do it here, so we cannot end up with two wizards (as this
232 * function might be called in modest_window_mgr_get_main_window as well */
234 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
235 TRUE); /* create if not existent */
239 ModestWindowMgr *mgr;
241 mgr = modest_runtime_get_window_mgr ();
243 window_list = modest_window_mgr_get_window_list (mgr);
244 if (window_list == NULL) {
245 win = MODEST_WINDOW (modest_accounts_window_new ());
246 if (modest_window_mgr_register_window (mgr, win, NULL)) {
247 gtk_widget_show_all (GTK_WIDGET (win));
249 gtk_widget_destroy (GTK_WIDGET (win));
254 g_list_free (window_list);
260 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
262 /* make sure the mainwindow is visible. We need to present the
263 wizard again to give it the focus back. show_all are needed
264 in order to get the widgets properly drawn (MainWindow main
265 paned won't be in its right position and the dialog will be
267 #ifndef MODEST_TOOLKIT_HILDON2
268 gtk_widget_show_all (GTK_WIDGET (win));
269 gtk_widget_show_all (GTK_WIDGET (wizard));
270 gtk_window_present (GTK_WINDOW (win));
271 gtk_window_present (GTK_WINDOW (wizard));
274 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
275 gtk_widget_destroy (GTK_WIDGET (wizard));
276 if (gtk_events_pending ())
277 gtk_main_iteration ();
279 if (dialog_response == GTK_RESPONSE_CANCEL) {
282 /* Check whether an account was created: */
283 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
290 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
293 const gchar *authors[] = {
294 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
297 about = gtk_about_dialog_new ();
298 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
299 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
300 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
301 _("Copyright (c) 2006, Nokia Corporation\n"
302 "All rights reserved."));
303 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
304 _("a modest e-mail client\n\n"
305 "design and implementation: Dirk-Jan C. Binnema\n"
306 "contributions from the fine people at KC and Ig\n"
307 "uses the tinymail email framework written by Philip van Hoof"));
308 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
309 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
310 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
311 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
313 gtk_dialog_run (GTK_DIALOG (about));
314 gtk_widget_destroy(about);
318 * Gets the list of currently selected messages. If the win is the
319 * main window, then it returns a newly allocated list of the headers
320 * selected in the header view. If win is the msg view window, then
321 * the value returned is a list with just a single header.
323 * The caller of this funcion must free the list.
326 get_selected_headers (ModestWindow *win)
328 if (MODEST_IS_MAIN_WINDOW(win)) {
329 GtkWidget *header_view;
331 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
332 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
333 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
335 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 /* for MsgViewWindows, we simply return a list with one element */
338 TnyList *list = NULL;
340 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
341 if (header != NULL) {
342 list = tny_simple_list_new ();
343 tny_list_prepend (list, G_OBJECT(header));
344 g_object_unref (G_OBJECT(header));
349 #ifdef MODEST_TOOLKIT_HILDON2
350 } else if (MODEST_IS_HEADER_WINDOW (win)) {
351 GtkWidget *header_view;
353 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
354 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
360 static GtkTreeRowReference *
361 get_next_after_selected_headers (ModestHeaderView *header_view)
363 GtkTreeSelection *sel;
364 GList *selected_rows, *node;
366 GtkTreeRowReference *result;
369 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
370 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
371 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
373 if (selected_rows == NULL)
376 node = g_list_last (selected_rows);
377 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
378 gtk_tree_path_next (path);
380 result = gtk_tree_row_reference_new (model, path);
382 gtk_tree_path_free (path);
383 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
384 g_list_free (selected_rows);
390 headers_action_mark_as_read (TnyHeader *header,
394 TnyHeaderFlags flags;
396 g_return_if_fail (TNY_IS_HEADER(header));
398 flags = tny_header_get_flags (header);
399 if (flags & TNY_HEADER_FLAG_SEEN) return;
400 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
404 headers_action_mark_as_unread (TnyHeader *header,
408 TnyHeaderFlags flags;
410 g_return_if_fail (TNY_IS_HEADER(header));
412 flags = tny_header_get_flags (header);
413 if (flags & TNY_HEADER_FLAG_SEEN) {
414 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
418 /** After deleing a message that is currently visible in a window,
419 * show the next message from the list, or close the window if there are no more messages.
422 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
424 /* Close msg view window or select next */
425 if (!modest_msg_view_window_select_next_message (win) &&
426 !modest_msg_view_window_select_previous_message (win)) {
428 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
434 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
436 modest_ui_actions_on_edit_mode_delete_message (win);
440 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
442 TnyList *header_list = NULL;
443 TnyIterator *iter = NULL;
444 TnyHeader *header = NULL;
445 gchar *message = NULL;
448 ModestWindowMgr *mgr;
449 GtkWidget *header_view = NULL;
450 gboolean retval = TRUE;
452 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
454 /* Check first if the header view has the focus */
455 if (MODEST_IS_MAIN_WINDOW (win)) {
457 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
458 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
459 if (!gtk_widget_is_focus (header_view))
463 /* Get the headers, either from the header view (if win is the main window),
464 * or from the message view window: */
465 header_list = get_selected_headers (win);
466 if (!header_list) return FALSE;
468 /* Check if any of the headers are already opened, or in the process of being opened */
469 if (MODEST_IS_MAIN_WINDOW (win)) {
470 gint opened_headers = 0;
472 iter = tny_list_create_iterator (header_list);
473 mgr = modest_runtime_get_window_mgr ();
474 while (!tny_iterator_is_done (iter)) {
475 header = TNY_HEADER (tny_iterator_get_current (iter));
477 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
479 g_object_unref (header);
481 tny_iterator_next (iter);
483 g_object_unref (iter);
485 if (opened_headers > 0) {
488 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
491 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
494 g_object_unref (header_list);
500 if (tny_list_get_length(header_list) == 1) {
501 iter = tny_list_create_iterator (header_list);
502 header = TNY_HEADER (tny_iterator_get_current (iter));
505 subject = tny_header_dup_subject (header);
507 subject = g_strdup (_("mail_va_no_subject"));
508 desc = g_strdup_printf ("%s", subject);
510 g_object_unref (header);
513 g_object_unref (iter);
515 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
516 tny_list_get_length(header_list)), desc);
518 /* Confirmation dialog */
519 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
523 if (response == GTK_RESPONSE_OK) {
524 ModestWindowMgr *mgr = NULL;
525 GtkTreeModel *model = NULL;
526 GtkTreeSelection *sel = NULL;
527 GList *sel_list = NULL, *tmp = NULL;
528 GtkTreeRowReference *next_row_reference = NULL;
529 GtkTreeRowReference *prev_row_reference = NULL;
530 GtkTreePath *next_path = NULL;
531 GtkTreePath *prev_path = NULL;
532 ModestMailOperation *mail_op = NULL;
534 /* Find last selected row */
535 if (MODEST_IS_MAIN_WINDOW (win)) {
536 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
537 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
538 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
539 for (tmp=sel_list; tmp; tmp=tmp->next) {
540 if (tmp->next == NULL) {
541 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
542 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
544 gtk_tree_path_prev (prev_path);
545 gtk_tree_path_next (next_path);
547 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
548 next_row_reference = gtk_tree_row_reference_new (model, next_path);
553 /* Disable window dimming management */
554 modest_window_disable_dimming (win);
556 /* Remove each header. If it's a view window header_view == NULL */
557 mail_op = modest_mail_operation_new ((GObject *) win);
558 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
560 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
561 g_object_unref (mail_op);
563 /* Enable window dimming management */
565 gtk_tree_selection_unselect_all (sel);
567 modest_window_enable_dimming (win);
569 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
570 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
572 /* Get main window */
573 mgr = modest_runtime_get_window_mgr ();
574 } else if (MODEST_IS_MAIN_WINDOW (win)) {
575 /* Select next or previous row */
576 if (gtk_tree_row_reference_valid (next_row_reference)) {
577 gtk_tree_selection_select_path (sel, next_path);
579 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
580 gtk_tree_selection_select_path (sel, prev_path);
584 if (gtk_tree_row_reference_valid (next_row_reference))
585 gtk_tree_row_reference_free (next_row_reference);
586 if (next_path != NULL)
587 gtk_tree_path_free (next_path);
588 if (gtk_tree_row_reference_valid (prev_row_reference))
589 gtk_tree_row_reference_free (prev_row_reference);
590 if (prev_path != NULL)
591 gtk_tree_path_free (prev_path);
594 /* Update toolbar dimming state */
595 modest_ui_actions_check_menu_dimming_rules (win);
596 modest_ui_actions_check_toolbar_dimming_rules (win);
599 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
600 g_list_free (sel_list);
609 g_object_unref (header_list);
617 /* delete either message or folder, based on where we are */
619 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
621 g_return_if_fail (MODEST_IS_WINDOW(win));
623 /* Check first if the header view has the focus */
624 if (MODEST_IS_MAIN_WINDOW (win)) {
626 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
627 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
628 if (gtk_widget_is_focus (w)) {
629 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
633 modest_ui_actions_on_delete_message (action, win);
637 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
639 ModestWindowMgr *mgr = NULL;
641 #ifdef MODEST_PLATFORM_MAEMO
642 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
643 #endif /* MODEST_PLATFORM_MAEMO */
645 g_debug ("closing down, clearing %d item(s) from operation queue",
646 modest_mail_operation_queue_num_elements
647 (modest_runtime_get_mail_operation_queue()));
649 /* cancel all outstanding operations */
650 modest_mail_operation_queue_cancel_all
651 (modest_runtime_get_mail_operation_queue());
653 g_debug ("queue has been cleared");
656 /* Check if there are opened editing windows */
657 mgr = modest_runtime_get_window_mgr ();
658 modest_window_mgr_close_all_windows (mgr);
660 /* note: when modest-tny-account-store is finalized,
661 it will automatically set all network connections
664 /* gtk_main_quit (); */
668 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
672 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
674 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
675 /* gtk_widget_destroy (GTK_WIDGET (win)); */
676 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
677 /* gboolean ret_value; */
678 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
679 /* } else if (MODEST_IS_WINDOW (win)) { */
680 /* gtk_widget_destroy (GTK_WIDGET (win)); */
682 /* g_return_if_reached (); */
687 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
689 if (MODEST_IS_MSG_VIEW_WINDOW (win))
690 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
691 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
692 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
696 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
698 GtkClipboard *clipboard = NULL;
699 gchar *selection = NULL;
701 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
702 selection = gtk_clipboard_wait_for_text (clipboard);
705 modest_address_book_add_address (selection, (GtkWindow *) win);
711 modest_ui_actions_on_new_account (GtkAction *action,
712 ModestWindow *window)
714 if (!modest_ui_actions_run_account_setup_wizard (window)) {
715 g_debug ("%s: wizard was already running", __FUNCTION__);
720 modest_ui_actions_on_accounts (GtkAction *action,
723 /* This is currently only implemented for Maemo */
724 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
725 if (!modest_ui_actions_run_account_setup_wizard (win))
726 g_debug ("%s: wizard was already running", __FUNCTION__);
730 /* Show the list of accounts */
731 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
733 /* The accounts dialog must be modal */
734 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
735 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
740 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
742 /* This is currently only implemented for Maemo,
743 * because it requires an API (libconic) to detect different connection
746 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
748 /* Create the window if necessary: */
749 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
750 modest_connection_specific_smtp_window_fill_with_connections (
751 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
752 modest_runtime_get_account_mgr());
754 /* Show the window: */
755 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
756 GTK_WINDOW (specific_window), (GtkWindow *) win);
757 gtk_widget_show (specific_window);
758 #endif /* !MODEST_TOOLKIT_GTK */
762 count_part_size (const gchar *part)
764 GnomeVFSURI *vfs_uri;
765 gchar *escaped_filename;
767 GnomeVFSFileInfo *info;
770 /* Estimation of attachment size if we cannot get it from file info */
773 vfs_uri = gnome_vfs_uri_new (part);
775 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
776 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
777 g_free (escaped_filename);
778 gnome_vfs_uri_unref (vfs_uri);
780 info = gnome_vfs_file_info_new ();
782 if (gnome_vfs_get_file_info (part,
784 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
786 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
791 gnome_vfs_file_info_unref (info);
797 count_parts_size (GSList *parts)
802 for (node = parts; node != NULL; node = g_slist_next (node)) {
803 result += count_part_size ((const gchar *) node->data);
810 modest_ui_actions_compose_msg(ModestWindow *win,
813 const gchar *bcc_str,
814 const gchar *subject_str,
815 const gchar *body_str,
817 gboolean set_as_modified)
819 gchar *account_name = NULL;
820 const gchar *mailbox;
822 TnyAccount *account = NULL;
823 TnyFolder *folder = NULL;
824 gchar *from_str = NULL, *signature = NULL, *body = NULL;
825 gchar *recipient = NULL;
826 gboolean use_signature = FALSE;
827 ModestWindow *msg_win = NULL;
828 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
829 ModestTnyAccountStore *store = modest_runtime_get_account_store();
830 GnomeVFSFileSize total_size, allowed_size;
831 guint64 available_disk, expected_size, parts_size;
834 /* we check for low-mem */
835 if (modest_platform_check_memory_low (win, TRUE))
838 available_disk = modest_utils_get_available_space (NULL);
839 parts_count = g_slist_length (attachments);
840 parts_size = count_parts_size (attachments);
841 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
843 /* Double check: disk full condition or message too big */
844 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
845 expected_size > available_disk) {
846 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
847 modest_platform_system_banner (NULL, NULL, msg);
853 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
854 modest_platform_run_information_dialog (
856 _("mail_ib_error_attachment_size"),
862 #ifdef MODEST_TOOLKIT_HILDON2
864 account_name = g_strdup (modest_window_get_active_account(win));
867 account_name = modest_account_mgr_get_default_account(mgr);
870 g_printerr ("modest: no account found\n");
875 mailbox = modest_window_get_active_mailbox (win);
878 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
880 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
883 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
885 g_printerr ("modest: failed to find Drafts folder\n");
888 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
890 g_printerr ("modest: failed get from string for '%s'\n", account_name);
894 recipient = modest_text_utils_get_email_address (from_str);
895 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
897 if (body_str != NULL) {
898 body = use_signature ? g_strconcat(body_str, "\n",
899 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
900 "\n", signature, NULL) : g_strdup(body_str);
902 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
903 "\n", signature, NULL) : g_strdup("");
906 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
908 g_printerr ("modest: failed to create new msg\n");
912 /* Create and register edit window */
913 /* This is destroyed by TODO. */
915 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
916 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
918 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
919 gtk_widget_destroy (GTK_WIDGET (msg_win));
922 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
923 gtk_widget_show_all (GTK_WIDGET (msg_win));
925 while (attachments) {
926 GnomeVFSFileSize att_size;
928 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
929 attachments->data, allowed_size);
930 total_size += att_size;
932 if (att_size > allowed_size) {
933 g_debug ("%s: total size: %u",
934 __FUNCTION__, (unsigned int)total_size);
937 allowed_size -= att_size;
939 attachments = g_slist_next(attachments);
946 g_free (account_name);
948 g_object_unref (G_OBJECT(account));
950 g_object_unref (G_OBJECT(folder));
952 g_object_unref (G_OBJECT(msg));
956 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
958 /* if there are no accounts yet, just show the wizard */
959 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
960 if (!modest_ui_actions_run_account_setup_wizard (win))
963 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
968 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
972 ModestMailOperationStatus status;
974 /* If there is no message or the operation was not successful */
975 status = modest_mail_operation_get_status (mail_op);
976 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
979 /* If it's a memory low issue, then show a banner */
980 error = modest_mail_operation_get_error (mail_op);
981 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
982 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
983 GObject *source = modest_mail_operation_get_source (mail_op);
984 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
985 _KR("memr_ib_operation_disabled"),
987 g_object_unref (source);
990 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
991 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
992 gchar *subject, *msg, *format = NULL;
995 subject = (header) ? tny_header_dup_subject (header) : NULL;
997 subject = g_strdup (_("mail_va_no_subject"));
999 account = modest_mail_operation_get_account (mail_op);
1001 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1002 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1005 if (tny_account_get_connection_status (account) ==
1006 TNY_CONNECTION_STATUS_CONNECTED) {
1008 format = modest_protocol_get_translation (protocol,
1009 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1012 format = modest_protocol_get_translation (protocol,
1013 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1016 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1017 tny_account_get_hostname (account));
1020 g_object_unref (account);
1025 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1027 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1031 msg = g_strdup_printf (format, subject);
1032 modest_platform_run_information_dialog (NULL, msg, FALSE);
1038 /* Remove the header from the preregistered uids */
1039 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1052 } OpenMsgBannerInfo;
1055 GtkTreeModel *model;
1057 ModestWindow *caller_window;
1058 OpenMsgBannerInfo *banner_info;
1059 GtkTreeRowReference *rowref;
1063 open_msg_banner_idle (gpointer userdata)
1065 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1067 gdk_threads_enter ();
1068 banner_info->idle_handler = 0;
1069 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1070 if (banner_info->banner)
1071 g_object_ref (banner_info->banner);
1073 gdk_threads_leave ();
1079 get_header_view_from_window (ModestWindow *window)
1081 GtkWidget *header_view;
1083 if (MODEST_IS_MAIN_WINDOW (window)) {
1084 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1085 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1086 #ifdef MODEST_TOOLKIT_HILDON2
1087 } else if (MODEST_IS_HEADER_WINDOW (window)){
1088 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1098 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1101 gchar *account = NULL;
1102 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1107 folder = tny_header_get_folder (header);
1108 /* Gets folder type (OUTBOX headers will be opened in edit window */
1109 if (modest_tny_folder_is_local_folder (folder)) {
1110 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1111 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1112 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1115 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1116 TnyTransportAccount *traccount = NULL;
1117 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1118 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1120 ModestTnySendQueue *send_queue = NULL;
1121 ModestTnySendQueueStatus status;
1123 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1124 TNY_ACCOUNT(traccount)));
1125 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1126 if (TNY_IS_SEND_QUEUE (send_queue)) {
1127 msg_id = modest_tny_send_queue_get_msg_id (header);
1128 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1130 /* Only open messages in outbox with the editor if they are in Failed state */
1131 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1134 #ifdef MODEST_TOOLKIT_HILDON2
1136 /* In Fremantle we can not
1137 open any message from
1138 outbox which is not in
1144 g_object_unref(traccount);
1146 g_warning("Cannot get transport account for message in outbox!!");
1148 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1149 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1153 TnyAccount *acc = tny_folder_get_account (folder);
1156 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1157 g_object_unref (acc);
1161 g_object_unref (folder);
1167 open_msg_cb (ModestMailOperation *mail_op,
1174 ModestWindowMgr *mgr = NULL;
1175 ModestWindow *parent_win = NULL;
1176 ModestWindow *win = NULL;
1177 gchar *account = NULL;
1178 gboolean open_in_editor = FALSE;
1180 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1182 /* Do nothing if there was any problem with the mail
1183 operation. The error will be shown by the error_handler of
1184 the mail operation */
1185 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1188 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1190 /* Mark header as read */
1191 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1193 account = get_info_from_header (header, &open_in_editor, &can_open);
1197 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1199 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1201 if (open_in_editor) {
1202 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1203 gchar *from_header = NULL, *acc_name;
1204 gchar *mailbox = NULL;
1206 from_header = tny_header_dup_from (header);
1208 /* we cannot edit without a valid account... */
1209 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1210 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1211 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1213 g_free (from_header);
1218 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1219 g_free (from_header);
1225 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1229 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1230 const gchar *mailbox = NULL;
1232 if (parent_win && MODEST_IS_WINDOW (parent_win))
1233 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1235 if (helper->rowref && helper->model) {
1236 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1237 helper->model, helper->rowref);
1239 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1244 /* Register and show new window */
1246 mgr = modest_runtime_get_window_mgr ();
1247 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1248 gtk_widget_destroy (GTK_WIDGET (win));
1251 gtk_widget_show_all (GTK_WIDGET(win));
1254 /* Update toolbar dimming state */
1255 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1256 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1262 g_object_unref (parent_win);
1266 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1269 const GError *error;
1270 GObject *win = NULL;
1271 ModestMailOperationStatus status;
1273 win = modest_mail_operation_get_source (mail_op);
1274 error = modest_mail_operation_get_error (mail_op);
1275 status = modest_mail_operation_get_status (mail_op);
1277 /* If the mail op has been cancelled then it's not an error:
1278 don't show any message */
1279 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1280 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1281 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1282 (GError *) error, account)) {
1283 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1284 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1286 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1287 modest_platform_information_banner ((GtkWidget *) win,
1288 NULL, _("emev_ui_imap_inbox_select_error"));
1289 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1290 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1291 modest_platform_information_banner ((GtkWidget *) win,
1292 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1293 } else if (user_data) {
1294 modest_platform_information_banner ((GtkWidget *) win,
1298 g_object_unref (account);
1302 g_object_unref (win);
1306 * Returns the account a list of headers belongs to. It returns a
1307 * *new* reference so don't forget to unref it
1310 get_account_from_header_list (TnyList *headers)
1312 TnyAccount *account = NULL;
1314 if (tny_list_get_length (headers) > 0) {
1315 TnyIterator *iter = tny_list_create_iterator (headers);
1316 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1317 TnyFolder *folder = tny_header_get_folder (header);
1320 g_object_unref (header);
1322 while (!tny_iterator_is_done (iter)) {
1323 header = TNY_HEADER (tny_iterator_get_current (iter));
1324 folder = tny_header_get_folder (header);
1327 g_object_unref (header);
1329 tny_iterator_next (iter);
1334 account = tny_folder_get_account (folder);
1335 g_object_unref (folder);
1339 g_object_unref (header);
1341 g_object_unref (iter);
1347 get_account_from_header (TnyHeader *header)
1349 TnyAccount *account = NULL;
1352 folder = tny_header_get_folder (header);
1355 account = tny_folder_get_account (folder);
1356 g_object_unref (folder);
1362 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1364 if (helper->caller_window)
1365 helper->caller_window = NULL;
1369 open_msg_helper_destroyer (gpointer user_data)
1371 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1373 if (helper->caller_window) {
1374 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1375 helper->caller_window = NULL;
1378 if (helper->banner_info) {
1379 g_free (helper->banner_info->message);
1380 if (helper->banner_info->idle_handler > 0) {
1381 g_source_remove (helper->banner_info->idle_handler);
1382 helper->banner_info->idle_handler = 0;
1384 if (helper->banner_info->banner != NULL) {
1385 gtk_widget_destroy (helper->banner_info->banner);
1386 g_object_unref (helper->banner_info->banner);
1387 helper->banner_info->banner = NULL;
1389 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1390 helper->banner_info = NULL;
1392 g_object_unref (helper->model);
1393 g_object_unref (helper->header);
1394 gtk_tree_row_reference_free (helper->rowref);
1395 g_slice_free (OpenMsgHelper, helper);
1399 open_msg_performer(gboolean canceled,
1401 GtkWindow *parent_window,
1402 TnyAccount *account,
1405 ModestMailOperation *mail_op = NULL;
1406 gchar *error_msg = NULL;
1407 ModestProtocolType proto;
1408 TnyConnectionStatus status;
1409 OpenMsgHelper *helper = NULL;
1410 ModestProtocol *protocol;
1411 ModestProtocolRegistry *protocol_registry;
1414 helper = (OpenMsgHelper *) user_data;
1416 status = tny_account_get_connection_status (account);
1417 if (err || canceled || helper->caller_window == NULL) {
1418 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1419 /* Free the helper */
1420 open_msg_helper_destroyer (helper);
1422 /* In disk full conditions we could get this error here */
1423 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1424 (GtkWidget *) parent_window, err,
1430 /* Get the error message depending on the protocol */
1431 proto = modest_tny_account_get_protocol_type (account);
1432 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1433 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1436 protocol_registry = modest_runtime_get_protocol_registry ();
1437 subject = tny_header_dup_subject (helper->header);
1439 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1440 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1444 if (error_msg == NULL) {
1445 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1448 #ifndef MODEST_TOOLKIT_HILDON2
1449 gboolean show_open_draft = FALSE;
1450 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1452 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1454 TnyFolderType folder_type;
1456 folder = tny_header_get_folder (helper->header);
1457 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1458 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1459 g_object_unref (folder);
1463 #ifdef MODEST_TOOLKIT_HILDON2
1466 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1469 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1470 g_free (account_name);
1471 open_msg_helper_destroyer (helper);
1476 ModestWindow *window;
1477 GtkWidget *header_view;
1480 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1481 uid = modest_tny_folder_get_header_unique_id (helper->header);
1483 const gchar *mailbox = NULL;
1484 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1485 window = modest_msg_view_window_new_from_header_view
1486 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1487 if (window != NULL) {
1488 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1490 gtk_widget_destroy (GTK_WIDGET (window));
1492 gtk_widget_show_all (GTK_WIDGET(window));
1496 g_free (account_name);
1498 open_msg_helper_destroyer (helper);
1501 g_free (account_name);
1503 /* Create the mail operation */
1505 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1506 modest_ui_actions_disk_operations_error_handler,
1507 g_strdup (error_msg), g_free);
1508 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1512 #ifndef MODEST_TOOLKIT_HILDON2
1513 if (show_open_draft) {
1514 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1515 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1516 helper->banner_info->banner = NULL;
1517 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1518 helper->banner_info);
1524 headers = TNY_LIST (tny_simple_list_new ());
1525 tny_list_prepend (headers, G_OBJECT (helper->header));
1526 modest_mail_operation_get_msgs_full (mail_op,
1530 open_msg_helper_destroyer);
1531 g_object_unref (headers);
1538 g_object_unref (mail_op);
1539 g_object_unref (account);
1543 * This function is used by both modest_ui_actions_on_open and
1544 * modest_ui_actions_on_header_activated. This way we always do the
1545 * same when trying to open messages.
1548 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1550 ModestWindowMgr *mgr = NULL;
1551 TnyAccount *account;
1552 gboolean cached = FALSE;
1554 GtkWidget *header_view = NULL;
1555 OpenMsgHelper *helper;
1556 ModestWindow *window;
1558 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1560 mgr = modest_runtime_get_window_mgr ();
1563 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1564 if (header_view == NULL)
1567 /* Get the account */
1568 account = get_account_from_header (header);
1573 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1575 /* Do not open again the message and present the
1576 window to the user */
1579 #ifndef MODEST_TOOLKIT_HILDON2
1580 gtk_window_present (GTK_WINDOW (window));
1583 /* the header has been registered already, we don't do
1584 * anything but wait for the window to come up*/
1585 g_debug ("header %p already registered, waiting for window", header);
1590 /* Open each message */
1591 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1593 /* Allways download if we are online. */
1594 if (!tny_device_is_online (modest_runtime_get_device ())) {
1597 /* If ask for user permission to download the messages */
1598 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1599 _("mcen_nc_get_msg"));
1601 /* End if the user does not want to continue */
1602 if (response == GTK_RESPONSE_CANCEL) {
1608 /* We register the window for opening */
1609 modest_window_mgr_register_header (mgr, header, NULL);
1611 /* Create the helper. We need to get a reference to the model
1612 here because it could change while the message is readed
1613 (the user could switch between folders) */
1614 helper = g_slice_new (OpenMsgHelper);
1615 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1616 helper->caller_window = win;
1617 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1618 helper->header = g_object_ref (header);
1619 helper->rowref = gtk_tree_row_reference_copy (rowref);
1620 helper->banner_info = NULL;
1622 /* Connect to the account and perform */
1624 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1625 open_msg_performer, helper);
1627 /* Call directly the performer, do not need to connect */
1628 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1629 g_object_ref (account), helper);
1634 g_object_unref (account);
1638 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1645 /* we check for low-mem; in that case, show a warning, and don't allow
1648 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1652 headers = get_selected_headers (win);
1656 headers_count = tny_list_get_length (headers);
1657 if (headers_count != 1) {
1658 if (headers_count > 1) {
1659 /* Don't allow activation if there are more than one message selected */
1660 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1663 g_object_unref (headers);
1667 iter = tny_list_create_iterator (headers);
1668 header = TNY_HEADER (tny_iterator_get_current (iter));
1669 g_object_unref (iter);
1673 open_msg_from_header (header, NULL, win);
1674 g_object_unref (header);
1677 g_object_unref(headers);
1681 rf_helper_window_closed (gpointer data,
1684 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1686 helper->parent_window = NULL;
1689 static ReplyForwardHelper*
1690 create_reply_forward_helper (ReplyForwardAction action,
1692 guint reply_forward_type,
1695 ReplyForwardHelper *rf_helper = NULL;
1696 const gchar *active_acc = modest_window_get_active_account (win);
1697 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1699 rf_helper = g_slice_new0 (ReplyForwardHelper);
1700 rf_helper->reply_forward_type = reply_forward_type;
1701 rf_helper->action = action;
1702 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1703 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1704 rf_helper->account_name = (active_acc) ?
1705 g_strdup (active_acc) :
1706 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1707 rf_helper->mailbox = g_strdup (active_mailbox);
1709 /* Note that window could be destroyed just AFTER calling
1710 register_window so we must ensure that this pointer does
1711 not hold invalid references */
1712 if (rf_helper->parent_window)
1713 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1714 rf_helper_window_closed, rf_helper);
1720 free_reply_forward_helper (gpointer data)
1722 ReplyForwardHelper *helper;
1724 helper = (ReplyForwardHelper *) data;
1725 g_free (helper->account_name);
1726 g_free (helper->mailbox);
1728 g_object_unref (helper->header);
1729 if (helper->parent_window)
1730 g_object_weak_unref (G_OBJECT (helper->parent_window),
1731 rf_helper_window_closed, helper);
1732 g_slice_free (ReplyForwardHelper, helper);
1736 reply_forward_cb (ModestMailOperation *mail_op,
1743 TnyMsg *new_msg = NULL;
1744 ReplyForwardHelper *rf_helper;
1745 ModestWindow *msg_win = NULL;
1746 ModestEditType edit_type;
1748 TnyAccount *account = NULL;
1749 ModestWindowMgr *mgr = NULL;
1750 gchar *signature = NULL;
1751 gboolean use_signature;
1754 /* If there was any error. The mail operation could be NULL,
1755 this means that we already have the message downloaded and
1756 that we didn't do a mail operation to retrieve it */
1757 rf_helper = (ReplyForwardHelper *) user_data;
1758 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1761 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1762 rf_helper->account_name, rf_helper->mailbox);
1763 recipient = modest_text_utils_get_email_address (from);
1764 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1769 /* Create reply mail */
1770 switch (rf_helper->action) {
1771 /* Use the msg_header to ensure that we have all the
1772 information. The summary can lack some data */
1773 TnyHeader *msg_header;
1775 msg_header = tny_msg_get_header (msg);
1777 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1778 (use_signature) ? signature : NULL,
1779 rf_helper->reply_forward_type,
1780 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1781 g_object_unref (msg_header);
1783 case ACTION_REPLY_TO_ALL:
1784 msg_header = tny_msg_get_header (msg);
1786 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1787 (use_signature) ? signature : NULL,
1788 rf_helper->reply_forward_type,
1789 MODEST_TNY_MSG_REPLY_MODE_ALL);
1790 edit_type = MODEST_EDIT_TYPE_REPLY;
1791 g_object_unref (msg_header);
1793 case ACTION_FORWARD:
1795 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1796 rf_helper->reply_forward_type);
1797 edit_type = MODEST_EDIT_TYPE_FORWARD;
1800 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1802 g_return_if_reached ();
1810 g_warning ("%s: failed to create message\n", __FUNCTION__);
1814 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1815 rf_helper->account_name,
1816 TNY_ACCOUNT_TYPE_STORE);
1818 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1822 /* Create and register the windows */
1823 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1824 mgr = modest_runtime_get_window_mgr ();
1825 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1827 /* Note that register_window could have deleted the account */
1828 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1829 gdouble parent_zoom;
1831 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1832 modest_window_set_zoom (msg_win, parent_zoom);
1835 /* Show edit window */
1836 gtk_widget_show_all (GTK_WIDGET (msg_win));
1839 /* We always unregister the header because the message is
1840 forwarded or replied so the original one is no longer
1842 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1845 g_object_unref (G_OBJECT (new_msg));
1847 g_object_unref (G_OBJECT (account));
1848 free_reply_forward_helper (rf_helper);
1851 /* Checks a list of headers. If any of them are not currently
1852 * downloaded (CACHED) then returns TRUE else returns FALSE.
1855 header_list_count_uncached_msgs (TnyList *header_list)
1858 gint uncached_messages = 0;
1860 iter = tny_list_create_iterator (header_list);
1861 while (!tny_iterator_is_done (iter)) {
1864 header = TNY_HEADER (tny_iterator_get_current (iter));
1866 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1867 uncached_messages ++;
1868 g_object_unref (header);
1871 tny_iterator_next (iter);
1873 g_object_unref (iter);
1875 return uncached_messages;
1878 /* Returns FALSE if the user does not want to download the
1879 * messages. Returns TRUE if the user allowed the download.
1882 connect_to_get_msg (ModestWindow *win,
1883 gint num_of_uncached_msgs,
1884 TnyAccount *account)
1886 GtkResponseType response;
1888 /* Allways download if we are online. */
1889 if (tny_device_is_online (modest_runtime_get_device ()))
1892 /* If offline, then ask for user permission to download the messages */
1893 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1894 ngettext("mcen_nc_get_msg",
1896 num_of_uncached_msgs));
1898 if (response == GTK_RESPONSE_CANCEL)
1901 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1905 reply_forward_performer (gboolean canceled,
1907 GtkWindow *parent_window,
1908 TnyAccount *account,
1911 ReplyForwardHelper *rf_helper = NULL;
1912 ModestMailOperation *mail_op;
1914 rf_helper = (ReplyForwardHelper *) user_data;
1916 if (canceled || err) {
1917 free_reply_forward_helper (rf_helper);
1921 /* Retrieve the message */
1922 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1923 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1924 modest_ui_actions_disk_operations_error_handler,
1926 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1927 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1930 g_object_unref(mail_op);
1934 * Common code for the reply and forward actions
1937 reply_forward (ReplyForwardAction action, ModestWindow *win)
1939 ReplyForwardHelper *rf_helper = NULL;
1940 guint reply_forward_type;
1942 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1944 /* we check for low-mem; in that case, show a warning, and don't allow
1945 * reply/forward (because it could potentially require a lot of memory */
1946 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1950 /* we need an account when editing */
1951 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1952 if (!modest_ui_actions_run_account_setup_wizard (win))
1956 reply_forward_type =
1957 modest_conf_get_int (modest_runtime_get_conf (),
1958 (action == ACTION_FORWARD) ?
1959 MODEST_CONF_FORWARD_TYPE :
1960 MODEST_CONF_REPLY_TYPE,
1963 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1965 TnyHeader *header = NULL;
1966 /* Get header and message. Do not free them here, the
1967 reply_forward_cb must do it */
1968 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1969 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1971 if (msg && header) {
1973 rf_helper = create_reply_forward_helper (action, win,
1974 reply_forward_type, header);
1975 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1977 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1981 g_object_unref (msg);
1983 g_object_unref (header);
1985 TnyHeader *header = NULL;
1987 gboolean do_retrieve = TRUE;
1988 TnyList *header_list = NULL;
1990 header_list = get_selected_headers (win);
1993 /* Check that only one message is selected for replying */
1994 if (tny_list_get_length (header_list) != 1) {
1995 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1996 NULL, _("mcen_ib_select_one_message"));
1997 g_object_unref (header_list);
2001 /* Only reply/forward to one message */
2002 iter = tny_list_create_iterator (header_list);
2003 header = TNY_HEADER (tny_iterator_get_current (iter));
2004 g_object_unref (iter);
2006 /* Retrieve messages */
2007 do_retrieve = (action == ACTION_FORWARD) ||
2008 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2011 TnyAccount *account = NULL;
2012 TnyFolder *folder = NULL;
2013 gdouble download = TRUE;
2014 guint uncached_msgs = 0;
2016 folder = tny_header_get_folder (header);
2018 goto do_retrieve_frees;
2019 account = tny_folder_get_account (folder);
2021 goto do_retrieve_frees;
2023 uncached_msgs = header_list_count_uncached_msgs (header_list);
2025 if (uncached_msgs > 0) {
2026 /* Allways download if we are online. */
2027 if (!tny_device_is_online (modest_runtime_get_device ())) {
2030 /* If ask for user permission to download the messages */
2031 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2032 ngettext("mcen_nc_get_msg",
2036 /* End if the user does not want to continue */
2037 if (response == GTK_RESPONSE_CANCEL)
2044 rf_helper = create_reply_forward_helper (action, win,
2045 reply_forward_type, header);
2046 if (uncached_msgs > 0) {
2047 modest_platform_connect_and_perform (GTK_WINDOW (win),
2049 reply_forward_performer,
2052 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2053 account, rf_helper);
2058 g_object_unref (account);
2060 g_object_unref (folder);
2062 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2065 g_object_unref (header_list);
2066 g_object_unref (header);
2071 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2073 g_return_if_fail (MODEST_IS_WINDOW(win));
2075 reply_forward (ACTION_REPLY, win);
2079 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2081 g_return_if_fail (MODEST_IS_WINDOW(win));
2083 reply_forward (ACTION_FORWARD, win);
2087 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2089 g_return_if_fail (MODEST_IS_WINDOW(win));
2091 reply_forward (ACTION_REPLY_TO_ALL, win);
2095 modest_ui_actions_on_next (GtkAction *action,
2096 ModestWindow *window)
2098 if (MODEST_IS_MAIN_WINDOW (window)) {
2099 GtkWidget *header_view;
2101 header_view = modest_main_window_get_child_widget (
2102 MODEST_MAIN_WINDOW(window),
2103 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2107 modest_header_view_select_next (
2108 MODEST_HEADER_VIEW(header_view));
2109 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2110 modest_msg_view_window_select_next_message (
2111 MODEST_MSG_VIEW_WINDOW (window));
2113 g_return_if_reached ();
2118 modest_ui_actions_on_prev (GtkAction *action,
2119 ModestWindow *window)
2121 g_return_if_fail (MODEST_IS_WINDOW(window));
2123 if (MODEST_IS_MAIN_WINDOW (window)) {
2124 GtkWidget *header_view;
2125 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2126 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2130 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2131 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2132 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2134 g_return_if_reached ();
2139 modest_ui_actions_on_sort (GtkAction *action,
2140 ModestWindow *window)
2142 GtkWidget *header_view = NULL;
2144 g_return_if_fail (MODEST_IS_WINDOW(window));
2146 if (MODEST_IS_MAIN_WINDOW (window)) {
2147 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2148 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2149 #ifdef MODEST_TOOLKIT_HILDON2
2150 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2151 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2156 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2161 /* Show sorting dialog */
2162 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2166 sync_folder_cb (ModestMailOperation *mail_op,
2170 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2172 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2173 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2175 /* We must clear first, because otherwise set_folder will ignore */
2176 /* the change as the folders are the same */
2177 modest_header_view_clear (header_view);
2178 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2180 g_object_unref (parent);
2183 g_object_unref (header_view);
2187 idle_refresh_folder (gpointer source)
2189 ModestHeaderView *header_view = NULL;
2191 /* If the window still exists */
2192 if (!GTK_IS_WIDGET (source) ||
2193 !GTK_WIDGET_VISIBLE (source))
2196 /* Refresh the current view */
2197 #ifdef MODEST_TOOLKIT_HILDON2
2198 if (MODEST_IS_HEADER_WINDOW (source))
2199 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2201 if (MODEST_IS_MAIN_WINDOW (source))
2202 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2203 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2206 TnyFolder *folder = modest_header_view_get_folder (header_view);
2208 /* Sync the folder status */
2209 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2210 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2211 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2212 g_object_unref (folder);
2213 g_object_unref (mail_op);
2221 update_account_cb (ModestMailOperation *self,
2222 TnyList *new_headers,
2226 gboolean show_visual_notifications;
2228 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2229 show_visual_notifications = (top) ? FALSE : TRUE;
2231 /* Notify new messages have been downloaded. If the
2232 send&receive was invoked by the user then do not show any
2233 visual notification, only play a sound and activate the LED
2234 (for the Maemo version) */
2235 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2237 /* We only notify about really new messages (not seen) we get */
2238 TnyList *actually_new_list;
2239 TnyIterator *iterator;
2240 actually_new_list = TNY_LIST (tny_simple_list_new ());
2241 for (iterator = tny_list_create_iterator (new_headers);
2242 !tny_iterator_is_done (iterator);
2243 tny_iterator_next (iterator)) {
2245 TnyHeaderFlags flags;
2246 header = TNY_HEADER (tny_iterator_get_current (iterator));
2247 flags = tny_header_get_flags (header);
2249 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2250 /* Messages are ordered from most
2251 recent to oldest. But we want to
2252 show notifications starting from
2253 the oldest message. That's why we
2255 tny_list_prepend (actually_new_list, G_OBJECT (header));
2257 g_object_unref (header);
2259 g_object_unref (iterator);
2261 if (tny_list_get_length (actually_new_list) > 0) {
2262 GList *new_headers_list = NULL;
2264 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2266 /* Send notifications */
2267 if (new_headers_list) {
2268 modest_platform_on_new_headers_received (new_headers_list,
2269 show_visual_notifications);
2271 modest_utils_free_notification_list (new_headers_list);
2274 g_object_unref (actually_new_list);
2278 /* Refresh the current folder in an idle. We do this
2279 in order to avoid refresh cancelations if the
2280 currently viewed folder is the inbox */
2281 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2282 idle_refresh_folder,
2289 TnyAccount *account;
2291 gchar *account_name;
2292 gboolean poke_status;
2293 gboolean interactive;
2294 ModestMailOperation *mail_op;
2298 do_send_receive_performer (gboolean canceled,
2300 GtkWindow *parent_window,
2301 TnyAccount *account,
2304 SendReceiveInfo *info;
2306 info = (SendReceiveInfo *) user_data;
2308 if (err || canceled) {
2309 /* In disk full conditions we could get this error here */
2310 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2311 (GtkWidget *) parent_window, err,
2314 if (info->mail_op) {
2315 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2321 /* Set send/receive operation in progress */
2322 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2323 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2326 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2327 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2328 G_CALLBACK (on_send_receive_finished),
2331 /* Send & receive. */
2332 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2333 update_account_cb, info->win);
2338 g_object_unref (G_OBJECT (info->mail_op));
2339 if (info->account_name)
2340 g_free (info->account_name);
2342 g_object_unref (info->win);
2344 g_object_unref (info->account);
2345 g_slice_free (SendReceiveInfo, info);
2349 * This function performs the send & receive required actions. The
2350 * window is used to create the mail operation. Typically it should
2351 * always be the main window, but we pass it as argument in order to
2355 modest_ui_actions_do_send_receive (const gchar *account_name,
2356 gboolean force_connection,
2357 gboolean poke_status,
2358 gboolean interactive,
2361 gchar *acc_name = NULL;
2362 SendReceiveInfo *info;
2363 ModestTnyAccountStore *acc_store;
2364 TnyAccount *account;
2366 /* If no account name was provided then get the current account, and if
2367 there is no current account then pick the default one: */
2368 if (!account_name) {
2370 acc_name = g_strdup (modest_window_get_active_account (win));
2372 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2374 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2378 acc_name = g_strdup (account_name);
2381 acc_store = modest_runtime_get_account_store ();
2382 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2386 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2390 /* Do not automatically refresh accounts that are flagged as
2391 NO_AUTO_UPDATE. This could be useful for accounts that
2392 handle their own update times */
2394 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2395 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2396 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2397 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2399 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2400 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2401 g_object_unref (account);
2408 /* Create the info for the connect and perform */
2409 info = g_slice_new (SendReceiveInfo);
2410 info->account_name = acc_name;
2411 info->win = (win) ? g_object_ref (win) : NULL;
2412 info->poke_status = poke_status;
2413 info->interactive = interactive;
2414 info->account = account;
2415 /* We need to create the operation here, because otherwise it
2416 could happen that the queue emits the queue-empty signal
2417 while we're trying to connect the account */
2418 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2419 modest_ui_actions_disk_operations_error_handler,
2421 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2423 /* Invoke the connect and perform */
2424 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2425 force_connection, info->account,
2426 do_send_receive_performer, info);
2431 modest_ui_actions_do_cancel_send (const gchar *account_name,
2434 TnyTransportAccount *transport_account;
2435 TnySendQueue *send_queue = NULL;
2436 GError *error = NULL;
2438 /* Get transport account */
2440 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2441 (modest_runtime_get_account_store(),
2443 TNY_ACCOUNT_TYPE_TRANSPORT));
2444 if (!transport_account) {
2445 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2450 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2451 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2452 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2453 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2454 "modest: could not find send queue for account\n");
2456 /* Cancel the current send */
2457 tny_account_cancel (TNY_ACCOUNT (transport_account));
2459 /* Suspend all pending messages */
2460 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2464 if (transport_account != NULL)
2465 g_object_unref (G_OBJECT (transport_account));
2469 modest_ui_actions_cancel_send_all (ModestWindow *win)
2471 GSList *account_names, *iter;
2473 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2476 iter = account_names;
2478 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2479 iter = g_slist_next (iter);
2482 modest_account_mgr_free_account_names (account_names);
2483 account_names = NULL;
2487 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2490 /* Check if accounts exist */
2491 gboolean accounts_exist =
2492 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2494 /* If not, allow the user to create an account before trying to send/receive. */
2495 if (!accounts_exist)
2496 modest_ui_actions_on_accounts (NULL, win);
2498 /* Cancel all sending operaitons */
2499 modest_ui_actions_cancel_send_all (win);
2503 * Refreshes all accounts. This function will be used by automatic
2507 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2508 gboolean force_connection,
2509 gboolean poke_status,
2510 gboolean interactive)
2512 GSList *account_names, *iter;
2514 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2517 iter = account_names;
2519 modest_ui_actions_do_send_receive ((const char*) iter->data,
2521 poke_status, interactive, win);
2522 iter = g_slist_next (iter);
2525 modest_account_mgr_free_account_names (account_names);
2526 account_names = NULL;
2530 * Handler of the click on Send&Receive button in the main toolbar
2533 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2535 /* Check if accounts exist */
2536 gboolean accounts_exist;
2539 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2541 /* If not, allow the user to create an account before trying to send/receive. */
2542 if (!accounts_exist)
2543 modest_ui_actions_on_accounts (NULL, win);
2545 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2546 if (MODEST_IS_MAIN_WINDOW (win)) {
2547 GtkWidget *folder_view;
2548 TnyFolderStore *folder_store;
2551 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2552 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2556 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2559 g_object_unref (folder_store);
2560 /* Refresh the active account. Force the connection if needed
2561 and poke the status of all folders */
2562 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2563 #ifdef MODEST_TOOLKIT_HILDON2
2564 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2565 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2568 const gchar *active_account;
2569 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2571 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2578 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2581 GtkWidget *header_view;
2583 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2585 header_view = modest_main_window_get_child_widget (main_window,
2586 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2590 conf = modest_runtime_get_conf ();
2592 /* what is saved/restored is depending on the style; thus; we save with
2593 * old style, then update the style, and restore for this new style
2595 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2597 if (modest_header_view_get_style
2598 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2599 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2600 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2602 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2603 MODEST_HEADER_VIEW_STYLE_DETAILS);
2605 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2606 MODEST_CONF_HEADER_VIEW_KEY);
2611 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2613 ModestMainWindow *main_window)
2615 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2616 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2618 /* in the case the folder is empty, show the empty folder message and focus
2620 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2621 if (modest_header_view_is_empty (header_view)) {
2622 TnyFolder *folder = modest_header_view_get_folder (header_view);
2623 GtkWidget *folder_view =
2624 modest_main_window_get_child_widget (main_window,
2625 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2626 if (folder != NULL) {
2627 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2628 g_object_unref (folder);
2630 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2634 /* If no header has been selected then exit */
2639 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2640 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2642 /* Update toolbar dimming state */
2643 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2644 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2648 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2651 ModestWindow *window)
2653 GtkWidget *open_widget;
2654 GtkTreeRowReference *rowref;
2656 g_return_if_fail (MODEST_IS_WINDOW(window));
2657 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2658 g_return_if_fail (TNY_IS_HEADER (header));
2660 if (modest_header_view_count_selected_headers (header_view) > 1) {
2661 /* Don't allow activation if there are more than one message selected */
2662 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2666 /* we check for low-mem; in that case, show a warning, and don't allow
2667 * activating headers
2669 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2672 if (MODEST_IS_MAIN_WINDOW (window)) {
2673 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2674 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2675 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2679 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2680 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2681 gtk_tree_row_reference_free (rowref);
2685 set_active_account_from_tny_account (TnyAccount *account,
2686 ModestWindow *window)
2688 const gchar *server_acc_name = tny_account_get_id (account);
2690 /* We need the TnyAccount provided by the
2691 account store because that is the one that
2692 knows the name of the Modest account */
2693 TnyAccount *modest_server_account =
2694 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2695 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2697 if (!modest_server_account) {
2698 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2702 /* Update active account, but only if it's not a pseudo-account */
2703 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2704 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2705 const gchar *modest_acc_name =
2706 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2707 if (modest_acc_name)
2708 modest_window_set_active_account (window, modest_acc_name);
2711 g_object_unref (modest_server_account);
2716 folder_refreshed_cb (ModestMailOperation *mail_op,
2720 ModestMainWindow *win = NULL;
2721 GtkWidget *folder_view, *header_view;
2722 const GError *error;
2724 g_return_if_fail (TNY_IS_FOLDER (folder));
2726 win = MODEST_MAIN_WINDOW (user_data);
2728 /* Check if the operation failed due to memory low conditions */
2729 error = modest_mail_operation_get_error (mail_op);
2730 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2731 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2732 modest_platform_run_information_dialog (GTK_WINDOW (win),
2733 _KR("memr_ib_operation_disabled"),
2739 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2741 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2744 TnyFolderStore *current_folder;
2746 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2747 if (current_folder) {
2748 gboolean different = ((TnyFolderStore *) folder != current_folder);
2749 g_object_unref (current_folder);
2755 /* Check if folder is empty and set headers view contents style */
2756 if ((tny_folder_get_all_count (folder) == 0) ||
2757 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2758 modest_main_window_set_contents_style (win,
2759 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2763 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2764 TnyFolderStore *folder_store,
2766 ModestMainWindow *main_window)
2768 GtkWidget *header_view;
2770 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2772 header_view = modest_main_window_get_child_widget(main_window,
2773 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2778 if (TNY_IS_ACCOUNT (folder_store)) {
2780 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2782 /* Show account details */
2783 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2786 if (TNY_IS_FOLDER (folder_store) && selected) {
2787 TnyAccount *account;
2789 /* Update the active account */
2790 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2792 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2793 g_object_unref (account);
2797 /* Set the header style by default, it could
2798 be changed later by the refresh callback to
2800 modest_main_window_set_contents_style (main_window,
2801 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2803 /* Set folder on header view. This function
2804 will call tny_folder_refresh_async so we
2805 pass a callback that will be called when
2806 finished. We use that callback to set the
2807 empty view if there are no messages */
2808 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2809 TNY_FOLDER (folder_store),
2811 MODEST_WINDOW (main_window),
2812 folder_refreshed_cb,
2815 /* Restore configuration. We need to do this
2816 *after* the set_folder because the widget
2817 memory asks the header view about its
2819 modest_widget_memory_restore (modest_runtime_get_conf (),
2820 G_OBJECT(header_view),
2821 MODEST_CONF_HEADER_VIEW_KEY);
2823 /* No need to save the header view
2824 configuration for Maemo because it only
2825 saves the sorting stuff and that it's
2826 already being done by the sort
2827 dialog. Remove it when the GNOME version
2828 has the same behaviour */
2829 #ifdef MODEST_TOOLKIT_GTK
2830 if (modest_main_window_get_contents_style (main_window) ==
2831 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2832 modest_widget_memory_save (modest_runtime_get_conf (),
2833 G_OBJECT (header_view),
2834 MODEST_CONF_HEADER_VIEW_KEY);
2836 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2840 /* Update dimming state */
2841 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2842 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2846 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2853 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2855 online = tny_device_is_online (modest_runtime_get_device());
2858 /* already online -- the item is simply not there... */
2859 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2861 GTK_MESSAGE_WARNING,
2863 _("The %s you selected cannot be found"),
2865 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2866 gtk_dialog_run (GTK_DIALOG(dialog));
2868 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2871 _("mcen_bd_dialog_cancel"),
2872 GTK_RESPONSE_REJECT,
2873 _("mcen_bd_dialog_ok"),
2874 GTK_RESPONSE_ACCEPT,
2876 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2877 "Do you want to get online?"), item);
2878 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2879 gtk_label_new (txt), FALSE, FALSE, 0);
2880 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2883 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2884 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2885 /* TODO: Comment about why is this commented out: */
2886 /* modest_platform_connect_and_wait (); */
2889 gtk_widget_destroy (dialog);
2893 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2896 /* g_debug ("%s %s", __FUNCTION__, link); */
2901 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2904 modest_platform_activate_uri (link);
2908 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2911 modest_platform_show_uri_popup (link);
2915 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2918 /* we check for low-mem; in that case, show a warning, and don't allow
2919 * viewing attachments
2921 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2924 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2928 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2929 const gchar *address,
2932 /* g_debug ("%s %s", __FUNCTION__, address); */
2936 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2937 TnyMsg *saved_draft,
2940 ModestMsgEditWindow *edit_window;
2942 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2943 #ifndef MODEST_TOOLKIT_HILDON2
2944 ModestMainWindow *win;
2946 /* FIXME. Make the header view sensitive again. This is a
2947 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2949 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2950 modest_runtime_get_window_mgr(), FALSE));
2952 GtkWidget *hdrview = modest_main_window_get_child_widget(
2953 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2954 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2958 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2960 /* Set draft is there was no error */
2961 if (!modest_mail_operation_get_error (mail_op))
2962 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2964 g_object_unref(edit_window);
2968 enough_space_for_message (ModestMsgEditWindow *edit_window,
2971 guint64 available_disk, expected_size;
2976 available_disk = modest_utils_get_available_space (NULL);
2977 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2978 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2983 /* Double check: disk full condition or message too big */
2984 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2985 expected_size > available_disk) {
2986 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2987 modest_platform_information_banner (NULL, NULL, msg);
2994 * djcb: if we're in low-memory state, we only allow for
2995 * saving messages smaller than
2996 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2997 * should still allow for sending anything critical...
2999 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3000 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3004 * djcb: we also make sure that the attachments are smaller than the max size
3005 * this is for the case where we'd try to forward a message with attachments
3006 * bigger than our max allowed size, or sending an message from drafts which
3007 * somehow got past our checks when attaching.
3009 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3010 modest_platform_run_information_dialog (
3011 GTK_WINDOW(edit_window),
3012 _("mail_ib_error_attachment_size"),
3021 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3023 TnyTransportAccount *transport_account;
3024 ModestMailOperation *mail_operation;
3026 gchar *account_name;
3027 ModestAccountMgr *account_mgr;
3028 gboolean had_error = FALSE;
3029 ModestMainWindow *win = NULL;
3031 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3033 data = modest_msg_edit_window_get_msg_data (edit_window);
3036 if (!enough_space_for_message (edit_window, data)) {
3037 modest_msg_edit_window_free_msg_data (edit_window, data);
3041 account_name = g_strdup (data->account_name);
3042 account_mgr = modest_runtime_get_account_mgr();
3044 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3046 account_name = modest_account_mgr_get_default_account (account_mgr);
3047 if (!account_name) {
3048 g_printerr ("modest: no account found\n");
3049 modest_msg_edit_window_free_msg_data (edit_window, data);
3053 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3054 account_name = g_strdup (data->account_name);
3058 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3059 (modest_runtime_get_account_store (),
3061 TNY_ACCOUNT_TYPE_TRANSPORT));
3062 if (!transport_account) {
3063 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3064 g_free (account_name);
3065 modest_msg_edit_window_free_msg_data (edit_window, data);
3069 /* Create the mail operation */
3070 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3072 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3074 modest_mail_operation_save_to_drafts (mail_operation,
3086 data->priority_flags,
3089 on_save_to_drafts_cb,
3090 g_object_ref(edit_window));
3092 #ifdef MODEST_TOOLKIT_HILDON2
3093 /* In hildon2 we always show the information banner on saving to drafts.
3094 * It will be a system information banner in this case.
3096 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3097 modest_platform_information_banner (NULL, NULL, text);
3100 /* Use the main window as the parent of the banner, if the
3101 main window does not exist it won't be shown, if the parent
3102 window exists then it's properly shown. We don't use the
3103 editor window because it could be closed (save to drafts
3104 could happen after closing the window */
3105 win = (ModestMainWindow *)
3106 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3108 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3109 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3113 modest_msg_edit_window_set_modified (edit_window, FALSE);
3116 g_free (account_name);
3117 g_object_unref (G_OBJECT (transport_account));
3118 g_object_unref (G_OBJECT (mail_operation));
3120 modest_msg_edit_window_free_msg_data (edit_window, data);
3123 * If the drafts folder is selected then make the header view
3124 * insensitive while the message is being saved to drafts
3125 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3126 * is not very clean but it avoids letting the drafts folder
3127 * in an inconsistent state: the user could edit the message
3128 * being saved and undesirable things would happen.
3129 * In the average case the user won't notice anything at
3130 * all. In the worst case (the user is editing a really big
3131 * file from Drafts) the header view will be insensitive
3132 * during the saving process (10 or 20 seconds, depending on
3133 * the message). Anyway this is just a quick workaround: once
3134 * we find a better solution it should be removed
3135 * See NB#65125 (commend #18) for details.
3137 if (!had_error && win != NULL) {
3138 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3139 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3141 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3143 if (modest_tny_folder_is_local_folder(folder)) {
3144 TnyFolderType folder_type;
3145 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3146 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3147 GtkWidget *hdrview = modest_main_window_get_child_widget(
3148 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3149 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3153 if (folder != NULL) g_object_unref(folder);
3160 /* For instance, when clicking the Send toolbar button when editing a message: */
3162 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3164 TnyTransportAccount *transport_account = NULL;
3165 gboolean had_error = FALSE, add_to_contacts;
3167 ModestAccountMgr *account_mgr;
3168 gchar *account_name;
3169 ModestMailOperation *mail_operation;
3172 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3174 /* Check whether to automatically add new contacts to addressbook or not */
3175 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3176 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3177 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3180 data = modest_msg_edit_window_get_msg_data (edit_window);
3182 recipients = g_strconcat (data->to?data->to:"",
3183 data->cc?data->cc:"",
3184 data->bcc?data->bcc:"",
3186 if (recipients == NULL || recipients[0] == '\0') {
3187 /* Empty subject -> no send */
3188 g_free (recipients);
3189 modest_msg_edit_window_free_msg_data (edit_window, data);
3192 g_free (recipients);
3195 if (!enough_space_for_message (edit_window, data)) {
3196 modest_msg_edit_window_free_msg_data (edit_window, data);
3200 account_mgr = modest_runtime_get_account_mgr();
3201 account_name = g_strdup (data->account_name);
3203 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3206 account_name = modest_account_mgr_get_default_account (account_mgr);
3208 if (!account_name) {
3209 modest_msg_edit_window_free_msg_data (edit_window, data);
3210 /* Run account setup wizard */
3211 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3216 /* Get the currently-active transport account for this modest account: */
3217 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3219 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3220 (modest_runtime_get_account_store (),
3221 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3224 if (!transport_account) {
3225 modest_msg_edit_window_free_msg_data (edit_window, data);
3226 /* Run account setup wizard */
3227 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3232 /* Create the mail operation */
3233 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3234 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3236 modest_mail_operation_send_new_mail (mail_operation,
3250 data->priority_flags);
3252 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3253 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3255 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3256 const GError *error = modest_mail_operation_get_error (mail_operation);
3257 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3258 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3259 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3260 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3266 g_free (account_name);
3267 g_object_unref (G_OBJECT (transport_account));
3268 g_object_unref (G_OBJECT (mail_operation));
3270 modest_msg_edit_window_free_msg_data (edit_window, data);
3273 modest_msg_edit_window_set_sent (edit_window, TRUE);
3275 /* Save settings and close the window: */
3276 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3283 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3284 ModestMsgEditWindow *window)
3286 ModestMsgEditFormatState *format_state = NULL;
3288 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3289 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3291 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3294 format_state = modest_msg_edit_window_get_format_state (window);
3295 g_return_if_fail (format_state != NULL);
3297 format_state->bold = gtk_toggle_action_get_active (action);
3298 modest_msg_edit_window_set_format_state (window, format_state);
3299 g_free (format_state);
3304 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3305 ModestMsgEditWindow *window)
3307 ModestMsgEditFormatState *format_state = NULL;
3309 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3310 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3312 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3315 format_state = modest_msg_edit_window_get_format_state (window);
3316 g_return_if_fail (format_state != NULL);
3318 format_state->italics = gtk_toggle_action_get_active (action);
3319 modest_msg_edit_window_set_format_state (window, format_state);
3320 g_free (format_state);
3325 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3326 ModestMsgEditWindow *window)
3328 ModestMsgEditFormatState *format_state = NULL;
3330 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3331 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3333 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3336 format_state = modest_msg_edit_window_get_format_state (window);
3337 g_return_if_fail (format_state != NULL);
3339 format_state->bullet = gtk_toggle_action_get_active (action);
3340 modest_msg_edit_window_set_format_state (window, format_state);
3341 g_free (format_state);
3346 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3347 GtkRadioAction *selected,
3348 ModestMsgEditWindow *window)
3350 ModestMsgEditFormatState *format_state = NULL;
3351 GtkJustification value;
3353 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3355 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3358 value = gtk_radio_action_get_current_value (selected);
3360 format_state = modest_msg_edit_window_get_format_state (window);
3361 g_return_if_fail (format_state != NULL);
3363 format_state->justification = value;
3364 modest_msg_edit_window_set_format_state (window, format_state);
3365 g_free (format_state);
3369 modest_ui_actions_on_select_editor_color (GtkAction *action,
3370 ModestMsgEditWindow *window)
3372 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3373 g_return_if_fail (GTK_IS_ACTION (action));
3375 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3378 modest_msg_edit_window_select_color (window);
3382 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3383 ModestMsgEditWindow *window)
3385 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3386 g_return_if_fail (GTK_IS_ACTION (action));
3388 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3391 modest_msg_edit_window_select_background_color (window);
3395 modest_ui_actions_on_insert_image (GObject *object,
3396 ModestMsgEditWindow *window)
3398 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3401 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3404 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3407 modest_msg_edit_window_insert_image (window);
3411 modest_ui_actions_on_attach_file (GtkAction *action,
3412 ModestMsgEditWindow *window)
3414 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3415 g_return_if_fail (GTK_IS_ACTION (action));
3417 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3420 modest_msg_edit_window_offer_attach_file (window);
3424 modest_ui_actions_on_remove_attachments (GtkAction *action,
3425 ModestMsgEditWindow *window)
3427 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3429 modest_msg_edit_window_remove_attachments (window, NULL);
3433 do_create_folder_cb (ModestMailOperation *mail_op,
3434 TnyFolderStore *parent_folder,
3435 TnyFolder *new_folder,
3438 gchar *suggested_name = (gchar *) user_data;
3439 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3440 const GError *error;
3442 error = modest_mail_operation_get_error (mail_op);
3444 gboolean disk_full = FALSE;
3445 TnyAccount *account;
3446 /* Show an error. If there was some problem writing to
3447 disk, show it, otherwise show the generic folder
3448 create error. We do it here and not in an error
3449 handler because the call to do_create_folder will
3450 stop the main loop in a gtk_dialog_run and then,
3451 the message won't be shown until that dialog is
3453 account = modest_mail_operation_get_account (mail_op);
3456 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3457 (GtkWidget *) source_win,
3460 _("mail_in_ui_folder_create_error_memory"));
3461 g_object_unref (account);
3464 /* Show an error and try again if there is no
3465 full memory condition */
3466 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3467 _("mail_in_ui_folder_create_error"));
3468 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3472 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3473 * FIXME: any other? */
3474 GtkWidget *folder_view;
3476 if (MODEST_IS_MAIN_WINDOW(source_win))
3478 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3479 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3481 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3482 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3484 /* Select the newly created folder. It could happen
3485 that the widget is no longer there (i.e. the window
3486 has been destroyed, so we need to check this */
3488 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3490 g_object_unref (new_folder);
3492 /* Free. Note that the first time it'll be NULL so noop */
3493 g_free (suggested_name);
3494 g_object_unref (source_win);
3499 TnyFolderStore *parent;
3500 } CreateFolderConnect;
3503 do_create_folder_performer (gboolean canceled,
3505 GtkWindow *parent_window,
3506 TnyAccount *account,
3509 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3510 ModestMailOperation *mail_op;
3512 if (canceled || err) {
3513 /* In disk full conditions we could get this error here */
3514 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3515 (GtkWidget *) parent_window, err,
3516 NULL, _("mail_in_ui_folder_create_error_memory"));
3518 /* This happens if we have selected the outbox folder
3520 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3521 TNY_IS_MERGE_FOLDER (helper->parent)) {
3522 /* Show an error and retry */
3523 modest_platform_information_banner ((GtkWidget *) parent_window,
3525 _("mail_in_ui_folder_create_error"));
3527 do_create_folder (parent_window, helper->parent, helper->folder_name);
3533 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3534 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3536 modest_mail_operation_create_folder (mail_op,
3538 (const gchar *) helper->folder_name,
3539 do_create_folder_cb,
3540 g_strdup (helper->folder_name));
3541 g_object_unref (mail_op);
3545 g_object_unref (helper->parent);
3546 if (helper->folder_name)
3547 g_free (helper->folder_name);
3548 g_slice_free (CreateFolderConnect, helper);
3553 do_create_folder (GtkWindow *parent_window,
3554 TnyFolderStore *suggested_parent,
3555 const gchar *suggested_name)
3558 gchar *folder_name = NULL;
3559 TnyFolderStore *parent_folder = NULL;
3561 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3563 (gchar *) suggested_name,
3567 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3568 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3569 helper->folder_name = g_strdup (folder_name);
3570 helper->parent = g_object_ref (parent_folder);
3572 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3575 do_create_folder_performer,
3580 g_free (folder_name);
3582 g_object_unref (parent_folder);
3586 modest_ui_actions_create_folder(GtkWidget *parent_window,
3587 GtkWidget *folder_view,
3588 TnyFolderStore *parent_folder)
3590 if (!parent_folder) {
3591 #ifdef MODEST_TOOLKIT_HILDON2
3592 ModestTnyAccountStore *acc_store;
3594 acc_store = modest_runtime_get_account_store ();
3596 parent_folder = (TnyFolderStore *)
3597 modest_tny_account_store_get_local_folders_account (acc_store);
3599 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3603 if (parent_folder) {
3604 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3605 g_object_unref (parent_folder);
3610 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3613 g_return_if_fail (MODEST_IS_WINDOW(window));
3615 if (MODEST_IS_MAIN_WINDOW (window)) {
3616 GtkWidget *folder_view;
3618 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3619 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3623 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3624 #ifdef MODEST_TOOLKIT_HILDON2
3625 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3626 GtkWidget *folder_view;
3628 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3629 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3632 g_assert_not_reached ();
3637 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3640 const GError *error = NULL;
3641 gchar *message = NULL;
3643 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3645 /* Get error message */
3646 error = modest_mail_operation_get_error (mail_op);
3648 g_return_if_reached ();
3650 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3651 (GError *) error, account);
3653 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3654 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3655 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3656 message = _CS("ckdg_ib_folder_already_exists");
3657 } else if (error->domain == TNY_ERROR_DOMAIN &&
3658 error->code == TNY_SERVICE_ERROR_STATE) {
3659 /* This means that the folder is already in use (a
3660 message is opened for example */
3661 message = _("emev_ni_internal_error");
3663 message = _CS("ckdg_ib_unable_to_rename");
3666 /* We don't set a parent for the dialog because the dialog
3667 will be destroyed so the banner won't appear */
3668 modest_platform_information_banner (NULL, NULL, message);
3671 g_object_unref (account);
3677 TnyFolderStore *folder;
3682 on_rename_folder_cb (ModestMailOperation *mail_op,
3683 TnyFolder *new_folder,
3686 ModestFolderView *folder_view;
3688 /* If the window was closed when renaming a folder, or if
3689 * it's not a main window this will happen */
3690 if (!MODEST_IS_FOLDER_VIEW (user_data))
3693 folder_view = MODEST_FOLDER_VIEW (user_data);
3694 /* Note that if the rename fails new_folder will be NULL */
3696 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3698 modest_folder_view_select_first_inbox_or_local (folder_view);
3700 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3704 on_rename_folder_performer (gboolean canceled,
3706 GtkWindow *parent_window,
3707 TnyAccount *account,
3710 ModestMailOperation *mail_op = NULL;
3711 GtkTreeSelection *sel = NULL;
3712 GtkWidget *folder_view = NULL;
3713 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3715 if (canceled || err) {
3716 /* In disk full conditions we could get this error here */
3717 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3718 (GtkWidget *) parent_window, err,
3723 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3724 modest_ui_actions_rename_folder_error_handler,
3725 parent_window, NULL);
3727 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3730 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3732 folder_view = modest_main_window_get_child_widget (
3733 MODEST_MAIN_WINDOW (parent_window),
3734 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3736 #ifdef MODEST_TOOLKIT_HILDON2
3737 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3738 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3739 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3743 /* Clear the folders view */
3744 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3745 gtk_tree_selection_unselect_all (sel);
3747 /* Actually rename the folder */
3748 modest_mail_operation_rename_folder (mail_op,
3749 TNY_FOLDER (data->folder),
3750 (const gchar *) (data->new_name),
3751 on_rename_folder_cb,
3753 g_object_unref (mail_op);
3756 g_object_unref (data->folder);
3757 g_free (data->new_name);
3762 modest_ui_actions_on_rename_folder (GtkAction *action,
3763 ModestWindow *window)
3765 modest_ui_actions_on_edit_mode_rename_folder (window);
3769 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3771 TnyFolderStore *folder;
3772 GtkWidget *folder_view;
3773 gboolean do_rename = TRUE;
3775 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3777 if (MODEST_IS_MAIN_WINDOW (window)) {
3778 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3779 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3783 #ifdef MODEST_TOOLKIT_HILDON2
3784 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3785 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3791 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3796 if (TNY_IS_FOLDER (folder)) {
3797 gchar *folder_name = NULL;
3799 const gchar *current_name;
3800 TnyFolderStore *parent;
3802 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3803 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3804 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3805 parent, current_name,
3807 g_object_unref (parent);
3809 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3812 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3813 rename_folder_data->folder = g_object_ref (folder);
3814 rename_folder_data->new_name = folder_name;
3815 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3816 folder, on_rename_folder_performer, rename_folder_data);
3819 g_object_unref (folder);
3824 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3827 GObject *win = modest_mail_operation_get_source (mail_op);
3829 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3830 _("mail_in_ui_folder_delete_error"),
3832 g_object_unref (win);
3836 TnyFolderStore *folder;
3837 gboolean move_to_trash;
3841 on_delete_folder_cb (gboolean canceled,
3843 GtkWindow *parent_window,
3844 TnyAccount *account,
3847 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3848 GtkWidget *folder_view;
3849 ModestMailOperation *mail_op;
3850 GtkTreeSelection *sel;
3852 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3853 /* Note that the connection process can fail due to
3854 memory low conditions as it can not successfully
3855 store the summary */
3856 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3857 (GtkWidget*) parent_window, err,
3859 g_debug ("Error connecting when trying to delete a folder");
3860 g_object_unref (G_OBJECT (info->folder));
3865 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3866 folder_view = modest_main_window_get_child_widget (
3867 MODEST_MAIN_WINDOW (parent_window),
3868 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3869 #ifdef MODEST_TOOLKIT_HILDON2
3870 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3871 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3874 g_object_unref (G_OBJECT (info->folder));
3879 /* Unselect the folder before deleting it to free the headers */
3880 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3881 gtk_tree_selection_unselect_all (sel);
3883 /* Create the mail operation */
3885 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3886 modest_ui_actions_delete_folder_error_handler,
3889 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3891 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3893 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3895 g_object_unref (mail_op);
3896 g_object_unref (info->folder);
3901 delete_folder (ModestWindow *window, gboolean move_to_trash)
3903 TnyFolderStore *folder;
3904 GtkWidget *folder_view;
3908 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3910 if (MODEST_IS_MAIN_WINDOW (window)) {
3912 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3913 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3914 #ifdef MODEST_TOOLKIT_HILDON2
3915 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3916 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3924 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3929 /* Show an error if it's an account */
3930 if (!TNY_IS_FOLDER (folder)) {
3931 modest_platform_run_information_dialog (GTK_WINDOW (window),
3932 _("mail_in_ui_folder_delete_error"),
3934 g_object_unref (G_OBJECT (folder));
3939 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3940 tny_folder_get_name (TNY_FOLDER (folder)));
3941 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3942 (const gchar *) message);
3945 if (response == GTK_RESPONSE_OK) {
3946 TnyAccount *account = NULL;
3947 DeleteFolderInfo *info = NULL;
3948 info = g_new0(DeleteFolderInfo, 1);
3949 info->folder = g_object_ref (folder);
3950 info->move_to_trash = move_to_trash;
3952 account = tny_folder_get_account (TNY_FOLDER (folder));
3953 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3955 TNY_FOLDER_STORE (account),
3956 on_delete_folder_cb, info);
3957 g_object_unref (account);
3958 g_object_unref (folder);
3966 modest_ui_actions_on_delete_folder (GtkAction *action,
3967 ModestWindow *window)
3969 modest_ui_actions_on_edit_mode_delete_folder (window);
3973 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3975 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3977 return delete_folder (window, FALSE);
3981 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3983 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3985 delete_folder (MODEST_WINDOW (main_window), TRUE);
3989 typedef struct _PasswordDialogFields {
3990 GtkWidget *username;
3991 GtkWidget *password;
3993 } PasswordDialogFields;
3996 password_dialog_check_field (GtkEditable *editable,
3997 PasswordDialogFields *fields)
4000 gboolean any_value_empty = FALSE;
4002 #ifdef MODEST_TOOLKIT_HILDON2
4003 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4005 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4007 if ((value == NULL) || value[0] == '\0') {
4008 any_value_empty = TRUE;
4010 #ifdef MODEST_TOOLKIT_HILDON2
4011 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4013 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4015 if ((value == NULL) || value[0] == '\0') {
4016 any_value_empty = TRUE;
4018 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4022 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4023 const gchar* server_account_name,
4028 ModestMainWindow *main_window)
4030 g_return_if_fail(server_account_name);
4031 gboolean completed = FALSE;
4032 PasswordDialogFields *fields = NULL;
4034 /* Initalize output parameters: */
4041 #ifndef MODEST_TOOLKIT_GTK
4042 /* Maemo uses a different (awkward) button order,
4043 * It should probably just use gtk_alternative_dialog_button_order ().
4045 #ifdef MODEST_TOOLKIT_HILDON2
4047 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4050 _HL("wdgt_bd_done"),
4051 GTK_RESPONSE_ACCEPT,
4053 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4054 HILDON_MARGIN_DOUBLE);
4057 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4060 _("mcen_bd_dialog_ok"),
4061 GTK_RESPONSE_ACCEPT,
4062 _("mcen_bd_dialog_cancel"),
4063 GTK_RESPONSE_REJECT,
4065 #endif /* MODEST_TOOLKIT_HILDON2 */
4068 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4072 GTK_RESPONSE_REJECT,
4074 GTK_RESPONSE_ACCEPT,
4076 #endif /* MODEST_TOOLKIT_GTK */
4078 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4080 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4081 modest_runtime_get_account_mgr(), server_account_name);
4082 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4083 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4086 gtk_widget_destroy (dialog);
4090 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4091 GtkWidget *label = gtk_label_new (txt);
4092 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4094 g_free (server_name);
4095 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4100 gchar *initial_username = modest_account_mgr_get_server_account_username (
4101 modest_runtime_get_account_mgr(), server_account_name);
4103 #ifdef MODEST_TOOLKIT_HILDON2
4104 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4105 if (initial_username)
4106 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4108 GtkWidget *entry_username = gtk_entry_new ();
4109 if (initial_username)
4110 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4112 /* Dim this if a connection has ever succeeded with this username,
4113 * as per the UI spec: */
4114 /* const gboolean username_known = */
4115 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4116 /* modest_runtime_get_account_mgr(), server_account_name); */
4117 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4119 /* We drop the username sensitive code and disallow changing it here
4120 * as tinymail does not support really changing the username in the callback
4122 gtk_widget_set_sensitive (entry_username, FALSE);
4124 #ifndef MODEST_TOOLKIT_GTK
4125 /* Auto-capitalization is the default, so let's turn it off: */
4126 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4128 /* Create a size group to be used by all captions.
4129 * Note that HildonCaption does not create a default size group if we do not specify one.
4130 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4131 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4133 #ifdef MODEST_TOOLKIT_HILDON2
4134 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4135 _("mail_fi_username"), FALSE,
4138 GtkWidget *caption = hildon_caption_new (sizegroup,
4139 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4141 gtk_widget_show (entry_username);
4142 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4143 FALSE, FALSE, MODEST_MARGIN_HALF);
4144 gtk_widget_show (caption);
4146 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4148 #endif /* !MODEST_TOOLKIT_GTK */
4151 #ifdef MODEST_TOOLKIT_HILDON2
4152 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4154 GtkWidget *entry_password = gtk_entry_new ();
4156 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4157 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4159 #ifndef MODEST_TOOLKIT_GTK
4160 /* Auto-capitalization is the default, so let's turn it off: */
4161 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4162 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4164 #ifdef MODEST_TOOLKIT_HILDON2
4165 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4166 _("mail_fi_password"), FALSE,
4169 caption = hildon_caption_new (sizegroup,
4170 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4172 gtk_widget_show (entry_password);
4173 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4174 FALSE, FALSE, MODEST_MARGIN_HALF);
4175 gtk_widget_show (caption);
4176 g_object_unref (sizegroup);
4178 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4180 #endif /* !MODEST_TOOLKIT_GTK */
4182 if (initial_username != NULL)
4183 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4185 /* This is not in the Maemo UI spec:
4186 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4187 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4191 fields = g_slice_new0 (PasswordDialogFields);
4192 fields->username = entry_username;
4193 fields->password = entry_password;
4194 fields->dialog = dialog;
4196 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4197 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4198 password_dialog_check_field (NULL, fields);
4200 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4202 while (!completed) {
4204 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4206 #ifdef MODEST_TOOLKIT_HILDON2
4207 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4209 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4212 /* Note that an empty field becomes the "" string */
4213 if (*username && strlen (*username) > 0) {
4214 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4215 server_account_name,
4219 const gboolean username_was_changed =
4220 (strcmp (*username, initial_username) != 0);
4221 if (username_was_changed) {
4222 g_warning ("%s: tinymail does not yet support changing the "
4223 "username in the get_password() callback.\n", __FUNCTION__);
4229 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4230 _("mcen_ib_username_pw_incorrect"));
4236 #ifdef MODEST_TOOLKIT_HILDON2
4237 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4239 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4242 /* We do not save the password in the configuration,
4243 * because this function is only called for passwords that should
4244 * not be remembered:
4245 modest_server_account_set_password (
4246 modest_runtime_get_account_mgr(), server_account_name,
4253 #ifndef MODEST_TOOLKIT_HILDON2
4254 /* Set parent to NULL or the banner will disappear with its parent dialog */
4255 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4267 /* This is not in the Maemo UI spec:
4268 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4274 g_free (initial_username);
4275 gtk_widget_destroy (dialog);
4276 g_slice_free (PasswordDialogFields, fields);
4278 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4282 modest_ui_actions_on_cut (GtkAction *action,
4283 ModestWindow *window)
4285 GtkWidget *focused_widget;
4286 GtkClipboard *clipboard;
4288 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4289 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4290 if (GTK_IS_EDITABLE (focused_widget)) {
4291 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4292 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4293 gtk_clipboard_store (clipboard);
4294 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4295 GtkTextBuffer *buffer;
4297 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4298 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4299 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4300 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4301 gtk_clipboard_store (clipboard);
4303 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4304 TnyList *header_list = modest_header_view_get_selected_headers (
4305 MODEST_HEADER_VIEW (focused_widget));
4306 gboolean continue_download = FALSE;
4307 gint num_of_unc_msgs;
4309 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4311 if (num_of_unc_msgs) {
4312 TnyAccount *account = get_account_from_header_list (header_list);
4314 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4315 g_object_unref (account);
4319 if (num_of_unc_msgs == 0 || continue_download) {
4320 /* modest_platform_information_banner (
4321 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4322 modest_header_view_cut_selection (
4323 MODEST_HEADER_VIEW (focused_widget));
4326 g_object_unref (header_list);
4327 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4328 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4333 modest_ui_actions_on_copy (GtkAction *action,
4334 ModestWindow *window)
4336 GtkClipboard *clipboard;
4337 GtkWidget *focused_widget;
4338 gboolean copied = TRUE;
4340 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4341 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4343 if (GTK_IS_LABEL (focused_widget)) {
4345 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4346 gtk_clipboard_set_text (clipboard, selection, -1);
4348 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4349 gtk_clipboard_store (clipboard);
4350 } else if (GTK_IS_EDITABLE (focused_widget)) {
4351 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4352 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4353 gtk_clipboard_store (clipboard);
4354 } else if (GTK_IS_HTML (focused_widget)) {
4357 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4358 if ((sel == NULL) || (sel[0] == '\0')) {
4361 gtk_html_copy (GTK_HTML (focused_widget));
4362 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4363 gtk_clipboard_store (clipboard);
4365 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4366 GtkTextBuffer *buffer;
4367 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4368 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4369 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4370 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4371 gtk_clipboard_store (clipboard);
4373 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4374 TnyList *header_list = modest_header_view_get_selected_headers (
4375 MODEST_HEADER_VIEW (focused_widget));
4376 gboolean continue_download = FALSE;
4377 gint num_of_unc_msgs;
4379 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4381 if (num_of_unc_msgs) {
4382 TnyAccount *account = get_account_from_header_list (header_list);
4384 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4385 g_object_unref (account);
4389 if (num_of_unc_msgs == 0 || continue_download) {
4390 modest_platform_information_banner (
4391 NULL, NULL, _CS("mcen_ib_getting_items"));
4392 modest_header_view_copy_selection (
4393 MODEST_HEADER_VIEW (focused_widget));
4397 g_object_unref (header_list);
4399 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4400 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4403 /* Show information banner if there was a copy to clipboard */
4405 modest_platform_information_banner (
4406 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4410 modest_ui_actions_on_undo (GtkAction *action,
4411 ModestWindow *window)
4413 ModestEmailClipboard *clipboard = NULL;
4415 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4416 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4417 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4418 /* Clear clipboard source */
4419 clipboard = modest_runtime_get_email_clipboard ();
4420 modest_email_clipboard_clear (clipboard);
4423 g_return_if_reached ();
4428 modest_ui_actions_on_redo (GtkAction *action,
4429 ModestWindow *window)
4431 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4432 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4435 g_return_if_reached ();
4441 destroy_information_note (ModestMailOperation *mail_op,
4444 /* destroy information note */
4445 gtk_widget_destroy (GTK_WIDGET(user_data));
4449 destroy_folder_information_note (ModestMailOperation *mail_op,
4450 TnyFolder *new_folder,
4453 /* destroy information note */
4454 gtk_widget_destroy (GTK_WIDGET(user_data));
4459 paste_as_attachment_free (gpointer data)
4461 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4463 if (helper->banner) {
4464 gtk_widget_destroy (helper->banner);
4465 g_object_unref (helper->banner);
4471 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4476 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4477 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4482 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4487 modest_ui_actions_on_paste (GtkAction *action,
4488 ModestWindow *window)
4490 GtkWidget *focused_widget = NULL;
4491 GtkWidget *inf_note = NULL;
4492 ModestMailOperation *mail_op = NULL;
4494 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4495 if (GTK_IS_EDITABLE (focused_widget)) {
4496 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4497 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4498 ModestEmailClipboard *e_clipboard = NULL;
4499 e_clipboard = modest_runtime_get_email_clipboard ();
4500 if (modest_email_clipboard_cleared (e_clipboard)) {
4501 GtkTextBuffer *buffer;
4502 GtkClipboard *clipboard;
4504 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4505 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4506 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4507 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4508 ModestMailOperation *mail_op;
4509 TnyFolder *src_folder = NULL;
4510 TnyList *data = NULL;
4512 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4513 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4514 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4515 _CS("ckct_nw_pasting"));
4516 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4517 mail_op = modest_mail_operation_new (G_OBJECT (window));
4518 if (helper->banner != NULL) {
4519 g_object_ref (G_OBJECT (helper->banner));
4520 gtk_widget_show (GTK_WIDGET (helper->banner));
4524 modest_mail_operation_get_msgs_full (mail_op,
4526 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4528 paste_as_attachment_free);
4532 g_object_unref (data);
4534 g_object_unref (src_folder);
4537 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4538 ModestEmailClipboard *clipboard = NULL;
4539 TnyFolder *src_folder = NULL;
4540 TnyFolderStore *folder_store = NULL;
4541 TnyList *data = NULL;
4542 gboolean delete = FALSE;
4544 /* Check clipboard source */
4545 clipboard = modest_runtime_get_email_clipboard ();
4546 if (modest_email_clipboard_cleared (clipboard))
4549 /* Get elements to paste */
4550 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4552 /* Create a new mail operation */
4553 mail_op = modest_mail_operation_new (G_OBJECT(window));
4555 /* Get destination folder */
4556 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4558 /* transfer messages */
4562 /* Ask for user confirmation */
4564 modest_ui_actions_msgs_move_to_confirmation (window,
4565 TNY_FOLDER (folder_store),
4569 if (response == GTK_RESPONSE_OK) {
4570 /* Launch notification */
4571 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4572 _CS("ckct_nw_pasting"));
4573 if (inf_note != NULL) {
4574 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4575 gtk_widget_show (GTK_WIDGET(inf_note));
4578 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4579 modest_mail_operation_xfer_msgs (mail_op,
4581 TNY_FOLDER (folder_store),
4583 destroy_information_note,
4586 g_object_unref (mail_op);
4589 } else if (src_folder != NULL) {
4590 /* Launch notification */
4591 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4592 _CS("ckct_nw_pasting"));
4593 if (inf_note != NULL) {
4594 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4595 gtk_widget_show (GTK_WIDGET(inf_note));
4598 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4599 modest_mail_operation_xfer_folder (mail_op,
4603 destroy_folder_information_note,
4609 g_object_unref (data);
4610 if (src_folder != NULL)
4611 g_object_unref (src_folder);
4612 if (folder_store != NULL)
4613 g_object_unref (folder_store);
4619 modest_ui_actions_on_select_all (GtkAction *action,
4620 ModestWindow *window)
4622 GtkWidget *focused_widget;
4624 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4625 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4626 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4627 } else if (GTK_IS_LABEL (focused_widget)) {
4628 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4629 } else if (GTK_IS_EDITABLE (focused_widget)) {
4630 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4631 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4632 GtkTextBuffer *buffer;
4633 GtkTextIter start, end;
4635 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4636 gtk_text_buffer_get_start_iter (buffer, &start);
4637 gtk_text_buffer_get_end_iter (buffer, &end);
4638 gtk_text_buffer_select_range (buffer, &start, &end);
4639 } else if (GTK_IS_HTML (focused_widget)) {
4640 gtk_html_select_all (GTK_HTML (focused_widget));
4641 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4642 GtkWidget *header_view = focused_widget;
4643 GtkTreeSelection *selection = NULL;
4645 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4646 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4647 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4650 /* Disable window dimming management */
4651 modest_window_disable_dimming (MODEST_WINDOW(window));
4653 /* Select all messages */
4654 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4655 gtk_tree_selection_select_all (selection);
4657 /* Set focuse on header view */
4658 gtk_widget_grab_focus (header_view);
4660 /* Enable window dimming management */
4661 modest_window_enable_dimming (MODEST_WINDOW(window));
4662 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4663 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4669 modest_ui_actions_on_mark_as_read (GtkAction *action,
4670 ModestWindow *window)
4672 g_return_if_fail (MODEST_IS_WINDOW(window));
4674 /* Mark each header as read */
4675 do_headers_action (window, headers_action_mark_as_read, NULL);
4679 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4680 ModestWindow *window)
4682 g_return_if_fail (MODEST_IS_WINDOW(window));
4684 /* Mark each header as read */
4685 do_headers_action (window, headers_action_mark_as_unread, NULL);
4689 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4690 GtkRadioAction *selected,
4691 ModestWindow *window)
4695 value = gtk_radio_action_get_current_value (selected);
4696 if (MODEST_IS_WINDOW (window)) {
4697 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4702 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4703 GtkRadioAction *selected,
4704 ModestWindow *window)
4706 TnyHeaderFlags flags;
4707 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4709 flags = gtk_radio_action_get_current_value (selected);
4710 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4714 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4715 GtkRadioAction *selected,
4716 ModestWindow *window)
4720 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4722 file_format = gtk_radio_action_get_current_value (selected);
4723 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4728 modest_ui_actions_on_zoom_plus (GtkAction *action,
4729 ModestWindow *window)
4731 g_return_if_fail (MODEST_IS_WINDOW (window));
4733 modest_window_zoom_plus (MODEST_WINDOW (window));
4737 modest_ui_actions_on_zoom_minus (GtkAction *action,
4738 ModestWindow *window)
4740 g_return_if_fail (MODEST_IS_WINDOW (window));
4742 modest_window_zoom_minus (MODEST_WINDOW (window));
4746 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4747 ModestWindow *window)
4749 ModestWindowMgr *mgr;
4750 gboolean fullscreen, active;
4751 g_return_if_fail (MODEST_IS_WINDOW (window));
4753 mgr = modest_runtime_get_window_mgr ();
4755 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4756 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4758 if (active != fullscreen) {
4759 modest_window_mgr_set_fullscreen_mode (mgr, active);
4760 #ifndef MODEST_TOOLKIT_HILDON2
4761 gtk_window_present (GTK_WINDOW (window));
4767 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4768 ModestWindow *window)
4770 ModestWindowMgr *mgr;
4771 gboolean fullscreen;
4773 g_return_if_fail (MODEST_IS_WINDOW (window));
4775 mgr = modest_runtime_get_window_mgr ();
4776 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4777 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4779 #ifndef MODEST_TOOLKIT_HILDON2
4780 gtk_window_present (GTK_WINDOW (window));
4785 * Used by modest_ui_actions_on_details to call do_headers_action
4788 headers_action_show_details (TnyHeader *header,
4789 ModestWindow *window,
4793 gboolean async_retrieval;
4796 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4797 async_retrieval = TRUE;
4798 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4800 async_retrieval = FALSE;
4802 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4804 g_object_unref (msg);
4808 * Show the header details in a ModestDetailsDialog widget
4811 modest_ui_actions_on_details (GtkAction *action,
4814 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4818 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4822 header = tny_msg_get_header (msg);
4824 headers_action_show_details (header, win, NULL);
4825 g_object_unref (header);
4827 g_object_unref (msg);
4829 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4830 GtkWidget *folder_view, *header_view;
4832 /* Check which widget has the focus */
4833 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4834 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4835 if (gtk_widget_is_focus (folder_view)) {
4836 TnyFolderStore *folder_store
4837 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4838 if (!folder_store) {
4839 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4842 /* Show only when it's a folder */
4843 /* This function should not be called for account items,
4844 * because we dim the menu item for them. */
4845 if (TNY_IS_FOLDER (folder_store)) {
4846 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4847 TNY_FOLDER (folder_store));
4850 g_object_unref (folder_store);
4853 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4854 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4855 /* Show details of each header */
4856 do_headers_action (win, headers_action_show_details, header_view);
4858 #ifdef MODEST_TOOLKIT_HILDON2
4859 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4861 GtkWidget *header_view;
4863 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4864 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4866 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4868 g_object_unref (folder);
4875 modest_ui_actions_on_limit_error (GtkAction *action,
4878 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4880 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4885 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4886 ModestMsgEditWindow *window)
4888 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4890 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4894 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4895 ModestMsgEditWindow *window)
4897 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4899 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4903 modest_ui_actions_toggle_folders_view (GtkAction *action,
4904 ModestMainWindow *main_window)
4906 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4908 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4909 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4911 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4915 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4916 ModestWindow *window)
4918 gboolean active, fullscreen = FALSE;
4919 ModestWindowMgr *mgr;
4921 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4923 /* Check if we want to toggle the toolbar view in fullscreen
4925 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4926 "ViewShowToolbarFullScreen")) {
4930 /* Toggle toolbar */
4931 mgr = modest_runtime_get_window_mgr ();
4932 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4936 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4937 ModestMsgEditWindow *window)
4939 modest_msg_edit_window_select_font (window);
4944 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4945 const gchar *display_name,
4948 /* don't update the display name if it was already set;
4949 * updating the display name apparently is expensive */
4950 const gchar* old_name = gtk_window_get_title (window);
4952 if (display_name == NULL)
4955 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4956 return; /* don't do anything */
4958 /* This is usually used to change the title of the main window, which
4959 * is the one that holds the folder view. Note that this change can
4960 * happen even when the widget doesn't have the focus. */
4961 gtk_window_set_title (window, display_name);
4966 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4968 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4969 modest_msg_edit_window_select_contacts (window);
4973 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4976 modest_msg_edit_window_check_names (window, FALSE);
4979 #ifndef MODEST_TOOLKIT_HILDON2
4981 * This function is used to track changes in the selection of the
4982 * folder view that is inside the "move to" dialog to enable/disable
4983 * the OK button because we do not want the user to select a disallowed
4984 * destination for a folder.
4985 * The user also not desired to be able to use NEW button on items where
4986 * folder creation is not possibel.
4989 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4990 TnyFolderStore *folder_store,
4994 GtkWidget *dialog = NULL;
4995 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4996 gboolean moving_folder = FALSE;
4997 gboolean is_local_account = TRUE;
4998 GtkWidget *folder_view = NULL;
4999 ModestTnyFolderRules rules;
5001 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5006 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5010 /* check if folder_store is an remote account */
5011 if (TNY_IS_ACCOUNT (folder_store)) {
5012 TnyAccount *local_account = NULL;
5013 TnyAccount *mmc_account = NULL;
5014 ModestTnyAccountStore *account_store = NULL;
5016 account_store = modest_runtime_get_account_store ();
5017 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5018 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5020 if ((gpointer) local_account != (gpointer) folder_store &&
5021 (gpointer) mmc_account != (gpointer) folder_store) {
5022 ModestProtocolType proto;
5023 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5024 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5025 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5027 is_local_account = FALSE;
5028 /* New button should be dimmed on remote
5030 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5032 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5034 g_object_unref (local_account);
5036 /* It could not exist */
5038 g_object_unref (mmc_account);
5041 /* Check the target folder rules */
5042 if (TNY_IS_FOLDER (folder_store)) {
5043 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5044 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5045 ok_sensitive = FALSE;
5046 new_sensitive = FALSE;
5051 /* Check if we're moving a folder */
5052 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5053 /* Get the widgets */
5054 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5055 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5056 if (gtk_widget_is_focus (folder_view))
5057 moving_folder = TRUE;
5060 if (moving_folder) {
5061 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5063 /* Get the folder to move */
5064 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5066 /* Check that we're not moving to the same folder */
5067 if (TNY_IS_FOLDER (moved_folder)) {
5068 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5069 if (parent == folder_store)
5070 ok_sensitive = FALSE;
5071 g_object_unref (parent);
5074 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5075 /* Do not allow to move to an account unless it's the
5076 local folders account */
5077 if (!is_local_account)
5078 ok_sensitive = FALSE;
5081 if (ok_sensitive && (moved_folder == folder_store)) {
5082 /* Do not allow to move to itself */
5083 ok_sensitive = FALSE;
5085 g_object_unref (moved_folder);
5087 TnyFolder *src_folder = NULL;
5089 /* Moving a message */
5090 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5092 TnyHeader *header = NULL;
5093 header = modest_msg_view_window_get_header
5094 (MODEST_MSG_VIEW_WINDOW (user_data));
5095 if (!TNY_IS_HEADER(header))
5096 g_warning ("%s: could not get source header", __FUNCTION__);
5098 src_folder = tny_header_get_folder (header);
5101 g_object_unref (header);
5104 TNY_FOLDER (modest_folder_view_get_selected
5105 (MODEST_FOLDER_VIEW (folder_view)));
5108 if (TNY_IS_FOLDER(src_folder)) {
5109 /* Do not allow to move the msg to the same folder */
5110 /* Do not allow to move the msg to an account */
5111 if ((gpointer) src_folder == (gpointer) folder_store ||
5112 TNY_IS_ACCOUNT (folder_store))
5113 ok_sensitive = FALSE;
5114 g_object_unref (src_folder);
5116 g_warning ("%s: could not get source folder", __FUNCTION__);
5120 /* Set sensitivity of the OK and NEW button */
5121 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5122 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5127 on_move_to_dialog_response (GtkDialog *dialog,
5131 GtkWidget *parent_win;
5132 MoveToInfo *helper = NULL;
5133 ModestFolderView *folder_view;
5134 gboolean unset_edit_mode = FALSE;
5136 helper = (MoveToInfo *) user_data;
5138 parent_win = (GtkWidget *) helper->win;
5139 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5140 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5142 TnyFolderStore *dst_folder;
5143 TnyFolderStore *selected;
5145 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5146 selected = modest_folder_view_get_selected (folder_view);
5147 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5148 g_object_unref (selected);
5150 case GTK_RESPONSE_NONE:
5151 case GTK_RESPONSE_CANCEL:
5152 case GTK_RESPONSE_DELETE_EVENT:
5154 case GTK_RESPONSE_OK:
5155 dst_folder = modest_folder_view_get_selected (folder_view);
5157 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5158 /* Clean list to move used for filtering */
5159 modest_folder_view_set_list_to_move (folder_view, NULL);
5161 modest_ui_actions_on_main_window_move_to (NULL,
5162 GTK_WIDGET (folder_view),
5164 MODEST_MAIN_WINDOW (parent_win));
5165 #ifdef MODEST_TOOLKIT_HILDON2
5166 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5167 /* Clean list to move used for filtering */
5168 modest_folder_view_set_list_to_move (folder_view, NULL);
5170 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5173 GTK_WINDOW (parent_win));
5176 /* if the user selected a root folder
5177 (account) then do not perform any action */
5178 if (TNY_IS_ACCOUNT (dst_folder)) {
5179 g_signal_stop_emission_by_name (dialog, "response");
5183 /* Clean list to move used for filtering */
5184 modest_folder_view_set_list_to_move (folder_view, NULL);
5186 /* Moving from headers window in edit mode */
5187 modest_ui_actions_on_window_move_to (NULL, helper->list,
5189 MODEST_WINDOW (parent_win));
5193 g_object_unref (dst_folder);
5195 unset_edit_mode = TRUE;
5198 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5201 /* Free the helper and exit */
5203 g_object_unref (helper->list);
5204 if (unset_edit_mode) {
5205 #ifdef MODEST_TOOLKIT_HILDON2
5206 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5209 g_slice_free (MoveToInfo, helper);
5210 gtk_widget_destroy (GTK_WIDGET (dialog));
5214 create_move_to_dialog (GtkWindow *win,
5215 GtkWidget *folder_view,
5216 TnyList *list_to_move)
5218 GtkWidget *dialog, *tree_view = NULL;
5220 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5222 #ifndef MODEST_TOOLKIT_HILDON2
5223 /* Track changes in the selection to
5224 * disable the OK button whenever "Move to" is not possible
5225 * disbale NEW button whenever New is not possible */
5226 g_signal_connect (tree_view,
5227 "folder_selection_changed",
5228 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5232 /* It could happen that we're trying to move a message from a
5233 window (msg window for example) after the main window was
5234 closed, so we can not just get the model of the folder
5236 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5237 const gchar *visible_id = NULL;
5239 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5240 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5241 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5242 MODEST_FOLDER_VIEW(tree_view));
5245 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5247 /* Show the same account than the one that is shown in the main window */
5248 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5251 const gchar *active_account_name = NULL;
5252 ModestAccountMgr *mgr = NULL;
5253 ModestAccountSettings *settings = NULL;
5254 ModestServerAccountSettings *store_settings = NULL;
5256 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5257 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5258 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5259 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5261 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5262 mgr = modest_runtime_get_account_mgr ();
5263 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5266 const gchar *store_account_name;
5267 store_settings = modest_account_settings_get_store_settings (settings);
5268 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5270 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5271 store_account_name);
5272 g_object_unref (store_settings);
5273 g_object_unref (settings);
5277 /* we keep a pointer to the embedded folder view, so we can
5278 * retrieve it with get_folder_view_from_move_to_dialog (see
5279 * above) later (needed for focus handling)
5281 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5283 /* Hide special folders */
5284 #ifndef MODEST_TOOLKIT_HILDON2
5285 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5288 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5289 #ifndef MODEST_TOOLKIT_HILDON2
5290 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5293 gtk_widget_show (GTK_WIDGET (tree_view));
5299 * Shows a confirmation dialog to the user when we're moving messages
5300 * from a remote server to the local storage. Returns the dialog
5301 * response. If it's other kind of movement then it always returns
5304 * This one is used by the next functions:
5305 * modest_ui_actions_on_paste - commented out
5306 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5309 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5310 TnyFolder *dest_folder,
5314 gint response = GTK_RESPONSE_OK;
5315 TnyAccount *account = NULL;
5316 TnyFolder *src_folder = NULL;
5317 TnyIterator *iter = NULL;
5318 TnyHeader *header = NULL;
5320 /* return with OK if the destination is a remote folder */
5321 if (modest_tny_folder_is_remote_folder (dest_folder))
5322 return GTK_RESPONSE_OK;
5324 /* Get source folder */
5325 iter = tny_list_create_iterator (headers);
5326 header = TNY_HEADER (tny_iterator_get_current (iter));
5328 src_folder = tny_header_get_folder (header);
5329 g_object_unref (header);
5331 g_object_unref (iter);
5333 /* if no src_folder, message may be an attahcment */
5334 if (src_folder == NULL)
5335 return GTK_RESPONSE_CANCEL;
5337 /* If the source is a local or MMC folder */
5338 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5339 g_object_unref (src_folder);
5340 return GTK_RESPONSE_OK;
5343 /* Get the account */
5344 account = tny_folder_get_account (src_folder);
5346 /* now if offline we ask the user */
5347 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5348 response = GTK_RESPONSE_OK;
5350 response = GTK_RESPONSE_CANCEL;
5353 g_object_unref (src_folder);
5354 g_object_unref (account);
5360 move_to_helper_destroyer (gpointer user_data)
5362 MoveToHelper *helper = (MoveToHelper *) user_data;
5364 /* Close the "Pasting" information banner */
5365 if (helper->banner) {
5366 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5367 g_object_unref (helper->banner);
5369 if (gtk_tree_row_reference_valid (helper->reference)) {
5370 gtk_tree_row_reference_free (helper->reference);
5371 helper->reference = NULL;
5377 move_to_cb (ModestMailOperation *mail_op,
5380 MoveToHelper *helper = (MoveToHelper *) user_data;
5381 GObject *object = modest_mail_operation_get_source (mail_op);
5383 /* Note that the operation could have failed, in that case do
5385 if (modest_mail_operation_get_status (mail_op) !=
5386 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5389 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5390 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5392 if (!modest_msg_view_window_select_next_message (self) &&
5393 !modest_msg_view_window_select_previous_message (self)) {
5394 /* No more messages to view, so close this window */
5395 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5397 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5398 gtk_tree_row_reference_valid (helper->reference)) {
5399 GtkWidget *header_view;
5401 GtkTreeSelection *sel;
5403 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5404 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5405 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5406 path = gtk_tree_row_reference_get_path (helper->reference);
5407 /* We need to unselect the previous one
5408 because we could be copying instead of
5410 gtk_tree_selection_unselect_all (sel);
5411 gtk_tree_selection_select_path (sel, path);
5412 gtk_tree_path_free (path);
5414 g_object_unref (object);
5417 /* Destroy the helper */
5418 move_to_helper_destroyer (helper);
5422 folder_move_to_cb (ModestMailOperation *mail_op,
5423 TnyFolder *new_folder,
5426 GtkWidget *folder_view;
5429 object = modest_mail_operation_get_source (mail_op);
5430 if (MODEST_IS_MAIN_WINDOW (object)) {
5431 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5432 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5433 g_object_ref (folder_view);
5434 g_object_unref (object);
5435 move_to_cb (mail_op, user_data);
5436 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5437 g_object_unref (folder_view);
5439 move_to_cb (mail_op, user_data);
5444 msgs_move_to_cb (ModestMailOperation *mail_op,
5447 move_to_cb (mail_op, user_data);
5451 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5454 GObject *win = NULL;
5455 const GError *error;
5456 TnyAccount *account = NULL;
5458 #ifndef MODEST_TOOLKIT_HILDON2
5459 ModestWindow *main_window = NULL;
5461 /* Disable next automatic folder selection */
5462 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5463 FALSE); /* don't create */
5465 /* Show notification dialog only if the main window exists */
5467 GtkWidget *folder_view = NULL;
5469 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5470 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5471 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5473 if (user_data && TNY_IS_FOLDER (user_data)) {
5474 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5475 TNY_FOLDER (user_data), FALSE);
5479 win = modest_mail_operation_get_source (mail_op);
5480 error = modest_mail_operation_get_error (mail_op);
5482 if (TNY_IS_FOLDER (user_data))
5483 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5484 else if (TNY_IS_ACCOUNT (user_data))
5485 account = g_object_ref (user_data);
5487 /* If it's not a disk full error then show a generic error */
5488 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5489 (GtkWidget *) win, (GError *) error,
5491 modest_platform_run_information_dialog ((GtkWindow *) win,
5492 _("mail_in_ui_folder_move_target_error"),
5495 g_object_unref (account);
5497 g_object_unref (win);
5501 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5510 gint pending_purges = 0;
5511 gboolean some_purged = FALSE;
5512 ModestWindow *win = MODEST_WINDOW (user_data);
5513 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5515 /* If there was any error */
5516 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5517 modest_window_mgr_unregister_header (mgr, header);
5521 /* Once the message has been retrieved for purging, we check if
5522 * it's all ok for purging */
5524 parts = tny_simple_list_new ();
5525 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5526 iter = tny_list_create_iterator (parts);
5528 while (!tny_iterator_is_done (iter)) {
5530 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5531 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5532 if (tny_mime_part_is_purged (part))
5539 g_object_unref (part);
5541 tny_iterator_next (iter);
5543 g_object_unref (iter);
5546 if (pending_purges>0) {
5548 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5550 if (response == GTK_RESPONSE_OK) {
5553 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5554 iter = tny_list_create_iterator (parts);
5555 while (!tny_iterator_is_done (iter)) {
5558 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5559 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5560 tny_mime_part_set_purged (part);
5563 g_object_unref (part);
5565 tny_iterator_next (iter);
5567 g_object_unref (iter);
5569 tny_msg_rewrite_cache (msg);
5571 gtk_widget_destroy (info);
5575 modest_window_mgr_unregister_header (mgr, header);
5577 g_object_unref (parts);
5581 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5582 ModestMainWindow *win)
5584 GtkWidget *header_view;
5585 TnyList *header_list;
5587 TnyHeaderFlags flags;
5588 ModestWindow *msg_view_window = NULL;
5591 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5593 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5594 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5596 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5598 g_warning ("%s: no header selected", __FUNCTION__);
5602 if (tny_list_get_length (header_list) == 1) {
5603 TnyIterator *iter = tny_list_create_iterator (header_list);
5604 header = TNY_HEADER (tny_iterator_get_current (iter));
5605 g_object_unref (iter);
5609 if (!header || !TNY_IS_HEADER(header)) {
5610 g_warning ("%s: header is not valid", __FUNCTION__);
5614 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5615 header, &msg_view_window);
5616 flags = tny_header_get_flags (header);
5617 if (!(flags & TNY_HEADER_FLAG_CACHED))
5620 if (msg_view_window != NULL)
5621 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5623 /* do nothing; uid was registered before, so window is probably on it's way */
5624 g_debug ("header %p has already been registered", header);
5627 ModestMailOperation *mail_op = NULL;
5628 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5629 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5630 modest_ui_actions_disk_operations_error_handler,
5632 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5633 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5635 g_object_unref (mail_op);
5638 g_object_unref (header);
5640 g_object_unref (header_list);
5644 * Checks if we need a connection to do the transfer and if the user
5645 * wants to connect to complete it
5648 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5649 TnyFolderStore *src_folder,
5651 TnyFolder *dst_folder,
5652 gboolean delete_originals,
5653 gboolean *need_connection,
5656 TnyAccount *src_account;
5657 gint uncached_msgs = 0;
5659 /* We don't need any further check if
5661 * 1- the source folder is local OR
5662 * 2- the device is already online
5664 if (!modest_tny_folder_store_is_remote (src_folder) ||
5665 tny_device_is_online (modest_runtime_get_device())) {
5666 *need_connection = FALSE;
5671 /* We must ask for a connection when
5673 * - the message(s) is not already cached OR
5674 * - the message(s) is cached but the leave_on_server setting
5675 * is FALSE (because we need to sync the source folder to
5676 * delete the message from the server (for IMAP we could do it
5677 * offline, it'll take place the next time we get a
5680 uncached_msgs = header_list_count_uncached_msgs (headers);
5681 src_account = get_account_from_folder_store (src_folder);
5682 if (uncached_msgs > 0) {
5686 *need_connection = TRUE;
5687 num_headers = tny_list_get_length (headers);
5688 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5690 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5691 GTK_RESPONSE_CANCEL) {
5697 /* The transfer is possible and the user wants to */
5700 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5701 const gchar *account_name;
5702 gboolean leave_on_server;
5704 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5705 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5708 if (leave_on_server == TRUE) {
5709 *need_connection = FALSE;
5711 *need_connection = TRUE;
5714 *need_connection = FALSE;
5719 g_object_unref (src_account);
5723 xfer_messages_error_handler (ModestMailOperation *mail_op,
5727 const GError *error;
5728 TnyAccount *account;
5730 win = modest_mail_operation_get_source (mail_op);
5731 error = modest_mail_operation_get_error (mail_op);
5733 /* We cannot get the account from the mail op as that is the
5734 source account and for checking memory full conditions we
5735 need the destination one */
5736 account = TNY_ACCOUNT (user_data);
5739 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5740 (GtkWidget *) win, (GError*) error,
5741 account, _KR("cerm_memory_card_full"))) {
5742 modest_platform_run_information_dialog ((GtkWindow *) win,
5743 _("mail_in_ui_folder_move_target_error"),
5747 g_object_unref (win);
5751 TnyFolderStore *dst_folder;
5756 * Utility function that transfer messages from both the main window
5757 * and the msg view window when using the "Move to" dialog
5760 xfer_messages_performer (gboolean canceled,
5762 GtkWindow *parent_window,
5763 TnyAccount *account,
5766 ModestWindow *win = MODEST_WINDOW (parent_window);
5767 TnyAccount *dst_account = NULL;
5768 gboolean dst_forbids_message_add = FALSE;
5769 XferMsgsHelper *helper;
5770 MoveToHelper *movehelper;
5771 ModestMailOperation *mail_op;
5773 helper = (XferMsgsHelper *) user_data;
5775 if (canceled || err) {
5776 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5777 (GtkWidget *) parent_window, err,
5779 /* Show the proper error message */
5780 modest_ui_actions_on_account_connection_error (parent_window, account);
5785 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5787 /* tinymail will return NULL for local folders it seems */
5788 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5789 modest_tny_account_get_protocol_type (dst_account),
5790 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5792 if (dst_forbids_message_add) {
5793 modest_platform_information_banner (GTK_WIDGET (win),
5795 ngettext("mail_in_ui_folder_move_target_error",
5796 "mail_in_ui_folder_move_targets_error",
5797 tny_list_get_length (helper->headers)));
5801 movehelper = g_new0 (MoveToHelper, 1);
5803 #ifndef MODEST_TOOLKIT_HILDON2
5804 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5805 _CS("ckct_nw_pasting"));
5806 if (movehelper->banner != NULL) {
5807 g_object_ref (movehelper->banner);
5808 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5812 if (MODEST_IS_MAIN_WINDOW (win)) {
5813 GtkWidget *header_view =
5814 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5815 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5816 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5819 /* Perform the mail operation */
5820 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5821 xfer_messages_error_handler,
5822 g_object_ref (dst_account),
5824 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5827 modest_mail_operation_xfer_msgs (mail_op,
5829 TNY_FOLDER (helper->dst_folder),
5834 g_object_unref (G_OBJECT (mail_op));
5837 g_object_unref (dst_account);
5838 g_object_unref (helper->dst_folder);
5839 g_object_unref (helper->headers);
5840 g_slice_free (XferMsgsHelper, helper);
5844 TnyFolder *src_folder;
5845 TnyFolderStore *dst_folder;
5846 gboolean delete_original;
5847 GtkWidget *folder_view;
5851 on_move_folder_cb (gboolean canceled,
5853 GtkWindow *parent_window,
5854 TnyAccount *account,
5857 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5858 GtkTreeSelection *sel;
5859 ModestMailOperation *mail_op = NULL;
5861 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5862 /* Note that the connection process can fail due to
5863 memory low conditions as it can not successfully
5864 store the summary */
5865 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5866 (GtkWidget*) parent_window, err,
5868 g_debug ("Error connecting when trying to move a folder");
5870 g_object_unref (G_OBJECT (info->src_folder));
5871 g_object_unref (G_OBJECT (info->dst_folder));
5876 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5877 #ifndef MODEST_TOOLKIT_HILDON2
5878 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5879 _CS("ckct_nw_pasting"));
5880 if (helper->banner != NULL) {
5881 g_object_ref (helper->banner);
5882 gtk_widget_show (GTK_WIDGET(helper->banner));
5885 /* Clean folder on header view before moving it */
5886 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5887 gtk_tree_selection_unselect_all (sel);
5889 /* Let gtk events run. We need that the folder
5890 view frees its reference to the source
5891 folder *before* issuing the mail operation
5892 so we need the signal handler of selection
5893 changed to happen before the mail
5895 while (gtk_events_pending ())
5896 gtk_main_iteration (); */
5899 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5900 modest_ui_actions_move_folder_error_handler,
5901 g_object_ref (info->dst_folder), g_object_unref);
5902 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5905 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5906 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5907 TNY_FOLDER (info->dst_folder), TRUE);
5909 modest_mail_operation_xfer_folder (mail_op,
5910 TNY_FOLDER (info->src_folder),
5912 info->delete_original,
5915 g_object_unref (G_OBJECT (info->src_folder));
5917 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5920 /* Unref mail operation */
5921 g_object_unref (G_OBJECT (mail_op));
5922 g_object_unref (G_OBJECT (info->dst_folder));
5927 get_account_from_folder_store (TnyFolderStore *folder_store)
5929 if (TNY_IS_ACCOUNT (folder_store))
5930 return g_object_ref (folder_store);
5932 return tny_folder_get_account (TNY_FOLDER (folder_store));
5936 * UI handler for the "Move to" action when invoked from the
5940 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5941 GtkWidget *folder_view,
5942 TnyFolderStore *dst_folder,
5943 ModestMainWindow *win)
5945 ModestHeaderView *header_view = NULL;
5946 TnyFolderStore *src_folder = NULL;
5948 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5950 /* Get the source folder */
5951 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5953 /* Get header view */
5954 header_view = (ModestHeaderView *)
5955 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5957 /* Get folder or messages to transfer */
5958 if (gtk_widget_is_focus (folder_view)) {
5959 gboolean do_xfer = TRUE;
5961 /* Allow only to transfer folders to the local root folder */
5962 if (TNY_IS_ACCOUNT (dst_folder) &&
5963 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5964 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5966 } else if (!TNY_IS_FOLDER (src_folder)) {
5967 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5972 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5973 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5975 info->src_folder = g_object_ref (src_folder);
5976 info->dst_folder = g_object_ref (dst_folder);
5977 info->delete_original = TRUE;
5978 info->folder_view = folder_view;
5980 connect_info->callback = on_move_folder_cb;
5981 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5982 connect_info->data = info;
5984 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5985 TNY_FOLDER_STORE (src_folder),
5988 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5991 headers = modest_header_view_get_selected_headers(header_view);
5993 /* Transfer the messages */
5994 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5995 headers, TNY_FOLDER (dst_folder));
5997 g_object_unref (headers);
6001 g_object_unref (src_folder);
6004 #ifdef MODEST_TOOLKIT_HILDON2
6006 * UI handler for the "Move to" action when invoked from the
6007 * ModestFolderWindow
6010 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6011 TnyFolderStore *dst_folder,
6015 TnyFolderStore *src_folder = NULL;
6016 TnyIterator *iterator;
6018 if (tny_list_get_length (selection) != 1)
6021 iterator = tny_list_create_iterator (selection);
6022 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6023 g_object_unref (iterator);
6026 gboolean do_xfer = TRUE;
6028 /* Allow only to transfer folders to the local root folder */
6029 if (TNY_IS_ACCOUNT (dst_folder) &&
6030 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6031 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6034 modest_platform_run_information_dialog (win,
6035 _("mail_in_ui_folder_move_target_error"),
6037 } else if (!TNY_IS_FOLDER (src_folder)) {
6038 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6043 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6044 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6046 info->src_folder = g_object_ref (src_folder);
6047 info->dst_folder = g_object_ref (dst_folder);
6048 info->delete_original = TRUE;
6049 info->folder_view = folder_view;
6051 connect_info->callback = on_move_folder_cb;
6052 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6053 connect_info->data = info;
6055 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6056 TNY_FOLDER_STORE (src_folder),
6061 g_object_unref (src_folder);
6067 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6068 TnyFolder *src_folder,
6070 TnyFolder *dst_folder)
6072 gboolean need_connection = TRUE;
6073 gboolean do_xfer = TRUE;
6074 XferMsgsHelper *helper;
6076 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6077 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6078 g_return_if_fail (TNY_IS_LIST (headers));
6080 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6081 headers, TNY_FOLDER (dst_folder),
6082 TRUE, &need_connection,
6085 /* If we don't want to transfer just return */
6089 /* Create the helper */
6090 helper = g_slice_new (XferMsgsHelper);
6091 helper->dst_folder = g_object_ref (dst_folder);
6092 helper->headers = g_object_ref (headers);
6094 if (need_connection) {
6095 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6096 connect_info->callback = xfer_messages_performer;
6097 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6098 connect_info->data = helper;
6100 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6101 TNY_FOLDER_STORE (src_folder),
6104 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6105 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6106 src_account, helper);
6107 g_object_unref (src_account);
6112 * UI handler for the "Move to" action when invoked from the
6113 * ModestMsgViewWindow
6116 modest_ui_actions_on_window_move_to (GtkAction *action,
6118 TnyFolderStore *dst_folder,
6121 TnyFolder *src_folder = NULL;
6123 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6126 TnyHeader *header = NULL;
6129 iter = tny_list_create_iterator (headers);
6130 header = (TnyHeader *) tny_iterator_get_current (iter);
6131 src_folder = tny_header_get_folder (header);
6133 /* Transfer the messages */
6134 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6136 TNY_FOLDER (dst_folder));
6139 g_object_unref (header);
6140 g_object_unref (iter);
6141 g_object_unref (src_folder);
6146 modest_ui_actions_on_move_to (GtkAction *action,
6149 modest_ui_actions_on_edit_mode_move_to (win);
6153 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6155 GtkWidget *dialog = NULL;
6156 MoveToInfo *helper = NULL;
6157 TnyList *list_to_move;
6159 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6161 #ifndef MODEST_TOOLKIT_HILDON2
6162 /* Get the main window if exists */
6163 ModestMainWindow *main_window;
6164 if (MODEST_IS_MAIN_WINDOW (win))
6165 main_window = MODEST_MAIN_WINDOW (win);
6168 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6169 FALSE)); /* don't create */
6172 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6177 if (tny_list_get_length (list_to_move) < 1) {
6178 g_object_unref (list_to_move);
6182 /* Create and run the dialog */
6183 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6184 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6185 GTK_WINDOW (dialog),
6189 helper = g_slice_new0 (MoveToInfo);
6190 helper->list = list_to_move;
6193 /* Listen to response signal */
6194 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6196 /* Show the dialog */
6197 gtk_widget_show (dialog);
6203 * Calls #HeadersFunc for each header already selected in the main
6204 * window or the message currently being shown in the msg view window
6207 do_headers_action (ModestWindow *win,
6211 TnyList *headers_list = NULL;
6212 TnyIterator *iter = NULL;
6213 TnyHeader *header = NULL;
6214 TnyFolder *folder = NULL;
6217 headers_list = get_selected_headers (win);
6221 /* Get the folder */
6222 iter = tny_list_create_iterator (headers_list);
6223 header = TNY_HEADER (tny_iterator_get_current (iter));
6225 folder = tny_header_get_folder (header);
6226 g_object_unref (header);
6229 /* Call the function for each header */
6230 while (!tny_iterator_is_done (iter)) {
6231 header = TNY_HEADER (tny_iterator_get_current (iter));
6232 func (header, win, user_data);
6233 g_object_unref (header);
6234 tny_iterator_next (iter);
6237 /* Trick: do a poke status in order to speed up the signaling
6240 tny_folder_poke_status (folder);
6241 g_object_unref (folder);
6245 g_object_unref (iter);
6246 g_object_unref (headers_list);
6250 modest_ui_actions_view_attachment (GtkAction *action,
6251 ModestWindow *window)
6253 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6254 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6256 /* not supported window for this action */
6257 g_return_if_reached ();
6262 modest_ui_actions_save_attachments (GtkAction *action,
6263 ModestWindow *window)
6265 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6267 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6270 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6272 /* not supported window for this action */
6273 g_return_if_reached ();
6278 modest_ui_actions_remove_attachments (GtkAction *action,
6279 ModestWindow *window)
6281 if (MODEST_IS_MAIN_WINDOW (window)) {
6282 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6283 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6284 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6286 /* not supported window for this action */
6287 g_return_if_reached ();
6292 modest_ui_actions_on_settings (GtkAction *action,
6297 dialog = modest_platform_get_global_settings_dialog ();
6298 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6299 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6300 gtk_widget_show_all (dialog);
6302 gtk_dialog_run (GTK_DIALOG (dialog));
6304 gtk_widget_destroy (dialog);
6308 modest_ui_actions_on_help (GtkAction *action,
6311 /* Help app is not available at all in fremantle */
6312 #ifndef MODEST_TOOLKIT_HILDON2
6313 const gchar *help_id;
6315 g_return_if_fail (win && GTK_IS_WINDOW(win));
6317 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6320 modest_platform_show_help (GTK_WINDOW (win), help_id);
6325 modest_ui_actions_on_csm_help (GtkAction *action,
6328 /* Help app is not available at all in fremantle */
6329 #ifndef MODEST_TOOLKIT_HILDON2
6331 const gchar* help_id = NULL;
6332 GtkWidget *folder_view;
6333 TnyFolderStore *folder_store;
6335 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6337 /* Get selected folder */
6338 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6339 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6340 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6342 /* Switch help_id */
6343 if (folder_store && TNY_IS_FOLDER (folder_store))
6344 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6347 g_object_unref (folder_store);
6350 modest_platform_show_help (GTK_WINDOW (win), help_id);
6352 modest_ui_actions_on_help (action, win);
6357 retrieve_contents_cb (ModestMailOperation *mail_op,
6364 /* We only need this callback to show an error in case of
6365 memory low condition */
6366 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6367 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6372 retrieve_msg_contents_performer (gboolean canceled,
6374 GtkWindow *parent_window,
6375 TnyAccount *account,
6378 ModestMailOperation *mail_op;
6379 TnyList *headers = TNY_LIST (user_data);
6381 if (err || canceled) {
6382 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6383 (GtkWidget *) parent_window, err,
6388 /* Create mail operation */
6389 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6390 modest_ui_actions_disk_operations_error_handler,
6392 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6393 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6396 g_object_unref (mail_op);
6398 g_object_unref (headers);
6399 g_object_unref (account);
6403 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6404 ModestWindow *window)
6406 TnyList *headers = NULL;
6407 TnyAccount *account = NULL;
6408 TnyIterator *iter = NULL;
6409 TnyHeader *header = NULL;
6410 TnyFolder *folder = NULL;
6413 headers = get_selected_headers (window);
6417 /* Pick the account */
6418 iter = tny_list_create_iterator (headers);
6419 header = TNY_HEADER (tny_iterator_get_current (iter));
6420 folder = tny_header_get_folder (header);
6421 account = tny_folder_get_account (folder);
6422 g_object_unref (folder);
6423 g_object_unref (header);
6424 g_object_unref (iter);
6426 /* Connect and perform the message retrieval */
6427 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6428 g_object_ref (account),
6429 retrieve_msg_contents_performer,
6430 g_object_ref (headers));
6433 g_object_unref (account);
6434 g_object_unref (headers);
6438 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6440 g_return_if_fail (MODEST_IS_WINDOW (window));
6443 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6447 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6449 g_return_if_fail (MODEST_IS_WINDOW (window));
6452 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6456 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6457 ModestWindow *window)
6459 g_return_if_fail (MODEST_IS_WINDOW (window));
6462 modest_ui_actions_check_menu_dimming_rules (window);
6466 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6467 ModestWindow *window)
6469 g_return_if_fail (MODEST_IS_WINDOW (window));
6472 modest_ui_actions_check_menu_dimming_rules (window);
6476 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6477 ModestWindow *window)
6479 g_return_if_fail (MODEST_IS_WINDOW (window));
6482 modest_ui_actions_check_menu_dimming_rules (window);
6486 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6487 ModestWindow *window)
6489 g_return_if_fail (MODEST_IS_WINDOW (window));
6492 modest_ui_actions_check_menu_dimming_rules (window);
6496 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6497 ModestWindow *window)
6499 g_return_if_fail (MODEST_IS_WINDOW (window));
6502 modest_ui_actions_check_menu_dimming_rules (window);
6506 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6507 ModestWindow *window)
6509 g_return_if_fail (MODEST_IS_WINDOW (window));
6512 modest_ui_actions_check_menu_dimming_rules (window);
6516 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6517 ModestWindow *window)
6519 g_return_if_fail (MODEST_IS_WINDOW (window));
6522 modest_ui_actions_check_menu_dimming_rules (window);
6526 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6527 ModestWindow *window)
6529 g_return_if_fail (MODEST_IS_WINDOW (window));
6532 modest_ui_actions_check_menu_dimming_rules (window);
6536 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6537 ModestWindow *window)
6539 g_return_if_fail (MODEST_IS_WINDOW (window));
6542 modest_ui_actions_check_menu_dimming_rules (window);
6546 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6548 g_return_if_fail (MODEST_IS_WINDOW (window));
6550 /* we check for low-mem; in that case, show a warning, and don't allow
6553 if (modest_platform_check_memory_low (window, TRUE))
6556 modest_platform_show_search_messages (GTK_WINDOW (window));
6560 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6562 g_return_if_fail (MODEST_IS_WINDOW (win));
6565 /* we check for low-mem; in that case, show a warning, and don't allow
6566 * for the addressbook
6568 if (modest_platform_check_memory_low (win, TRUE))
6572 modest_platform_show_addressbook (GTK_WINDOW (win));
6577 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6578 ModestWindow *window)
6581 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6583 if (GTK_IS_TOGGLE_ACTION (action))
6584 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6588 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6593 on_send_receive_finished (ModestMailOperation *mail_op,
6596 GtkWidget *header_view, *folder_view;
6597 TnyFolderStore *folder_store;
6598 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6600 /* Set send/receive operation finished */
6601 modest_main_window_notify_send_receive_completed (main_win);
6603 /* Don't refresh the current folder if there were any errors */
6604 if (modest_mail_operation_get_status (mail_op) !=
6605 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6608 /* Refresh the current folder if we're viewing a window. We do
6609 this because the user won't be able to see the new mails in
6610 the selected folder after a Send&Receive because it only
6611 performs a poke_status, i.e, only the number of read/unread
6612 messages is updated, but the new headers are not
6614 folder_view = modest_main_window_get_child_widget (main_win,
6615 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6619 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6621 /* Do not need to refresh INBOX again because the
6622 update_account does it always automatically */
6623 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6624 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6625 ModestMailOperation *refresh_op;
6627 header_view = modest_main_window_get_child_widget (main_win,
6628 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6630 /* We do not need to set the contents style
6631 because it hasn't changed. We also do not
6632 need to save the widget status. Just force
6634 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6635 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6636 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6637 folder_refreshed_cb, main_win);
6638 g_object_unref (refresh_op);
6642 g_object_unref (folder_store);
6647 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6653 const gchar* server_name = NULL;
6654 TnyTransportAccount *transport;
6655 gchar *message = NULL;
6656 ModestProtocol *protocol;
6658 /* Don't show anything if the user cancelled something or the
6659 * send receive request is not interactive. Authentication
6660 * errors are managed by the account store so no need to show
6661 * a dialog here again */
6662 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6663 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6664 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6668 /* Get the server name. Note that we could be using a
6669 connection specific transport account */
6670 transport = (TnyTransportAccount *)
6671 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6673 ModestTnyAccountStore *acc_store;
6674 const gchar *acc_name;
6675 TnyTransportAccount *conn_specific;
6677 acc_store = modest_runtime_get_account_store();
6678 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6679 conn_specific = (TnyTransportAccount *)
6680 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6681 if (conn_specific) {
6682 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6683 g_object_unref (conn_specific);
6685 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6687 g_object_unref (transport);
6691 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6692 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6693 tny_account_get_proto (TNY_ACCOUNT (transport)));
6695 g_warning ("%s: Account with no proto", __FUNCTION__);
6699 /* Show the appropriate message text for the GError: */
6700 switch (err->code) {
6701 case TNY_SERVICE_ERROR_CONNECT:
6702 message = modest_protocol_get_translation (protocol,
6703 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6706 case TNY_SERVICE_ERROR_SEND:
6707 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6709 case TNY_SERVICE_ERROR_UNAVAILABLE:
6710 message = modest_protocol_get_translation (protocol,
6711 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6715 g_warning ("%s: unexpected ERROR %d",
6716 __FUNCTION__, err->code);
6717 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6721 modest_platform_run_information_dialog (NULL, message, FALSE);
6726 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6731 ModestWindow *top_window = NULL;
6732 ModestWindowMgr *mgr = NULL;
6733 GtkWidget *header_view = NULL;
6734 TnyFolder *selected_folder = NULL;
6735 TnyFolderType folder_type;
6737 mgr = modest_runtime_get_window_mgr ();
6738 top_window = modest_window_mgr_get_current_top (mgr);
6743 #ifndef MODEST_TOOLKIT_HILDON2
6744 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6745 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6746 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6749 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6750 header_view = (GtkWidget *)
6751 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6755 /* Get selected folder */
6757 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6758 if (!selected_folder)
6761 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6762 #if GTK_CHECK_VERSION(2, 8, 0)
6763 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6764 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6765 GtkTreeViewColumn *tree_column;
6767 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6768 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6770 gtk_tree_view_column_queue_resize (tree_column);
6772 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6773 gtk_widget_queue_draw (header_view);
6776 #ifndef MODEST_TOOLKIT_HILDON2
6777 /* Rerun dimming rules, because the message could become deletable for example */
6778 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6779 MODEST_DIMMING_RULES_TOOLBAR);
6780 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6781 MODEST_DIMMING_RULES_MENU);
6785 g_object_unref (selected_folder);
6789 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6790 TnyAccount *account)
6792 ModestProtocolType protocol_type;
6793 ModestProtocol *protocol;
6794 gchar *error_note = NULL;
6796 protocol_type = modest_tny_account_get_protocol_type (account);
6797 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6800 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6801 if (error_note == NULL) {
6802 g_warning ("%s: This should not be reached", __FUNCTION__);
6804 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6805 g_free (error_note);
6810 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6814 TnyFolderStore *folder = NULL;
6815 TnyAccount *account = NULL;
6816 ModestProtocolType proto;
6817 ModestProtocol *protocol;
6818 TnyHeader *header = NULL;
6820 if (MODEST_IS_MAIN_WINDOW (win)) {
6821 GtkWidget *header_view;
6822 TnyList* headers = NULL;
6824 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6825 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6826 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6827 if (!headers || tny_list_get_length (headers) == 0) {
6829 g_object_unref (headers);
6832 iter = tny_list_create_iterator (headers);
6833 header = TNY_HEADER (tny_iterator_get_current (iter));
6834 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6835 g_object_unref (iter);
6836 g_object_unref (headers);
6837 #ifdef MODEST_TOOLKIT_HILDON2
6838 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6839 GtkWidget *header_view;
6840 TnyList* headers = NULL;
6842 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6843 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6844 if (!headers || tny_list_get_length (headers) == 0) {
6846 g_object_unref (headers);
6849 iter = tny_list_create_iterator (headers);
6850 header = TNY_HEADER (tny_iterator_get_current (iter));
6852 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6854 g_warning ("List should contain headers");
6856 g_object_unref (iter);
6857 g_object_unref (headers);
6859 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6860 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6862 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6865 if (!header || !folder)
6868 /* Get the account type */
6869 account = tny_folder_get_account (TNY_FOLDER (folder));
6870 proto = modest_tny_account_get_protocol_type (account);
6871 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6874 subject = tny_header_dup_subject (header);
6875 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6879 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6885 g_object_unref (account);
6887 g_object_unref (folder);
6889 g_object_unref (header);
6895 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6896 const gchar *account_name,
6897 const gchar *account_title)
6899 ModestAccountMgr *account_mgr;
6902 ModestProtocol *protocol;
6903 gboolean removed = FALSE;
6905 g_return_val_if_fail (account_name, FALSE);
6906 g_return_val_if_fail (account_title, FALSE);
6908 account_mgr = modest_runtime_get_account_mgr();
6910 /* The warning text depends on the account type: */
6911 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6912 modest_account_mgr_get_store_protocol (account_mgr,
6914 txt = modest_protocol_get_translation (protocol,
6915 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6918 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6920 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6924 if (response == GTK_RESPONSE_OK) {
6925 /* Remove account. If it succeeds then it also removes
6926 the account from the ModestAccountView: */
6927 gboolean is_default = FALSE;
6928 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6929 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6931 g_free (default_account_name);
6933 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6935 /* Close all email notifications, we cannot
6936 distinguish if the notification belongs to
6937 this account or not, so for safety reasons
6938 we remove them all */
6939 modest_platform_remove_new_mail_notifications (FALSE);
6941 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6948 on_fetch_images_performer (gboolean canceled,
6950 GtkWindow *parent_window,
6951 TnyAccount *account,
6954 if (err || canceled) {
6955 /* Show an unable to retrieve images ??? */
6959 /* Note that the user could have closed the window while connecting */
6960 if (GTK_WIDGET_VISIBLE (parent_window))
6961 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6962 g_object_unref ((GObject *) user_data);
6966 modest_ui_actions_on_fetch_images (GtkAction *action,
6967 ModestWindow *window)
6969 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6971 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6973 on_fetch_images_performer,
6974 g_object_ref (window));
6978 modest_ui_actions_on_reload_message (const gchar *msg_id)
6980 ModestWindow *window = NULL;
6982 g_return_if_fail (msg_id && msg_id[0] != '\0');
6983 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6989 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6992 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
6995 /** Check whether any connections are active, and cancel them if
6997 * Returns TRUE is there was no problem,
6998 * or if an operation was cancelled so we can continue.
6999 * Returns FALSE if the user chose to cancel his request instead.
7003 modest_ui_actions_check_for_active_account (ModestWindow *self,
7004 const gchar* account_name)
7006 ModestTnySendQueue *send_queue;
7007 ModestTnyAccountStore *acc_store;
7008 ModestMailOperationQueue* queue;
7009 TnyConnectionStatus store_conn_status;
7010 TnyAccount *store_account = NULL, *transport_account = NULL;
7011 gboolean retval = TRUE, sending = FALSE;
7013 acc_store = modest_runtime_get_account_store ();
7014 queue = modest_runtime_get_mail_operation_queue ();
7017 modest_tny_account_store_get_server_account (acc_store,
7019 TNY_ACCOUNT_TYPE_STORE);
7021 /* This could happen if the account was deleted before the
7022 call to this function */
7027 modest_tny_account_store_get_server_account (acc_store,
7029 TNY_ACCOUNT_TYPE_TRANSPORT);
7031 /* This could happen if the account was deleted before the
7032 call to this function */
7033 if (!transport_account) {
7034 g_object_unref (store_account);
7038 /* If the transport account was not used yet, then the send
7039 queue could not exist (it's created on demand) */
7040 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7041 if (TNY_IS_SEND_QUEUE (send_queue))
7042 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7044 store_conn_status = tny_account_get_connection_status (store_account);
7045 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7048 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7049 _("emev_nc_disconnect_account"));
7050 if (response == GTK_RESPONSE_OK) {
7059 /* FIXME: We should only cancel those of this account */
7060 modest_mail_operation_queue_cancel_all (queue);
7062 /* Also disconnect the account */
7063 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7064 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7065 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7069 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7075 g_object_unref (store_account);
7076 g_object_unref (transport_account);