1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #ifdef MODEST_PLATFORM_MAEMO
63 #include "maemo/modest-osso-state-saving.h"
64 #endif /* MODEST_PLATFORM_MAEMO */
65 #ifndef MODEST_TOOLKIT_GTK
66 #include "maemo/modest-hildon-includes.h"
67 #include "maemo/modest-connection-specific-smtp-window.h"
68 #endif /* !MODEST_TOOLKIT_GTK */
70 #include <modest-utils.h>
71 #include "widgets/modest-ui-constants.h"
72 #include <widgets/modest-main-window.h>
73 #include <widgets/modest-msg-view-window.h>
74 #include <widgets/modest-account-view-window.h>
75 #include <widgets/modest-details-dialog.h>
76 #include <widgets/modest-attachments-view.h>
77 #include "widgets/modest-folder-view.h"
78 #include "widgets/modest-global-settings-dialog.h"
79 #include "modest-account-mgr-helpers.h"
80 #include "modest-mail-operation.h"
81 #include "modest-text-utils.h"
82 #include <modest-widget-memory.h>
83 #include <tny-error.h>
84 #include <tny-simple-list.h>
85 #include <tny-msg-view.h>
86 #include <tny-device.h>
87 #include <tny-merge-folder.h>
88 #include <tny-camel-bs-msg.h>
89 #include <tny-camel-bs-mime-part.h>
91 #include <gtkhtml/gtkhtml.h>
93 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
95 typedef struct _GetMsgAsyncHelper {
97 ModestMailOperation *mail_op;
104 typedef enum _ReplyForwardAction {
108 } ReplyForwardAction;
110 typedef struct _ReplyForwardHelper {
111 guint reply_forward_type;
112 ReplyForwardAction action;
115 GtkWidget *parent_window;
118 } ReplyForwardHelper;
120 typedef struct _MoveToHelper {
121 GtkTreeRowReference *reference;
125 typedef struct _PasteAsAttachmentHelper {
126 ModestMsgEditWindow *window;
128 } PasteAsAttachmentHelper;
136 * The do_headers_action uses this kind of functions to perform some
137 * action to each member of a list of headers
139 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
141 static void do_headers_action (ModestWindow *win,
145 static void open_msg_cb (ModestMailOperation *mail_op,
152 static void reply_forward_cb (ModestMailOperation *mail_op,
159 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
161 static void folder_refreshed_cb (ModestMailOperation *mail_op,
165 static void on_send_receive_finished (ModestMailOperation *mail_op,
168 static gint header_list_count_uncached_msgs (TnyList *header_list);
170 static gboolean connect_to_get_msg (ModestWindow *win,
171 gint num_of_uncached_msgs,
172 TnyAccount *account);
174 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
176 static void do_create_folder (GtkWindow *window,
177 TnyFolderStore *parent_folder,
178 const gchar *suggested_name);
180 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
182 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
183 GtkWidget *folder_view,
184 TnyFolderStore *dst_folder,
185 ModestMainWindow *win);
186 #ifdef MODEST_TOOLKIT_HILDON2
187 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
188 TnyFolderStore *dst_folder,
193 static void modest_ui_actions_on_window_move_to (GtkAction *action,
194 TnyList *list_to_move,
195 TnyFolderStore *dst_folder,
199 * This function checks whether a TnyFolderStore is a pop account
202 remote_folder_has_leave_on_server (TnyFolderStore *folder)
207 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
209 account = get_account_from_folder_store (folder);
210 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
211 modest_tny_account_get_protocol_type (account)));
212 g_object_unref (account);
217 /* FIXME: this should be merged with the similar code in modest-account-view-window */
218 /* Show the account creation wizard dialog.
219 * returns: TRUE if an account was created. FALSE if the user cancelled.
222 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
224 gboolean result = FALSE;
226 gint dialog_response;
228 /* there is no such wizard yet */
229 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
230 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
232 #ifndef MODEST_TOOLKIT_HILDON2
233 /* always present a main window in the background
234 * we do it here, so we cannot end up with two wizards (as this
235 * function might be called in modest_window_mgr_get_main_window as well */
237 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
238 TRUE); /* create if not existent */
242 ModestWindowMgr *mgr;
244 mgr = modest_runtime_get_window_mgr ();
246 window_list = modest_window_mgr_get_window_list (mgr);
247 if (window_list == NULL) {
248 win = MODEST_WINDOW (modest_accounts_window_new ());
249 if (modest_window_mgr_register_window (mgr, win, NULL)) {
250 gtk_widget_show_all (GTK_WIDGET (win));
252 gtk_widget_destroy (GTK_WIDGET (win));
257 g_list_free (window_list);
263 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
265 /* make sure the mainwindow is visible. We need to present the
266 wizard again to give it the focus back. show_all are needed
267 in order to get the widgets properly drawn (MainWindow main
268 paned won't be in its right position and the dialog will be
270 #ifndef MODEST_TOOLKIT_HILDON2
271 gtk_widget_show_all (GTK_WIDGET (win));
272 gtk_widget_show_all (GTK_WIDGET (wizard));
273 gtk_window_present (GTK_WINDOW (win));
274 gtk_window_present (GTK_WINDOW (wizard));
277 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
278 gtk_widget_destroy (GTK_WIDGET (wizard));
279 if (gtk_events_pending ())
280 gtk_main_iteration ();
282 if (dialog_response == GTK_RESPONSE_CANCEL) {
285 /* Check whether an account was created: */
286 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
293 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
296 const gchar *authors[] = {
297 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
300 about = gtk_about_dialog_new ();
301 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
302 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
303 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
304 _("Copyright (c) 2006, Nokia Corporation\n"
305 "All rights reserved."));
306 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
307 _("a modest e-mail client\n\n"
308 "design and implementation: Dirk-Jan C. Binnema\n"
309 "contributions from the fine people at KC and Ig\n"
310 "uses the tinymail email framework written by Philip van Hoof"));
311 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
312 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
313 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
314 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
316 gtk_dialog_run (GTK_DIALOG (about));
317 gtk_widget_destroy(about);
321 * Gets the list of currently selected messages. If the win is the
322 * main window, then it returns a newly allocated list of the headers
323 * selected in the header view. If win is the msg view window, then
324 * the value returned is a list with just a single header.
326 * The caller of this funcion must free the list.
329 get_selected_headers (ModestWindow *win)
331 if (MODEST_IS_MAIN_WINDOW(win)) {
332 GtkWidget *header_view;
334 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
335 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
336 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
338 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
339 /* for MsgViewWindows, we simply return a list with one element */
341 TnyList *list = NULL;
343 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
344 if (header != NULL) {
345 list = tny_simple_list_new ();
346 tny_list_prepend (list, G_OBJECT(header));
347 g_object_unref (G_OBJECT(header));
352 #ifdef MODEST_TOOLKIT_HILDON2
353 } else if (MODEST_IS_HEADER_WINDOW (win)) {
354 GtkWidget *header_view;
356 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
357 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
363 static GtkTreeRowReference *
364 get_next_after_selected_headers (ModestHeaderView *header_view)
366 GtkTreeSelection *sel;
367 GList *selected_rows, *node;
369 GtkTreeRowReference *result;
372 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
373 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
374 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
376 if (selected_rows == NULL)
379 node = g_list_last (selected_rows);
380 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
381 gtk_tree_path_next (path);
383 result = gtk_tree_row_reference_new (model, path);
385 gtk_tree_path_free (path);
386 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
387 g_list_free (selected_rows);
393 headers_action_mark_as_read (TnyHeader *header,
397 TnyHeaderFlags flags;
399 g_return_if_fail (TNY_IS_HEADER(header));
401 flags = tny_header_get_flags (header);
402 if (flags & TNY_HEADER_FLAG_SEEN) return;
403 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
407 headers_action_mark_as_unread (TnyHeader *header,
411 TnyHeaderFlags flags;
413 g_return_if_fail (TNY_IS_HEADER(header));
415 flags = tny_header_get_flags (header);
416 if (flags & TNY_HEADER_FLAG_SEEN) {
417 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
421 /** After deleing a message that is currently visible in a window,
422 * show the next message from the list, or close the window if there are no more messages.
425 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
427 /* Close msg view window or select next */
428 if (!modest_msg_view_window_select_next_message (win) &&
429 !modest_msg_view_window_select_previous_message (win)) {
431 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
437 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
439 modest_ui_actions_on_edit_mode_delete_message (win);
443 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
445 TnyList *header_list = NULL;
446 TnyIterator *iter = NULL;
447 TnyHeader *header = NULL;
448 gchar *message = NULL;
451 ModestWindowMgr *mgr;
452 GtkWidget *header_view = NULL;
453 gboolean retval = TRUE;
455 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
457 /* Check first if the header view has the focus */
458 if (MODEST_IS_MAIN_WINDOW (win)) {
460 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
461 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
462 if (!gtk_widget_is_focus (header_view))
466 /* Get the headers, either from the header view (if win is the main window),
467 * or from the message view window: */
468 header_list = get_selected_headers (win);
469 if (!header_list) return FALSE;
471 /* Check if any of the headers are already opened, or in the process of being opened */
472 if (MODEST_IS_MAIN_WINDOW (win)) {
473 gint opened_headers = 0;
475 iter = tny_list_create_iterator (header_list);
476 mgr = modest_runtime_get_window_mgr ();
477 while (!tny_iterator_is_done (iter)) {
478 header = TNY_HEADER (tny_iterator_get_current (iter));
480 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
482 g_object_unref (header);
484 tny_iterator_next (iter);
486 g_object_unref (iter);
488 if (opened_headers > 0) {
491 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
494 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
497 g_object_unref (header_list);
503 if (tny_list_get_length(header_list) == 1) {
504 iter = tny_list_create_iterator (header_list);
505 header = TNY_HEADER (tny_iterator_get_current (iter));
508 subject = tny_header_dup_subject (header);
510 subject = g_strdup (_("mail_va_no_subject"));
511 desc = g_strdup_printf ("%s", subject);
513 g_object_unref (header);
516 g_object_unref (iter);
518 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
519 tny_list_get_length(header_list)), desc);
521 /* Confirmation dialog */
522 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
526 if (response == GTK_RESPONSE_OK) {
527 ModestWindowMgr *mgr = NULL;
528 GtkTreeModel *model = NULL;
529 GtkTreeSelection *sel = NULL;
530 GList *sel_list = NULL, *tmp = NULL;
531 GtkTreeRowReference *next_row_reference = NULL;
532 GtkTreeRowReference *prev_row_reference = NULL;
533 GtkTreePath *next_path = NULL;
534 GtkTreePath *prev_path = NULL;
535 ModestMailOperation *mail_op = NULL;
537 /* Find last selected row */
538 if (MODEST_IS_MAIN_WINDOW (win)) {
539 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
540 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
541 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
542 for (tmp=sel_list; tmp; tmp=tmp->next) {
543 if (tmp->next == NULL) {
544 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
545 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
547 gtk_tree_path_prev (prev_path);
548 gtk_tree_path_next (next_path);
550 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
551 next_row_reference = gtk_tree_row_reference_new (model, next_path);
556 /* Disable window dimming management */
557 modest_window_disable_dimming (win);
559 /* Remove each header. If it's a view window header_view == NULL */
560 mail_op = modest_mail_operation_new ((GObject *) win);
561 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
563 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
564 g_object_unref (mail_op);
566 /* Enable window dimming management */
568 gtk_tree_selection_unselect_all (sel);
570 modest_window_enable_dimming (win);
572 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
573 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
575 /* Get main window */
576 mgr = modest_runtime_get_window_mgr ();
577 } else if (MODEST_IS_MAIN_WINDOW (win)) {
578 /* Select next or previous row */
579 if (gtk_tree_row_reference_valid (next_row_reference)) {
580 gtk_tree_selection_select_path (sel, next_path);
582 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
583 gtk_tree_selection_select_path (sel, prev_path);
587 if (gtk_tree_row_reference_valid (next_row_reference))
588 gtk_tree_row_reference_free (next_row_reference);
589 if (next_path != NULL)
590 gtk_tree_path_free (next_path);
591 if (gtk_tree_row_reference_valid (prev_row_reference))
592 gtk_tree_row_reference_free (prev_row_reference);
593 if (prev_path != NULL)
594 gtk_tree_path_free (prev_path);
597 /* Update toolbar dimming state */
598 modest_ui_actions_check_menu_dimming_rules (win);
599 modest_ui_actions_check_toolbar_dimming_rules (win);
602 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
603 g_list_free (sel_list);
612 g_object_unref (header_list);
620 /* delete either message or folder, based on where we are */
622 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
624 g_return_if_fail (MODEST_IS_WINDOW(win));
626 /* Check first if the header view has the focus */
627 if (MODEST_IS_MAIN_WINDOW (win)) {
629 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
630 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
631 if (gtk_widget_is_focus (w)) {
632 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
636 modest_ui_actions_on_delete_message (action, win);
640 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
642 ModestWindowMgr *mgr = NULL;
644 #ifdef MODEST_PLATFORM_MAEMO
645 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
646 #endif /* MODEST_PLATFORM_MAEMO */
648 g_debug ("closing down, clearing %d item(s) from operation queue",
649 modest_mail_operation_queue_num_elements
650 (modest_runtime_get_mail_operation_queue()));
652 /* cancel all outstanding operations */
653 modest_mail_operation_queue_cancel_all
654 (modest_runtime_get_mail_operation_queue());
656 g_debug ("queue has been cleared");
659 /* Check if there are opened editing windows */
660 mgr = modest_runtime_get_window_mgr ();
661 modest_window_mgr_close_all_windows (mgr);
663 /* note: when modest-tny-account-store is finalized,
664 it will automatically set all network connections
667 /* gtk_main_quit (); */
671 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
675 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
677 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
678 /* gtk_widget_destroy (GTK_WIDGET (win)); */
679 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
680 /* gboolean ret_value; */
681 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
682 /* } else if (MODEST_IS_WINDOW (win)) { */
683 /* gtk_widget_destroy (GTK_WIDGET (win)); */
685 /* g_return_if_reached (); */
690 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
692 if (MODEST_IS_MSG_VIEW_WINDOW (win))
693 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
694 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
695 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
699 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
701 GtkClipboard *clipboard = NULL;
702 gchar *selection = NULL;
704 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
705 selection = gtk_clipboard_wait_for_text (clipboard);
708 modest_address_book_add_address (selection, (GtkWindow *) win);
714 modest_ui_actions_on_new_account (GtkAction *action,
715 ModestWindow *window)
717 if (!modest_ui_actions_run_account_setup_wizard (window)) {
718 g_debug ("%s: wizard was already running", __FUNCTION__);
723 modest_ui_actions_on_accounts (GtkAction *action,
726 /* This is currently only implemented for Maemo */
727 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
728 if (!modest_ui_actions_run_account_setup_wizard (win))
729 g_debug ("%s: wizard was already running", __FUNCTION__);
733 /* Show the list of accounts */
734 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
736 /* The accounts dialog must be modal */
737 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
738 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
743 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
745 /* This is currently only implemented for Maemo,
746 * because it requires an API (libconic) to detect different connection
749 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
751 /* Create the window if necessary: */
752 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
753 modest_connection_specific_smtp_window_fill_with_connections (
754 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
755 modest_runtime_get_account_mgr());
757 /* Show the window: */
758 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
759 GTK_WINDOW (specific_window), (GtkWindow *) win);
760 gtk_widget_show (specific_window);
761 #endif /* !MODEST_TOOLKIT_GTK */
765 count_part_size (const gchar *part)
767 GnomeVFSURI *vfs_uri;
768 gchar *escaped_filename;
770 GnomeVFSFileInfo *info;
773 /* Estimation of attachment size if we cannot get it from file info */
776 vfs_uri = gnome_vfs_uri_new (part);
778 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
779 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
780 g_free (escaped_filename);
781 gnome_vfs_uri_unref (vfs_uri);
783 info = gnome_vfs_file_info_new ();
785 if (gnome_vfs_get_file_info (part,
787 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
789 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
794 gnome_vfs_file_info_unref (info);
800 count_parts_size (GSList *parts)
805 for (node = parts; node != NULL; node = g_slist_next (node)) {
806 result += count_part_size ((const gchar *) node->data);
813 modest_ui_actions_compose_msg(ModestWindow *win,
816 const gchar *bcc_str,
817 const gchar *subject_str,
818 const gchar *body_str,
820 gboolean set_as_modified)
822 gchar *account_name = NULL;
823 const gchar *mailbox;
825 TnyAccount *account = NULL;
826 TnyFolder *folder = NULL;
827 gchar *from_str = NULL, *signature = NULL, *body = NULL;
828 gchar *recipient = NULL;
829 gboolean use_signature = FALSE;
830 ModestWindow *msg_win = NULL;
831 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
832 ModestTnyAccountStore *store = modest_runtime_get_account_store();
833 GnomeVFSFileSize total_size, allowed_size;
834 guint64 available_disk, expected_size, parts_size;
837 /* we check for low-mem */
838 if (modest_platform_check_memory_low (win, TRUE))
841 available_disk = modest_utils_get_available_space (NULL);
842 parts_count = g_slist_length (attachments);
843 parts_size = count_parts_size (attachments);
844 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
846 /* Double check: disk full condition or message too big */
847 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
848 expected_size > available_disk) {
849 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
850 modest_platform_system_banner (NULL, NULL, msg);
856 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
857 modest_platform_run_information_dialog (
859 _("mail_ib_error_attachment_size"),
865 #ifdef MODEST_TOOLKIT_HILDON2
867 account_name = g_strdup (modest_window_get_active_account(win));
870 account_name = modest_account_mgr_get_default_account(mgr);
873 g_printerr ("modest: no account found\n");
878 mailbox = modest_window_get_active_mailbox (win);
881 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
883 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
886 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
888 g_printerr ("modest: failed to find Drafts folder\n");
891 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
893 g_printerr ("modest: failed get from string for '%s'\n", account_name);
897 recipient = modest_text_utils_get_email_address (from_str);
898 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
900 if (body_str != NULL) {
901 body = use_signature ? g_strconcat(body_str, "\n",
902 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
903 "\n", signature, NULL) : g_strdup(body_str);
905 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
906 "\n", signature, NULL) : g_strdup("");
909 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
911 g_printerr ("modest: failed to create new msg\n");
915 /* Create and register edit window */
916 /* This is destroyed by TODO. */
918 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
919 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
921 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
922 gtk_widget_destroy (GTK_WIDGET (msg_win));
925 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
926 gtk_widget_show_all (GTK_WIDGET (msg_win));
928 while (attachments) {
929 GnomeVFSFileSize att_size;
931 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
932 attachments->data, allowed_size);
933 total_size += att_size;
935 if (att_size > allowed_size) {
936 g_debug ("%s: total size: %u",
937 __FUNCTION__, (unsigned int)total_size);
940 allowed_size -= att_size;
942 attachments = g_slist_next(attachments);
949 g_free (account_name);
951 g_object_unref (G_OBJECT(account));
953 g_object_unref (G_OBJECT(folder));
955 g_object_unref (G_OBJECT(msg));
959 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
961 /* if there are no accounts yet, just show the wizard */
962 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
963 if (!modest_ui_actions_run_account_setup_wizard (win))
966 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
971 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
975 ModestMailOperationStatus status;
977 /* If there is no message or the operation was not successful */
978 status = modest_mail_operation_get_status (mail_op);
979 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
982 /* If it's a memory low issue, then show a banner */
983 error = modest_mail_operation_get_error (mail_op);
984 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
985 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
986 GObject *source = modest_mail_operation_get_source (mail_op);
987 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
988 _KR("memr_ib_operation_disabled"),
990 g_object_unref (source);
993 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
994 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
995 gchar *subject, *msg, *format = NULL;
998 subject = (header) ? tny_header_dup_subject (header) : NULL;
1000 subject = g_strdup (_("mail_va_no_subject"));
1002 account = modest_mail_operation_get_account (mail_op);
1004 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1005 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1008 if (tny_account_get_connection_status (account) ==
1009 TNY_CONNECTION_STATUS_CONNECTED) {
1011 format = modest_protocol_get_translation (protocol,
1012 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1015 format = modest_protocol_get_translation (protocol,
1016 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1019 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1020 tny_account_get_hostname (account));
1023 g_object_unref (account);
1028 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1030 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1034 msg = g_strdup_printf (format, subject);
1035 modest_platform_run_information_dialog (NULL, msg, FALSE);
1041 /* Remove the header from the preregistered uids */
1042 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1055 } OpenMsgBannerInfo;
1058 GtkTreeModel *model;
1060 ModestWindow *caller_window;
1061 OpenMsgBannerInfo *banner_info;
1062 GtkTreeRowReference *rowref;
1066 open_msg_banner_idle (gpointer userdata)
1068 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1070 gdk_threads_enter ();
1071 banner_info->idle_handler = 0;
1072 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1073 if (banner_info->banner)
1074 g_object_ref (banner_info->banner);
1076 gdk_threads_leave ();
1082 get_header_view_from_window (ModestWindow *window)
1084 GtkWidget *header_view;
1086 if (MODEST_IS_MAIN_WINDOW (window)) {
1087 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1088 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1089 #ifdef MODEST_TOOLKIT_HILDON2
1090 } else if (MODEST_IS_HEADER_WINDOW (window)){
1091 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1101 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1104 gchar *account = NULL;
1105 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1110 folder = tny_header_get_folder (header);
1111 /* Gets folder type (OUTBOX headers will be opened in edit window */
1112 if (modest_tny_folder_is_local_folder (folder)) {
1113 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1114 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1115 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1118 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1119 TnyTransportAccount *traccount = NULL;
1120 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1121 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1123 ModestTnySendQueue *send_queue = NULL;
1124 ModestTnySendQueueStatus status;
1126 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1127 TNY_ACCOUNT(traccount)));
1128 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1129 if (TNY_IS_SEND_QUEUE (send_queue)) {
1130 msg_id = modest_tny_send_queue_get_msg_id (header);
1131 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1133 /* Only open messages in outbox with the editor if they are in Failed state */
1134 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1137 #ifdef MODEST_TOOLKIT_HILDON2
1139 /* In Fremantle we can not
1140 open any message from
1141 outbox which is not in
1147 g_object_unref(traccount);
1149 g_warning("Cannot get transport account for message in outbox!!");
1151 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1152 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1156 TnyAccount *acc = tny_folder_get_account (folder);
1159 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1160 g_object_unref (acc);
1164 g_object_unref (folder);
1170 open_msg_cb (ModestMailOperation *mail_op,
1177 ModestWindowMgr *mgr = NULL;
1178 ModestWindow *parent_win = NULL;
1179 ModestWindow *win = NULL;
1180 gchar *account = NULL;
1181 gboolean open_in_editor = FALSE;
1183 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1185 /* Do nothing if there was any problem with the mail
1186 operation. The error will be shown by the error_handler of
1187 the mail operation */
1188 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1191 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1193 /* Mark header as read */
1194 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1196 account = get_info_from_header (header, &open_in_editor, &can_open);
1200 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1202 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1204 if (open_in_editor) {
1205 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1206 gchar *from_header = NULL, *acc_name;
1207 gchar *mailbox = NULL;
1209 from_header = tny_header_dup_from (header);
1211 /* we cannot edit without a valid account... */
1212 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1213 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1214 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1216 g_free (from_header);
1221 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1222 g_free (from_header);
1228 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1232 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1233 const gchar *mailbox = NULL;
1235 if (parent_win && MODEST_IS_WINDOW (parent_win))
1236 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1238 if (helper->rowref && helper->model) {
1239 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1240 helper->model, helper->rowref);
1242 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1247 /* Register and show new window */
1249 mgr = modest_runtime_get_window_mgr ();
1250 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1251 gtk_widget_destroy (GTK_WIDGET (win));
1254 gtk_widget_show_all (GTK_WIDGET(win));
1257 /* Update toolbar dimming state */
1258 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1259 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1265 g_object_unref (parent_win);
1269 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1272 const GError *error;
1273 GObject *win = NULL;
1274 ModestMailOperationStatus status;
1276 win = modest_mail_operation_get_source (mail_op);
1277 error = modest_mail_operation_get_error (mail_op);
1278 status = modest_mail_operation_get_status (mail_op);
1280 /* If the mail op has been cancelled then it's not an error:
1281 don't show any message */
1282 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1283 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1284 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1285 (GError *) error, account)) {
1286 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1287 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1289 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1290 modest_platform_information_banner ((GtkWidget *) win,
1291 NULL, _("emev_ui_imap_inbox_select_error"));
1292 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1293 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1294 modest_platform_information_banner ((GtkWidget *) win,
1295 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1296 } else if (user_data) {
1297 modest_platform_information_banner ((GtkWidget *) win,
1301 g_object_unref (account);
1305 g_object_unref (win);
1309 * Returns the account a list of headers belongs to. It returns a
1310 * *new* reference so don't forget to unref it
1313 get_account_from_header_list (TnyList *headers)
1315 TnyAccount *account = NULL;
1317 if (tny_list_get_length (headers) > 0) {
1318 TnyIterator *iter = tny_list_create_iterator (headers);
1319 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1320 TnyFolder *folder = tny_header_get_folder (header);
1323 g_object_unref (header);
1325 while (!tny_iterator_is_done (iter)) {
1326 header = TNY_HEADER (tny_iterator_get_current (iter));
1327 folder = tny_header_get_folder (header);
1330 g_object_unref (header);
1332 tny_iterator_next (iter);
1337 account = tny_folder_get_account (folder);
1338 g_object_unref (folder);
1342 g_object_unref (header);
1344 g_object_unref (iter);
1350 get_account_from_header (TnyHeader *header)
1352 TnyAccount *account = NULL;
1355 folder = tny_header_get_folder (header);
1358 account = tny_folder_get_account (folder);
1359 g_object_unref (folder);
1365 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1367 if (helper->caller_window)
1368 helper->caller_window = NULL;
1372 open_msg_helper_destroyer (gpointer user_data)
1374 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1376 if (helper->caller_window) {
1377 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1378 helper->caller_window = NULL;
1381 if (helper->banner_info) {
1382 g_free (helper->banner_info->message);
1383 if (helper->banner_info->idle_handler > 0) {
1384 g_source_remove (helper->banner_info->idle_handler);
1385 helper->banner_info->idle_handler = 0;
1387 if (helper->banner_info->banner != NULL) {
1388 gtk_widget_destroy (helper->banner_info->banner);
1389 g_object_unref (helper->banner_info->banner);
1390 helper->banner_info->banner = NULL;
1392 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1393 helper->banner_info = NULL;
1395 g_object_unref (helper->model);
1396 g_object_unref (helper->header);
1397 gtk_tree_row_reference_free (helper->rowref);
1398 g_slice_free (OpenMsgHelper, helper);
1402 open_msg_performer(gboolean canceled,
1404 GtkWindow *parent_window,
1405 TnyAccount *account,
1408 ModestMailOperation *mail_op = NULL;
1409 gchar *error_msg = NULL;
1410 ModestProtocolType proto;
1411 TnyConnectionStatus status;
1412 OpenMsgHelper *helper = NULL;
1413 ModestProtocol *protocol;
1414 ModestProtocolRegistry *protocol_registry;
1417 helper = (OpenMsgHelper *) user_data;
1419 status = tny_account_get_connection_status (account);
1420 if (err || canceled || helper->caller_window == NULL) {
1421 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1422 /* Free the helper */
1423 open_msg_helper_destroyer (helper);
1425 /* In disk full conditions we could get this error here */
1426 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1427 (GtkWidget *) parent_window, err,
1433 /* Get the error message depending on the protocol */
1434 proto = modest_tny_account_get_protocol_type (account);
1435 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1436 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1439 protocol_registry = modest_runtime_get_protocol_registry ();
1440 subject = tny_header_dup_subject (helper->header);
1442 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1443 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1447 if (error_msg == NULL) {
1448 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1451 #ifndef MODEST_TOOLKIT_HILDON2
1452 gboolean show_open_draft = FALSE;
1453 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1455 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1457 TnyFolderType folder_type;
1459 folder = tny_header_get_folder (helper->header);
1460 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1461 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1462 g_object_unref (folder);
1466 #ifdef MODEST_TOOLKIT_HILDON2
1469 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1472 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1473 g_free (account_name);
1474 open_msg_helper_destroyer (helper);
1479 ModestWindow *window;
1480 GtkWidget *header_view;
1483 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1484 uid = modest_tny_folder_get_header_unique_id (helper->header);
1486 const gchar *mailbox = NULL;
1487 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1488 window = modest_msg_view_window_new_from_header_view
1489 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1490 if (window != NULL) {
1491 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1493 gtk_widget_destroy (GTK_WIDGET (window));
1495 gtk_widget_show_all (GTK_WIDGET(window));
1499 g_free (account_name);
1501 open_msg_helper_destroyer (helper);
1504 g_free (account_name);
1506 /* Create the mail operation */
1508 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1509 modest_ui_actions_disk_operations_error_handler,
1510 g_strdup (error_msg), g_free);
1511 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1515 #ifndef MODEST_TOOLKIT_HILDON2
1516 if (show_open_draft) {
1517 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1518 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1519 helper->banner_info->banner = NULL;
1520 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1521 helper->banner_info);
1527 headers = TNY_LIST (tny_simple_list_new ());
1528 tny_list_prepend (headers, G_OBJECT (helper->header));
1529 modest_mail_operation_get_msgs_full (mail_op,
1533 open_msg_helper_destroyer);
1534 g_object_unref (headers);
1541 g_object_unref (mail_op);
1542 g_object_unref (account);
1546 * This function is used by both modest_ui_actions_on_open and
1547 * modest_ui_actions_on_header_activated. This way we always do the
1548 * same when trying to open messages.
1551 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1553 ModestWindowMgr *mgr = NULL;
1554 TnyAccount *account;
1555 gboolean cached = FALSE;
1557 GtkWidget *header_view = NULL;
1558 OpenMsgHelper *helper;
1559 ModestWindow *window;
1561 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1563 mgr = modest_runtime_get_window_mgr ();
1566 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1567 if (header_view == NULL)
1570 /* Get the account */
1571 account = get_account_from_header (header);
1576 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1578 /* Do not open again the message and present the
1579 window to the user */
1582 #ifndef MODEST_TOOLKIT_HILDON2
1583 gtk_window_present (GTK_WINDOW (window));
1586 /* the header has been registered already, we don't do
1587 * anything but wait for the window to come up*/
1588 g_debug ("header %p already registered, waiting for window", header);
1593 /* Open each message */
1594 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1596 /* Allways download if we are online. */
1597 if (!tny_device_is_online (modest_runtime_get_device ())) {
1600 /* If ask for user permission to download the messages */
1601 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1602 _("mcen_nc_get_msg"));
1604 /* End if the user does not want to continue */
1605 if (response == GTK_RESPONSE_CANCEL) {
1611 /* We register the window for opening */
1612 modest_window_mgr_register_header (mgr, header, NULL);
1614 /* Create the helper. We need to get a reference to the model
1615 here because it could change while the message is readed
1616 (the user could switch between folders) */
1617 helper = g_slice_new (OpenMsgHelper);
1618 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1619 helper->caller_window = win;
1620 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1621 helper->header = g_object_ref (header);
1622 helper->rowref = gtk_tree_row_reference_copy (rowref);
1623 helper->banner_info = NULL;
1625 /* Connect to the account and perform */
1627 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1628 open_msg_performer, helper);
1630 /* Call directly the performer, do not need to connect */
1631 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1632 g_object_ref (account), helper);
1637 g_object_unref (account);
1641 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1648 /* we check for low-mem; in that case, show a warning, and don't allow
1651 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1655 headers = get_selected_headers (win);
1659 headers_count = tny_list_get_length (headers);
1660 if (headers_count != 1) {
1661 if (headers_count > 1) {
1662 /* Don't allow activation if there are more than one message selected */
1663 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1666 g_object_unref (headers);
1670 iter = tny_list_create_iterator (headers);
1671 header = TNY_HEADER (tny_iterator_get_current (iter));
1672 g_object_unref (iter);
1676 open_msg_from_header (header, NULL, win);
1677 g_object_unref (header);
1680 g_object_unref(headers);
1684 rf_helper_window_closed (gpointer data,
1687 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1689 helper->parent_window = NULL;
1692 static ReplyForwardHelper*
1693 create_reply_forward_helper (ReplyForwardAction action,
1695 guint reply_forward_type,
1699 ReplyForwardHelper *rf_helper = NULL;
1700 const gchar *active_acc = modest_window_get_active_account (win);
1701 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1703 rf_helper = g_slice_new0 (ReplyForwardHelper);
1704 rf_helper->reply_forward_type = reply_forward_type;
1705 rf_helper->action = action;
1706 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1707 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1708 rf_helper->account_name = (active_acc) ?
1709 g_strdup (active_acc) :
1710 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1711 rf_helper->mailbox = g_strdup (active_mailbox);
1713 rf_helper->parts = g_object_ref (parts);
1715 rf_helper->parts = NULL;
1717 /* Note that window could be destroyed just AFTER calling
1718 register_window so we must ensure that this pointer does
1719 not hold invalid references */
1720 if (rf_helper->parent_window)
1721 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1722 rf_helper_window_closed, rf_helper);
1728 free_reply_forward_helper (gpointer data)
1730 ReplyForwardHelper *helper;
1732 helper = (ReplyForwardHelper *) data;
1733 g_free (helper->account_name);
1734 g_free (helper->mailbox);
1736 g_object_unref (helper->header);
1738 g_object_unref (helper->parts);
1739 if (helper->parent_window)
1740 g_object_weak_unref (G_OBJECT (helper->parent_window),
1741 rf_helper_window_closed, helper);
1742 g_slice_free (ReplyForwardHelper, helper);
1746 reply_forward_cb (ModestMailOperation *mail_op,
1753 TnyMsg *new_msg = NULL;
1754 ReplyForwardHelper *rf_helper;
1755 ModestWindow *msg_win = NULL;
1756 ModestEditType edit_type;
1758 TnyAccount *account = NULL;
1759 ModestWindowMgr *mgr = NULL;
1760 gchar *signature = NULL;
1761 gboolean use_signature;
1764 /* If there was any error. The mail operation could be NULL,
1765 this means that we already have the message downloaded and
1766 that we didn't do a mail operation to retrieve it */
1767 rf_helper = (ReplyForwardHelper *) user_data;
1768 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1771 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1772 rf_helper->account_name, rf_helper->mailbox);
1773 recipient = modest_text_utils_get_email_address (from);
1774 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1779 /* Create reply mail */
1780 switch (rf_helper->action) {
1781 /* Use the msg_header to ensure that we have all the
1782 information. The summary can lack some data */
1783 TnyHeader *msg_header;
1785 msg_header = tny_msg_get_header (msg);
1787 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1788 (use_signature) ? signature : NULL,
1789 rf_helper->reply_forward_type,
1790 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1791 g_object_unref (msg_header);
1793 case ACTION_REPLY_TO_ALL:
1794 msg_header = tny_msg_get_header (msg);
1796 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1797 (use_signature) ? signature : NULL,
1798 rf_helper->reply_forward_type,
1799 MODEST_TNY_MSG_REPLY_MODE_ALL);
1800 edit_type = MODEST_EDIT_TYPE_REPLY;
1801 g_object_unref (msg_header);
1803 case ACTION_FORWARD:
1805 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1806 rf_helper->reply_forward_type);
1807 edit_type = MODEST_EDIT_TYPE_FORWARD;
1810 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1812 g_return_if_reached ();
1820 g_warning ("%s: failed to create message\n", __FUNCTION__);
1824 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1825 rf_helper->account_name,
1826 TNY_ACCOUNT_TYPE_STORE);
1828 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1832 /* Create and register the windows */
1833 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1834 mgr = modest_runtime_get_window_mgr ();
1835 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1837 /* Note that register_window could have deleted the account */
1838 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1839 gdouble parent_zoom;
1841 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1842 modest_window_set_zoom (msg_win, parent_zoom);
1845 /* Show edit window */
1846 gtk_widget_show_all (GTK_WIDGET (msg_win));
1849 /* We always unregister the header because the message is
1850 forwarded or replied so the original one is no longer
1852 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1855 g_object_unref (G_OBJECT (new_msg));
1857 g_object_unref (G_OBJECT (account));
1858 free_reply_forward_helper (rf_helper);
1861 /* Checks a list of headers. If any of them are not currently
1862 * downloaded (CACHED) then returns TRUE else returns FALSE.
1865 header_list_count_uncached_msgs (TnyList *header_list)
1868 gint uncached_messages = 0;
1870 iter = tny_list_create_iterator (header_list);
1871 while (!tny_iterator_is_done (iter)) {
1874 header = TNY_HEADER (tny_iterator_get_current (iter));
1876 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1877 uncached_messages ++;
1878 g_object_unref (header);
1881 tny_iterator_next (iter);
1883 g_object_unref (iter);
1885 return uncached_messages;
1888 /* Returns FALSE if the user does not want to download the
1889 * messages. Returns TRUE if the user allowed the download.
1892 connect_to_get_msg (ModestWindow *win,
1893 gint num_of_uncached_msgs,
1894 TnyAccount *account)
1896 GtkResponseType response;
1898 /* Allways download if we are online. */
1899 if (tny_device_is_online (modest_runtime_get_device ()))
1902 /* If offline, then ask for user permission to download the messages */
1903 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1904 ngettext("mcen_nc_get_msg",
1906 num_of_uncached_msgs));
1908 if (response == GTK_RESPONSE_CANCEL)
1911 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1915 reply_forward_performer (gboolean canceled,
1917 GtkWindow *parent_window,
1918 TnyAccount *account,
1921 ReplyForwardHelper *rf_helper = NULL;
1922 ModestMailOperation *mail_op;
1924 rf_helper = (ReplyForwardHelper *) user_data;
1926 if (canceled || err) {
1927 free_reply_forward_helper (rf_helper);
1931 /* Retrieve the message */
1932 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1933 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1934 modest_ui_actions_disk_operations_error_handler,
1936 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1937 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1940 g_object_unref(mail_op);
1944 all_parts_retrieved (TnyMimePart *part)
1946 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1949 TnyList *pending_parts;
1950 TnyIterator *iterator;
1951 gboolean all_retrieved = TRUE;
1953 pending_parts = TNY_LIST (tny_simple_list_new ());
1954 tny_mime_part_get_parts (part, pending_parts);
1955 iterator = tny_list_create_iterator (pending_parts);
1956 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1959 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1961 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1962 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1964 all_retrieved = FALSE;
1967 g_object_unref (child);
1968 tny_iterator_next (iterator);
1970 g_object_unref (iterator);
1971 g_object_unref (pending_parts);
1972 return all_retrieved;
1977 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1980 TnyIterator *iterator;
1982 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
1983 tny_list_append (list, G_OBJECT (part));
1985 parts = TNY_LIST (tny_simple_list_new ());
1986 tny_mime_part_get_parts (part, parts);
1987 for (iterator = tny_list_create_iterator (parts);
1988 !tny_iterator_is_done (iterator);
1989 tny_iterator_next (iterator)) {
1992 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1993 forward_pending_parts_helper (child, list);
1994 g_object_unref (child);
1996 g_object_unref (iterator);
1997 g_object_unref (parts);
2001 forward_pending_parts (TnyMsg *msg)
2003 TnyList *result = TNY_LIST (tny_simple_list_new ());
2004 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2005 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2012 * Common code for the reply and forward actions
2015 reply_forward (ReplyForwardAction action, ModestWindow *win)
2017 ReplyForwardHelper *rf_helper = NULL;
2018 guint reply_forward_type;
2020 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2022 /* we check for low-mem; in that case, show a warning, and don't allow
2023 * reply/forward (because it could potentially require a lot of memory */
2024 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2028 /* we need an account when editing */
2029 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2030 if (!modest_ui_actions_run_account_setup_wizard (win))
2034 reply_forward_type =
2035 modest_conf_get_int (modest_runtime_get_conf (),
2036 (action == ACTION_FORWARD) ?
2037 MODEST_CONF_FORWARD_TYPE :
2038 MODEST_CONF_REPLY_TYPE,
2041 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2043 TnyHeader *header = NULL;
2044 /* Get header and message. Do not free them here, the
2045 reply_forward_cb must do it */
2046 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2047 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2049 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2051 rf_helper = create_reply_forward_helper (action, win,
2052 reply_forward_type, header, NULL);
2053 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2055 gboolean do_download = TRUE;
2057 if (msg && header && action == ACTION_FORWARD) {
2058 /* Not all parts retrieved. Then we have to retrieve them all before
2059 * creating the forward message */
2060 if (!tny_device_is_online (modest_runtime_get_device ())) {
2063 /* If ask for user permission to download the messages */
2064 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2065 ngettext("mcen_nc_get_msg",
2069 /* End if the user does not want to continue */
2070 if (response == GTK_RESPONSE_CANCEL)
2071 do_download = FALSE;
2075 TnyList *pending_parts;
2077 TnyAccount *account;
2080 pending_parts = forward_pending_parts (msg);
2081 rf_helper = create_reply_forward_helper (action, win,
2082 reply_forward_type, header, pending_parts);
2083 g_object_unref (pending_parts);
2085 folder = tny_header_get_folder (header);
2086 account = tny_folder_get_account (folder);
2087 modest_platform_connect_and_perform (GTK_WINDOW (win),
2089 reply_forward_performer,
2091 g_object_unref (folder);
2092 g_object_unref (account);
2096 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2101 g_object_unref (msg);
2103 g_object_unref (header);
2105 TnyHeader *header = NULL;
2107 gboolean do_retrieve = TRUE;
2108 TnyList *header_list = NULL;
2110 header_list = get_selected_headers (win);
2113 /* Check that only one message is selected for replying */
2114 if (tny_list_get_length (header_list) != 1) {
2115 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2116 NULL, _("mcen_ib_select_one_message"));
2117 g_object_unref (header_list);
2121 /* Only reply/forward to one message */
2122 iter = tny_list_create_iterator (header_list);
2123 header = TNY_HEADER (tny_iterator_get_current (iter));
2124 g_object_unref (iter);
2126 /* Retrieve messages */
2127 do_retrieve = (action == ACTION_FORWARD) ||
2128 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2131 TnyAccount *account = NULL;
2132 TnyFolder *folder = NULL;
2133 gdouble download = TRUE;
2134 guint uncached_msgs = 0;
2136 folder = tny_header_get_folder (header);
2138 goto do_retrieve_frees;
2139 account = tny_folder_get_account (folder);
2141 goto do_retrieve_frees;
2143 uncached_msgs = header_list_count_uncached_msgs (header_list);
2145 if (uncached_msgs > 0) {
2146 /* Allways download if we are online. */
2147 if (!tny_device_is_online (modest_runtime_get_device ())) {
2150 /* If ask for user permission to download the messages */
2151 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2152 ngettext("mcen_nc_get_msg",
2156 /* End if the user does not want to continue */
2157 if (response == GTK_RESPONSE_CANCEL)
2164 rf_helper = create_reply_forward_helper (action, win,
2165 reply_forward_type, header, NULL);
2166 if (uncached_msgs > 0) {
2167 modest_platform_connect_and_perform (GTK_WINDOW (win),
2169 reply_forward_performer,
2172 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2173 account, rf_helper);
2178 g_object_unref (account);
2180 g_object_unref (folder);
2182 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2185 g_object_unref (header_list);
2186 g_object_unref (header);
2191 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2193 g_return_if_fail (MODEST_IS_WINDOW(win));
2195 reply_forward (ACTION_REPLY, win);
2199 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2201 g_return_if_fail (MODEST_IS_WINDOW(win));
2203 reply_forward (ACTION_FORWARD, win);
2207 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2209 g_return_if_fail (MODEST_IS_WINDOW(win));
2211 reply_forward (ACTION_REPLY_TO_ALL, win);
2215 modest_ui_actions_on_next (GtkAction *action,
2216 ModestWindow *window)
2218 if (MODEST_IS_MAIN_WINDOW (window)) {
2219 GtkWidget *header_view;
2221 header_view = modest_main_window_get_child_widget (
2222 MODEST_MAIN_WINDOW(window),
2223 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2227 modest_header_view_select_next (
2228 MODEST_HEADER_VIEW(header_view));
2229 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2230 modest_msg_view_window_select_next_message (
2231 MODEST_MSG_VIEW_WINDOW (window));
2233 g_return_if_reached ();
2238 modest_ui_actions_on_prev (GtkAction *action,
2239 ModestWindow *window)
2241 g_return_if_fail (MODEST_IS_WINDOW(window));
2243 if (MODEST_IS_MAIN_WINDOW (window)) {
2244 GtkWidget *header_view;
2245 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2246 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2250 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2251 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2252 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2254 g_return_if_reached ();
2259 modest_ui_actions_on_sort (GtkAction *action,
2260 ModestWindow *window)
2262 GtkWidget *header_view = NULL;
2264 g_return_if_fail (MODEST_IS_WINDOW(window));
2266 if (MODEST_IS_MAIN_WINDOW (window)) {
2267 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2268 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2269 #ifdef MODEST_TOOLKIT_HILDON2
2270 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2271 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2276 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2281 /* Show sorting dialog */
2282 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2286 sync_folder_cb (ModestMailOperation *mail_op,
2290 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2292 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2293 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2295 /* We must clear first, because otherwise set_folder will ignore */
2296 /* the change as the folders are the same */
2297 modest_header_view_clear (header_view);
2298 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2300 g_object_unref (parent);
2303 g_object_unref (header_view);
2307 idle_refresh_folder (gpointer source)
2309 ModestHeaderView *header_view = NULL;
2311 /* If the window still exists */
2312 if (!GTK_IS_WIDGET (source) ||
2313 !GTK_WIDGET_VISIBLE (source))
2316 /* Refresh the current view */
2317 #ifdef MODEST_TOOLKIT_HILDON2
2318 if (MODEST_IS_HEADER_WINDOW (source))
2319 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2321 if (MODEST_IS_MAIN_WINDOW (source))
2322 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2323 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2326 TnyFolder *folder = modest_header_view_get_folder (header_view);
2328 /* Sync the folder status */
2329 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2330 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2331 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2332 g_object_unref (folder);
2333 g_object_unref (mail_op);
2341 update_account_cb (ModestMailOperation *self,
2342 TnyList *new_headers,
2346 gboolean show_visual_notifications;
2348 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2349 show_visual_notifications = (top) ? FALSE : TRUE;
2351 /* Notify new messages have been downloaded. If the
2352 send&receive was invoked by the user then do not show any
2353 visual notification, only play a sound and activate the LED
2354 (for the Maemo version) */
2355 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2357 /* We only notify about really new messages (not seen) we get */
2358 TnyList *actually_new_list;
2359 TnyIterator *iterator;
2360 actually_new_list = TNY_LIST (tny_simple_list_new ());
2361 for (iterator = tny_list_create_iterator (new_headers);
2362 !tny_iterator_is_done (iterator);
2363 tny_iterator_next (iterator)) {
2365 TnyHeaderFlags flags;
2366 header = TNY_HEADER (tny_iterator_get_current (iterator));
2367 flags = tny_header_get_flags (header);
2369 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2370 /* Messages are ordered from most
2371 recent to oldest. But we want to
2372 show notifications starting from
2373 the oldest message. That's why we
2375 tny_list_prepend (actually_new_list, G_OBJECT (header));
2377 g_object_unref (header);
2379 g_object_unref (iterator);
2381 if (tny_list_get_length (actually_new_list) > 0) {
2382 GList *new_headers_list = NULL;
2384 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2386 /* Send notifications */
2387 if (new_headers_list) {
2388 modest_platform_on_new_headers_received (new_headers_list,
2389 show_visual_notifications);
2391 modest_utils_free_notification_list (new_headers_list);
2394 g_object_unref (actually_new_list);
2398 /* Refresh the current folder in an idle. We do this
2399 in order to avoid refresh cancelations if the
2400 currently viewed folder is the inbox */
2401 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2402 idle_refresh_folder,
2409 TnyAccount *account;
2411 gchar *account_name;
2412 gboolean poke_status;
2413 gboolean interactive;
2414 ModestMailOperation *mail_op;
2418 do_send_receive_performer (gboolean canceled,
2420 GtkWindow *parent_window,
2421 TnyAccount *account,
2424 SendReceiveInfo *info;
2426 info = (SendReceiveInfo *) user_data;
2428 if (err || canceled) {
2429 /* In disk full conditions we could get this error here */
2430 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2431 (GtkWidget *) parent_window, err,
2434 if (info->mail_op) {
2435 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2441 /* Set send/receive operation in progress */
2442 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2443 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2446 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2447 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2448 G_CALLBACK (on_send_receive_finished),
2451 /* Send & receive. */
2452 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2453 update_account_cb, info->win);
2458 g_object_unref (G_OBJECT (info->mail_op));
2459 if (info->account_name)
2460 g_free (info->account_name);
2462 g_object_unref (info->win);
2464 g_object_unref (info->account);
2465 g_slice_free (SendReceiveInfo, info);
2469 * This function performs the send & receive required actions. The
2470 * window is used to create the mail operation. Typically it should
2471 * always be the main window, but we pass it as argument in order to
2475 modest_ui_actions_do_send_receive (const gchar *account_name,
2476 gboolean force_connection,
2477 gboolean poke_status,
2478 gboolean interactive,
2481 gchar *acc_name = NULL;
2482 SendReceiveInfo *info;
2483 ModestTnyAccountStore *acc_store;
2484 TnyAccount *account;
2486 /* If no account name was provided then get the current account, and if
2487 there is no current account then pick the default one: */
2488 if (!account_name) {
2490 acc_name = g_strdup (modest_window_get_active_account (win));
2492 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2494 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2498 acc_name = g_strdup (account_name);
2501 acc_store = modest_runtime_get_account_store ();
2502 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2506 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2510 /* Do not automatically refresh accounts that are flagged as
2511 NO_AUTO_UPDATE. This could be useful for accounts that
2512 handle their own update times */
2514 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2515 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2516 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2517 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2519 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2520 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2521 g_object_unref (account);
2528 /* Create the info for the connect and perform */
2529 info = g_slice_new (SendReceiveInfo);
2530 info->account_name = acc_name;
2531 info->win = (win) ? g_object_ref (win) : NULL;
2532 info->poke_status = poke_status;
2533 info->interactive = interactive;
2534 info->account = account;
2535 /* We need to create the operation here, because otherwise it
2536 could happen that the queue emits the queue-empty signal
2537 while we're trying to connect the account */
2538 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2539 modest_ui_actions_disk_operations_error_handler,
2541 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2543 /* Invoke the connect and perform */
2544 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2545 force_connection, info->account,
2546 do_send_receive_performer, info);
2551 modest_ui_actions_do_cancel_send (const gchar *account_name,
2554 TnyTransportAccount *transport_account;
2555 TnySendQueue *send_queue = NULL;
2556 GError *error = NULL;
2558 /* Get transport account */
2560 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2561 (modest_runtime_get_account_store(),
2563 TNY_ACCOUNT_TYPE_TRANSPORT));
2564 if (!transport_account) {
2565 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2570 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2571 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2572 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2573 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2574 "modest: could not find send queue for account\n");
2576 /* Cancel the current send */
2577 tny_account_cancel (TNY_ACCOUNT (transport_account));
2579 /* Suspend all pending messages */
2580 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2584 if (transport_account != NULL)
2585 g_object_unref (G_OBJECT (transport_account));
2589 modest_ui_actions_cancel_send_all (ModestWindow *win)
2591 GSList *account_names, *iter;
2593 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2596 iter = account_names;
2598 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2599 iter = g_slist_next (iter);
2602 modest_account_mgr_free_account_names (account_names);
2603 account_names = NULL;
2607 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2610 /* Check if accounts exist */
2611 gboolean accounts_exist =
2612 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2614 /* If not, allow the user to create an account before trying to send/receive. */
2615 if (!accounts_exist)
2616 modest_ui_actions_on_accounts (NULL, win);
2618 /* Cancel all sending operaitons */
2619 modest_ui_actions_cancel_send_all (win);
2623 * Refreshes all accounts. This function will be used by automatic
2627 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2628 gboolean force_connection,
2629 gboolean poke_status,
2630 gboolean interactive)
2632 GSList *account_names, *iter;
2634 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2637 iter = account_names;
2639 modest_ui_actions_do_send_receive ((const char*) iter->data,
2641 poke_status, interactive, win);
2642 iter = g_slist_next (iter);
2645 modest_account_mgr_free_account_names (account_names);
2646 account_names = NULL;
2650 * Handler of the click on Send&Receive button in the main toolbar
2653 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2655 /* Check if accounts exist */
2656 gboolean accounts_exist;
2659 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2661 /* If not, allow the user to create an account before trying to send/receive. */
2662 if (!accounts_exist)
2663 modest_ui_actions_on_accounts (NULL, win);
2665 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2666 if (MODEST_IS_MAIN_WINDOW (win)) {
2667 GtkWidget *folder_view;
2668 TnyFolderStore *folder_store;
2671 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2672 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2676 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2679 g_object_unref (folder_store);
2680 /* Refresh the active account. Force the connection if needed
2681 and poke the status of all folders */
2682 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2683 #ifdef MODEST_TOOLKIT_HILDON2
2684 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2685 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2688 const gchar *active_account;
2689 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2691 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2698 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2701 GtkWidget *header_view;
2703 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2705 header_view = modest_main_window_get_child_widget (main_window,
2706 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2710 conf = modest_runtime_get_conf ();
2712 /* what is saved/restored is depending on the style; thus; we save with
2713 * old style, then update the style, and restore for this new style
2715 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2717 if (modest_header_view_get_style
2718 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2719 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2720 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2722 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2723 MODEST_HEADER_VIEW_STYLE_DETAILS);
2725 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2726 MODEST_CONF_HEADER_VIEW_KEY);
2731 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2733 ModestMainWindow *main_window)
2735 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2736 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2738 /* in the case the folder is empty, show the empty folder message and focus
2740 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2741 if (modest_header_view_is_empty (header_view)) {
2742 TnyFolder *folder = modest_header_view_get_folder (header_view);
2743 GtkWidget *folder_view =
2744 modest_main_window_get_child_widget (main_window,
2745 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2746 if (folder != NULL) {
2747 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2748 g_object_unref (folder);
2750 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2754 /* If no header has been selected then exit */
2759 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2760 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2762 /* Update toolbar dimming state */
2763 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2764 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2768 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2771 ModestWindow *window)
2773 GtkWidget *open_widget;
2774 GtkTreeRowReference *rowref;
2776 g_return_if_fail (MODEST_IS_WINDOW(window));
2777 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2778 g_return_if_fail (TNY_IS_HEADER (header));
2780 if (modest_header_view_count_selected_headers (header_view) > 1) {
2781 /* Don't allow activation if there are more than one message selected */
2782 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2786 /* we check for low-mem; in that case, show a warning, and don't allow
2787 * activating headers
2789 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2792 if (MODEST_IS_MAIN_WINDOW (window)) {
2793 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2794 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2795 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2799 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2800 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2801 gtk_tree_row_reference_free (rowref);
2805 set_active_account_from_tny_account (TnyAccount *account,
2806 ModestWindow *window)
2808 const gchar *server_acc_name = tny_account_get_id (account);
2810 /* We need the TnyAccount provided by the
2811 account store because that is the one that
2812 knows the name of the Modest account */
2813 TnyAccount *modest_server_account =
2814 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2815 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2817 if (!modest_server_account) {
2818 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2822 /* Update active account, but only if it's not a pseudo-account */
2823 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2824 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2825 const gchar *modest_acc_name =
2826 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2827 if (modest_acc_name)
2828 modest_window_set_active_account (window, modest_acc_name);
2831 g_object_unref (modest_server_account);
2836 folder_refreshed_cb (ModestMailOperation *mail_op,
2840 ModestMainWindow *win = NULL;
2841 GtkWidget *folder_view, *header_view;
2842 const GError *error;
2844 g_return_if_fail (TNY_IS_FOLDER (folder));
2846 win = MODEST_MAIN_WINDOW (user_data);
2848 /* Check if the operation failed due to memory low conditions */
2849 error = modest_mail_operation_get_error (mail_op);
2850 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2851 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2852 modest_platform_run_information_dialog (GTK_WINDOW (win),
2853 _KR("memr_ib_operation_disabled"),
2859 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2861 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2864 TnyFolderStore *current_folder;
2866 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2867 if (current_folder) {
2868 gboolean different = ((TnyFolderStore *) folder != current_folder);
2869 g_object_unref (current_folder);
2875 /* Check if folder is empty and set headers view contents style */
2876 if ((tny_folder_get_all_count (folder) == 0) ||
2877 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2878 modest_main_window_set_contents_style (win,
2879 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2883 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2884 TnyFolderStore *folder_store,
2886 ModestMainWindow *main_window)
2888 GtkWidget *header_view;
2890 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2892 header_view = modest_main_window_get_child_widget(main_window,
2893 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2898 if (TNY_IS_ACCOUNT (folder_store)) {
2900 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2902 /* Show account details */
2903 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2906 if (TNY_IS_FOLDER (folder_store) && selected) {
2907 TnyAccount *account;
2909 /* Update the active account */
2910 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2912 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2913 g_object_unref (account);
2917 /* Set the header style by default, it could
2918 be changed later by the refresh callback to
2920 modest_main_window_set_contents_style (main_window,
2921 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2923 /* Set folder on header view. This function
2924 will call tny_folder_refresh_async so we
2925 pass a callback that will be called when
2926 finished. We use that callback to set the
2927 empty view if there are no messages */
2928 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2929 TNY_FOLDER (folder_store),
2931 MODEST_WINDOW (main_window),
2932 folder_refreshed_cb,
2935 /* Restore configuration. We need to do this
2936 *after* the set_folder because the widget
2937 memory asks the header view about its
2939 modest_widget_memory_restore (modest_runtime_get_conf (),
2940 G_OBJECT(header_view),
2941 MODEST_CONF_HEADER_VIEW_KEY);
2943 /* No need to save the header view
2944 configuration for Maemo because it only
2945 saves the sorting stuff and that it's
2946 already being done by the sort
2947 dialog. Remove it when the GNOME version
2948 has the same behaviour */
2949 #ifdef MODEST_TOOLKIT_GTK
2950 if (modest_main_window_get_contents_style (main_window) ==
2951 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2952 modest_widget_memory_save (modest_runtime_get_conf (),
2953 G_OBJECT (header_view),
2954 MODEST_CONF_HEADER_VIEW_KEY);
2956 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2960 /* Update dimming state */
2961 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2962 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2966 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2973 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2975 online = tny_device_is_online (modest_runtime_get_device());
2978 /* already online -- the item is simply not there... */
2979 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2981 GTK_MESSAGE_WARNING,
2983 _("The %s you selected cannot be found"),
2985 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2986 gtk_dialog_run (GTK_DIALOG(dialog));
2988 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2991 _("mcen_bd_dialog_cancel"),
2992 GTK_RESPONSE_REJECT,
2993 _("mcen_bd_dialog_ok"),
2994 GTK_RESPONSE_ACCEPT,
2996 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2997 "Do you want to get online?"), item);
2998 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2999 gtk_label_new (txt), FALSE, FALSE, 0);
3000 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3003 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3004 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3005 /* TODO: Comment about why is this commented out: */
3006 /* modest_platform_connect_and_wait (); */
3009 gtk_widget_destroy (dialog);
3013 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3016 /* g_debug ("%s %s", __FUNCTION__, link); */
3021 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3024 modest_platform_activate_uri (link);
3028 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3031 modest_platform_show_uri_popup (link);
3035 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3038 /* we check for low-mem; in that case, show a warning, and don't allow
3039 * viewing attachments
3041 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3044 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3048 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3049 const gchar *address,
3052 /* g_debug ("%s %s", __FUNCTION__, address); */
3056 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3057 TnyMsg *saved_draft,
3060 ModestMsgEditWindow *edit_window;
3062 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3063 #ifndef MODEST_TOOLKIT_HILDON2
3064 ModestMainWindow *win;
3066 /* FIXME. Make the header view sensitive again. This is a
3067 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3069 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3070 modest_runtime_get_window_mgr(), FALSE));
3072 GtkWidget *hdrview = modest_main_window_get_child_widget(
3073 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3074 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3078 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3080 /* Set draft is there was no error */
3081 if (!modest_mail_operation_get_error (mail_op))
3082 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3084 g_object_unref(edit_window);
3088 enough_space_for_message (ModestMsgEditWindow *edit_window,
3091 guint64 available_disk, expected_size;
3096 available_disk = modest_utils_get_available_space (NULL);
3097 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3098 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3103 /* Double check: disk full condition or message too big */
3104 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3105 expected_size > available_disk) {
3106 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3107 modest_platform_information_banner (NULL, NULL, msg);
3114 * djcb: if we're in low-memory state, we only allow for
3115 * saving messages smaller than
3116 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3117 * should still allow for sending anything critical...
3119 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3120 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3124 * djcb: we also make sure that the attachments are smaller than the max size
3125 * this is for the case where we'd try to forward a message with attachments
3126 * bigger than our max allowed size, or sending an message from drafts which
3127 * somehow got past our checks when attaching.
3129 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3130 modest_platform_run_information_dialog (
3131 GTK_WINDOW(edit_window),
3132 _("mail_ib_error_attachment_size"),
3141 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3143 TnyTransportAccount *transport_account;
3144 ModestMailOperation *mail_operation;
3146 gchar *account_name;
3147 ModestAccountMgr *account_mgr;
3148 gboolean had_error = FALSE;
3149 ModestMainWindow *win = NULL;
3151 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3153 data = modest_msg_edit_window_get_msg_data (edit_window);
3156 if (!enough_space_for_message (edit_window, data)) {
3157 modest_msg_edit_window_free_msg_data (edit_window, data);
3161 account_name = g_strdup (data->account_name);
3162 account_mgr = modest_runtime_get_account_mgr();
3164 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3166 account_name = modest_account_mgr_get_default_account (account_mgr);
3167 if (!account_name) {
3168 g_printerr ("modest: no account found\n");
3169 modest_msg_edit_window_free_msg_data (edit_window, data);
3173 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3174 account_name = g_strdup (data->account_name);
3178 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3179 (modest_runtime_get_account_store (),
3181 TNY_ACCOUNT_TYPE_TRANSPORT));
3182 if (!transport_account) {
3183 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3184 g_free (account_name);
3185 modest_msg_edit_window_free_msg_data (edit_window, data);
3189 /* Create the mail operation */
3190 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3192 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3194 modest_mail_operation_save_to_drafts (mail_operation,
3206 data->priority_flags,
3209 on_save_to_drafts_cb,
3210 g_object_ref(edit_window));
3212 #ifdef MODEST_TOOLKIT_HILDON2
3213 /* In hildon2 we always show the information banner on saving to drafts.
3214 * It will be a system information banner in this case.
3216 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3217 modest_platform_information_banner (NULL, NULL, text);
3220 /* Use the main window as the parent of the banner, if the
3221 main window does not exist it won't be shown, if the parent
3222 window exists then it's properly shown. We don't use the
3223 editor window because it could be closed (save to drafts
3224 could happen after closing the window */
3225 win = (ModestMainWindow *)
3226 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3228 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3229 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3233 modest_msg_edit_window_set_modified (edit_window, FALSE);
3236 g_free (account_name);
3237 g_object_unref (G_OBJECT (transport_account));
3238 g_object_unref (G_OBJECT (mail_operation));
3240 modest_msg_edit_window_free_msg_data (edit_window, data);
3243 * If the drafts folder is selected then make the header view
3244 * insensitive while the message is being saved to drafts
3245 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3246 * is not very clean but it avoids letting the drafts folder
3247 * in an inconsistent state: the user could edit the message
3248 * being saved and undesirable things would happen.
3249 * In the average case the user won't notice anything at
3250 * all. In the worst case (the user is editing a really big
3251 * file from Drafts) the header view will be insensitive
3252 * during the saving process (10 or 20 seconds, depending on
3253 * the message). Anyway this is just a quick workaround: once
3254 * we find a better solution it should be removed
3255 * See NB#65125 (commend #18) for details.
3257 if (!had_error && win != NULL) {
3258 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3259 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3261 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3263 if (modest_tny_folder_is_local_folder(folder)) {
3264 TnyFolderType folder_type;
3265 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3266 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3267 GtkWidget *hdrview = modest_main_window_get_child_widget(
3268 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3269 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3273 if (folder != NULL) g_object_unref(folder);
3280 /* For instance, when clicking the Send toolbar button when editing a message: */
3282 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3284 TnyTransportAccount *transport_account = NULL;
3285 gboolean had_error = FALSE, add_to_contacts;
3287 ModestAccountMgr *account_mgr;
3288 gchar *account_name;
3289 ModestMailOperation *mail_operation;
3292 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3294 /* Check whether to automatically add new contacts to addressbook or not */
3295 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3296 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3297 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3300 data = modest_msg_edit_window_get_msg_data (edit_window);
3302 recipients = g_strconcat (data->to?data->to:"",
3303 data->cc?data->cc:"",
3304 data->bcc?data->bcc:"",
3306 if (recipients == NULL || recipients[0] == '\0') {
3307 /* Empty subject -> no send */
3308 g_free (recipients);
3309 modest_msg_edit_window_free_msg_data (edit_window, data);
3312 g_free (recipients);
3315 if (!enough_space_for_message (edit_window, data)) {
3316 modest_msg_edit_window_free_msg_data (edit_window, data);
3320 account_mgr = modest_runtime_get_account_mgr();
3321 account_name = g_strdup (data->account_name);
3323 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3326 account_name = modest_account_mgr_get_default_account (account_mgr);
3328 if (!account_name) {
3329 modest_msg_edit_window_free_msg_data (edit_window, data);
3330 /* Run account setup wizard */
3331 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3336 /* Get the currently-active transport account for this modest account: */
3337 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3339 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3340 (modest_runtime_get_account_store (),
3341 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3344 if (!transport_account) {
3345 modest_msg_edit_window_free_msg_data (edit_window, data);
3346 /* Run account setup wizard */
3347 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3352 /* Create the mail operation */
3353 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3354 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3356 modest_mail_operation_send_new_mail (mail_operation,
3370 data->priority_flags);
3372 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3373 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3375 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3376 const GError *error = modest_mail_operation_get_error (mail_operation);
3377 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3378 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3379 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3380 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3386 g_free (account_name);
3387 g_object_unref (G_OBJECT (transport_account));
3388 g_object_unref (G_OBJECT (mail_operation));
3390 modest_msg_edit_window_free_msg_data (edit_window, data);
3393 modest_msg_edit_window_set_sent (edit_window, TRUE);
3395 /* Save settings and close the window: */
3396 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3403 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3404 ModestMsgEditWindow *window)
3406 ModestMsgEditFormatState *format_state = NULL;
3408 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3409 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3411 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3414 format_state = modest_msg_edit_window_get_format_state (window);
3415 g_return_if_fail (format_state != NULL);
3417 format_state->bold = gtk_toggle_action_get_active (action);
3418 modest_msg_edit_window_set_format_state (window, format_state);
3419 g_free (format_state);
3424 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3425 ModestMsgEditWindow *window)
3427 ModestMsgEditFormatState *format_state = NULL;
3429 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3430 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3432 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3435 format_state = modest_msg_edit_window_get_format_state (window);
3436 g_return_if_fail (format_state != NULL);
3438 format_state->italics = gtk_toggle_action_get_active (action);
3439 modest_msg_edit_window_set_format_state (window, format_state);
3440 g_free (format_state);
3445 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3446 ModestMsgEditWindow *window)
3448 ModestMsgEditFormatState *format_state = NULL;
3450 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3451 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3453 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3456 format_state = modest_msg_edit_window_get_format_state (window);
3457 g_return_if_fail (format_state != NULL);
3459 format_state->bullet = gtk_toggle_action_get_active (action);
3460 modest_msg_edit_window_set_format_state (window, format_state);
3461 g_free (format_state);
3466 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3467 GtkRadioAction *selected,
3468 ModestMsgEditWindow *window)
3470 ModestMsgEditFormatState *format_state = NULL;
3471 GtkJustification value;
3473 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3475 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3478 value = gtk_radio_action_get_current_value (selected);
3480 format_state = modest_msg_edit_window_get_format_state (window);
3481 g_return_if_fail (format_state != NULL);
3483 format_state->justification = value;
3484 modest_msg_edit_window_set_format_state (window, format_state);
3485 g_free (format_state);
3489 modest_ui_actions_on_select_editor_color (GtkAction *action,
3490 ModestMsgEditWindow *window)
3492 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3493 g_return_if_fail (GTK_IS_ACTION (action));
3495 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3498 modest_msg_edit_window_select_color (window);
3502 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3503 ModestMsgEditWindow *window)
3505 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3506 g_return_if_fail (GTK_IS_ACTION (action));
3508 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3511 modest_msg_edit_window_select_background_color (window);
3515 modest_ui_actions_on_insert_image (GObject *object,
3516 ModestMsgEditWindow *window)
3518 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3521 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3524 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3527 modest_msg_edit_window_insert_image (window);
3531 modest_ui_actions_on_attach_file (GtkAction *action,
3532 ModestMsgEditWindow *window)
3534 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3535 g_return_if_fail (GTK_IS_ACTION (action));
3537 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3540 modest_msg_edit_window_offer_attach_file (window);
3544 modest_ui_actions_on_remove_attachments (GtkAction *action,
3545 ModestMsgEditWindow *window)
3547 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3549 modest_msg_edit_window_remove_attachments (window, NULL);
3553 do_create_folder_cb (ModestMailOperation *mail_op,
3554 TnyFolderStore *parent_folder,
3555 TnyFolder *new_folder,
3558 gchar *suggested_name = (gchar *) user_data;
3559 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3560 const GError *error;
3562 error = modest_mail_operation_get_error (mail_op);
3564 gboolean disk_full = FALSE;
3565 TnyAccount *account;
3566 /* Show an error. If there was some problem writing to
3567 disk, show it, otherwise show the generic folder
3568 create error. We do it here and not in an error
3569 handler because the call to do_create_folder will
3570 stop the main loop in a gtk_dialog_run and then,
3571 the message won't be shown until that dialog is
3573 account = modest_mail_operation_get_account (mail_op);
3576 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3577 (GtkWidget *) source_win,
3580 _("mail_in_ui_folder_create_error_memory"));
3581 g_object_unref (account);
3584 /* Show an error and try again if there is no
3585 full memory condition */
3586 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3587 _("mail_in_ui_folder_create_error"));
3588 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3592 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3593 * FIXME: any other? */
3594 GtkWidget *folder_view;
3596 if (MODEST_IS_MAIN_WINDOW(source_win))
3598 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3599 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3601 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3602 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3604 /* Select the newly created folder. It could happen
3605 that the widget is no longer there (i.e. the window
3606 has been destroyed, so we need to check this */
3608 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3610 g_object_unref (new_folder);
3612 /* Free. Note that the first time it'll be NULL so noop */
3613 g_free (suggested_name);
3614 g_object_unref (source_win);
3619 TnyFolderStore *parent;
3620 } CreateFolderConnect;
3623 do_create_folder_performer (gboolean canceled,
3625 GtkWindow *parent_window,
3626 TnyAccount *account,
3629 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3630 ModestMailOperation *mail_op;
3632 if (canceled || err) {
3633 /* In disk full conditions we could get this error here */
3634 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3635 (GtkWidget *) parent_window, err,
3636 NULL, _("mail_in_ui_folder_create_error_memory"));
3638 /* This happens if we have selected the outbox folder
3640 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3641 TNY_IS_MERGE_FOLDER (helper->parent)) {
3642 /* Show an error and retry */
3643 modest_platform_information_banner ((GtkWidget *) parent_window,
3645 _("mail_in_ui_folder_create_error"));
3647 do_create_folder (parent_window, helper->parent, helper->folder_name);
3653 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3654 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3656 modest_mail_operation_create_folder (mail_op,
3658 (const gchar *) helper->folder_name,
3659 do_create_folder_cb,
3660 g_strdup (helper->folder_name));
3661 g_object_unref (mail_op);
3665 g_object_unref (helper->parent);
3666 if (helper->folder_name)
3667 g_free (helper->folder_name);
3668 g_slice_free (CreateFolderConnect, helper);
3673 do_create_folder (GtkWindow *parent_window,
3674 TnyFolderStore *suggested_parent,
3675 const gchar *suggested_name)
3678 gchar *folder_name = NULL;
3679 TnyFolderStore *parent_folder = NULL;
3681 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3683 (gchar *) suggested_name,
3687 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3688 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3689 helper->folder_name = g_strdup (folder_name);
3690 helper->parent = g_object_ref (parent_folder);
3692 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3695 do_create_folder_performer,
3700 g_free (folder_name);
3702 g_object_unref (parent_folder);
3706 modest_ui_actions_create_folder(GtkWidget *parent_window,
3707 GtkWidget *folder_view,
3708 TnyFolderStore *parent_folder)
3710 if (!parent_folder) {
3711 #ifdef MODEST_TOOLKIT_HILDON2
3712 ModestTnyAccountStore *acc_store;
3714 acc_store = modest_runtime_get_account_store ();
3716 parent_folder = (TnyFolderStore *)
3717 modest_tny_account_store_get_local_folders_account (acc_store);
3719 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3723 if (parent_folder) {
3724 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3725 g_object_unref (parent_folder);
3730 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3733 g_return_if_fail (MODEST_IS_WINDOW(window));
3735 if (MODEST_IS_MAIN_WINDOW (window)) {
3736 GtkWidget *folder_view;
3738 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3739 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3743 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3744 #ifdef MODEST_TOOLKIT_HILDON2
3745 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3746 GtkWidget *folder_view;
3748 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3749 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3752 g_assert_not_reached ();
3757 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3760 const GError *error = NULL;
3761 gchar *message = NULL;
3763 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3765 /* Get error message */
3766 error = modest_mail_operation_get_error (mail_op);
3768 g_return_if_reached ();
3770 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3771 (GError *) error, account);
3773 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3774 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3775 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3776 message = _CS("ckdg_ib_folder_already_exists");
3777 } else if (error->domain == TNY_ERROR_DOMAIN &&
3778 error->code == TNY_SERVICE_ERROR_STATE) {
3779 /* This means that the folder is already in use (a
3780 message is opened for example */
3781 message = _("emev_ni_internal_error");
3783 message = _CS("ckdg_ib_unable_to_rename");
3786 /* We don't set a parent for the dialog because the dialog
3787 will be destroyed so the banner won't appear */
3788 modest_platform_information_banner (NULL, NULL, message);
3791 g_object_unref (account);
3797 TnyFolderStore *folder;
3802 on_rename_folder_cb (ModestMailOperation *mail_op,
3803 TnyFolder *new_folder,
3806 ModestFolderView *folder_view;
3808 /* If the window was closed when renaming a folder, or if
3809 * it's not a main window this will happen */
3810 if (!MODEST_IS_FOLDER_VIEW (user_data))
3813 folder_view = MODEST_FOLDER_VIEW (user_data);
3814 /* Note that if the rename fails new_folder will be NULL */
3816 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3818 modest_folder_view_select_first_inbox_or_local (folder_view);
3820 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3824 on_rename_folder_performer (gboolean canceled,
3826 GtkWindow *parent_window,
3827 TnyAccount *account,
3830 ModestMailOperation *mail_op = NULL;
3831 GtkTreeSelection *sel = NULL;
3832 GtkWidget *folder_view = NULL;
3833 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3835 if (canceled || err) {
3836 /* In disk full conditions we could get this error here */
3837 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3838 (GtkWidget *) parent_window, err,
3843 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3844 modest_ui_actions_rename_folder_error_handler,
3845 parent_window, NULL);
3847 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3850 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3852 folder_view = modest_main_window_get_child_widget (
3853 MODEST_MAIN_WINDOW (parent_window),
3854 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3856 #ifdef MODEST_TOOLKIT_HILDON2
3857 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3858 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3859 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3863 /* Clear the folders view */
3864 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3865 gtk_tree_selection_unselect_all (sel);
3867 /* Actually rename the folder */
3868 modest_mail_operation_rename_folder (mail_op,
3869 TNY_FOLDER (data->folder),
3870 (const gchar *) (data->new_name),
3871 on_rename_folder_cb,
3873 g_object_unref (mail_op);
3876 g_object_unref (data->folder);
3877 g_free (data->new_name);
3882 modest_ui_actions_on_rename_folder (GtkAction *action,
3883 ModestWindow *window)
3885 modest_ui_actions_on_edit_mode_rename_folder (window);
3889 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3891 TnyFolderStore *folder;
3892 GtkWidget *folder_view;
3893 gboolean do_rename = TRUE;
3895 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3897 if (MODEST_IS_MAIN_WINDOW (window)) {
3898 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3899 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3903 #ifdef MODEST_TOOLKIT_HILDON2
3904 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3905 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3911 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3916 if (TNY_IS_FOLDER (folder)) {
3917 gchar *folder_name = NULL;
3919 const gchar *current_name;
3920 TnyFolderStore *parent;
3922 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3923 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3924 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3925 parent, current_name,
3927 g_object_unref (parent);
3929 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3932 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3933 rename_folder_data->folder = g_object_ref (folder);
3934 rename_folder_data->new_name = folder_name;
3935 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3936 folder, on_rename_folder_performer, rename_folder_data);
3939 g_object_unref (folder);
3944 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3947 GObject *win = modest_mail_operation_get_source (mail_op);
3949 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3950 _("mail_in_ui_folder_delete_error"),
3952 g_object_unref (win);
3956 TnyFolderStore *folder;
3957 gboolean move_to_trash;
3961 on_delete_folder_cb (gboolean canceled,
3963 GtkWindow *parent_window,
3964 TnyAccount *account,
3967 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3968 GtkWidget *folder_view;
3969 ModestMailOperation *mail_op;
3970 GtkTreeSelection *sel;
3972 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3973 /* Note that the connection process can fail due to
3974 memory low conditions as it can not successfully
3975 store the summary */
3976 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3977 (GtkWidget*) parent_window, err,
3979 g_debug ("Error connecting when trying to delete a folder");
3980 g_object_unref (G_OBJECT (info->folder));
3985 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3986 folder_view = modest_main_window_get_child_widget (
3987 MODEST_MAIN_WINDOW (parent_window),
3988 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3989 #ifdef MODEST_TOOLKIT_HILDON2
3990 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3991 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3994 g_object_unref (G_OBJECT (info->folder));
3999 /* Unselect the folder before deleting it to free the headers */
4000 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4001 gtk_tree_selection_unselect_all (sel);
4003 /* Create the mail operation */
4005 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4006 modest_ui_actions_delete_folder_error_handler,
4009 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4011 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4013 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4015 g_object_unref (mail_op);
4016 g_object_unref (info->folder);
4021 delete_folder (ModestWindow *window, gboolean move_to_trash)
4023 TnyFolderStore *folder;
4024 GtkWidget *folder_view;
4028 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4030 if (MODEST_IS_MAIN_WINDOW (window)) {
4032 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4033 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4034 #ifdef MODEST_TOOLKIT_HILDON2
4035 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4036 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4044 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4049 /* Show an error if it's an account */
4050 if (!TNY_IS_FOLDER (folder)) {
4051 modest_platform_run_information_dialog (GTK_WINDOW (window),
4052 _("mail_in_ui_folder_delete_error"),
4054 g_object_unref (G_OBJECT (folder));
4059 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4060 tny_folder_get_name (TNY_FOLDER (folder)));
4061 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4062 (const gchar *) message);
4065 if (response == GTK_RESPONSE_OK) {
4066 TnyAccount *account = NULL;
4067 DeleteFolderInfo *info = NULL;
4068 info = g_new0(DeleteFolderInfo, 1);
4069 info->folder = g_object_ref (folder);
4070 info->move_to_trash = move_to_trash;
4072 account = tny_folder_get_account (TNY_FOLDER (folder));
4073 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4075 TNY_FOLDER_STORE (account),
4076 on_delete_folder_cb, info);
4077 g_object_unref (account);
4078 g_object_unref (folder);
4086 modest_ui_actions_on_delete_folder (GtkAction *action,
4087 ModestWindow *window)
4089 modest_ui_actions_on_edit_mode_delete_folder (window);
4093 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4095 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4097 return delete_folder (window, FALSE);
4101 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4103 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4105 delete_folder (MODEST_WINDOW (main_window), TRUE);
4109 typedef struct _PasswordDialogFields {
4110 GtkWidget *username;
4111 GtkWidget *password;
4113 } PasswordDialogFields;
4116 password_dialog_check_field (GtkEditable *editable,
4117 PasswordDialogFields *fields)
4120 gboolean any_value_empty = FALSE;
4122 #ifdef MODEST_TOOLKIT_HILDON2
4123 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4125 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4127 if ((value == NULL) || value[0] == '\0') {
4128 any_value_empty = TRUE;
4130 #ifdef MODEST_TOOLKIT_HILDON2
4131 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4133 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4135 if ((value == NULL) || value[0] == '\0') {
4136 any_value_empty = TRUE;
4138 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4142 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4143 const gchar* server_account_name,
4148 ModestMainWindow *main_window)
4150 g_return_if_fail(server_account_name);
4151 gboolean completed = FALSE;
4152 PasswordDialogFields *fields = NULL;
4154 /* Initalize output parameters: */
4161 #ifndef MODEST_TOOLKIT_GTK
4162 /* Maemo uses a different (awkward) button order,
4163 * It should probably just use gtk_alternative_dialog_button_order ().
4165 #ifdef MODEST_TOOLKIT_HILDON2
4167 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4170 _HL("wdgt_bd_done"),
4171 GTK_RESPONSE_ACCEPT,
4173 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4174 HILDON_MARGIN_DOUBLE);
4177 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4180 _("mcen_bd_dialog_ok"),
4181 GTK_RESPONSE_ACCEPT,
4182 _("mcen_bd_dialog_cancel"),
4183 GTK_RESPONSE_REJECT,
4185 #endif /* MODEST_TOOLKIT_HILDON2 */
4188 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4192 GTK_RESPONSE_REJECT,
4194 GTK_RESPONSE_ACCEPT,
4196 #endif /* MODEST_TOOLKIT_GTK */
4198 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4200 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4201 modest_runtime_get_account_mgr(), server_account_name);
4202 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4203 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4206 gtk_widget_destroy (dialog);
4210 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4211 GtkWidget *label = gtk_label_new (txt);
4212 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4214 g_free (server_name);
4215 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4220 gchar *initial_username = modest_account_mgr_get_server_account_username (
4221 modest_runtime_get_account_mgr(), server_account_name);
4223 #ifdef MODEST_TOOLKIT_HILDON2
4224 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4225 if (initial_username)
4226 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4228 GtkWidget *entry_username = gtk_entry_new ();
4229 if (initial_username)
4230 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4232 /* Dim this if a connection has ever succeeded with this username,
4233 * as per the UI spec: */
4234 /* const gboolean username_known = */
4235 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4236 /* modest_runtime_get_account_mgr(), server_account_name); */
4237 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4239 /* We drop the username sensitive code and disallow changing it here
4240 * as tinymail does not support really changing the username in the callback
4242 gtk_widget_set_sensitive (entry_username, FALSE);
4244 #ifndef MODEST_TOOLKIT_GTK
4245 /* Auto-capitalization is the default, so let's turn it off: */
4246 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4248 /* Create a size group to be used by all captions.
4249 * Note that HildonCaption does not create a default size group if we do not specify one.
4250 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4251 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4253 #ifdef MODEST_TOOLKIT_HILDON2
4254 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4255 _("mail_fi_username"), FALSE,
4258 GtkWidget *caption = hildon_caption_new (sizegroup,
4259 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4261 gtk_widget_show (entry_username);
4262 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4263 FALSE, FALSE, MODEST_MARGIN_HALF);
4264 gtk_widget_show (caption);
4266 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4268 #endif /* !MODEST_TOOLKIT_GTK */
4271 #ifdef MODEST_TOOLKIT_HILDON2
4272 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4274 GtkWidget *entry_password = gtk_entry_new ();
4276 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4277 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4279 #ifndef MODEST_TOOLKIT_GTK
4280 /* Auto-capitalization is the default, so let's turn it off: */
4281 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4282 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4284 #ifdef MODEST_TOOLKIT_HILDON2
4285 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4286 _("mail_fi_password"), FALSE,
4289 caption = hildon_caption_new (sizegroup,
4290 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4292 gtk_widget_show (entry_password);
4293 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4294 FALSE, FALSE, MODEST_MARGIN_HALF);
4295 gtk_widget_show (caption);
4296 g_object_unref (sizegroup);
4298 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4300 #endif /* !MODEST_TOOLKIT_GTK */
4302 if (initial_username != NULL)
4303 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4305 /* This is not in the Maemo UI spec:
4306 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4307 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4311 fields = g_slice_new0 (PasswordDialogFields);
4312 fields->username = entry_username;
4313 fields->password = entry_password;
4314 fields->dialog = dialog;
4316 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4317 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4318 password_dialog_check_field (NULL, fields);
4320 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4322 while (!completed) {
4324 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4326 #ifdef MODEST_TOOLKIT_HILDON2
4327 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4329 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4332 /* Note that an empty field becomes the "" string */
4333 if (*username && strlen (*username) > 0) {
4334 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4335 server_account_name,
4339 const gboolean username_was_changed =
4340 (strcmp (*username, initial_username) != 0);
4341 if (username_was_changed) {
4342 g_warning ("%s: tinymail does not yet support changing the "
4343 "username in the get_password() callback.\n", __FUNCTION__);
4349 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4350 _("mcen_ib_username_pw_incorrect"));
4356 #ifdef MODEST_TOOLKIT_HILDON2
4357 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4359 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4362 /* We do not save the password in the configuration,
4363 * because this function is only called for passwords that should
4364 * not be remembered:
4365 modest_server_account_set_password (
4366 modest_runtime_get_account_mgr(), server_account_name,
4373 #ifndef MODEST_TOOLKIT_HILDON2
4374 /* Set parent to NULL or the banner will disappear with its parent dialog */
4375 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4387 /* This is not in the Maemo UI spec:
4388 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4394 g_free (initial_username);
4395 gtk_widget_destroy (dialog);
4396 g_slice_free (PasswordDialogFields, fields);
4398 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4402 modest_ui_actions_on_cut (GtkAction *action,
4403 ModestWindow *window)
4405 GtkWidget *focused_widget;
4406 GtkClipboard *clipboard;
4408 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4409 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4410 if (GTK_IS_EDITABLE (focused_widget)) {
4411 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4412 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4413 gtk_clipboard_store (clipboard);
4414 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4415 GtkTextBuffer *buffer;
4417 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4418 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4419 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4420 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4421 gtk_clipboard_store (clipboard);
4423 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4424 TnyList *header_list = modest_header_view_get_selected_headers (
4425 MODEST_HEADER_VIEW (focused_widget));
4426 gboolean continue_download = FALSE;
4427 gint num_of_unc_msgs;
4429 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4431 if (num_of_unc_msgs) {
4432 TnyAccount *account = get_account_from_header_list (header_list);
4434 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4435 g_object_unref (account);
4439 if (num_of_unc_msgs == 0 || continue_download) {
4440 /* modest_platform_information_banner (
4441 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4442 modest_header_view_cut_selection (
4443 MODEST_HEADER_VIEW (focused_widget));
4446 g_object_unref (header_list);
4447 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4448 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4453 modest_ui_actions_on_copy (GtkAction *action,
4454 ModestWindow *window)
4456 GtkClipboard *clipboard;
4457 GtkWidget *focused_widget;
4458 gboolean copied = TRUE;
4460 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4461 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4463 if (GTK_IS_LABEL (focused_widget)) {
4465 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4466 gtk_clipboard_set_text (clipboard, selection, -1);
4468 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4469 gtk_clipboard_store (clipboard);
4470 } else if (GTK_IS_EDITABLE (focused_widget)) {
4471 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4472 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4473 gtk_clipboard_store (clipboard);
4474 } else if (GTK_IS_HTML (focused_widget)) {
4477 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4478 if ((sel == NULL) || (sel[0] == '\0')) {
4481 gtk_html_copy (GTK_HTML (focused_widget));
4482 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4483 gtk_clipboard_store (clipboard);
4485 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4486 GtkTextBuffer *buffer;
4487 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4488 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4489 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4490 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4491 gtk_clipboard_store (clipboard);
4493 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4494 TnyList *header_list = modest_header_view_get_selected_headers (
4495 MODEST_HEADER_VIEW (focused_widget));
4496 gboolean continue_download = FALSE;
4497 gint num_of_unc_msgs;
4499 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4501 if (num_of_unc_msgs) {
4502 TnyAccount *account = get_account_from_header_list (header_list);
4504 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4505 g_object_unref (account);
4509 if (num_of_unc_msgs == 0 || continue_download) {
4510 modest_platform_information_banner (
4511 NULL, NULL, _CS("mcen_ib_getting_items"));
4512 modest_header_view_copy_selection (
4513 MODEST_HEADER_VIEW (focused_widget));
4517 g_object_unref (header_list);
4519 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4520 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4523 /* Show information banner if there was a copy to clipboard */
4525 modest_platform_information_banner (
4526 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4530 modest_ui_actions_on_undo (GtkAction *action,
4531 ModestWindow *window)
4533 ModestEmailClipboard *clipboard = NULL;
4535 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4536 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4537 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4538 /* Clear clipboard source */
4539 clipboard = modest_runtime_get_email_clipboard ();
4540 modest_email_clipboard_clear (clipboard);
4543 g_return_if_reached ();
4548 modest_ui_actions_on_redo (GtkAction *action,
4549 ModestWindow *window)
4551 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4552 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4555 g_return_if_reached ();
4561 destroy_information_note (ModestMailOperation *mail_op,
4564 /* destroy information note */
4565 gtk_widget_destroy (GTK_WIDGET(user_data));
4569 destroy_folder_information_note (ModestMailOperation *mail_op,
4570 TnyFolder *new_folder,
4573 /* destroy information note */
4574 gtk_widget_destroy (GTK_WIDGET(user_data));
4579 paste_as_attachment_free (gpointer data)
4581 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4583 if (helper->banner) {
4584 gtk_widget_destroy (helper->banner);
4585 g_object_unref (helper->banner);
4591 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4596 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4597 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4602 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4607 modest_ui_actions_on_paste (GtkAction *action,
4608 ModestWindow *window)
4610 GtkWidget *focused_widget = NULL;
4611 GtkWidget *inf_note = NULL;
4612 ModestMailOperation *mail_op = NULL;
4614 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4615 if (GTK_IS_EDITABLE (focused_widget)) {
4616 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4617 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4618 ModestEmailClipboard *e_clipboard = NULL;
4619 e_clipboard = modest_runtime_get_email_clipboard ();
4620 if (modest_email_clipboard_cleared (e_clipboard)) {
4621 GtkTextBuffer *buffer;
4622 GtkClipboard *clipboard;
4624 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4625 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4626 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4627 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4628 ModestMailOperation *mail_op;
4629 TnyFolder *src_folder = NULL;
4630 TnyList *data = NULL;
4632 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4633 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4634 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4635 _CS("ckct_nw_pasting"));
4636 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4637 mail_op = modest_mail_operation_new (G_OBJECT (window));
4638 if (helper->banner != NULL) {
4639 g_object_ref (G_OBJECT (helper->banner));
4640 gtk_widget_show (GTK_WIDGET (helper->banner));
4644 modest_mail_operation_get_msgs_full (mail_op,
4646 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4648 paste_as_attachment_free);
4652 g_object_unref (data);
4654 g_object_unref (src_folder);
4657 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4658 ModestEmailClipboard *clipboard = NULL;
4659 TnyFolder *src_folder = NULL;
4660 TnyFolderStore *folder_store = NULL;
4661 TnyList *data = NULL;
4662 gboolean delete = FALSE;
4664 /* Check clipboard source */
4665 clipboard = modest_runtime_get_email_clipboard ();
4666 if (modest_email_clipboard_cleared (clipboard))
4669 /* Get elements to paste */
4670 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4672 /* Create a new mail operation */
4673 mail_op = modest_mail_operation_new (G_OBJECT(window));
4675 /* Get destination folder */
4676 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4678 /* transfer messages */
4682 /* Ask for user confirmation */
4684 modest_ui_actions_msgs_move_to_confirmation (window,
4685 TNY_FOLDER (folder_store),
4689 if (response == GTK_RESPONSE_OK) {
4690 /* Launch notification */
4691 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4692 _CS("ckct_nw_pasting"));
4693 if (inf_note != NULL) {
4694 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4695 gtk_widget_show (GTK_WIDGET(inf_note));
4698 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4699 modest_mail_operation_xfer_msgs (mail_op,
4701 TNY_FOLDER (folder_store),
4703 destroy_information_note,
4706 g_object_unref (mail_op);
4709 } else if (src_folder != NULL) {
4710 /* Launch notification */
4711 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4712 _CS("ckct_nw_pasting"));
4713 if (inf_note != NULL) {
4714 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4715 gtk_widget_show (GTK_WIDGET(inf_note));
4718 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4719 modest_mail_operation_xfer_folder (mail_op,
4723 destroy_folder_information_note,
4729 g_object_unref (data);
4730 if (src_folder != NULL)
4731 g_object_unref (src_folder);
4732 if (folder_store != NULL)
4733 g_object_unref (folder_store);
4739 modest_ui_actions_on_select_all (GtkAction *action,
4740 ModestWindow *window)
4742 GtkWidget *focused_widget;
4744 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4745 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4746 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4747 } else if (GTK_IS_LABEL (focused_widget)) {
4748 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4749 } else if (GTK_IS_EDITABLE (focused_widget)) {
4750 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4751 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4752 GtkTextBuffer *buffer;
4753 GtkTextIter start, end;
4755 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4756 gtk_text_buffer_get_start_iter (buffer, &start);
4757 gtk_text_buffer_get_end_iter (buffer, &end);
4758 gtk_text_buffer_select_range (buffer, &start, &end);
4759 } else if (GTK_IS_HTML (focused_widget)) {
4760 gtk_html_select_all (GTK_HTML (focused_widget));
4761 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4762 GtkWidget *header_view = focused_widget;
4763 GtkTreeSelection *selection = NULL;
4765 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4766 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4767 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4770 /* Disable window dimming management */
4771 modest_window_disable_dimming (MODEST_WINDOW(window));
4773 /* Select all messages */
4774 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4775 gtk_tree_selection_select_all (selection);
4777 /* Set focuse on header view */
4778 gtk_widget_grab_focus (header_view);
4780 /* Enable window dimming management */
4781 modest_window_enable_dimming (MODEST_WINDOW(window));
4782 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4783 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4789 modest_ui_actions_on_mark_as_read (GtkAction *action,
4790 ModestWindow *window)
4792 g_return_if_fail (MODEST_IS_WINDOW(window));
4794 /* Mark each header as read */
4795 do_headers_action (window, headers_action_mark_as_read, NULL);
4799 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4800 ModestWindow *window)
4802 g_return_if_fail (MODEST_IS_WINDOW(window));
4804 /* Mark each header as read */
4805 do_headers_action (window, headers_action_mark_as_unread, NULL);
4809 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4810 GtkRadioAction *selected,
4811 ModestWindow *window)
4815 value = gtk_radio_action_get_current_value (selected);
4816 if (MODEST_IS_WINDOW (window)) {
4817 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4822 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4823 GtkRadioAction *selected,
4824 ModestWindow *window)
4826 TnyHeaderFlags flags;
4827 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4829 flags = gtk_radio_action_get_current_value (selected);
4830 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4834 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4835 GtkRadioAction *selected,
4836 ModestWindow *window)
4840 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4842 file_format = gtk_radio_action_get_current_value (selected);
4843 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4848 modest_ui_actions_on_zoom_plus (GtkAction *action,
4849 ModestWindow *window)
4851 g_return_if_fail (MODEST_IS_WINDOW (window));
4853 modest_window_zoom_plus (MODEST_WINDOW (window));
4857 modest_ui_actions_on_zoom_minus (GtkAction *action,
4858 ModestWindow *window)
4860 g_return_if_fail (MODEST_IS_WINDOW (window));
4862 modest_window_zoom_minus (MODEST_WINDOW (window));
4866 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4867 ModestWindow *window)
4869 ModestWindowMgr *mgr;
4870 gboolean fullscreen, active;
4871 g_return_if_fail (MODEST_IS_WINDOW (window));
4873 mgr = modest_runtime_get_window_mgr ();
4875 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4876 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4878 if (active != fullscreen) {
4879 modest_window_mgr_set_fullscreen_mode (mgr, active);
4880 #ifndef MODEST_TOOLKIT_HILDON2
4881 gtk_window_present (GTK_WINDOW (window));
4887 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4888 ModestWindow *window)
4890 ModestWindowMgr *mgr;
4891 gboolean fullscreen;
4893 g_return_if_fail (MODEST_IS_WINDOW (window));
4895 mgr = modest_runtime_get_window_mgr ();
4896 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4897 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4899 #ifndef MODEST_TOOLKIT_HILDON2
4900 gtk_window_present (GTK_WINDOW (window));
4905 * Used by modest_ui_actions_on_details to call do_headers_action
4908 headers_action_show_details (TnyHeader *header,
4909 ModestWindow *window,
4913 gboolean async_retrieval;
4916 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4917 async_retrieval = TRUE;
4918 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4920 async_retrieval = FALSE;
4922 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4924 g_object_unref (msg);
4928 * Show the header details in a ModestDetailsDialog widget
4931 modest_ui_actions_on_details (GtkAction *action,
4934 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4938 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4942 header = tny_msg_get_header (msg);
4944 headers_action_show_details (header, win, NULL);
4945 g_object_unref (header);
4947 g_object_unref (msg);
4949 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4950 GtkWidget *folder_view, *header_view;
4952 /* Check which widget has the focus */
4953 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4954 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4955 if (gtk_widget_is_focus (folder_view)) {
4956 TnyFolderStore *folder_store
4957 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4958 if (!folder_store) {
4959 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4962 /* Show only when it's a folder */
4963 /* This function should not be called for account items,
4964 * because we dim the menu item for them. */
4965 if (TNY_IS_FOLDER (folder_store)) {
4966 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4967 TNY_FOLDER (folder_store));
4970 g_object_unref (folder_store);
4973 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4974 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4975 /* Show details of each header */
4976 do_headers_action (win, headers_action_show_details, header_view);
4978 #ifdef MODEST_TOOLKIT_HILDON2
4979 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4981 GtkWidget *header_view;
4983 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4984 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4986 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4988 g_object_unref (folder);
4995 modest_ui_actions_on_limit_error (GtkAction *action,
4998 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5000 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5005 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5006 ModestMsgEditWindow *window)
5008 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5010 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5014 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5015 ModestMsgEditWindow *window)
5017 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5019 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5023 modest_ui_actions_toggle_folders_view (GtkAction *action,
5024 ModestMainWindow *main_window)
5026 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5028 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5029 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5031 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5035 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5036 ModestWindow *window)
5038 gboolean active, fullscreen = FALSE;
5039 ModestWindowMgr *mgr;
5041 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5043 /* Check if we want to toggle the toolbar view in fullscreen
5045 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5046 "ViewShowToolbarFullScreen")) {
5050 /* Toggle toolbar */
5051 mgr = modest_runtime_get_window_mgr ();
5052 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5056 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5057 ModestMsgEditWindow *window)
5059 modest_msg_edit_window_select_font (window);
5064 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5065 const gchar *display_name,
5068 /* don't update the display name if it was already set;
5069 * updating the display name apparently is expensive */
5070 const gchar* old_name = gtk_window_get_title (window);
5072 if (display_name == NULL)
5075 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5076 return; /* don't do anything */
5078 /* This is usually used to change the title of the main window, which
5079 * is the one that holds the folder view. Note that this change can
5080 * happen even when the widget doesn't have the focus. */
5081 gtk_window_set_title (window, display_name);
5086 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5088 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5089 modest_msg_edit_window_select_contacts (window);
5093 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5095 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5096 modest_msg_edit_window_check_names (window, FALSE);
5099 #ifndef MODEST_TOOLKIT_HILDON2
5101 * This function is used to track changes in the selection of the
5102 * folder view that is inside the "move to" dialog to enable/disable
5103 * the OK button because we do not want the user to select a disallowed
5104 * destination for a folder.
5105 * The user also not desired to be able to use NEW button on items where
5106 * folder creation is not possibel.
5109 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5110 TnyFolderStore *folder_store,
5114 GtkWidget *dialog = NULL;
5115 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5116 gboolean moving_folder = FALSE;
5117 gboolean is_local_account = TRUE;
5118 GtkWidget *folder_view = NULL;
5119 ModestTnyFolderRules rules;
5121 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5126 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5130 /* check if folder_store is an remote account */
5131 if (TNY_IS_ACCOUNT (folder_store)) {
5132 TnyAccount *local_account = NULL;
5133 TnyAccount *mmc_account = NULL;
5134 ModestTnyAccountStore *account_store = NULL;
5136 account_store = modest_runtime_get_account_store ();
5137 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5138 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5140 if ((gpointer) local_account != (gpointer) folder_store &&
5141 (gpointer) mmc_account != (gpointer) folder_store) {
5142 ModestProtocolType proto;
5143 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5144 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5145 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5147 is_local_account = FALSE;
5148 /* New button should be dimmed on remote
5150 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5152 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5154 g_object_unref (local_account);
5156 /* It could not exist */
5158 g_object_unref (mmc_account);
5161 /* Check the target folder rules */
5162 if (TNY_IS_FOLDER (folder_store)) {
5163 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5164 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5165 ok_sensitive = FALSE;
5166 new_sensitive = FALSE;
5171 /* Check if we're moving a folder */
5172 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5173 /* Get the widgets */
5174 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5175 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5176 if (gtk_widget_is_focus (folder_view))
5177 moving_folder = TRUE;
5180 if (moving_folder) {
5181 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5183 /* Get the folder to move */
5184 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5186 /* Check that we're not moving to the same folder */
5187 if (TNY_IS_FOLDER (moved_folder)) {
5188 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5189 if (parent == folder_store)
5190 ok_sensitive = FALSE;
5191 g_object_unref (parent);
5194 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5195 /* Do not allow to move to an account unless it's the
5196 local folders account */
5197 if (!is_local_account)
5198 ok_sensitive = FALSE;
5201 if (ok_sensitive && (moved_folder == folder_store)) {
5202 /* Do not allow to move to itself */
5203 ok_sensitive = FALSE;
5205 g_object_unref (moved_folder);
5207 TnyFolder *src_folder = NULL;
5209 /* Moving a message */
5210 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5212 TnyHeader *header = NULL;
5213 header = modest_msg_view_window_get_header
5214 (MODEST_MSG_VIEW_WINDOW (user_data));
5215 if (!TNY_IS_HEADER(header))
5216 g_warning ("%s: could not get source header", __FUNCTION__);
5218 src_folder = tny_header_get_folder (header);
5221 g_object_unref (header);
5224 TNY_FOLDER (modest_folder_view_get_selected
5225 (MODEST_FOLDER_VIEW (folder_view)));
5228 if (TNY_IS_FOLDER(src_folder)) {
5229 /* Do not allow to move the msg to the same folder */
5230 /* Do not allow to move the msg to an account */
5231 if ((gpointer) src_folder == (gpointer) folder_store ||
5232 TNY_IS_ACCOUNT (folder_store))
5233 ok_sensitive = FALSE;
5234 g_object_unref (src_folder);
5236 g_warning ("%s: could not get source folder", __FUNCTION__);
5240 /* Set sensitivity of the OK and NEW button */
5241 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5242 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5247 on_move_to_dialog_response (GtkDialog *dialog,
5251 GtkWidget *parent_win;
5252 MoveToInfo *helper = NULL;
5253 ModestFolderView *folder_view;
5254 gboolean unset_edit_mode = FALSE;
5256 helper = (MoveToInfo *) user_data;
5258 parent_win = (GtkWidget *) helper->win;
5259 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5260 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5262 TnyFolderStore *dst_folder;
5263 TnyFolderStore *selected;
5265 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5266 selected = modest_folder_view_get_selected (folder_view);
5267 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5268 g_object_unref (selected);
5270 case GTK_RESPONSE_NONE:
5271 case GTK_RESPONSE_CANCEL:
5272 case GTK_RESPONSE_DELETE_EVENT:
5274 case GTK_RESPONSE_OK:
5275 dst_folder = modest_folder_view_get_selected (folder_view);
5277 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5278 /* Clean list to move used for filtering */
5279 modest_folder_view_set_list_to_move (folder_view, NULL);
5281 modest_ui_actions_on_main_window_move_to (NULL,
5282 GTK_WIDGET (folder_view),
5284 MODEST_MAIN_WINDOW (parent_win));
5285 #ifdef MODEST_TOOLKIT_HILDON2
5286 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5287 /* Clean list to move used for filtering */
5288 modest_folder_view_set_list_to_move (folder_view, NULL);
5290 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5293 GTK_WINDOW (parent_win));
5296 /* if the user selected a root folder
5297 (account) then do not perform any action */
5298 if (TNY_IS_ACCOUNT (dst_folder)) {
5299 g_signal_stop_emission_by_name (dialog, "response");
5303 /* Clean list to move used for filtering */
5304 modest_folder_view_set_list_to_move (folder_view, NULL);
5306 /* Moving from headers window in edit mode */
5307 modest_ui_actions_on_window_move_to (NULL, helper->list,
5309 MODEST_WINDOW (parent_win));
5313 g_object_unref (dst_folder);
5315 unset_edit_mode = TRUE;
5318 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5321 /* Free the helper and exit */
5323 g_object_unref (helper->list);
5324 if (unset_edit_mode) {
5325 #ifdef MODEST_TOOLKIT_HILDON2
5326 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5329 g_slice_free (MoveToInfo, helper);
5330 gtk_widget_destroy (GTK_WIDGET (dialog));
5334 create_move_to_dialog (GtkWindow *win,
5335 GtkWidget *folder_view,
5336 TnyList *list_to_move)
5338 GtkWidget *dialog, *tree_view = NULL;
5340 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5342 #ifndef MODEST_TOOLKIT_HILDON2
5343 /* Track changes in the selection to
5344 * disable the OK button whenever "Move to" is not possible
5345 * disbale NEW button whenever New is not possible */
5346 g_signal_connect (tree_view,
5347 "folder_selection_changed",
5348 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5352 /* It could happen that we're trying to move a message from a
5353 window (msg window for example) after the main window was
5354 closed, so we can not just get the model of the folder
5356 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5357 const gchar *visible_id = NULL;
5359 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5360 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5361 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5362 MODEST_FOLDER_VIEW(tree_view));
5365 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5367 /* Show the same account than the one that is shown in the main window */
5368 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5371 const gchar *active_account_name = NULL;
5372 ModestAccountMgr *mgr = NULL;
5373 ModestAccountSettings *settings = NULL;
5374 ModestServerAccountSettings *store_settings = NULL;
5376 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5377 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5378 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5379 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5381 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5382 mgr = modest_runtime_get_account_mgr ();
5383 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5386 const gchar *store_account_name;
5387 store_settings = modest_account_settings_get_store_settings (settings);
5388 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5390 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5391 store_account_name);
5392 g_object_unref (store_settings);
5393 g_object_unref (settings);
5397 /* we keep a pointer to the embedded folder view, so we can
5398 * retrieve it with get_folder_view_from_move_to_dialog (see
5399 * above) later (needed for focus handling)
5401 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5403 /* Hide special folders */
5404 #ifndef MODEST_TOOLKIT_HILDON2
5405 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5408 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5409 #ifndef MODEST_TOOLKIT_HILDON2
5410 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5413 gtk_widget_show (GTK_WIDGET (tree_view));
5419 * Shows a confirmation dialog to the user when we're moving messages
5420 * from a remote server to the local storage. Returns the dialog
5421 * response. If it's other kind of movement then it always returns
5424 * This one is used by the next functions:
5425 * modest_ui_actions_on_paste - commented out
5426 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5429 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5430 TnyFolder *dest_folder,
5434 gint response = GTK_RESPONSE_OK;
5435 TnyAccount *account = NULL;
5436 TnyFolder *src_folder = NULL;
5437 TnyIterator *iter = NULL;
5438 TnyHeader *header = NULL;
5440 /* return with OK if the destination is a remote folder */
5441 if (modest_tny_folder_is_remote_folder (dest_folder))
5442 return GTK_RESPONSE_OK;
5444 /* Get source folder */
5445 iter = tny_list_create_iterator (headers);
5446 header = TNY_HEADER (tny_iterator_get_current (iter));
5448 src_folder = tny_header_get_folder (header);
5449 g_object_unref (header);
5451 g_object_unref (iter);
5453 /* if no src_folder, message may be an attahcment */
5454 if (src_folder == NULL)
5455 return GTK_RESPONSE_CANCEL;
5457 /* If the source is a local or MMC folder */
5458 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5459 g_object_unref (src_folder);
5460 return GTK_RESPONSE_OK;
5463 /* Get the account */
5464 account = tny_folder_get_account (src_folder);
5466 /* now if offline we ask the user */
5467 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5468 response = GTK_RESPONSE_OK;
5470 response = GTK_RESPONSE_CANCEL;
5473 g_object_unref (src_folder);
5474 g_object_unref (account);
5480 move_to_helper_destroyer (gpointer user_data)
5482 MoveToHelper *helper = (MoveToHelper *) user_data;
5484 /* Close the "Pasting" information banner */
5485 if (helper->banner) {
5486 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5487 g_object_unref (helper->banner);
5489 if (gtk_tree_row_reference_valid (helper->reference)) {
5490 gtk_tree_row_reference_free (helper->reference);
5491 helper->reference = NULL;
5497 move_to_cb (ModestMailOperation *mail_op,
5500 MoveToHelper *helper = (MoveToHelper *) user_data;
5501 GObject *object = modest_mail_operation_get_source (mail_op);
5503 /* Note that the operation could have failed, in that case do
5505 if (modest_mail_operation_get_status (mail_op) !=
5506 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5509 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5510 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5512 if (!modest_msg_view_window_select_next_message (self) &&
5513 !modest_msg_view_window_select_previous_message (self)) {
5514 /* No more messages to view, so close this window */
5515 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5517 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5518 gtk_tree_row_reference_valid (helper->reference)) {
5519 GtkWidget *header_view;
5521 GtkTreeSelection *sel;
5523 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5524 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5525 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5526 path = gtk_tree_row_reference_get_path (helper->reference);
5527 /* We need to unselect the previous one
5528 because we could be copying instead of
5530 gtk_tree_selection_unselect_all (sel);
5531 gtk_tree_selection_select_path (sel, path);
5532 gtk_tree_path_free (path);
5534 g_object_unref (object);
5537 /* Destroy the helper */
5538 move_to_helper_destroyer (helper);
5542 folder_move_to_cb (ModestMailOperation *mail_op,
5543 TnyFolder *new_folder,
5546 GtkWidget *folder_view;
5549 object = modest_mail_operation_get_source (mail_op);
5550 if (MODEST_IS_MAIN_WINDOW (object)) {
5551 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5552 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5553 g_object_ref (folder_view);
5554 g_object_unref (object);
5555 move_to_cb (mail_op, user_data);
5556 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5557 g_object_unref (folder_view);
5559 move_to_cb (mail_op, user_data);
5564 msgs_move_to_cb (ModestMailOperation *mail_op,
5567 move_to_cb (mail_op, user_data);
5571 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5574 GObject *win = NULL;
5575 const GError *error;
5576 TnyAccount *account = NULL;
5578 #ifndef MODEST_TOOLKIT_HILDON2
5579 ModestWindow *main_window = NULL;
5581 /* Disable next automatic folder selection */
5582 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5583 FALSE); /* don't create */
5585 /* Show notification dialog only if the main window exists */
5587 GtkWidget *folder_view = NULL;
5589 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5590 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5591 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5593 if (user_data && TNY_IS_FOLDER (user_data)) {
5594 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5595 TNY_FOLDER (user_data), FALSE);
5599 win = modest_mail_operation_get_source (mail_op);
5600 error = modest_mail_operation_get_error (mail_op);
5602 if (TNY_IS_FOLDER (user_data))
5603 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5604 else if (TNY_IS_ACCOUNT (user_data))
5605 account = g_object_ref (user_data);
5607 /* If it's not a disk full error then show a generic error */
5608 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5609 (GtkWidget *) win, (GError *) error,
5611 modest_platform_run_information_dialog ((GtkWindow *) win,
5612 _("mail_in_ui_folder_move_target_error"),
5615 g_object_unref (account);
5617 g_object_unref (win);
5621 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5630 gint pending_purges = 0;
5631 gboolean some_purged = FALSE;
5632 ModestWindow *win = MODEST_WINDOW (user_data);
5633 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5635 /* If there was any error */
5636 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5637 modest_window_mgr_unregister_header (mgr, header);
5641 /* Once the message has been retrieved for purging, we check if
5642 * it's all ok for purging */
5644 parts = tny_simple_list_new ();
5645 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5646 iter = tny_list_create_iterator (parts);
5648 while (!tny_iterator_is_done (iter)) {
5650 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5651 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5652 if (tny_mime_part_is_purged (part))
5659 g_object_unref (part);
5661 tny_iterator_next (iter);
5663 g_object_unref (iter);
5666 if (pending_purges>0) {
5668 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5670 if (response == GTK_RESPONSE_OK) {
5673 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5674 iter = tny_list_create_iterator (parts);
5675 while (!tny_iterator_is_done (iter)) {
5678 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5679 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5680 tny_mime_part_set_purged (part);
5683 g_object_unref (part);
5685 tny_iterator_next (iter);
5687 g_object_unref (iter);
5689 tny_msg_rewrite_cache (msg);
5691 gtk_widget_destroy (info);
5695 modest_window_mgr_unregister_header (mgr, header);
5697 g_object_unref (parts);
5701 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5702 ModestMainWindow *win)
5704 GtkWidget *header_view;
5705 TnyList *header_list;
5707 TnyHeaderFlags flags;
5708 ModestWindow *msg_view_window = NULL;
5711 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5713 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5714 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5716 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5718 g_warning ("%s: no header selected", __FUNCTION__);
5722 if (tny_list_get_length (header_list) == 1) {
5723 TnyIterator *iter = tny_list_create_iterator (header_list);
5724 header = TNY_HEADER (tny_iterator_get_current (iter));
5725 g_object_unref (iter);
5729 if (!header || !TNY_IS_HEADER(header)) {
5730 g_warning ("%s: header is not valid", __FUNCTION__);
5734 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5735 header, &msg_view_window);
5736 flags = tny_header_get_flags (header);
5737 if (!(flags & TNY_HEADER_FLAG_CACHED))
5740 if (msg_view_window != NULL)
5741 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5743 /* do nothing; uid was registered before, so window is probably on it's way */
5744 g_debug ("header %p has already been registered", header);
5747 ModestMailOperation *mail_op = NULL;
5748 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5749 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5750 modest_ui_actions_disk_operations_error_handler,
5752 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5753 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5755 g_object_unref (mail_op);
5758 g_object_unref (header);
5760 g_object_unref (header_list);
5764 * Checks if we need a connection to do the transfer and if the user
5765 * wants to connect to complete it
5768 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5769 TnyFolderStore *src_folder,
5771 TnyFolder *dst_folder,
5772 gboolean delete_originals,
5773 gboolean *need_connection,
5776 TnyAccount *src_account;
5777 gint uncached_msgs = 0;
5779 /* We don't need any further check if
5781 * 1- the source folder is local OR
5782 * 2- the device is already online
5784 if (!modest_tny_folder_store_is_remote (src_folder) ||
5785 tny_device_is_online (modest_runtime_get_device())) {
5786 *need_connection = FALSE;
5791 /* We must ask for a connection when
5793 * - the message(s) is not already cached OR
5794 * - the message(s) is cached but the leave_on_server setting
5795 * is FALSE (because we need to sync the source folder to
5796 * delete the message from the server (for IMAP we could do it
5797 * offline, it'll take place the next time we get a
5800 uncached_msgs = header_list_count_uncached_msgs (headers);
5801 src_account = get_account_from_folder_store (src_folder);
5802 if (uncached_msgs > 0) {
5806 *need_connection = TRUE;
5807 num_headers = tny_list_get_length (headers);
5808 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5810 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5811 GTK_RESPONSE_CANCEL) {
5817 /* The transfer is possible and the user wants to */
5820 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5821 const gchar *account_name;
5822 gboolean leave_on_server;
5824 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5825 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5828 if (leave_on_server == TRUE) {
5829 *need_connection = FALSE;
5831 *need_connection = TRUE;
5834 *need_connection = FALSE;
5839 g_object_unref (src_account);
5843 xfer_messages_error_handler (ModestMailOperation *mail_op,
5847 const GError *error;
5848 TnyAccount *account;
5850 win = modest_mail_operation_get_source (mail_op);
5851 error = modest_mail_operation_get_error (mail_op);
5853 /* We cannot get the account from the mail op as that is the
5854 source account and for checking memory full conditions we
5855 need the destination one */
5856 account = TNY_ACCOUNT (user_data);
5859 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5860 (GtkWidget *) win, (GError*) error,
5861 account, _KR("cerm_memory_card_full"))) {
5862 modest_platform_run_information_dialog ((GtkWindow *) win,
5863 _("mail_in_ui_folder_move_target_error"),
5867 g_object_unref (win);
5871 TnyFolderStore *dst_folder;
5876 * Utility function that transfer messages from both the main window
5877 * and the msg view window when using the "Move to" dialog
5880 xfer_messages_performer (gboolean canceled,
5882 GtkWindow *parent_window,
5883 TnyAccount *account,
5886 ModestWindow *win = MODEST_WINDOW (parent_window);
5887 TnyAccount *dst_account = NULL;
5888 gboolean dst_forbids_message_add = FALSE;
5889 XferMsgsHelper *helper;
5890 MoveToHelper *movehelper;
5891 ModestMailOperation *mail_op;
5893 helper = (XferMsgsHelper *) user_data;
5895 if (canceled || err) {
5896 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5897 (GtkWidget *) parent_window, err,
5899 /* Show the proper error message */
5900 modest_ui_actions_on_account_connection_error (parent_window, account);
5905 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5907 /* tinymail will return NULL for local folders it seems */
5908 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5909 modest_tny_account_get_protocol_type (dst_account),
5910 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5912 if (dst_forbids_message_add) {
5913 modest_platform_information_banner (GTK_WIDGET (win),
5915 ngettext("mail_in_ui_folder_move_target_error",
5916 "mail_in_ui_folder_move_targets_error",
5917 tny_list_get_length (helper->headers)));
5921 movehelper = g_new0 (MoveToHelper, 1);
5923 #ifndef MODEST_TOOLKIT_HILDON2
5924 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5925 _CS("ckct_nw_pasting"));
5926 if (movehelper->banner != NULL) {
5927 g_object_ref (movehelper->banner);
5928 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5932 if (MODEST_IS_MAIN_WINDOW (win)) {
5933 GtkWidget *header_view =
5934 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5935 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5936 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5939 /* Perform the mail operation */
5940 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5941 xfer_messages_error_handler,
5942 g_object_ref (dst_account),
5944 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5947 modest_mail_operation_xfer_msgs (mail_op,
5949 TNY_FOLDER (helper->dst_folder),
5954 g_object_unref (G_OBJECT (mail_op));
5957 g_object_unref (dst_account);
5958 g_object_unref (helper->dst_folder);
5959 g_object_unref (helper->headers);
5960 g_slice_free (XferMsgsHelper, helper);
5964 TnyFolder *src_folder;
5965 TnyFolderStore *dst_folder;
5966 gboolean delete_original;
5967 GtkWidget *folder_view;
5971 on_move_folder_cb (gboolean canceled,
5973 GtkWindow *parent_window,
5974 TnyAccount *account,
5977 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5978 GtkTreeSelection *sel;
5979 ModestMailOperation *mail_op = NULL;
5981 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5982 /* Note that the connection process can fail due to
5983 memory low conditions as it can not successfully
5984 store the summary */
5985 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5986 (GtkWidget*) parent_window, err,
5988 g_debug ("Error connecting when trying to move a folder");
5990 g_object_unref (G_OBJECT (info->src_folder));
5991 g_object_unref (G_OBJECT (info->dst_folder));
5996 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5997 #ifndef MODEST_TOOLKIT_HILDON2
5998 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5999 _CS("ckct_nw_pasting"));
6000 if (helper->banner != NULL) {
6001 g_object_ref (helper->banner);
6002 gtk_widget_show (GTK_WIDGET(helper->banner));
6005 /* Clean folder on header view before moving it */
6006 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6007 gtk_tree_selection_unselect_all (sel);
6009 /* Let gtk events run. We need that the folder
6010 view frees its reference to the source
6011 folder *before* issuing the mail operation
6012 so we need the signal handler of selection
6013 changed to happen before the mail
6015 while (gtk_events_pending ())
6016 gtk_main_iteration (); */
6019 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6020 modest_ui_actions_move_folder_error_handler,
6021 g_object_ref (info->dst_folder), g_object_unref);
6022 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6025 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6026 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6027 TNY_FOLDER (info->dst_folder), TRUE);
6029 modest_mail_operation_xfer_folder (mail_op,
6030 TNY_FOLDER (info->src_folder),
6032 info->delete_original,
6035 g_object_unref (G_OBJECT (info->src_folder));
6037 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6040 /* Unref mail operation */
6041 g_object_unref (G_OBJECT (mail_op));
6042 g_object_unref (G_OBJECT (info->dst_folder));
6047 get_account_from_folder_store (TnyFolderStore *folder_store)
6049 if (TNY_IS_ACCOUNT (folder_store))
6050 return g_object_ref (folder_store);
6052 return tny_folder_get_account (TNY_FOLDER (folder_store));
6056 * UI handler for the "Move to" action when invoked from the
6060 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6061 GtkWidget *folder_view,
6062 TnyFolderStore *dst_folder,
6063 ModestMainWindow *win)
6065 ModestHeaderView *header_view = NULL;
6066 TnyFolderStore *src_folder = NULL;
6068 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6070 /* Get the source folder */
6071 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6073 /* Get header view */
6074 header_view = (ModestHeaderView *)
6075 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6077 /* Get folder or messages to transfer */
6078 if (gtk_widget_is_focus (folder_view)) {
6079 gboolean do_xfer = TRUE;
6081 /* Allow only to transfer folders to the local root folder */
6082 if (TNY_IS_ACCOUNT (dst_folder) &&
6083 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6084 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6086 } else if (!TNY_IS_FOLDER (src_folder)) {
6087 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6092 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6093 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6095 info->src_folder = g_object_ref (src_folder);
6096 info->dst_folder = g_object_ref (dst_folder);
6097 info->delete_original = TRUE;
6098 info->folder_view = folder_view;
6100 connect_info->callback = on_move_folder_cb;
6101 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6102 connect_info->data = info;
6104 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6105 TNY_FOLDER_STORE (src_folder),
6108 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6111 headers = modest_header_view_get_selected_headers(header_view);
6113 /* Transfer the messages */
6114 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6115 headers, TNY_FOLDER (dst_folder));
6117 g_object_unref (headers);
6121 g_object_unref (src_folder);
6124 #ifdef MODEST_TOOLKIT_HILDON2
6126 * UI handler for the "Move to" action when invoked from the
6127 * ModestFolderWindow
6130 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6131 TnyFolderStore *dst_folder,
6135 TnyFolderStore *src_folder = NULL;
6136 TnyIterator *iterator;
6138 if (tny_list_get_length (selection) != 1)
6141 iterator = tny_list_create_iterator (selection);
6142 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6143 g_object_unref (iterator);
6146 gboolean do_xfer = TRUE;
6148 /* Allow only to transfer folders to the local root folder */
6149 if (TNY_IS_ACCOUNT (dst_folder) &&
6150 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6151 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6154 modest_platform_run_information_dialog (win,
6155 _("mail_in_ui_folder_move_target_error"),
6157 } else if (!TNY_IS_FOLDER (src_folder)) {
6158 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6163 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6164 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6166 info->src_folder = g_object_ref (src_folder);
6167 info->dst_folder = g_object_ref (dst_folder);
6168 info->delete_original = TRUE;
6169 info->folder_view = folder_view;
6171 connect_info->callback = on_move_folder_cb;
6172 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6173 connect_info->data = info;
6175 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6176 TNY_FOLDER_STORE (src_folder),
6181 g_object_unref (src_folder);
6187 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6188 TnyFolder *src_folder,
6190 TnyFolder *dst_folder)
6192 gboolean need_connection = TRUE;
6193 gboolean do_xfer = TRUE;
6194 XferMsgsHelper *helper;
6196 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6197 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6198 g_return_if_fail (TNY_IS_LIST (headers));
6200 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6201 headers, TNY_FOLDER (dst_folder),
6202 TRUE, &need_connection,
6205 /* If we don't want to transfer just return */
6209 /* Create the helper */
6210 helper = g_slice_new (XferMsgsHelper);
6211 helper->dst_folder = g_object_ref (dst_folder);
6212 helper->headers = g_object_ref (headers);
6214 if (need_connection) {
6215 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6216 connect_info->callback = xfer_messages_performer;
6217 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6218 connect_info->data = helper;
6220 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6221 TNY_FOLDER_STORE (src_folder),
6224 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6225 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6226 src_account, helper);
6227 g_object_unref (src_account);
6232 * UI handler for the "Move to" action when invoked from the
6233 * ModestMsgViewWindow
6236 modest_ui_actions_on_window_move_to (GtkAction *action,
6238 TnyFolderStore *dst_folder,
6241 TnyFolder *src_folder = NULL;
6243 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6246 TnyHeader *header = NULL;
6249 iter = tny_list_create_iterator (headers);
6250 header = (TnyHeader *) tny_iterator_get_current (iter);
6251 src_folder = tny_header_get_folder (header);
6253 /* Transfer the messages */
6254 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6256 TNY_FOLDER (dst_folder));
6259 g_object_unref (header);
6260 g_object_unref (iter);
6261 g_object_unref (src_folder);
6266 modest_ui_actions_on_move_to (GtkAction *action,
6269 modest_ui_actions_on_edit_mode_move_to (win);
6273 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6275 GtkWidget *dialog = NULL;
6276 MoveToInfo *helper = NULL;
6277 TnyList *list_to_move;
6279 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6281 #ifndef MODEST_TOOLKIT_HILDON2
6282 /* Get the main window if exists */
6283 ModestMainWindow *main_window;
6284 if (MODEST_IS_MAIN_WINDOW (win))
6285 main_window = MODEST_MAIN_WINDOW (win);
6288 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6289 FALSE)); /* don't create */
6292 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6297 if (tny_list_get_length (list_to_move) < 1) {
6298 g_object_unref (list_to_move);
6302 /* Create and run the dialog */
6303 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6304 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6305 GTK_WINDOW (dialog),
6309 helper = g_slice_new0 (MoveToInfo);
6310 helper->list = list_to_move;
6313 /* Listen to response signal */
6314 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6316 /* Show the dialog */
6317 gtk_widget_show (dialog);
6323 * Calls #HeadersFunc for each header already selected in the main
6324 * window or the message currently being shown in the msg view window
6327 do_headers_action (ModestWindow *win,
6331 TnyList *headers_list = NULL;
6332 TnyIterator *iter = NULL;
6333 TnyHeader *header = NULL;
6334 TnyFolder *folder = NULL;
6337 headers_list = get_selected_headers (win);
6341 /* Get the folder */
6342 iter = tny_list_create_iterator (headers_list);
6343 header = TNY_HEADER (tny_iterator_get_current (iter));
6345 folder = tny_header_get_folder (header);
6346 g_object_unref (header);
6349 /* Call the function for each header */
6350 while (!tny_iterator_is_done (iter)) {
6351 header = TNY_HEADER (tny_iterator_get_current (iter));
6352 func (header, win, user_data);
6353 g_object_unref (header);
6354 tny_iterator_next (iter);
6357 /* Trick: do a poke status in order to speed up the signaling
6360 tny_folder_poke_status (folder);
6361 g_object_unref (folder);
6365 g_object_unref (iter);
6366 g_object_unref (headers_list);
6370 modest_ui_actions_view_attachment (GtkAction *action,
6371 ModestWindow *window)
6373 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6374 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6376 /* not supported window for this action */
6377 g_return_if_reached ();
6382 modest_ui_actions_save_attachments (GtkAction *action,
6383 ModestWindow *window)
6385 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6387 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6390 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6392 /* not supported window for this action */
6393 g_return_if_reached ();
6398 modest_ui_actions_remove_attachments (GtkAction *action,
6399 ModestWindow *window)
6401 if (MODEST_IS_MAIN_WINDOW (window)) {
6402 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6403 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6404 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6406 /* not supported window for this action */
6407 g_return_if_reached ();
6412 modest_ui_actions_on_settings (GtkAction *action,
6417 dialog = modest_platform_get_global_settings_dialog ();
6418 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6419 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6420 gtk_widget_show_all (dialog);
6422 gtk_dialog_run (GTK_DIALOG (dialog));
6424 gtk_widget_destroy (dialog);
6428 modest_ui_actions_on_help (GtkAction *action,
6431 /* Help app is not available at all in fremantle */
6432 #ifndef MODEST_TOOLKIT_HILDON2
6433 const gchar *help_id;
6435 g_return_if_fail (win && GTK_IS_WINDOW(win));
6437 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6440 modest_platform_show_help (GTK_WINDOW (win), help_id);
6445 modest_ui_actions_on_csm_help (GtkAction *action,
6448 /* Help app is not available at all in fremantle */
6449 #ifndef MODEST_TOOLKIT_HILDON2
6451 const gchar* help_id = NULL;
6452 GtkWidget *folder_view;
6453 TnyFolderStore *folder_store;
6455 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6457 /* Get selected folder */
6458 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6459 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6460 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6462 /* Switch help_id */
6463 if (folder_store && TNY_IS_FOLDER (folder_store))
6464 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6467 g_object_unref (folder_store);
6470 modest_platform_show_help (GTK_WINDOW (win), help_id);
6472 modest_ui_actions_on_help (action, win);
6477 retrieve_contents_cb (ModestMailOperation *mail_op,
6484 /* We only need this callback to show an error in case of
6485 memory low condition */
6486 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6487 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6492 retrieve_msg_contents_performer (gboolean canceled,
6494 GtkWindow *parent_window,
6495 TnyAccount *account,
6498 ModestMailOperation *mail_op;
6499 TnyList *headers = TNY_LIST (user_data);
6501 if (err || canceled) {
6502 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6503 (GtkWidget *) parent_window, err,
6508 /* Create mail operation */
6509 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6510 modest_ui_actions_disk_operations_error_handler,
6512 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6513 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6516 g_object_unref (mail_op);
6518 g_object_unref (headers);
6519 g_object_unref (account);
6523 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6524 ModestWindow *window)
6526 TnyList *headers = NULL;
6527 TnyAccount *account = NULL;
6528 TnyIterator *iter = NULL;
6529 TnyHeader *header = NULL;
6530 TnyFolder *folder = NULL;
6533 headers = get_selected_headers (window);
6537 /* Pick the account */
6538 iter = tny_list_create_iterator (headers);
6539 header = TNY_HEADER (tny_iterator_get_current (iter));
6540 folder = tny_header_get_folder (header);
6541 account = tny_folder_get_account (folder);
6542 g_object_unref (folder);
6543 g_object_unref (header);
6544 g_object_unref (iter);
6546 /* Connect and perform the message retrieval */
6547 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6548 g_object_ref (account),
6549 retrieve_msg_contents_performer,
6550 g_object_ref (headers));
6553 g_object_unref (account);
6554 g_object_unref (headers);
6558 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6560 g_return_if_fail (MODEST_IS_WINDOW (window));
6563 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6567 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6569 g_return_if_fail (MODEST_IS_WINDOW (window));
6572 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6576 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6577 ModestWindow *window)
6579 g_return_if_fail (MODEST_IS_WINDOW (window));
6582 modest_ui_actions_check_menu_dimming_rules (window);
6586 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6587 ModestWindow *window)
6589 g_return_if_fail (MODEST_IS_WINDOW (window));
6592 modest_ui_actions_check_menu_dimming_rules (window);
6596 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6597 ModestWindow *window)
6599 g_return_if_fail (MODEST_IS_WINDOW (window));
6602 modest_ui_actions_check_menu_dimming_rules (window);
6606 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6607 ModestWindow *window)
6609 g_return_if_fail (MODEST_IS_WINDOW (window));
6612 modest_ui_actions_check_menu_dimming_rules (window);
6616 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6617 ModestWindow *window)
6619 g_return_if_fail (MODEST_IS_WINDOW (window));
6622 modest_ui_actions_check_menu_dimming_rules (window);
6626 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6627 ModestWindow *window)
6629 g_return_if_fail (MODEST_IS_WINDOW (window));
6632 modest_ui_actions_check_menu_dimming_rules (window);
6636 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6637 ModestWindow *window)
6639 g_return_if_fail (MODEST_IS_WINDOW (window));
6642 modest_ui_actions_check_menu_dimming_rules (window);
6646 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6647 ModestWindow *window)
6649 g_return_if_fail (MODEST_IS_WINDOW (window));
6652 modest_ui_actions_check_menu_dimming_rules (window);
6656 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6657 ModestWindow *window)
6659 g_return_if_fail (MODEST_IS_WINDOW (window));
6662 modest_ui_actions_check_menu_dimming_rules (window);
6666 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6668 g_return_if_fail (MODEST_IS_WINDOW (window));
6670 /* we check for low-mem; in that case, show a warning, and don't allow
6673 if (modest_platform_check_memory_low (window, TRUE))
6676 modest_platform_show_search_messages (GTK_WINDOW (window));
6680 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6682 g_return_if_fail (MODEST_IS_WINDOW (win));
6685 /* we check for low-mem; in that case, show a warning, and don't allow
6686 * for the addressbook
6688 if (modest_platform_check_memory_low (win, TRUE))
6692 modest_platform_show_addressbook (GTK_WINDOW (win));
6697 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6698 ModestWindow *window)
6701 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6703 if (GTK_IS_TOGGLE_ACTION (action))
6704 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6708 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6713 on_send_receive_finished (ModestMailOperation *mail_op,
6716 GtkWidget *header_view, *folder_view;
6717 TnyFolderStore *folder_store;
6718 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6720 /* Set send/receive operation finished */
6721 modest_main_window_notify_send_receive_completed (main_win);
6723 /* Don't refresh the current folder if there were any errors */
6724 if (modest_mail_operation_get_status (mail_op) !=
6725 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6728 /* Refresh the current folder if we're viewing a window. We do
6729 this because the user won't be able to see the new mails in
6730 the selected folder after a Send&Receive because it only
6731 performs a poke_status, i.e, only the number of read/unread
6732 messages is updated, but the new headers are not
6734 folder_view = modest_main_window_get_child_widget (main_win,
6735 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6739 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6741 /* Do not need to refresh INBOX again because the
6742 update_account does it always automatically */
6743 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6744 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6745 ModestMailOperation *refresh_op;
6747 header_view = modest_main_window_get_child_widget (main_win,
6748 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6750 /* We do not need to set the contents style
6751 because it hasn't changed. We also do not
6752 need to save the widget status. Just force
6754 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6755 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6756 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6757 folder_refreshed_cb, main_win);
6758 g_object_unref (refresh_op);
6762 g_object_unref (folder_store);
6767 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6773 const gchar* server_name = NULL;
6774 TnyTransportAccount *transport;
6775 gchar *message = NULL;
6776 ModestProtocol *protocol;
6778 /* Don't show anything if the user cancelled something or the
6779 * send receive request is not interactive. Authentication
6780 * errors are managed by the account store so no need to show
6781 * a dialog here again */
6782 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6783 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6784 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6788 /* Get the server name. Note that we could be using a
6789 connection specific transport account */
6790 transport = (TnyTransportAccount *)
6791 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6793 ModestTnyAccountStore *acc_store;
6794 const gchar *acc_name;
6795 TnyTransportAccount *conn_specific;
6797 acc_store = modest_runtime_get_account_store();
6798 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6799 conn_specific = (TnyTransportAccount *)
6800 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6801 if (conn_specific) {
6802 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6803 g_object_unref (conn_specific);
6805 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6807 g_object_unref (transport);
6811 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6812 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6813 tny_account_get_proto (TNY_ACCOUNT (transport)));
6815 g_warning ("%s: Account with no proto", __FUNCTION__);
6819 /* Show the appropriate message text for the GError: */
6820 switch (err->code) {
6821 case TNY_SERVICE_ERROR_CONNECT:
6822 message = modest_protocol_get_translation (protocol,
6823 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6826 case TNY_SERVICE_ERROR_SEND:
6827 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6829 case TNY_SERVICE_ERROR_UNAVAILABLE:
6830 message = modest_protocol_get_translation (protocol,
6831 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6835 g_warning ("%s: unexpected ERROR %d",
6836 __FUNCTION__, err->code);
6837 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6841 modest_platform_run_information_dialog (NULL, message, FALSE);
6846 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6851 ModestWindow *top_window = NULL;
6852 ModestWindowMgr *mgr = NULL;
6853 GtkWidget *header_view = NULL;
6854 TnyFolder *selected_folder = NULL;
6855 TnyFolderType folder_type;
6857 mgr = modest_runtime_get_window_mgr ();
6858 top_window = modest_window_mgr_get_current_top (mgr);
6863 #ifndef MODEST_TOOLKIT_HILDON2
6864 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6865 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6866 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6869 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6870 header_view = (GtkWidget *)
6871 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6875 /* Get selected folder */
6877 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6878 if (!selected_folder)
6881 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6882 #if GTK_CHECK_VERSION(2, 8, 0)
6883 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6884 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6885 GtkTreeViewColumn *tree_column;
6887 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6888 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6890 gtk_tree_view_column_queue_resize (tree_column);
6892 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6893 gtk_widget_queue_draw (header_view);
6896 #ifndef MODEST_TOOLKIT_HILDON2
6897 /* Rerun dimming rules, because the message could become deletable for example */
6898 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6899 MODEST_DIMMING_RULES_TOOLBAR);
6900 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6901 MODEST_DIMMING_RULES_MENU);
6905 g_object_unref (selected_folder);
6909 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6910 TnyAccount *account)
6912 ModestProtocolType protocol_type;
6913 ModestProtocol *protocol;
6914 gchar *error_note = NULL;
6916 protocol_type = modest_tny_account_get_protocol_type (account);
6917 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6920 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6921 if (error_note == NULL) {
6922 g_warning ("%s: This should not be reached", __FUNCTION__);
6924 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6925 g_free (error_note);
6930 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6934 TnyFolderStore *folder = NULL;
6935 TnyAccount *account = NULL;
6936 ModestProtocolType proto;
6937 ModestProtocol *protocol;
6938 TnyHeader *header = NULL;
6940 if (MODEST_IS_MAIN_WINDOW (win)) {
6941 GtkWidget *header_view;
6942 TnyList* headers = NULL;
6944 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6945 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6946 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6947 if (!headers || tny_list_get_length (headers) == 0) {
6949 g_object_unref (headers);
6952 iter = tny_list_create_iterator (headers);
6953 header = TNY_HEADER (tny_iterator_get_current (iter));
6954 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6955 g_object_unref (iter);
6956 g_object_unref (headers);
6957 #ifdef MODEST_TOOLKIT_HILDON2
6958 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6959 GtkWidget *header_view;
6960 TnyList* headers = NULL;
6962 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6963 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6964 if (!headers || tny_list_get_length (headers) == 0) {
6966 g_object_unref (headers);
6969 iter = tny_list_create_iterator (headers);
6970 header = TNY_HEADER (tny_iterator_get_current (iter));
6972 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6974 g_warning ("List should contain headers");
6976 g_object_unref (iter);
6977 g_object_unref (headers);
6979 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6980 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6982 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6985 if (!header || !folder)
6988 /* Get the account type */
6989 account = tny_folder_get_account (TNY_FOLDER (folder));
6990 proto = modest_tny_account_get_protocol_type (account);
6991 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6994 subject = tny_header_dup_subject (header);
6995 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6999 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7005 g_object_unref (account);
7007 g_object_unref (folder);
7009 g_object_unref (header);
7015 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7016 const gchar *account_name,
7017 const gchar *account_title)
7019 ModestAccountMgr *account_mgr;
7022 ModestProtocol *protocol;
7023 gboolean removed = FALSE;
7025 g_return_val_if_fail (account_name, FALSE);
7026 g_return_val_if_fail (account_title, FALSE);
7028 account_mgr = modest_runtime_get_account_mgr();
7030 /* The warning text depends on the account type: */
7031 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7032 modest_account_mgr_get_store_protocol (account_mgr,
7034 txt = modest_protocol_get_translation (protocol,
7035 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7038 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7040 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7044 if (response == GTK_RESPONSE_OK) {
7045 /* Remove account. If it succeeds then it also removes
7046 the account from the ModestAccountView: */
7047 gboolean is_default = FALSE;
7048 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7049 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7051 g_free (default_account_name);
7053 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7055 /* Close all email notifications, we cannot
7056 distinguish if the notification belongs to
7057 this account or not, so for safety reasons
7058 we remove them all */
7059 modest_platform_remove_new_mail_notifications (FALSE);
7061 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7068 on_fetch_images_performer (gboolean canceled,
7070 GtkWindow *parent_window,
7071 TnyAccount *account,
7074 if (err || canceled) {
7075 /* Show an unable to retrieve images ??? */
7079 /* Note that the user could have closed the window while connecting */
7080 if (GTK_WIDGET_VISIBLE (parent_window))
7081 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7082 g_object_unref ((GObject *) user_data);
7086 modest_ui_actions_on_fetch_images (GtkAction *action,
7087 ModestWindow *window)
7089 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7091 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7093 on_fetch_images_performer,
7094 g_object_ref (window));
7098 modest_ui_actions_on_reload_message (const gchar *msg_id)
7100 ModestWindow *window = NULL;
7102 g_return_if_fail (msg_id && msg_id[0] != '\0');
7103 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7109 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7112 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7115 /** Check whether any connections are active, and cancel them if
7117 * Returns TRUE is there was no problem,
7118 * or if an operation was cancelled so we can continue.
7119 * Returns FALSE if the user chose to cancel his request instead.
7123 modest_ui_actions_check_for_active_account (ModestWindow *self,
7124 const gchar* account_name)
7126 ModestTnySendQueue *send_queue;
7127 ModestTnyAccountStore *acc_store;
7128 ModestMailOperationQueue* queue;
7129 TnyConnectionStatus store_conn_status;
7130 TnyAccount *store_account = NULL, *transport_account = NULL;
7131 gboolean retval = TRUE, sending = FALSE;
7133 acc_store = modest_runtime_get_account_store ();
7134 queue = modest_runtime_get_mail_operation_queue ();
7137 modest_tny_account_store_get_server_account (acc_store,
7139 TNY_ACCOUNT_TYPE_STORE);
7141 /* This could happen if the account was deleted before the
7142 call to this function */
7147 modest_tny_account_store_get_server_account (acc_store,
7149 TNY_ACCOUNT_TYPE_TRANSPORT);
7151 /* This could happen if the account was deleted before the
7152 call to this function */
7153 if (!transport_account) {
7154 g_object_unref (store_account);
7158 /* If the transport account was not used yet, then the send
7159 queue could not exist (it's created on demand) */
7160 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7161 if (TNY_IS_SEND_QUEUE (send_queue))
7162 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7164 store_conn_status = tny_account_get_connection_status (store_account);
7165 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7168 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7169 _("emev_nc_disconnect_account"));
7170 if (response == GTK_RESPONSE_OK) {
7179 /* FIXME: We should only cancel those of this account */
7180 modest_mail_operation_queue_cancel_all (queue);
7182 /* Also disconnect the account */
7183 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7184 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7185 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7189 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7195 g_object_unref (store_account);
7196 g_object_unref (transport_account);