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-gtk.h>
56 #include <modest-header-window.h>
57 #include <modest-folder-window.h>
58 #include <modest-maemo-utils.h>
60 #include "modest-utils.h"
61 #include "widgets/modest-connection-specific-smtp-window.h"
62 #include "widgets/modest-ui-constants.h"
63 #include <widgets/modest-main-window.h>
64 #include <widgets/modest-msg-view-window.h>
65 #include <widgets/modest-account-view-window.h>
66 #include <widgets/modest-details-dialog.h>
67 #include <widgets/modest-attachments-view.h>
68 #include "widgets/modest-folder-view.h"
69 #include "widgets/modest-global-settings-dialog.h"
70 #include "modest-account-mgr-helpers.h"
71 #include "modest-mail-operation.h"
72 #include "modest-text-utils.h"
73 #include <modest-widget-memory.h>
74 #include <tny-error.h>
75 #include <tny-simple-list.h>
76 #include <tny-msg-view.h>
77 #include <tny-device.h>
78 #include <tny-merge-folder.h>
80 #include <gtkhtml/gtkhtml.h>
82 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
104 GtkWidget *parent_window;
106 } ReplyForwardHelper;
108 typedef struct _MoveToHelper {
109 GtkTreeRowReference *reference;
113 typedef struct _PasteAsAttachmentHelper {
114 ModestMsgEditWindow *window;
116 } PasteAsAttachmentHelper;
124 * The do_headers_action uses this kind of functions to perform some
125 * action to each member of a list of headers
127 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
129 static void do_headers_action (ModestWindow *win,
133 static void open_msg_cb (ModestMailOperation *mail_op,
140 static void reply_forward_cb (ModestMailOperation *mail_op,
147 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
149 #ifndef MODEST_TOOLKIT_HILDON2
150 static void folder_refreshed_cb (ModestMailOperation *mail_op,
154 static void on_send_receive_finished (ModestMailOperation *mail_op,
158 static gint header_list_count_uncached_msgs (TnyList *header_list);
160 static gboolean connect_to_get_msg (ModestWindow *win,
161 gint num_of_uncached_msgs,
162 TnyAccount *account);
164 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
166 static void do_create_folder (GtkWindow *window,
167 TnyFolderStore *parent_folder,
168 const gchar *suggested_name);
170 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
172 #ifndef MODEST_TOOLKIT_HILDON2
173 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
174 GtkWidget *folder_view,
175 TnyFolderStore *dst_folder,
176 ModestMainWindow *win);
179 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
180 TnyFolderStore *dst_folder,
185 static void modest_ui_actions_on_window_move_to (GtkAction *action,
186 TnyList *list_to_move,
187 TnyFolderStore *dst_folder,
191 * This function checks whether a TnyFolderStore is a pop account
194 remote_folder_has_leave_on_server (TnyFolderStore *folder)
199 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
201 account = get_account_from_folder_store (folder);
202 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
203 modest_tny_account_get_protocol_type (account)));
204 g_object_unref (account);
209 /* FIXME: this should be merged with the similar code in modest-account-view-window */
210 /* Show the account creation wizard dialog.
211 * returns: TRUE if an account was created. FALSE if the user cancelled.
214 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
216 gboolean result = FALSE;
218 gint dialog_response;
220 /* there is no such wizard yet */
221 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
222 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
224 #ifndef MODEST_TOOLKIT_HILDON2
225 /* always present a main window in the background
226 * we do it here, so we cannot end up with two wizards (as this
227 * function might be called in modest_window_mgr_get_main_window as well */
229 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
230 TRUE); /* create if not existent */
234 ModestWindowMgr *mgr;
236 mgr = modest_runtime_get_window_mgr ();
238 window_list = modest_window_mgr_get_window_list (mgr);
239 if (window_list == NULL) {
240 win = MODEST_WINDOW (modest_accounts_window_new ());
241 if (modest_window_mgr_register_window (mgr, win, NULL)) {
242 gtk_widget_show_all (GTK_WIDGET (win));
244 gtk_widget_destroy (GTK_WIDGET (win));
249 g_list_free (window_list);
255 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
257 /* make sure the mainwindow is visible. We need to present the
258 wizard again to give it the focus back. show_all are needed
259 in order to get the widgets properly drawn (MainWindow main
260 paned won't be in its right position and the dialog will be
262 #ifndef MODEST_TOOLKIT_HILDON2
263 gtk_widget_show_all (GTK_WIDGET (win));
264 gtk_widget_show_all (GTK_WIDGET (wizard));
265 gtk_window_present (GTK_WINDOW (win));
266 gtk_window_present (GTK_WINDOW (wizard));
269 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
270 gtk_widget_destroy (GTK_WIDGET (wizard));
271 if (gtk_events_pending ())
272 gtk_main_iteration ();
274 if (dialog_response == GTK_RESPONSE_CANCEL) {
277 /* Check whether an account was created: */
278 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
285 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
288 const gchar *authors[] = {
289 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
292 about = gtk_about_dialog_new ();
293 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
294 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
295 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
296 _("Copyright (c) 2006, Nokia Corporation\n"
297 "All rights reserved."));
298 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
299 _("a modest e-mail client\n\n"
300 "design and implementation: Dirk-Jan C. Binnema\n"
301 "contributions from the fine people at KC and Ig\n"
302 "uses the tinymail email framework written by Philip van Hoof"));
303 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
304 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
305 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
306 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
308 gtk_dialog_run (GTK_DIALOG (about));
309 gtk_widget_destroy(about);
313 * Gets the list of currently selected messages. If the win is the
314 * main window, then it returns a newly allocated list of the headers
315 * selected in the header view. If win is the msg view window, then
316 * the value returned is a list with just a single header.
318 * The caller of this funcion must free the list.
321 get_selected_headers (ModestWindow *win)
323 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
324 /* for MsgViewWindows, we simply return a list with one element */
326 TnyList *list = NULL;
328 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
329 if (header != NULL) {
330 list = tny_simple_list_new ();
331 tny_list_prepend (list, G_OBJECT(header));
332 g_object_unref (G_OBJECT(header));
336 #ifndef MODEST_TOOLKIT_HILDON2
337 } else if (MODEST_IS_MAIN_WINDOW(win)) {
338 GtkWidget *header_view;
340 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
341 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
342 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
344 } else if (MODEST_IS_HEADER_WINDOW (win)) {
345 GtkWidget *header_view;
347 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
348 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
355 #ifndef MODEST_TOOLKIT_HILDON2
356 static GtkTreeRowReference *
357 get_next_after_selected_headers (ModestHeaderView *header_view)
359 GtkTreeSelection *sel;
360 GList *selected_rows, *node;
362 GtkTreeRowReference *result;
365 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
366 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
367 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
369 if (selected_rows == NULL)
372 node = g_list_last (selected_rows);
373 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
374 gtk_tree_path_next (path);
376 result = gtk_tree_row_reference_new (model, path);
378 gtk_tree_path_free (path);
379 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
380 g_list_free (selected_rows);
387 headers_action_mark_as_read (TnyHeader *header,
391 TnyHeaderFlags flags;
393 g_return_if_fail (TNY_IS_HEADER(header));
395 flags = tny_header_get_flags (header);
396 if (flags & TNY_HEADER_FLAG_SEEN) return;
397 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
401 headers_action_mark_as_unread (TnyHeader *header,
405 TnyHeaderFlags flags;
407 g_return_if_fail (TNY_IS_HEADER(header));
409 flags = tny_header_get_flags (header);
410 if (flags & TNY_HEADER_FLAG_SEEN) {
411 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
415 /** After deleing a message that is currently visible in a window,
416 * show the next message from the list, or close the window if there are no more messages.
419 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
421 /* Close msg view window or select next */
422 if (!modest_msg_view_window_select_next_message (win) &&
423 !modest_msg_view_window_select_previous_message (win)) {
425 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
431 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
433 modest_ui_actions_on_edit_mode_delete_message (win);
437 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
439 TnyList *header_list = NULL;
440 TnyIterator *iter = NULL;
441 TnyHeader *header = NULL;
442 gchar *message = NULL;
445 ModestWindowMgr *mgr;
446 gboolean retval = TRUE;
448 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
450 #ifndef MODEST_TOOLKIT_HILDON2
451 /* Check first if the header view has the focus */
452 if (MODEST_IS_MAIN_WINDOW (win)) {
453 GtkWidget *header_view = NULL;
456 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
457 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
458 if (!gtk_widget_is_focus (header_view))
462 /* Get the headers, either from the header view (if win is the main window),
463 * or from the message view window: */
464 header_list = get_selected_headers (win);
465 if (!header_list) return FALSE;
467 /* Check if any of the headers are already opened, or in the process of being opened */
468 #ifndef MODEST_TOOLKIT_HILDON2
469 if (MODEST_IS_MAIN_WINDOW (win)) {
470 gint opened_headers = 0;
472 iter = tny_list_create_iterator (header_list);
473 mgr = modest_runtime_get_window_mgr ();
474 while (!tny_iterator_is_done (iter)) {
475 header = TNY_HEADER (tny_iterator_get_current (iter));
477 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
479 g_object_unref (header);
481 tny_iterator_next (iter);
483 g_object_unref (iter);
485 if (opened_headers > 0) {
488 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
491 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
494 g_object_unref (header_list);
501 if (tny_list_get_length(header_list) == 1) {
502 iter = tny_list_create_iterator (header_list);
503 header = TNY_HEADER (tny_iterator_get_current (iter));
506 subject = tny_header_dup_subject (header);
508 subject = g_strdup (_("mail_va_no_subject"));
509 desc = g_strdup_printf ("%s", subject);
511 g_object_unref (header);
514 g_object_unref (iter);
516 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
517 tny_list_get_length(header_list)), desc);
519 /* Confirmation dialog */
520 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
523 if (response == GTK_RESPONSE_OK) {
524 GtkTreeSelection *sel = NULL;
525 GList *sel_list = NULL;
526 ModestMailOperation *mail_op = NULL;
528 /* Find last selected row */
529 #ifndef MODEST_TOOLKIT_HILDON2
530 if (MODEST_IS_MAIN_WINDOW (win)) {
532 ModestWindowMgr *mgr = NULL;
533 GtkTreeModel *model = NULL;
534 GtkTreeRowReference *next_row_reference = NULL, *prev_row_reference = NULL;
535 GtkTreePath *next_path = NULL, *prev_path = NULL;
537 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
538 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
539 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
540 for (tmp=sel_list; tmp; tmp=tmp->next) {
541 if (tmp->next == NULL) {
542 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
543 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
545 gtk_tree_path_prev (prev_path);
546 gtk_tree_path_next (next_path);
548 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
549 next_row_reference = gtk_tree_row_reference_new (model, next_path);
555 /* Disable window dimming management */
556 modest_window_disable_dimming (win);
558 /* Remove each header. If it's a view window header_view == NULL */
559 mail_op = modest_mail_operation_new ((GObject *) win);
560 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
562 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
563 g_object_unref (mail_op);
565 /* Enable window dimming management */
567 gtk_tree_selection_unselect_all (sel);
569 modest_window_enable_dimming (win);
571 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
572 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
574 /* Get main window */
575 mgr = modest_runtime_get_window_mgr ();
576 #ifndef MODEST_TOOLKIT_HILDON2
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);
598 /* Update toolbar dimming state */
599 modest_ui_actions_check_menu_dimming_rules (win);
600 modest_ui_actions_check_toolbar_dimming_rules (win);
603 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
604 g_list_free (sel_list);
613 g_object_unref (header_list);
621 /* delete either message or folder, based on where we are */
623 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
625 g_return_if_fail (MODEST_IS_WINDOW(win));
627 /* Check first if the header view has the focus */
628 #ifndef MODEST_TOOLKIT_HILDON2
629 if (MODEST_IS_MAIN_WINDOW (win)) {
631 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
632 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
633 if (gtk_widget_is_focus (w)) {
634 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
639 modest_ui_actions_on_delete_message (action, win);
643 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
645 ModestWindowMgr *mgr = NULL;
647 #ifdef MODEST_PLATFORM_MAEMO
648 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
649 #endif /* MODEST_PLATFORM_MAEMO */
651 g_debug ("closing down, clearing %d item(s) from operation queue",
652 modest_mail_operation_queue_num_elements
653 (modest_runtime_get_mail_operation_queue()));
655 /* cancel all outstanding operations */
656 modest_mail_operation_queue_cancel_all
657 (modest_runtime_get_mail_operation_queue());
659 g_debug ("queue has been cleared");
662 /* Check if there are opened editing windows */
663 mgr = modest_runtime_get_window_mgr ();
664 modest_window_mgr_close_all_windows (mgr);
666 /* note: when modest-tny-account-store is finalized,
667 it will automatically set all network connections
670 /* gtk_main_quit (); */
674 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
678 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
680 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
681 /* gtk_widget_destroy (GTK_WIDGET (win)); */
682 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
683 /* gboolean ret_value; */
684 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
685 /* } else if (MODEST_IS_WINDOW (win)) { */
686 /* gtk_widget_destroy (GTK_WIDGET (win)); */
688 /* g_return_if_reached (); */
693 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
695 if (MODEST_IS_MSG_VIEW_WINDOW (win))
696 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
697 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
698 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
702 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
704 GtkClipboard *clipboard = NULL;
705 gchar *selection = NULL;
707 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
708 selection = gtk_clipboard_wait_for_text (clipboard);
711 modest_address_book_add_address (selection, (GtkWindow *) win);
717 modest_ui_actions_on_new_account (GtkAction *action,
718 ModestWindow *window)
720 if (!modest_ui_actions_run_account_setup_wizard (window)) {
721 g_debug ("%s: wizard was already running", __FUNCTION__);
726 modest_ui_actions_on_accounts (GtkAction *action,
729 /* This is currently only implemented for Maemo */
730 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
731 if (!modest_ui_actions_run_account_setup_wizard (win))
732 g_debug ("%s: wizard was already running", __FUNCTION__);
736 /* Show the list of accounts */
737 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
739 /* The accounts dialog must be modal */
740 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
741 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
746 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
748 /* This is currently only implemented for Maemo,
749 * because it requires an API (libconic) to detect different connection
752 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
754 /* Create the window if necessary: */
755 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
756 modest_connection_specific_smtp_window_fill_with_connections (
757 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
758 modest_runtime_get_account_mgr());
760 /* Show the window: */
761 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
762 GTK_WINDOW (specific_window), (GtkWindow *) win);
763 gtk_widget_show (specific_window);
764 #endif /* !MODEST_TOOLKIT_GTK */
768 count_part_size (const gchar *part)
770 GnomeVFSURI *vfs_uri;
771 gchar *escaped_filename;
773 GnomeVFSFileInfo *info;
776 /* Estimation of attachment size if we cannot get it from file info */
779 vfs_uri = gnome_vfs_uri_new (part);
781 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
782 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
783 g_free (escaped_filename);
784 gnome_vfs_uri_unref (vfs_uri);
786 info = gnome_vfs_file_info_new ();
788 if (gnome_vfs_get_file_info (part,
790 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
792 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
797 gnome_vfs_file_info_unref (info);
803 count_parts_size (GSList *parts)
808 for (node = parts; node != NULL; node = g_slist_next (node)) {
809 result += count_part_size ((const gchar *) node->data);
816 modest_ui_actions_compose_msg(ModestWindow *win,
819 const gchar *bcc_str,
820 const gchar *subject_str,
821 const gchar *body_str,
823 gboolean set_as_modified)
825 gchar *account_name = NULL;
826 const gchar *mailbox;
828 TnyAccount *account = NULL;
829 TnyFolder *folder = NULL;
830 gchar *from_str = NULL, *signature = NULL, *body = NULL;
831 gchar *recipient = NULL;
832 gboolean use_signature = FALSE;
833 ModestWindow *msg_win = NULL;
834 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
835 ModestTnyAccountStore *store = modest_runtime_get_account_store();
836 GnomeVFSFileSize total_size, allowed_size;
837 guint64 available_disk, expected_size, parts_size;
840 /* we check for low-mem */
841 if (modest_platform_check_memory_low (win, TRUE))
844 available_disk = modest_utils_get_available_space (NULL);
845 parts_count = g_slist_length (attachments);
846 parts_size = count_parts_size (attachments);
847 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
849 /* Double check: disk full condition or message too big */
850 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
851 expected_size > available_disk) {
852 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
853 modest_platform_system_banner (NULL, NULL, msg);
859 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
860 modest_platform_run_information_dialog (
862 _("mail_ib_error_attachment_size"),
868 #ifdef MODEST_TOOLKIT_HILDON2
870 account_name = g_strdup (modest_window_get_active_account(win));
873 account_name = modest_account_mgr_get_default_account(mgr);
876 g_printerr ("modest: no account found\n");
881 mailbox = modest_window_get_active_mailbox (win);
884 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
886 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
889 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
891 g_printerr ("modest: failed to find Drafts folder\n");
894 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
896 g_printerr ("modest: failed get from string for '%s'\n", account_name);
900 recipient = modest_text_utils_get_email_address (from_str);
901 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
903 if (body_str != NULL) {
904 body = use_signature ? g_strconcat(body_str, "\n",
905 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
906 "\n", signature, NULL) : g_strdup(body_str);
908 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
909 "\n", signature, NULL) : g_strdup("");
912 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
914 g_printerr ("modest: failed to create new msg\n");
918 /* Create and register edit window */
919 /* This is destroyed by TODO. */
921 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
922 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
924 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
925 gtk_widget_destroy (GTK_WIDGET (msg_win));
928 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
929 gtk_widget_show_all (GTK_WIDGET (msg_win));
931 while (attachments) {
932 GnomeVFSFileSize att_size;
934 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
935 attachments->data, allowed_size);
936 total_size += att_size;
938 if (att_size > allowed_size) {
939 g_debug ("%s: total size: %u",
940 __FUNCTION__, (unsigned int)total_size);
943 allowed_size -= att_size;
945 attachments = g_slist_next(attachments);
952 g_free (account_name);
954 g_object_unref (G_OBJECT(account));
956 g_object_unref (G_OBJECT(folder));
958 g_object_unref (G_OBJECT(msg));
962 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
964 /* if there are no accounts yet, just show the wizard */
965 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
966 if (!modest_ui_actions_run_account_setup_wizard (win))
969 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
974 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
978 ModestMailOperationStatus status;
980 /* If there is no message or the operation was not successful */
981 status = modest_mail_operation_get_status (mail_op);
982 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
985 /* If it's a memory low issue, then show a banner */
986 error = modest_mail_operation_get_error (mail_op);
987 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
988 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
989 GObject *source = modest_mail_operation_get_source (mail_op);
990 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
991 _KR("memr_ib_operation_disabled"),
993 g_object_unref (source);
996 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
997 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
998 gchar *subject, *msg, *format = NULL;
1001 subject = (header) ? tny_header_dup_subject (header) : NULL;
1003 subject = g_strdup (_("mail_va_no_subject"));
1005 account = modest_mail_operation_get_account (mail_op);
1007 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1008 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1011 if (tny_account_get_connection_status (account) ==
1012 TNY_CONNECTION_STATUS_CONNECTED) {
1013 format = modest_protocol_get_translation (protocol,
1014 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1017 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1018 tny_account_get_hostname (account));
1021 g_object_unref (account);
1025 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1027 msg = g_strdup_printf (format, subject);
1028 modest_platform_run_information_dialog (NULL, msg, FALSE);
1034 /* Remove the header from the preregistered uids */
1035 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1048 } OpenMsgBannerInfo;
1051 GtkTreeModel *model;
1053 ModestWindow *caller_window;
1054 OpenMsgBannerInfo *banner_info;
1055 GtkTreeRowReference *rowref;
1059 open_msg_banner_idle (gpointer userdata)
1061 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1063 gdk_threads_enter ();
1064 banner_info->idle_handler = 0;
1065 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1066 if (banner_info->banner)
1067 g_object_ref (banner_info->banner);
1069 gdk_threads_leave ();
1075 get_header_view_from_window (ModestWindow *window)
1077 GtkWidget *header_view;
1079 #ifndef MODEST_TOOLKIT_HILDON2
1080 if (MODEST_IS_MAIN_WINDOW (window)) {
1081 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1082 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1084 if (MODEST_IS_HEADER_WINDOW (window)){
1085 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1095 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1098 gchar *account = NULL;
1099 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1104 folder = tny_header_get_folder (header);
1105 /* Gets folder type (OUTBOX headers will be opened in edit window */
1106 if (modest_tny_folder_is_local_folder (folder)) {
1107 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1108 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1109 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1112 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1113 TnyTransportAccount *traccount = NULL;
1114 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1115 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1117 ModestTnySendQueue *send_queue = NULL;
1118 ModestTnySendQueueStatus status;
1120 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1121 TNY_ACCOUNT(traccount)));
1122 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1123 if (TNY_IS_SEND_QUEUE (send_queue)) {
1124 msg_id = modest_tny_send_queue_get_msg_id (header);
1125 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1127 /* Only open messages in outbox with the editor if they are in Failed state */
1128 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1131 #ifdef MODEST_TOOLKIT_HILDON2
1133 /* In Fremantle we can not
1134 open any message from
1135 outbox which is not in
1141 g_object_unref(traccount);
1143 g_warning("Cannot get transport account for message in outbox!!");
1145 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1146 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1150 TnyAccount *acc = tny_folder_get_account (folder);
1153 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1154 g_object_unref (acc);
1158 g_object_unref (folder);
1164 open_msg_cb (ModestMailOperation *mail_op,
1171 ModestWindowMgr *mgr = NULL;
1172 ModestWindow *parent_win = NULL;
1173 ModestWindow *win = NULL;
1174 gchar *account = NULL;
1175 gboolean open_in_editor = FALSE;
1177 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1179 /* Do nothing if there was any problem with the mail
1180 operation. The error will be shown by the error_handler of
1181 the mail operation */
1182 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1185 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1187 /* Mark header as read */
1188 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1190 account = get_info_from_header (header, &open_in_editor, &can_open);
1194 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1196 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1198 if (open_in_editor) {
1199 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1200 gchar *from_header = NULL, *acc_name;
1201 gchar *mailbox = NULL;
1203 from_header = tny_header_dup_from (header);
1205 /* we cannot edit without a valid account... */
1206 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1207 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1208 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1210 g_free (from_header);
1215 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1216 g_free (from_header);
1222 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1226 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1227 const gchar *mailbox = NULL;
1229 if (parent_win && MODEST_IS_WINDOW (parent_win))
1230 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1232 if (helper->rowref && helper->model) {
1233 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1234 helper->model, helper->rowref);
1236 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1241 /* Register and show new window */
1243 mgr = modest_runtime_get_window_mgr ();
1244 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1245 gtk_widget_destroy (GTK_WIDGET (win));
1248 gtk_widget_show_all (GTK_WIDGET(win));
1251 #ifndef MODEST_TOOLKIT_HILDON2
1252 /* Update toolbar dimming state */
1253 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1254 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1261 g_object_unref (parent_win);
1265 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1268 const GError *error;
1269 GObject *win = NULL;
1270 ModestMailOperationStatus status;
1272 win = modest_mail_operation_get_source (mail_op);
1273 error = modest_mail_operation_get_error (mail_op);
1274 status = modest_mail_operation_get_status (mail_op);
1276 /* If the mail op has been cancelled then it's not an error:
1277 don't show any message */
1278 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1279 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1280 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1281 (GError *) error, account)) {
1282 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1283 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1285 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1286 modest_platform_information_banner ((GtkWidget *) win,
1287 NULL, _("emev_ui_imap_inbox_select_error"));
1288 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1289 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1290 modest_platform_information_banner ((GtkWidget *) win,
1291 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1292 } else if (user_data) {
1293 modest_platform_information_banner ((GtkWidget *) win,
1297 g_object_unref (account);
1301 g_object_unref (win);
1305 * Returns the account a list of headers belongs to. It returns a
1306 * *new* reference so don't forget to unref it
1309 get_account_from_header_list (TnyList *headers)
1311 TnyAccount *account = NULL;
1313 if (tny_list_get_length (headers) > 0) {
1314 TnyIterator *iter = tny_list_create_iterator (headers);
1315 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1316 TnyFolder *folder = tny_header_get_folder (header);
1319 g_object_unref (header);
1321 while (!tny_iterator_is_done (iter)) {
1322 header = TNY_HEADER (tny_iterator_get_current (iter));
1323 folder = tny_header_get_folder (header);
1326 g_object_unref (header);
1328 tny_iterator_next (iter);
1333 account = tny_folder_get_account (folder);
1334 g_object_unref (folder);
1338 g_object_unref (header);
1340 g_object_unref (iter);
1346 get_account_from_header (TnyHeader *header)
1348 TnyAccount *account = NULL;
1351 folder = tny_header_get_folder (header);
1354 account = tny_folder_get_account (folder);
1355 g_object_unref (folder);
1361 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1363 if (helper->caller_window)
1364 helper->caller_window = NULL;
1368 open_msg_helper_destroyer (gpointer user_data)
1370 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1372 if (helper->caller_window) {
1373 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1374 helper->caller_window = NULL;
1377 if (helper->banner_info) {
1378 g_free (helper->banner_info->message);
1379 if (helper->banner_info->idle_handler > 0) {
1380 g_source_remove (helper->banner_info->idle_handler);
1381 helper->banner_info->idle_handler = 0;
1383 if (helper->banner_info->banner != NULL) {
1384 gtk_widget_destroy (helper->banner_info->banner);
1385 g_object_unref (helper->banner_info->banner);
1386 helper->banner_info->banner = NULL;
1388 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1389 helper->banner_info = NULL;
1391 g_object_unref (helper->model);
1392 g_object_unref (helper->header);
1393 gtk_tree_row_reference_free (helper->rowref);
1394 g_slice_free (OpenMsgHelper, helper);
1398 open_msg_performer(gboolean canceled,
1400 GtkWindow *parent_window,
1401 TnyAccount *account,
1404 ModestMailOperation *mail_op = NULL;
1405 gchar *error_msg = NULL;
1406 ModestProtocolType proto;
1407 TnyConnectionStatus status;
1408 OpenMsgHelper *helper = NULL;
1409 ModestProtocol *protocol;
1410 ModestProtocolRegistry *protocol_registry;
1413 helper = (OpenMsgHelper *) user_data;
1415 status = tny_account_get_connection_status (account);
1416 if (err || canceled || helper->caller_window == NULL) {
1417 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1418 /* Free the helper */
1419 open_msg_helper_destroyer (helper);
1421 /* In disk full conditions we could get this error here */
1422 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1423 (GtkWidget *) parent_window, err,
1429 /* Get the error message depending on the protocol */
1430 proto = modest_tny_account_get_protocol_type (account);
1431 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1432 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1435 protocol_registry = modest_runtime_get_protocol_registry ();
1436 subject = tny_header_dup_subject (helper->header);
1438 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1439 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1443 if (error_msg == NULL) {
1444 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1447 #ifndef MODEST_TOOLKIT_HILDON2
1448 gboolean show_open_draft = FALSE;
1449 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1451 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1453 TnyFolderType folder_type;
1455 folder = tny_header_get_folder (helper->header);
1456 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1457 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1458 g_object_unref (folder);
1462 #ifdef MODEST_TOOLKIT_HILDON2
1465 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1468 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1469 g_free (account_name);
1470 open_msg_helper_destroyer (helper);
1475 ModestWindow *window;
1476 GtkWidget *header_view;
1479 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1480 uid = modest_tny_folder_get_header_unique_id (helper->header);
1482 const gchar *mailbox = NULL;
1483 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1484 window = modest_msg_view_window_new_from_header_view
1485 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1486 if (window != NULL) {
1487 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1489 gtk_widget_destroy (GTK_WIDGET (window));
1491 gtk_widget_show_all (GTK_WIDGET(window));
1495 g_free (account_name);
1497 open_msg_helper_destroyer (helper);
1500 g_free (account_name);
1502 /* Create the mail operation */
1504 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1505 modest_ui_actions_disk_operations_error_handler,
1506 g_strdup (error_msg), g_free);
1507 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1511 #ifndef MODEST_TOOLKIT_HILDON2
1512 if (show_open_draft) {
1513 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1514 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1515 helper->banner_info->banner = NULL;
1516 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1517 helper->banner_info);
1523 headers = TNY_LIST (tny_simple_list_new ());
1524 tny_list_prepend (headers, G_OBJECT (helper->header));
1525 modest_mail_operation_get_msgs_full (mail_op,
1529 open_msg_helper_destroyer);
1530 g_object_unref (headers);
1537 g_object_unref (mail_op);
1538 g_object_unref (account);
1542 * This function is used by both modest_ui_actions_on_open and
1543 * modest_ui_actions_on_header_activated. This way we always do the
1544 * same when trying to open messages.
1547 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1549 ModestWindowMgr *mgr = NULL;
1550 TnyAccount *account;
1551 gboolean cached = FALSE;
1553 GtkWidget *header_view = NULL;
1554 OpenMsgHelper *helper;
1555 ModestWindow *window;
1557 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1559 mgr = modest_runtime_get_window_mgr ();
1562 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1563 if (header_view == NULL)
1566 /* Get the account */
1567 account = get_account_from_header (header);
1572 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1574 /* Do not open again the message and present the
1575 window to the user */
1578 #ifndef MODEST_TOOLKIT_HILDON2
1579 gtk_window_present (GTK_WINDOW (window));
1582 /* the header has been registered already, we don't do
1583 * anything but wait for the window to come up*/
1584 g_debug ("header %p already registered, waiting for window", header);
1589 /* Open each message */
1590 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1592 /* Allways download if we are online. */
1593 if (!tny_device_is_online (modest_runtime_get_device ())) {
1596 /* If ask for user permission to download the messages */
1597 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1598 _("mcen_nc_get_msg"));
1600 /* End if the user does not want to continue */
1601 if (response == GTK_RESPONSE_CANCEL) {
1607 /* We register the window for opening */
1608 modest_window_mgr_register_header (mgr, header, NULL);
1610 /* Create the helper. We need to get a reference to the model
1611 here because it could change while the message is readed
1612 (the user could switch between folders) */
1613 helper = g_slice_new (OpenMsgHelper);
1614 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1615 helper->caller_window = win;
1616 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1617 helper->header = g_object_ref (header);
1618 helper->rowref = gtk_tree_row_reference_copy (rowref);
1619 helper->banner_info = NULL;
1621 /* Connect to the account and perform */
1623 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1624 open_msg_performer, helper);
1626 /* Call directly the performer, do not need to connect */
1627 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1628 g_object_ref (account), helper);
1633 g_object_unref (account);
1637 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1644 /* we check for low-mem; in that case, show a warning, and don't allow
1647 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1651 headers = get_selected_headers (win);
1655 headers_count = tny_list_get_length (headers);
1656 if (headers_count != 1) {
1657 if (headers_count > 1) {
1658 /* Don't allow activation if there are more than one message selected */
1659 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1662 g_object_unref (headers);
1666 iter = tny_list_create_iterator (headers);
1667 header = TNY_HEADER (tny_iterator_get_current (iter));
1668 g_object_unref (iter);
1672 open_msg_from_header (header, NULL, win);
1673 g_object_unref (header);
1676 g_object_unref(headers);
1680 rf_helper_window_closed (gpointer data,
1683 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1685 helper->parent_window = NULL;
1688 static ReplyForwardHelper*
1689 create_reply_forward_helper (ReplyForwardAction action,
1691 guint reply_forward_type,
1694 ReplyForwardHelper *rf_helper = NULL;
1695 const gchar *active_acc = modest_window_get_active_account (win);
1696 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1698 rf_helper = g_slice_new0 (ReplyForwardHelper);
1699 rf_helper->reply_forward_type = reply_forward_type;
1700 rf_helper->action = action;
1701 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1702 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1703 rf_helper->account_name = (active_acc) ?
1704 g_strdup (active_acc) :
1705 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1706 rf_helper->mailbox = g_strdup (active_mailbox);
1708 /* Note that window could be destroyed just AFTER calling
1709 register_window so we must ensure that this pointer does
1710 not hold invalid references */
1711 if (rf_helper->parent_window)
1712 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1713 rf_helper_window_closed, rf_helper);
1719 free_reply_forward_helper (gpointer data)
1721 ReplyForwardHelper *helper;
1723 helper = (ReplyForwardHelper *) data;
1724 g_free (helper->account_name);
1725 g_free (helper->mailbox);
1727 g_object_unref (helper->header);
1728 if (helper->parent_window)
1729 g_object_weak_unref (G_OBJECT (helper->parent_window),
1730 rf_helper_window_closed, helper);
1731 g_slice_free (ReplyForwardHelper, helper);
1735 reply_forward_cb (ModestMailOperation *mail_op,
1742 TnyMsg *new_msg = NULL;
1743 ReplyForwardHelper *rf_helper;
1744 ModestWindow *msg_win = NULL;
1745 ModestEditType edit_type;
1747 TnyAccount *account = NULL;
1748 ModestWindowMgr *mgr = NULL;
1749 gchar *signature = NULL;
1750 gboolean use_signature;
1753 /* If there was any error. The mail operation could be NULL,
1754 this means that we already have the message downloaded and
1755 that we didn't do a mail operation to retrieve it */
1756 rf_helper = (ReplyForwardHelper *) user_data;
1757 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1760 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1761 rf_helper->account_name, rf_helper->mailbox);
1762 recipient = modest_text_utils_get_email_address (from);
1763 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1768 /* Create reply mail */
1769 switch (rf_helper->action) {
1770 /* Use the msg_header to ensure that we have all the
1771 information. The summary can lack some data */
1772 TnyHeader *msg_header;
1774 msg_header = tny_msg_get_header (msg);
1776 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1777 (use_signature) ? signature : NULL,
1778 rf_helper->reply_forward_type,
1779 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1780 g_object_unref (msg_header);
1782 case ACTION_REPLY_TO_ALL:
1783 msg_header = tny_msg_get_header (msg);
1785 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1786 (use_signature) ? signature : NULL,
1787 rf_helper->reply_forward_type,
1788 MODEST_TNY_MSG_REPLY_MODE_ALL);
1789 edit_type = MODEST_EDIT_TYPE_REPLY;
1790 g_object_unref (msg_header);
1792 case ACTION_FORWARD:
1794 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1795 rf_helper->reply_forward_type);
1796 edit_type = MODEST_EDIT_TYPE_FORWARD;
1799 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1801 g_return_if_reached ();
1809 g_warning ("%s: failed to create message\n", __FUNCTION__);
1813 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1814 rf_helper->account_name,
1815 TNY_ACCOUNT_TYPE_STORE);
1817 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1821 /* Create and register the windows */
1822 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1823 mgr = modest_runtime_get_window_mgr ();
1824 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1826 /* Note that register_window could have deleted the account */
1827 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1828 gdouble parent_zoom;
1830 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1831 modest_window_set_zoom (msg_win, parent_zoom);
1834 /* Show edit window */
1835 gtk_widget_show_all (GTK_WIDGET (msg_win));
1838 /* We always unregister the header because the message is
1839 forwarded or replied so the original one is no longer
1841 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1844 g_object_unref (G_OBJECT (new_msg));
1846 g_object_unref (G_OBJECT (account));
1847 free_reply_forward_helper (rf_helper);
1850 /* Checks a list of headers. If any of them are not currently
1851 * downloaded (CACHED) then returns TRUE else returns FALSE.
1854 header_list_count_uncached_msgs (TnyList *header_list)
1857 gint uncached_messages = 0;
1859 iter = tny_list_create_iterator (header_list);
1860 while (!tny_iterator_is_done (iter)) {
1863 header = TNY_HEADER (tny_iterator_get_current (iter));
1865 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1866 uncached_messages ++;
1867 g_object_unref (header);
1870 tny_iterator_next (iter);
1872 g_object_unref (iter);
1874 return uncached_messages;
1877 /* Returns FALSE if the user does not want to download the
1878 * messages. Returns TRUE if the user allowed the download.
1881 connect_to_get_msg (ModestWindow *win,
1882 gint num_of_uncached_msgs,
1883 TnyAccount *account)
1885 GtkResponseType response;
1887 /* Allways download if we are online. */
1888 if (tny_device_is_online (modest_runtime_get_device ()))
1891 /* If offline, then ask for user permission to download the messages */
1892 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1893 ngettext("mcen_nc_get_msg",
1895 num_of_uncached_msgs));
1897 if (response == GTK_RESPONSE_CANCEL)
1900 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1904 reply_forward_performer (gboolean canceled,
1906 GtkWindow *parent_window,
1907 TnyAccount *account,
1910 ReplyForwardHelper *rf_helper = NULL;
1911 ModestMailOperation *mail_op;
1913 rf_helper = (ReplyForwardHelper *) user_data;
1915 if (canceled || err) {
1916 free_reply_forward_helper (rf_helper);
1920 /* Retrieve the message */
1921 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1922 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1923 modest_ui_actions_disk_operations_error_handler,
1925 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1926 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1929 g_object_unref(mail_op);
1933 * Common code for the reply and forward actions
1936 reply_forward (ReplyForwardAction action, ModestWindow *win)
1938 ReplyForwardHelper *rf_helper = NULL;
1939 guint reply_forward_type;
1941 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1943 /* we check for low-mem; in that case, show a warning, and don't allow
1944 * reply/forward (because it could potentially require a lot of memory */
1945 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1949 /* we need an account when editing */
1950 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1951 if (!modest_ui_actions_run_account_setup_wizard (win))
1955 reply_forward_type =
1956 modest_conf_get_int (modest_runtime_get_conf (),
1957 (action == ACTION_FORWARD) ?
1958 MODEST_CONF_FORWARD_TYPE :
1959 MODEST_CONF_REPLY_TYPE,
1962 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1964 TnyHeader *header = NULL;
1965 /* Get header and message. Do not free them here, the
1966 reply_forward_cb must do it */
1967 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1968 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1970 if (msg && header) {
1972 rf_helper = create_reply_forward_helper (action, win,
1973 reply_forward_type, header);
1974 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1976 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1980 g_object_unref (msg);
1982 g_object_unref (header);
1984 TnyHeader *header = NULL;
1986 gboolean do_retrieve = TRUE;
1987 TnyList *header_list = NULL;
1989 header_list = get_selected_headers (win);
1992 /* Check that only one message is selected for replying */
1993 if (tny_list_get_length (header_list) != 1) {
1994 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1995 NULL, _("mcen_ib_select_one_message"));
1996 g_object_unref (header_list);
2000 /* Only reply/forward to one message */
2001 iter = tny_list_create_iterator (header_list);
2002 header = TNY_HEADER (tny_iterator_get_current (iter));
2003 g_object_unref (iter);
2005 /* Retrieve messages */
2006 do_retrieve = (action == ACTION_FORWARD) ||
2007 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2010 TnyAccount *account = NULL;
2011 TnyFolder *folder = NULL;
2012 gdouble download = TRUE;
2013 guint uncached_msgs = 0;
2015 folder = tny_header_get_folder (header);
2017 goto do_retrieve_frees;
2018 account = tny_folder_get_account (folder);
2020 goto do_retrieve_frees;
2022 uncached_msgs = header_list_count_uncached_msgs (header_list);
2024 if (uncached_msgs > 0) {
2025 /* Allways download if we are online. */
2026 if (!tny_device_is_online (modest_runtime_get_device ())) {
2029 /* If ask for user permission to download the messages */
2030 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2031 ngettext("mcen_nc_get_msg",
2035 /* End if the user does not want to continue */
2036 if (response == GTK_RESPONSE_CANCEL)
2043 rf_helper = create_reply_forward_helper (action, win,
2044 reply_forward_type, header);
2045 if (uncached_msgs > 0) {
2046 modest_platform_connect_and_perform (GTK_WINDOW (win),
2048 reply_forward_performer,
2051 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2052 account, rf_helper);
2057 g_object_unref (account);
2059 g_object_unref (folder);
2061 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2064 g_object_unref (header_list);
2065 g_object_unref (header);
2070 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2072 g_return_if_fail (MODEST_IS_WINDOW(win));
2074 reply_forward (ACTION_REPLY, win);
2078 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2080 g_return_if_fail (MODEST_IS_WINDOW(win));
2082 reply_forward (ACTION_FORWARD, win);
2086 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2088 g_return_if_fail (MODEST_IS_WINDOW(win));
2090 reply_forward (ACTION_REPLY_TO_ALL, win);
2094 modest_ui_actions_on_next (GtkAction *action,
2095 ModestWindow *window)
2097 #ifndef MODEST_TOOLKIT_HILDON2
2098 if (MODEST_IS_MAIN_WINDOW (window)) {
2099 GtkWidget *header_view;
2101 header_view = modest_main_window_get_child_widget (
2102 MODEST_MAIN_WINDOW(window),
2103 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2107 modest_header_view_select_next (
2108 MODEST_HEADER_VIEW(header_view));
2110 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2111 modest_msg_view_window_select_next_message (
2112 MODEST_MSG_VIEW_WINDOW (window));
2115 g_return_if_reached ();
2120 modest_ui_actions_on_prev (GtkAction *action,
2121 ModestWindow *window)
2123 g_return_if_fail (MODEST_IS_WINDOW(window));
2125 #ifndef MODEST_TOOLKIT_HILDON2
2126 if (MODEST_IS_MAIN_WINDOW (window)) {
2127 GtkWidget *header_view;
2128 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2129 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2133 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2135 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2136 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2139 g_return_if_reached ();
2144 modest_ui_actions_on_sort (GtkAction *action,
2145 ModestWindow *window)
2147 GtkWidget *header_view = NULL;
2149 g_return_if_fail (MODEST_IS_WINDOW(window));
2151 #ifndef MODEST_TOOLKIT_HILDON2
2152 if (MODEST_IS_MAIN_WINDOW (window)) {
2153 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2154 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2156 if (MODEST_IS_HEADER_WINDOW (window)) {
2157 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2162 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2167 /* Show sorting dialog */
2168 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2172 sync_folder_cb (ModestMailOperation *mail_op,
2176 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2178 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2179 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2181 /* We must clear first, because otherwise set_folder will ignore */
2182 /* the change as the folders are the same */
2183 modest_header_view_clear (header_view);
2184 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2186 g_object_unref (parent);
2189 g_object_unref (header_view);
2193 idle_refresh_folder (gpointer source)
2195 ModestHeaderView *header_view = NULL;
2197 /* If the window still exists */
2198 if (!GTK_IS_WIDGET (source) ||
2199 !GTK_WIDGET_VISIBLE (source))
2202 /* Refresh the current view */
2203 #ifdef MODEST_TOOLKIT_HILDON2
2204 if (MODEST_IS_HEADER_WINDOW (source))
2205 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2207 if (MODEST_IS_MAIN_WINDOW (source))
2208 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2209 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2212 TnyFolder *folder = modest_header_view_get_folder (header_view);
2214 /* Sync the folder status */
2215 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2216 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2217 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2218 g_object_unref (folder);
2219 g_object_unref (mail_op);
2227 update_account_cb (ModestMailOperation *self,
2228 TnyList *new_headers,
2232 gboolean show_visual_notifications;
2234 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2235 show_visual_notifications = (top) ? FALSE : TRUE;
2237 /* Notify new messages have been downloaded. If the
2238 send&receive was invoked by the user then do not show any
2239 visual notification, only play a sound and activate the LED
2240 (for the Maemo version) */
2241 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2243 /* We only notify about really new messages (not seen) we get */
2244 TnyList *actually_new_list;
2245 TnyIterator *iterator;
2246 actually_new_list = TNY_LIST (tny_simple_list_new ());
2247 for (iterator = tny_list_create_iterator (new_headers);
2248 !tny_iterator_is_done (iterator);
2249 tny_iterator_next (iterator)) {
2251 TnyHeaderFlags flags;
2252 header = TNY_HEADER (tny_iterator_get_current (iterator));
2253 flags = tny_header_get_flags (header);
2255 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2256 /* Messages are ordered from most
2257 recent to oldest. But we want to
2258 show notifications starting from
2259 the oldest message. That's why we
2261 tny_list_prepend (actually_new_list, G_OBJECT (header));
2263 g_object_unref (header);
2265 g_object_unref (iterator);
2267 if (tny_list_get_length (actually_new_list) > 0) {
2268 GList *new_headers_list = NULL;
2270 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2272 /* Send notifications */
2273 if (new_headers_list) {
2274 modest_platform_on_new_headers_received (new_headers_list,
2275 show_visual_notifications);
2277 modest_utils_free_notification_list (new_headers_list);
2280 g_object_unref (actually_new_list);
2284 /* Refresh the current folder in an idle. We do this
2285 in order to avoid refresh cancelations if the
2286 currently viewed folder is the inbox */
2287 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2288 idle_refresh_folder,
2295 TnyAccount *account;
2297 gchar *account_name;
2298 gboolean poke_status;
2299 gboolean interactive;
2300 ModestMailOperation *mail_op;
2304 do_send_receive_performer (gboolean canceled,
2306 GtkWindow *parent_window,
2307 TnyAccount *account,
2310 SendReceiveInfo *info;
2312 info = (SendReceiveInfo *) user_data;
2314 if (err || canceled) {
2315 /* In disk full conditions we could get this error here */
2316 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2317 (GtkWidget *) parent_window, err,
2320 if (info->mail_op) {
2321 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2327 #ifndef MODEST_TOOLKIT_HILDON2
2328 /* Set send/receive operation in progress */
2329 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2330 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2333 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2334 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2335 G_CALLBACK (on_send_receive_finished),
2339 /* Send & receive. */
2340 modest_mail_operation_update_account (info->mail_op, info->account_name,
2341 info->poke_status, info->interactive,
2342 update_account_cb, info->win);
2347 g_object_unref (G_OBJECT (info->mail_op));
2348 if (info->account_name)
2349 g_free (info->account_name);
2351 g_object_unref (info->win);
2353 g_object_unref (info->account);
2354 g_slice_free (SendReceiveInfo, info);
2358 * This function performs the send & receive required actions. The
2359 * window is used to create the mail operation. Typically it should
2360 * always be the main window, but we pass it as argument in order to
2364 modest_ui_actions_do_send_receive (const gchar *account_name,
2365 gboolean force_connection,
2366 gboolean poke_status,
2367 gboolean interactive,
2370 gchar *acc_name = NULL;
2371 SendReceiveInfo *info;
2372 ModestTnyAccountStore *acc_store;
2373 TnyAccount *account;
2375 /* If no account name was provided then get the current account, and if
2376 there is no current account then pick the default one: */
2377 if (!account_name) {
2379 acc_name = g_strdup (modest_window_get_active_account (win));
2381 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2383 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2387 acc_name = g_strdup (account_name);
2390 acc_store = modest_runtime_get_account_store ();
2391 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2395 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2399 /* Do not automatically refresh accounts that are flagged as
2400 NO_AUTO_UPDATE. This could be useful for accounts that
2401 handle their own update times */
2403 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2404 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2405 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2406 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2408 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2409 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2410 g_object_unref (account);
2417 /* Create the info for the connect and perform */
2418 info = g_slice_new (SendReceiveInfo);
2419 info->account_name = acc_name;
2420 info->win = (win) ? g_object_ref (win) : NULL;
2421 info->poke_status = poke_status;
2422 info->interactive = interactive;
2423 info->account = account;
2424 /* We need to create the operation here, because otherwise it
2425 could happen that the queue emits the queue-empty signal
2426 while we're trying to connect the account */
2427 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2428 modest_ui_actions_disk_operations_error_handler,
2430 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2432 /* Invoke the connect and perform */
2433 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2434 force_connection, info->account,
2435 do_send_receive_performer, info);
2440 modest_ui_actions_do_cancel_send (const gchar *account_name,
2443 TnyTransportAccount *transport_account;
2444 TnySendQueue *send_queue = NULL;
2445 GError *error = NULL;
2447 /* Get transport account */
2449 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2450 (modest_runtime_get_account_store(),
2452 TNY_ACCOUNT_TYPE_TRANSPORT));
2453 if (!transport_account) {
2454 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2459 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2460 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2461 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2462 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2463 "modest: could not find send queue for account\n");
2465 /* Cancel the current send */
2466 tny_account_cancel (TNY_ACCOUNT (transport_account));
2468 /* Suspend all pending messages */
2469 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2473 if (transport_account != NULL)
2474 g_object_unref (G_OBJECT (transport_account));
2478 modest_ui_actions_cancel_send_all (ModestWindow *win)
2480 GSList *account_names, *iter;
2482 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2485 iter = account_names;
2487 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2488 iter = g_slist_next (iter);
2491 modest_account_mgr_free_account_names (account_names);
2492 account_names = NULL;
2496 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2499 /* Check if accounts exist */
2500 gboolean accounts_exist =
2501 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2503 /* If not, allow the user to create an account before trying to send/receive. */
2504 if (!accounts_exist)
2505 modest_ui_actions_on_accounts (NULL, win);
2507 /* Cancel all sending operaitons */
2508 modest_ui_actions_cancel_send_all (win);
2512 * Refreshes all accounts. This function will be used by automatic
2516 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2517 gboolean force_connection,
2518 gboolean poke_status,
2519 gboolean interactive)
2521 GSList *account_names, *iter;
2523 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2526 iter = account_names;
2528 modest_ui_actions_do_send_receive ((const char*) iter->data,
2530 poke_status, interactive, win);
2531 iter = g_slist_next (iter);
2534 modest_account_mgr_free_account_names (account_names);
2535 account_names = NULL;
2539 * Handler of the click on Send&Receive button in the main toolbar
2542 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2544 /* Check if accounts exist */
2545 gboolean accounts_exist;
2548 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2550 /* If not, allow the user to create an account before trying to send/receive. */
2551 if (!accounts_exist)
2552 modest_ui_actions_on_accounts (NULL, win);
2554 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2555 #ifndef MODEST_TOOLKIT_HILDON2
2556 if (MODEST_IS_MAIN_WINDOW (win)) {
2557 GtkWidget *folder_view;
2558 TnyFolderStore *folder_store;
2561 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2562 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2566 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2569 g_object_unref (folder_store);
2570 /* Refresh the active account. Force the connection if needed
2571 and poke the status of all folders */
2572 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2574 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2575 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2578 const gchar *active_account;
2579 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2581 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2586 #ifndef MODEST_TOOLKIT_HILDON2
2588 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2591 GtkWidget *header_view;
2593 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2595 header_view = modest_main_window_get_child_widget (main_window,
2596 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2600 conf = modest_runtime_get_conf ();
2602 /* what is saved/restored is depending on the style; thus; we save with
2603 * old style, then update the style, and restore for this new style
2605 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2607 if (modest_header_view_get_style
2608 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2609 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2610 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2612 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2613 MODEST_HEADER_VIEW_STYLE_DETAILS);
2615 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2616 MODEST_CONF_HEADER_VIEW_KEY);
2620 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2622 ModestMainWindow *main_window)
2624 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2625 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2627 /* in the case the folder is empty, show the empty folder message and focus
2629 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2630 if (modest_header_view_is_empty (header_view)) {
2631 TnyFolder *folder = modest_header_view_get_folder (header_view);
2632 GtkWidget *folder_view =
2633 modest_main_window_get_child_widget (main_window,
2634 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2635 if (folder != NULL) {
2636 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2637 g_object_unref (folder);
2639 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2643 /* If no header has been selected then exit */
2648 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2649 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2651 /* Update toolbar dimming state */
2652 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2653 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2658 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2661 ModestWindow *window)
2663 GtkTreeRowReference *rowref;
2665 g_return_if_fail (MODEST_IS_WINDOW(window));
2666 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2667 g_return_if_fail (TNY_IS_HEADER (header));
2669 if (modest_header_view_count_selected_headers (header_view) > 1) {
2670 /* Don't allow activation if there are more than one message selected */
2671 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2675 /* we check for low-mem; in that case, show a warning, and don't allow
2676 * activating headers
2678 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2681 #ifndef MODEST_TOOLKIT_HILDON2
2682 GtkWidget *open_widget;
2683 if (MODEST_IS_MAIN_WINDOW (window)) {
2684 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2685 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2686 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2691 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2692 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2693 gtk_tree_row_reference_free (rowref);
2696 #ifndef MODEST_TOOLKIT_HILDON2
2698 set_active_account_from_tny_account (TnyAccount *account,
2699 ModestWindow *window)
2701 const gchar *server_acc_name = tny_account_get_id (account);
2703 /* We need the TnyAccount provided by the
2704 account store because that is the one that
2705 knows the name of the Modest account */
2706 TnyAccount *modest_server_account =
2707 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2708 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2710 if (!modest_server_account) {
2711 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2715 /* Update active account, but only if it's not a pseudo-account */
2716 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2717 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2718 const gchar *modest_acc_name =
2719 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2720 if (modest_acc_name)
2721 modest_window_set_active_account (window, modest_acc_name);
2724 g_object_unref (modest_server_account);
2728 folder_refreshed_cb (ModestMailOperation *mail_op,
2732 ModestMainWindow *win = NULL;
2733 GtkWidget *folder_view, *header_view;
2734 const GError *error;
2736 g_return_if_fail (TNY_IS_FOLDER (folder));
2738 win = MODEST_MAIN_WINDOW (user_data);
2740 /* Check if the operation failed due to memory low conditions */
2741 error = modest_mail_operation_get_error (mail_op);
2742 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2743 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2744 modest_platform_run_information_dialog (GTK_WINDOW (win),
2745 _KR("memr_ib_operation_disabled"),
2751 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2753 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2756 TnyFolderStore *current_folder;
2758 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2759 if (current_folder) {
2760 gboolean different = ((TnyFolderStore *) folder != current_folder);
2761 g_object_unref (current_folder);
2767 /* Check if folder is empty and set headers view contents style */
2768 if ((tny_folder_get_all_count (folder) == 0) ||
2769 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2770 modest_main_window_set_contents_style (win,
2771 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2775 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2776 TnyFolderStore *folder_store,
2778 ModestMainWindow *main_window)
2780 GtkWidget *header_view;
2782 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2784 header_view = modest_main_window_get_child_widget(main_window,
2785 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2790 if (TNY_IS_ACCOUNT (folder_store)) {
2792 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2794 /* Show account details */
2795 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2798 if (TNY_IS_FOLDER (folder_store) && selected) {
2799 TnyAccount *account;
2801 /* Update the active account */
2802 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2804 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2805 g_object_unref (account);
2809 /* Set the header style by default, it could
2810 be changed later by the refresh callback to
2812 modest_main_window_set_contents_style (main_window,
2813 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2815 /* Set folder on header view. This function
2816 will call tny_folder_refresh_async so we
2817 pass a callback that will be called when
2818 finished. We use that callback to set the
2819 empty view if there are no messages */
2820 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2821 TNY_FOLDER (folder_store),
2823 MODEST_WINDOW (main_window),
2824 folder_refreshed_cb,
2827 /* Restore configuration. We need to do this
2828 *after* the set_folder because the widget
2829 memory asks the header view about its
2831 modest_widget_memory_restore (modest_runtime_get_conf (),
2832 G_OBJECT(header_view),
2833 MODEST_CONF_HEADER_VIEW_KEY);
2835 /* No need to save the header view
2836 configuration for Maemo because it only
2837 saves the sorting stuff and that it's
2838 already being done by the sort
2839 dialog. Remove it when the GNOME version
2840 has the same behaviour */
2841 #ifdef MODEST_TOOLKIT_GTK
2842 if (modest_main_window_get_contents_style (main_window) ==
2843 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2844 modest_widget_memory_save (modest_runtime_get_conf (),
2845 G_OBJECT (header_view),
2846 MODEST_CONF_HEADER_VIEW_KEY);
2848 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2852 /* Update dimming state */
2853 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2854 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2859 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2866 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2868 online = tny_device_is_online (modest_runtime_get_device());
2871 /* already online -- the item is simply not there... */
2872 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2874 GTK_MESSAGE_WARNING,
2876 _("The %s you selected cannot be found"),
2878 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2879 gtk_dialog_run (GTK_DIALOG(dialog));
2881 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2884 _("mcen_bd_dialog_cancel"),
2885 GTK_RESPONSE_REJECT,
2886 _("mcen_bd_dialog_ok"),
2887 GTK_RESPONSE_ACCEPT,
2889 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2890 "Do you want to get online?"), item);
2891 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2892 gtk_label_new (txt), FALSE, FALSE, 0);
2893 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2896 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2897 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2898 /* TODO: Comment about why is this commented out: */
2899 /* modest_platform_connect_and_wait (); */
2902 gtk_widget_destroy (dialog);
2906 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2909 /* g_debug ("%s %s", __FUNCTION__, link); */
2914 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2917 modest_platform_activate_uri (link);
2921 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2924 modest_platform_show_uri_popup (link);
2928 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2931 /* we check for low-mem; in that case, show a warning, and don't allow
2932 * viewing attachments
2934 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2937 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2941 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2942 const gchar *address,
2945 /* g_debug ("%s %s", __FUNCTION__, address); */
2949 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2950 TnyMsg *saved_draft,
2953 ModestMsgEditWindow *edit_window;
2955 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2956 #ifndef MODEST_TOOLKIT_HILDON2
2957 ModestMainWindow *win;
2959 /* FIXME. Make the header view sensitive again. This is a
2960 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2962 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2963 modest_runtime_get_window_mgr(), FALSE));
2965 GtkWidget *hdrview = modest_main_window_get_child_widget(
2966 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2967 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2971 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2973 /* Set draft is there was no error */
2974 if (!modest_mail_operation_get_error (mail_op))
2975 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2977 g_object_unref(edit_window);
2981 enough_space_for_message (ModestMsgEditWindow *edit_window,
2984 guint64 available_disk, expected_size;
2989 available_disk = modest_utils_get_available_space (NULL);
2990 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2991 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2996 /* Double check: disk full condition or message too big */
2997 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2998 expected_size > available_disk) {
2999 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3000 modest_platform_information_banner (NULL, NULL, msg);
3007 * djcb: if we're in low-memory state, we only allow for
3008 * saving messages smaller than
3009 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3010 * should still allow for sending anything critical...
3012 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3013 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3017 * djcb: we also make sure that the attachments are smaller than the max size
3018 * this is for the case where we'd try to forward a message with attachments
3019 * bigger than our max allowed size, or sending an message from drafts which
3020 * somehow got past our checks when attaching.
3022 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3023 modest_platform_run_information_dialog (
3024 GTK_WINDOW(edit_window),
3025 _("mail_ib_error_attachment_size"),
3034 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3036 TnyTransportAccount *transport_account;
3037 ModestMailOperation *mail_operation;
3039 gchar *account_name;
3040 ModestAccountMgr *account_mgr;
3041 gboolean had_error = FALSE;
3043 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3045 data = modest_msg_edit_window_get_msg_data (edit_window);
3048 if (!enough_space_for_message (edit_window, data)) {
3049 modest_msg_edit_window_free_msg_data (edit_window, data);
3053 account_name = g_strdup (data->account_name);
3054 account_mgr = modest_runtime_get_account_mgr();
3056 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3058 account_name = modest_account_mgr_get_default_account (account_mgr);
3059 if (!account_name) {
3060 g_printerr ("modest: no account found\n");
3061 modest_msg_edit_window_free_msg_data (edit_window, data);
3065 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3066 account_name = g_strdup (data->account_name);
3070 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3071 (modest_runtime_get_account_store (),
3073 TNY_ACCOUNT_TYPE_TRANSPORT));
3074 if (!transport_account) {
3075 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3076 g_free (account_name);
3077 modest_msg_edit_window_free_msg_data (edit_window, data);
3081 /* Create the mail operation */
3082 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3084 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3086 modest_mail_operation_save_to_drafts (mail_operation,
3098 data->priority_flags,
3101 on_save_to_drafts_cb,
3102 g_object_ref(edit_window));
3104 #ifdef MODEST_TOOLKIT_HILDON2
3105 /* In hildon2 we always show the information banner on saving to drafts.
3106 * It will be a system information banner in this case.
3108 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3109 modest_platform_information_banner (NULL, NULL, text);
3112 ModestMainWindow *win = NULL;
3114 /* Use the main window as the parent of the banner, if the
3115 main window does not exist it won't be shown, if the parent
3116 window exists then it's properly shown. We don't use the
3117 editor window because it could be closed (save to drafts
3118 could happen after closing the window */
3119 win = (ModestMainWindow *)
3120 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3122 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3123 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3127 modest_msg_edit_window_set_modified (edit_window, FALSE);
3130 g_free (account_name);
3131 g_object_unref (G_OBJECT (transport_account));
3132 g_object_unref (G_OBJECT (mail_operation));
3134 modest_msg_edit_window_free_msg_data (edit_window, data);
3136 #ifndef MODEST_TOOLKIT_HILDON2
3138 * If the drafts folder is selected then make the header view
3139 * insensitive while the message is being saved to drafts
3140 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3141 * is not very clean but it avoids letting the drafts folder
3142 * in an inconsistent state: the user could edit the message
3143 * being saved and undesirable things would happen.
3144 * In the average case the user won't notice anything at
3145 * all. In the worst case (the user is editing a really big
3146 * file from Drafts) the header view will be insensitive
3147 * during the saving process (10 or 20 seconds, depending on
3148 * the message). Anyway this is just a quick workaround: once
3149 * we find a better solution it should be removed
3150 * See NB#65125 (commend #18) for details.
3152 if (!had_error && win != NULL) {
3153 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3154 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3156 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3158 if (modest_tny_folder_is_local_folder(folder)) {
3159 TnyFolderType folder_type;
3160 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3161 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3162 GtkWidget *hdrview = modest_main_window_get_child_widget(
3163 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3164 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3168 if (folder != NULL) g_object_unref(folder);
3176 /* For instance, when clicking the Send toolbar button when editing a message: */
3178 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3180 TnyTransportAccount *transport_account = NULL;
3181 gboolean had_error = FALSE;
3183 ModestAccountMgr *account_mgr;
3184 gchar *account_name;
3185 ModestMailOperation *mail_operation;
3188 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3190 /* Check names but do not automatically add them to addressbook */
3191 if (!modest_msg_edit_window_check_names (edit_window, FALSE))
3194 data = modest_msg_edit_window_get_msg_data (edit_window);
3196 recipients = g_strconcat (data->to?data->to:"",
3197 data->cc?data->cc:"",
3198 data->bcc?data->bcc:"",
3200 if (recipients == NULL || recipients[0] == '\0') {
3201 /* Empty subject -> no send */
3202 g_free (recipients);
3203 modest_msg_edit_window_free_msg_data (edit_window, data);
3206 g_free (recipients);
3209 if (!enough_space_for_message (edit_window, data)) {
3210 modest_msg_edit_window_free_msg_data (edit_window, data);
3214 account_mgr = modest_runtime_get_account_mgr();
3215 account_name = g_strdup (data->account_name);
3217 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3220 account_name = modest_account_mgr_get_default_account (account_mgr);
3222 if (!account_name) {
3223 modest_msg_edit_window_free_msg_data (edit_window, data);
3224 /* Run account setup wizard */
3225 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3230 /* Get the currently-active transport account for this modest account: */
3231 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3233 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3234 (modest_runtime_get_account_store (),
3235 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3238 if (!transport_account) {
3239 modest_msg_edit_window_free_msg_data (edit_window, data);
3240 /* Run account setup wizard */
3241 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3246 /* Create the mail operation */
3247 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3248 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3250 modest_mail_operation_send_new_mail (mail_operation,
3264 data->priority_flags);
3266 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3267 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3269 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3270 const GError *error = modest_mail_operation_get_error (mail_operation);
3271 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3272 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3273 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3274 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3280 g_free (account_name);
3281 g_object_unref (G_OBJECT (transport_account));
3282 g_object_unref (G_OBJECT (mail_operation));
3284 modest_msg_edit_window_free_msg_data (edit_window, data);
3287 modest_msg_edit_window_set_sent (edit_window, TRUE);
3289 /* Save settings and close the window: */
3290 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3297 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3298 ModestMsgEditWindow *window)
3300 ModestMsgEditFormatState *format_state = NULL;
3302 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3303 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3305 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3308 format_state = modest_msg_edit_window_get_format_state (window);
3309 g_return_if_fail (format_state != NULL);
3311 format_state->bold = gtk_toggle_action_get_active (action);
3312 modest_msg_edit_window_set_format_state (window, format_state);
3313 g_free (format_state);
3318 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3319 ModestMsgEditWindow *window)
3321 ModestMsgEditFormatState *format_state = NULL;
3323 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3324 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3326 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3329 format_state = modest_msg_edit_window_get_format_state (window);
3330 g_return_if_fail (format_state != NULL);
3332 format_state->italics = gtk_toggle_action_get_active (action);
3333 modest_msg_edit_window_set_format_state (window, format_state);
3334 g_free (format_state);
3339 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3340 ModestMsgEditWindow *window)
3342 ModestMsgEditFormatState *format_state = NULL;
3344 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3345 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3347 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3350 format_state = modest_msg_edit_window_get_format_state (window);
3351 g_return_if_fail (format_state != NULL);
3353 format_state->bullet = gtk_toggle_action_get_active (action);
3354 modest_msg_edit_window_set_format_state (window, format_state);
3355 g_free (format_state);
3360 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3361 GtkRadioAction *selected,
3362 ModestMsgEditWindow *window)
3364 ModestMsgEditFormatState *format_state = NULL;
3365 GtkJustification value;
3367 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3369 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3372 value = gtk_radio_action_get_current_value (selected);
3374 format_state = modest_msg_edit_window_get_format_state (window);
3375 g_return_if_fail (format_state != NULL);
3377 format_state->justification = value;
3378 modest_msg_edit_window_set_format_state (window, format_state);
3379 g_free (format_state);
3383 modest_ui_actions_on_select_editor_color (GtkAction *action,
3384 ModestMsgEditWindow *window)
3386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3387 g_return_if_fail (GTK_IS_ACTION (action));
3389 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3392 modest_msg_edit_window_select_color (window);
3396 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3397 ModestMsgEditWindow *window)
3399 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3400 g_return_if_fail (GTK_IS_ACTION (action));
3402 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3405 modest_msg_edit_window_select_background_color (window);
3409 modest_ui_actions_on_insert_image (GObject *object,
3410 ModestMsgEditWindow *window)
3412 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3415 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3418 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3421 modest_msg_edit_window_insert_image (window);
3425 modest_ui_actions_on_attach_file (GtkAction *action,
3426 ModestMsgEditWindow *window)
3428 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3429 g_return_if_fail (GTK_IS_ACTION (action));
3431 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3434 modest_msg_edit_window_offer_attach_file (window);
3438 modest_ui_actions_on_remove_attachments (GtkAction *action,
3439 ModestMsgEditWindow *window)
3441 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3443 modest_msg_edit_window_remove_attachments (window, NULL);
3447 do_create_folder_cb (ModestMailOperation *mail_op,
3448 TnyFolderStore *parent_folder,
3449 TnyFolder *new_folder,
3452 gchar *suggested_name = (gchar *) user_data;
3453 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3454 const GError *error;
3456 error = modest_mail_operation_get_error (mail_op);
3458 gboolean disk_full = FALSE;
3459 TnyAccount *account;
3460 /* Show an error. If there was some problem writing to
3461 disk, show it, otherwise show the generic folder
3462 create error. We do it here and not in an error
3463 handler because the call to do_create_folder will
3464 stop the main loop in a gtk_dialog_run and then,
3465 the message won't be shown until that dialog is
3467 account = modest_mail_operation_get_account (mail_op);
3470 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3471 (GtkWidget *) source_win,
3474 _("mail_in_ui_folder_create_error_memory"));
3475 g_object_unref (account);
3478 /* Show an error and try again if there is no
3479 full memory condition */
3480 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3481 _("mail_in_ui_folder_create_error"));
3482 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3486 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3487 * FIXME: any other? */
3488 GtkWidget *folder_view;
3490 #ifndef MODEST_TOOLKIT_HILDON2
3491 if (MODEST_IS_MAIN_WINDOW(source_win))
3493 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3494 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3497 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3498 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3500 /* Select the newly created folder. It could happen
3501 that the widget is no longer there (i.e. the window
3502 has been destroyed, so we need to check this */
3504 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3506 g_object_unref (new_folder);
3508 /* Free. Note that the first time it'll be NULL so noop */
3509 g_free (suggested_name);
3510 g_object_unref (source_win);
3515 TnyFolderStore *parent;
3516 } CreateFolderConnect;
3519 do_create_folder_performer (gboolean canceled,
3521 GtkWindow *parent_window,
3522 TnyAccount *account,
3525 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3526 ModestMailOperation *mail_op;
3528 if (canceled || err) {
3529 /* In disk full conditions we could get this error here */
3530 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3531 (GtkWidget *) parent_window, err,
3532 NULL, _("mail_in_ui_folder_create_error_memory"));
3534 /* This happens if we have selected the outbox folder
3536 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3537 TNY_IS_MERGE_FOLDER (helper->parent)) {
3538 /* Show an error and retry */
3539 modest_platform_information_banner ((GtkWidget *) parent_window,
3541 _("mail_in_ui_folder_create_error"));
3543 do_create_folder (parent_window, helper->parent, helper->folder_name);
3549 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3550 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3552 modest_mail_operation_create_folder (mail_op,
3554 (const gchar *) helper->folder_name,
3555 do_create_folder_cb,
3556 g_strdup (helper->folder_name));
3557 g_object_unref (mail_op);
3561 g_object_unref (helper->parent);
3562 if (helper->folder_name)
3563 g_free (helper->folder_name);
3564 g_slice_free (CreateFolderConnect, helper);
3569 do_create_folder (GtkWindow *parent_window,
3570 TnyFolderStore *suggested_parent,
3571 const gchar *suggested_name)
3574 gchar *folder_name = NULL;
3575 TnyFolderStore *parent_folder = NULL;
3577 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3579 (gchar *) suggested_name,
3583 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3584 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3585 helper->folder_name = g_strdup (folder_name);
3586 helper->parent = g_object_ref (parent_folder);
3588 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3591 do_create_folder_performer,
3596 g_free (folder_name);
3598 g_object_unref (parent_folder);
3602 modest_ui_actions_create_folder(GtkWidget *parent_window,
3603 GtkWidget *folder_view,
3604 TnyFolderStore *parent_folder)
3606 if (!parent_folder) {
3607 #ifdef MODEST_TOOLKIT_HILDON2
3608 ModestTnyAccountStore *acc_store;
3610 acc_store = modest_runtime_get_account_store ();
3612 parent_folder = (TnyFolderStore *)
3613 modest_tny_account_store_get_local_folders_account (acc_store);
3615 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3619 if (parent_folder) {
3620 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3621 g_object_unref (parent_folder);
3626 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3629 g_return_if_fail (MODEST_IS_WINDOW(window));
3631 #ifndef MODEST_TOOLKIT_HILDON2
3632 if (MODEST_IS_MAIN_WINDOW (window)) {
3633 GtkWidget *folder_view;
3635 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3636 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3640 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3642 if (MODEST_IS_FOLDER_WINDOW (window)) {
3643 GtkWidget *folder_view;
3645 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3646 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3649 g_assert_not_reached ();
3654 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3657 const GError *error = NULL;
3658 gchar *message = NULL;
3660 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3662 /* Get error message */
3663 error = modest_mail_operation_get_error (mail_op);
3665 g_return_if_reached ();
3667 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3668 (GError *) error, account);
3670 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3671 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3672 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3673 message = _CS("ckdg_ib_folder_already_exists");
3674 } else if (error->domain == TNY_ERROR_DOMAIN &&
3675 error->code == TNY_SERVICE_ERROR_STATE) {
3676 /* This means that the folder is already in use (a
3677 message is opened for example */
3678 message = _("emev_ni_internal_error");
3680 message = _CS("ckdg_ib_unable_to_rename");
3683 /* We don't set a parent for the dialog because the dialog
3684 will be destroyed so the banner won't appear */
3685 modest_platform_information_banner (NULL, NULL, message);
3688 g_object_unref (account);
3694 TnyFolderStore *folder;
3699 on_rename_folder_cb (ModestMailOperation *mail_op,
3700 TnyFolder *new_folder,
3703 ModestFolderView *folder_view;
3705 /* If the window was closed when renaming a folder, or if
3706 * it's not a main window this will happen */
3707 if (!MODEST_IS_FOLDER_VIEW (user_data))
3710 folder_view = MODEST_FOLDER_VIEW (user_data);
3711 /* Note that if the rename fails new_folder will be NULL */
3713 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3714 #ifndef MODEST_TOOLKIT_HILDON2
3716 modest_folder_view_select_first_inbox_or_local (folder_view);
3719 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3723 on_rename_folder_performer (gboolean canceled,
3725 GtkWindow *parent_window,
3726 TnyAccount *account,
3729 ModestMailOperation *mail_op = NULL;
3730 GtkTreeSelection *sel = NULL;
3731 GtkWidget *folder_view = NULL;
3732 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3734 if (canceled || err) {
3735 /* In disk full conditions we could get this error here */
3736 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3737 (GtkWidget *) parent_window, err,
3742 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3743 modest_ui_actions_rename_folder_error_handler,
3744 parent_window, NULL);
3746 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3748 #ifndef MODEST_TOOLKIT_HILDON2
3749 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3751 folder_view = modest_main_window_get_child_widget (
3752 MODEST_MAIN_WINDOW (parent_window),
3753 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3756 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3757 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3758 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3762 /* Clear the folders view */
3763 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3764 gtk_tree_selection_unselect_all (sel);
3766 /* Actually rename the folder */
3767 modest_mail_operation_rename_folder (mail_op,
3768 TNY_FOLDER (data->folder),
3769 (const gchar *) (data->new_name),
3770 on_rename_folder_cb,
3772 g_object_unref (mail_op);
3775 g_object_unref (data->folder);
3776 g_free (data->new_name);
3781 modest_ui_actions_on_rename_folder (GtkAction *action,
3782 ModestWindow *window)
3784 modest_ui_actions_on_edit_mode_rename_folder (window);
3788 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3790 TnyFolderStore *folder;
3791 GtkWidget *folder_view;
3792 gboolean do_rename = TRUE;
3794 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3796 #ifndef MODEST_TOOLKIT_HILDON2
3797 if (MODEST_IS_MAIN_WINDOW (window)) {
3798 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3799 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3803 if (MODEST_IS_FOLDER_WINDOW (window)) {
3804 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3810 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3815 if (TNY_IS_FOLDER (folder)) {
3816 gchar *folder_name = NULL;
3818 const gchar *current_name;
3819 TnyFolderStore *parent;
3821 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3822 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3823 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3824 parent, current_name,
3826 g_object_unref (parent);
3828 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3831 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3832 rename_folder_data->folder = g_object_ref (folder);
3833 rename_folder_data->new_name = folder_name;
3834 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3835 folder, on_rename_folder_performer, rename_folder_data);
3838 g_object_unref (folder);
3843 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3846 GObject *win = modest_mail_operation_get_source (mail_op);
3848 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3849 _("mail_in_ui_folder_delete_error"),
3851 g_object_unref (win);
3855 TnyFolderStore *folder;
3856 gboolean move_to_trash;
3860 on_delete_folder_cb (gboolean canceled,
3862 GtkWindow *parent_window,
3863 TnyAccount *account,
3866 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3867 GtkWidget *folder_view;
3868 ModestMailOperation *mail_op;
3869 GtkTreeSelection *sel;
3871 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3872 /* Note that the connection process can fail due to
3873 memory low conditions as it can not successfully
3874 store the summary */
3875 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3876 (GtkWidget*) parent_window, err,
3878 g_debug ("Error connecting when trying to delete a folder");
3879 g_object_unref (G_OBJECT (info->folder));
3884 #ifndef MODEST_TOOLKIT_HILDON2
3885 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3886 folder_view = modest_main_window_get_child_widget (
3887 MODEST_MAIN_WINDOW (parent_window),
3888 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3890 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3891 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3894 g_object_unref (G_OBJECT (info->folder));
3899 /* Unselect the folder before deleting it to free the headers */
3900 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3901 gtk_tree_selection_unselect_all (sel);
3903 /* Create the mail operation */
3905 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3906 modest_ui_actions_delete_folder_error_handler,
3909 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3911 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3913 #ifndef MODEST_TOOLKIT_HILDON2
3914 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3917 g_object_unref (mail_op);
3918 g_object_unref (info->folder);
3923 delete_folder (ModestWindow *window, gboolean move_to_trash)
3925 TnyFolderStore *folder;
3926 GtkWidget *folder_view;
3930 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3932 #ifndef MODEST_TOOLKIT_HILDON2
3933 if (MODEST_IS_MAIN_WINDOW (window)) {
3935 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3936 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3938 if (MODEST_IS_FOLDER_WINDOW (window)) {
3939 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3947 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3952 /* Show an error if it's an account */
3953 if (!TNY_IS_FOLDER (folder)) {
3954 modest_platform_run_information_dialog (GTK_WINDOW (window),
3955 _("mail_in_ui_folder_delete_error"),
3957 g_object_unref (G_OBJECT (folder));
3962 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3963 tny_folder_get_name (TNY_FOLDER (folder)));
3964 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3965 (const gchar *) message);
3968 if (response == GTK_RESPONSE_OK) {
3969 TnyAccount *account = NULL;
3970 DeleteFolderInfo *info = NULL;
3971 info = g_new0(DeleteFolderInfo, 1);
3972 info->folder = g_object_ref (folder);
3973 info->move_to_trash = move_to_trash;
3975 account = tny_folder_get_account (TNY_FOLDER (folder));
3976 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3978 TNY_FOLDER_STORE (account),
3979 on_delete_folder_cb, info);
3980 g_object_unref (account);
3981 g_object_unref (folder);
3989 modest_ui_actions_on_delete_folder (GtkAction *action,
3990 ModestWindow *window)
3992 modest_ui_actions_on_edit_mode_delete_folder (window);
3996 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3998 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4000 return delete_folder (window, FALSE);
4003 #ifndef MODEST_TOOLKIT_HILDON2
4005 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4007 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4009 delete_folder (MODEST_WINDOW (main_window), TRUE);
4013 typedef struct _PasswordDialogFields {
4014 GtkWidget *username;
4015 GtkWidget *password;
4017 } PasswordDialogFields;
4020 password_dialog_check_field (GtkEditable *editable,
4021 PasswordDialogFields *fields)
4024 gboolean any_value_empty = FALSE;
4026 value = modest_entry_get_text (fields->username);
4027 if ((value == NULL) || value[0] == '\0') {
4028 any_value_empty = TRUE;
4030 value = modest_entry_get_text (fields->password);
4031 if ((value == NULL) || value[0] == '\0') {
4032 any_value_empty = TRUE;
4034 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4038 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4039 const gchar* server_account_name,
4044 ModestMainWindow *main_window)
4046 g_return_if_fail(server_account_name);
4047 gboolean completed = FALSE;
4048 PasswordDialogFields *fields = NULL;
4050 /* Initalize output parameters: */
4057 #ifndef MODEST_TOOLKIT_GTK
4058 /* Maemo uses a different (awkward) button order,
4059 * It should probably just use gtk_alternative_dialog_button_order ().
4061 #ifdef MODEST_TOOLKIT_HILDON2
4063 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4066 _HL("wdgt_bd_done"),
4067 GTK_RESPONSE_ACCEPT,
4069 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4070 HILDON_MARGIN_DOUBLE);
4073 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4076 _("mcen_bd_dialog_ok"),
4077 GTK_RESPONSE_ACCEPT,
4078 _("mcen_bd_dialog_cancel"),
4079 GTK_RESPONSE_REJECT,
4081 #endif /* MODEST_TOOLKIT_HILDON2 */
4084 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4088 GTK_RESPONSE_REJECT,
4090 GTK_RESPONSE_ACCEPT,
4092 #endif /* MODEST_TOOLKIT_GTK */
4094 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4096 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4097 modest_runtime_get_account_mgr(), server_account_name);
4098 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4099 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4102 gtk_widget_destroy (dialog);
4106 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4107 GtkWidget *label = gtk_label_new (txt);
4108 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4110 g_free (server_name);
4111 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4116 gchar *initial_username = modest_account_mgr_get_server_account_username (
4117 modest_runtime_get_account_mgr(), server_account_name);
4119 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
4120 if (initial_username)
4121 modest_entry_set_text (entry_username, initial_username);
4123 /* Dim this if a connection has ever succeeded with this username,
4124 * as per the UI spec: */
4125 /* const gboolean username_known = */
4126 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4127 /* modest_runtime_get_account_mgr(), server_account_name); */
4128 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4130 /* We drop the username sensitive code and disallow changing it here
4131 * as tinymail does not support really changing the username in the callback
4133 gtk_widget_set_sensitive (entry_username, FALSE);
4135 #ifndef MODEST_TOOLKIT_GTK
4136 /* Auto-capitalization is the default, so let's turn it off: */
4137 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4139 /* Create a size group to be used by all captions.
4140 * Note that HildonCaption does not create a default size group if we do not specify one.
4141 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4142 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4144 #ifdef MODEST_TOOLKIT_HILDON2
4145 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4146 _("mail_fi_username"), FALSE,
4149 GtkWidget *caption = hildon_caption_new (sizegroup,
4150 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4152 gtk_widget_show (entry_username);
4153 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4154 FALSE, FALSE, MODEST_MARGIN_HALF);
4155 gtk_widget_show (caption);
4157 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4159 #endif /* !MODEST_TOOLKIT_GTK */
4162 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
4163 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4164 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4166 #ifndef MODEST_TOOLKIT_GTK
4167 /* Auto-capitalization is the default, so let's turn it off: */
4168 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4169 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4171 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4172 _("mail_fi_password"), FALSE,
4174 gtk_widget_show (entry_password);
4175 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4176 FALSE, FALSE, MODEST_MARGIN_HALF);
4177 gtk_widget_show (caption);
4178 g_object_unref (sizegroup);
4180 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4182 #endif /* !MODEST_TOOLKIT_GTK */
4184 if (initial_username != NULL)
4185 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4187 /* This is not in the Maemo UI spec:
4188 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4189 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4193 fields = g_slice_new0 (PasswordDialogFields);
4194 fields->username = entry_username;
4195 fields->password = entry_password;
4196 fields->dialog = dialog;
4198 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4199 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4200 password_dialog_check_field (NULL, fields);
4202 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4204 while (!completed) {
4206 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4208 *username = g_strdup (modest_entry_get_text (entry_username));
4210 /* Note that an empty field becomes the "" string */
4211 if (*username && strlen (*username) > 0) {
4212 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4213 server_account_name,
4217 const gboolean username_was_changed =
4218 (strcmp (*username, initial_username) != 0);
4219 if (username_was_changed) {
4220 g_warning ("%s: tinymail does not yet support changing the "
4221 "username in the get_password() callback.\n", __FUNCTION__);
4227 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4228 _("mcen_ib_username_pw_incorrect"));
4234 *password = g_strdup (modest_entry_get_text (entry_password));
4236 /* We do not save the password in the configuration,
4237 * because this function is only called for passwords that should
4238 * not be remembered:
4239 modest_server_account_set_password (
4240 modest_runtime_get_account_mgr(), server_account_name,
4247 #ifndef MODEST_TOOLKIT_HILDON2
4248 /* Set parent to NULL or the banner will disappear with its parent dialog */
4249 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4261 /* This is not in the Maemo UI spec:
4262 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4268 g_free (initial_username);
4269 gtk_widget_destroy (dialog);
4270 g_slice_free (PasswordDialogFields, fields);
4272 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4276 modest_ui_actions_on_cut (GtkAction *action,
4277 ModestWindow *window)
4279 GtkWidget *focused_widget;
4280 GtkClipboard *clipboard;
4282 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4283 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4284 if (GTK_IS_EDITABLE (focused_widget)) {
4285 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4286 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4287 gtk_clipboard_store (clipboard);
4288 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4289 GtkTextBuffer *buffer;
4291 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4292 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4293 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4294 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4295 gtk_clipboard_store (clipboard);
4297 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4298 TnyList *header_list = modest_header_view_get_selected_headers (
4299 MODEST_HEADER_VIEW (focused_widget));
4300 gboolean continue_download = FALSE;
4301 gint num_of_unc_msgs;
4303 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4305 if (num_of_unc_msgs) {
4306 TnyAccount *account = get_account_from_header_list (header_list);
4308 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4309 g_object_unref (account);
4313 if (num_of_unc_msgs == 0 || continue_download) {
4314 /* modest_platform_information_banner (
4315 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4316 modest_header_view_cut_selection (
4317 MODEST_HEADER_VIEW (focused_widget));
4320 g_object_unref (header_list);
4321 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4322 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4327 modest_ui_actions_on_copy (GtkAction *action,
4328 ModestWindow *window)
4330 GtkClipboard *clipboard;
4331 GtkWidget *focused_widget;
4332 gboolean copied = TRUE;
4334 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4335 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4337 if (GTK_IS_LABEL (focused_widget)) {
4339 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4340 gtk_clipboard_set_text (clipboard, selection, -1);
4342 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4343 gtk_clipboard_store (clipboard);
4344 } else if (GTK_IS_EDITABLE (focused_widget)) {
4345 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4346 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4347 gtk_clipboard_store (clipboard);
4348 } else if (GTK_IS_HTML (focused_widget)) {
4351 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4352 if ((sel == NULL) || (sel[0] == '\0')) {
4355 gtk_html_copy (GTK_HTML (focused_widget));
4356 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4357 gtk_clipboard_store (clipboard);
4359 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4360 GtkTextBuffer *buffer;
4361 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4362 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4363 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4364 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4365 gtk_clipboard_store (clipboard);
4367 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4368 TnyList *header_list = modest_header_view_get_selected_headers (
4369 MODEST_HEADER_VIEW (focused_widget));
4370 gboolean continue_download = FALSE;
4371 gint num_of_unc_msgs;
4373 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4375 if (num_of_unc_msgs) {
4376 TnyAccount *account = get_account_from_header_list (header_list);
4378 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4379 g_object_unref (account);
4383 if (num_of_unc_msgs == 0 || continue_download) {
4384 modest_platform_information_banner (
4385 NULL, NULL, _CS("mcen_ib_getting_items"));
4386 modest_header_view_copy_selection (
4387 MODEST_HEADER_VIEW (focused_widget));
4391 g_object_unref (header_list);
4393 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4394 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4397 /* Show information banner if there was a copy to clipboard */
4399 modest_platform_information_banner (
4400 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4404 modest_ui_actions_on_undo (GtkAction *action,
4405 ModestWindow *window)
4407 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4408 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4409 #ifndef MODEST_TOOLKIT_HILDON2
4410 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4411 ModestEmailClipboard *clipboard = NULL;
4412 /* Clear clipboard source */
4413 clipboard = modest_runtime_get_email_clipboard ();
4414 modest_email_clipboard_clear (clipboard);
4417 g_return_if_reached ();
4422 modest_ui_actions_on_redo (GtkAction *action,
4423 ModestWindow *window)
4425 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4426 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4429 g_return_if_reached ();
4435 destroy_information_note (ModestMailOperation *mail_op,
4438 /* destroy information note */
4439 gtk_widget_destroy (GTK_WIDGET(user_data));
4443 destroy_folder_information_note (ModestMailOperation *mail_op,
4444 TnyFolder *new_folder,
4447 /* destroy information note */
4448 gtk_widget_destroy (GTK_WIDGET(user_data));
4453 paste_as_attachment_free (gpointer data)
4455 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4457 if (helper->banner) {
4458 gtk_widget_destroy (helper->banner);
4459 g_object_unref (helper->banner);
4465 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4470 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4471 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4476 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4481 modest_ui_actions_on_paste (GtkAction *action,
4482 ModestWindow *window)
4484 GtkWidget *focused_widget = NULL;
4485 GtkWidget *inf_note = NULL;
4486 ModestMailOperation *mail_op = NULL;
4488 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4489 if (GTK_IS_EDITABLE (focused_widget)) {
4490 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4491 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4492 ModestEmailClipboard *e_clipboard = NULL;
4493 e_clipboard = modest_runtime_get_email_clipboard ();
4494 if (modest_email_clipboard_cleared (e_clipboard)) {
4495 GtkTextBuffer *buffer;
4496 GtkClipboard *clipboard;
4498 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4499 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4500 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4501 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4502 ModestMailOperation *mail_op;
4503 TnyFolder *src_folder = NULL;
4504 TnyList *data = NULL;
4506 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4507 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4508 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4509 _CS("ckct_nw_pasting"));
4510 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4511 mail_op = modest_mail_operation_new (G_OBJECT (window));
4512 if (helper->banner != NULL) {
4513 g_object_ref (G_OBJECT (helper->banner));
4514 gtk_widget_show (GTK_WIDGET (helper->banner));
4518 modest_mail_operation_get_msgs_full (mail_op,
4520 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4522 paste_as_attachment_free);
4526 g_object_unref (data);
4528 g_object_unref (src_folder);
4531 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4532 ModestEmailClipboard *clipboard = NULL;
4533 TnyFolder *src_folder = NULL;
4534 TnyFolderStore *folder_store = NULL;
4535 TnyList *data = NULL;
4536 gboolean delete = FALSE;
4538 /* Check clipboard source */
4539 clipboard = modest_runtime_get_email_clipboard ();
4540 if (modest_email_clipboard_cleared (clipboard))
4543 /* Get elements to paste */
4544 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4546 /* Create a new mail operation */
4547 mail_op = modest_mail_operation_new (G_OBJECT(window));
4549 /* Get destination folder */
4550 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4552 /* transfer messages */
4556 /* Ask for user confirmation */
4558 modest_ui_actions_msgs_move_to_confirmation (window,
4559 TNY_FOLDER (folder_store),
4563 if (response == GTK_RESPONSE_OK) {
4564 /* Launch notification */
4565 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4566 _CS("ckct_nw_pasting"));
4567 if (inf_note != NULL) {
4568 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4569 gtk_widget_show (GTK_WIDGET(inf_note));
4572 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4573 modest_mail_operation_xfer_msgs (mail_op,
4575 TNY_FOLDER (folder_store),
4577 destroy_information_note,
4580 g_object_unref (mail_op);
4583 } else if (src_folder != NULL) {
4584 /* Launch notification */
4585 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4586 _CS("ckct_nw_pasting"));
4587 if (inf_note != NULL) {
4588 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4589 gtk_widget_show (GTK_WIDGET(inf_note));
4592 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4593 modest_mail_operation_xfer_folder (mail_op,
4597 destroy_folder_information_note,
4603 g_object_unref (data);
4604 if (src_folder != NULL)
4605 g_object_unref (src_folder);
4606 if (folder_store != NULL)
4607 g_object_unref (folder_store);
4613 modest_ui_actions_on_select_all (GtkAction *action,
4614 ModestWindow *window)
4616 GtkWidget *focused_widget;
4618 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4619 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4620 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4621 } else if (GTK_IS_LABEL (focused_widget)) {
4622 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4623 } else if (GTK_IS_EDITABLE (focused_widget)) {
4624 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4625 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4626 GtkTextBuffer *buffer;
4627 GtkTextIter start, end;
4629 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4630 gtk_text_buffer_get_start_iter (buffer, &start);
4631 gtk_text_buffer_get_end_iter (buffer, &end);
4632 gtk_text_buffer_select_range (buffer, &start, &end);
4633 } else if (GTK_IS_HTML (focused_widget)) {
4634 gtk_html_select_all (GTK_HTML (focused_widget));
4635 #ifndef MODEST_TOOLKIT_HILDON2
4636 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4637 GtkWidget *header_view = focused_widget;
4638 GtkTreeSelection *selection = NULL;
4640 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4641 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4642 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4645 /* Disable window dimming management */
4646 modest_window_disable_dimming (MODEST_WINDOW(window));
4648 /* Select all messages */
4649 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4650 gtk_tree_selection_select_all (selection);
4652 /* Set focuse on header view */
4653 gtk_widget_grab_focus (header_view);
4655 /* Enable window dimming management */
4656 modest_window_enable_dimming (MODEST_WINDOW(window));
4657 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4658 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4665 modest_ui_actions_on_mark_as_read (GtkAction *action,
4666 ModestWindow *window)
4668 g_return_if_fail (MODEST_IS_WINDOW(window));
4670 /* Mark each header as read */
4671 do_headers_action (window, headers_action_mark_as_read, NULL);
4675 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4676 ModestWindow *window)
4678 g_return_if_fail (MODEST_IS_WINDOW(window));
4680 /* Mark each header as read */
4681 do_headers_action (window, headers_action_mark_as_unread, NULL);
4685 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4686 GtkRadioAction *selected,
4687 ModestWindow *window)
4691 value = gtk_radio_action_get_current_value (selected);
4692 if (MODEST_IS_WINDOW (window)) {
4693 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4698 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4699 GtkRadioAction *selected,
4700 ModestWindow *window)
4702 TnyHeaderFlags flags;
4703 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4705 flags = gtk_radio_action_get_current_value (selected);
4706 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4710 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4711 GtkRadioAction *selected,
4712 ModestWindow *window)
4716 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4718 file_format = gtk_radio_action_get_current_value (selected);
4719 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4724 modest_ui_actions_on_zoom_plus (GtkAction *action,
4725 ModestWindow *window)
4727 g_return_if_fail (MODEST_IS_WINDOW (window));
4729 modest_window_zoom_plus (MODEST_WINDOW (window));
4733 modest_ui_actions_on_zoom_minus (GtkAction *action,
4734 ModestWindow *window)
4736 g_return_if_fail (MODEST_IS_WINDOW (window));
4738 modest_window_zoom_minus (MODEST_WINDOW (window));
4742 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4743 ModestWindow *window)
4745 ModestWindowMgr *mgr;
4746 gboolean fullscreen, active;
4747 g_return_if_fail (MODEST_IS_WINDOW (window));
4749 mgr = modest_runtime_get_window_mgr ();
4751 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4752 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4754 if (active != fullscreen) {
4755 modest_window_mgr_set_fullscreen_mode (mgr, active);
4756 #ifndef MODEST_TOOLKIT_HILDON2
4757 gtk_window_present (GTK_WINDOW (window));
4763 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4764 ModestWindow *window)
4766 ModestWindowMgr *mgr;
4767 gboolean fullscreen;
4769 g_return_if_fail (MODEST_IS_WINDOW (window));
4771 mgr = modest_runtime_get_window_mgr ();
4772 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4773 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4775 #ifndef MODEST_TOOLKIT_HILDON2
4776 gtk_window_present (GTK_WINDOW (window));
4781 * Used by modest_ui_actions_on_details to call do_headers_action
4784 headers_action_show_details (TnyHeader *header,
4785 ModestWindow *window,
4789 gboolean async_retrieval;
4792 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4793 async_retrieval = TRUE;
4794 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4796 async_retrieval = FALSE;
4798 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4800 g_object_unref (msg);
4804 * Show the header details in a ModestDetailsDialog widget
4807 modest_ui_actions_on_details (GtkAction *action,
4810 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4814 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4818 header = tny_msg_get_header (msg);
4820 headers_action_show_details (header, win, NULL);
4821 g_object_unref (header);
4823 g_object_unref (msg);
4824 #ifndef MODEST_TOOLKIT_HILDON2
4825 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4826 GtkWidget *folder_view, *header_view;
4828 /* Check which widget has the focus */
4829 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4830 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4831 if (gtk_widget_is_focus (folder_view)) {
4832 TnyFolderStore *folder_store
4833 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4834 if (!folder_store) {
4835 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4838 /* Show only when it's a folder */
4839 /* This function should not be called for account items,
4840 * because we dim the menu item for them. */
4841 if (TNY_IS_FOLDER (folder_store)) {
4842 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4843 TNY_FOLDER (folder_store));
4846 g_object_unref (folder_store);
4849 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4850 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4851 /* Show details of each header */
4852 do_headers_action (win, headers_action_show_details, header_view);
4855 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4857 GtkWidget *header_view;
4859 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4860 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4862 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4864 g_object_unref (folder);
4871 modest_ui_actions_on_limit_error (GtkAction *action,
4874 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4876 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4881 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4882 ModestMsgEditWindow *window)
4884 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4886 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4890 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4891 ModestMsgEditWindow *window)
4893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4895 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4898 #ifndef MODEST_TOOLKIT_HILDON2
4900 modest_ui_actions_toggle_folders_view (GtkAction *action,
4901 ModestMainWindow *main_window)
4903 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4905 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4906 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4908 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4913 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4914 ModestWindow *window)
4916 gboolean active, fullscreen = FALSE;
4917 ModestWindowMgr *mgr;
4919 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4921 /* Check if we want to toggle the toolbar view in fullscreen
4923 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4924 "ViewShowToolbarFullScreen")) {
4928 /* Toggle toolbar */
4929 mgr = modest_runtime_get_window_mgr ();
4930 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4934 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4935 ModestMsgEditWindow *window)
4937 modest_msg_edit_window_select_font (window);
4942 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4943 const gchar *display_name,
4946 /* don't update the display name if it was already set;
4947 * updating the display name apparently is expensive */
4948 const gchar* old_name = gtk_window_get_title (window);
4950 if (display_name == NULL)
4953 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4954 return; /* don't do anything */
4956 /* This is usually used to change the title of the main window, which
4957 * is the one that holds the folder view. Note that this change can
4958 * happen even when the widget doesn't have the focus. */
4959 gtk_window_set_title (window, display_name);
4964 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4966 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4967 modest_msg_edit_window_select_contacts (window);
4971 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4973 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4974 modest_msg_edit_window_check_names (window, FALSE);
4977 #ifndef MODEST_TOOLKIT_HILDON2
4979 * This function is used to track changes in the selection of the
4980 * folder view that is inside the "move to" dialog to enable/disable
4981 * the OK button because we do not want the user to select a disallowed
4982 * destination for a folder.
4983 * The user also not desired to be able to use NEW button on items where
4984 * folder creation is not possibel.
4987 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4988 TnyFolderStore *folder_store,
4992 GtkWidget *dialog = NULL;
4993 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4994 gboolean moving_folder = FALSE;
4995 gboolean is_local_account = TRUE;
4996 GtkWidget *folder_view = NULL;
4997 ModestTnyFolderRules rules;
4999 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5004 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5008 /* check if folder_store is an remote account */
5009 if (TNY_IS_ACCOUNT (folder_store)) {
5010 TnyAccount *local_account = NULL;
5011 TnyAccount *mmc_account = NULL;
5012 ModestTnyAccountStore *account_store = NULL;
5014 account_store = modest_runtime_get_account_store ();
5015 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5016 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5018 if ((gpointer) local_account != (gpointer) folder_store &&
5019 (gpointer) mmc_account != (gpointer) folder_store) {
5020 ModestProtocolType proto;
5021 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5022 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5023 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5025 is_local_account = FALSE;
5026 /* New button should be dimmed on remote
5028 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5030 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5032 g_object_unref (local_account);
5034 /* It could not exist */
5036 g_object_unref (mmc_account);
5039 /* Check the target folder rules */
5040 if (TNY_IS_FOLDER (folder_store)) {
5041 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5042 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5043 ok_sensitive = FALSE;
5044 new_sensitive = FALSE;
5049 /* Check if we're moving a folder */
5050 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5051 /* Get the widgets */
5052 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5053 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5054 if (gtk_widget_is_focus (folder_view))
5055 moving_folder = TRUE;
5058 if (moving_folder) {
5059 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5061 /* Get the folder to move */
5062 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5064 /* Check that we're not moving to the same folder */
5065 if (TNY_IS_FOLDER (moved_folder)) {
5066 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5067 if (parent == folder_store)
5068 ok_sensitive = FALSE;
5069 g_object_unref (parent);
5072 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5073 /* Do not allow to move to an account unless it's the
5074 local folders account */
5075 if (!is_local_account)
5076 ok_sensitive = FALSE;
5079 if (ok_sensitive && (moved_folder == folder_store)) {
5080 /* Do not allow to move to itself */
5081 ok_sensitive = FALSE;
5083 g_object_unref (moved_folder);
5085 TnyFolder *src_folder = NULL;
5087 /* Moving a message */
5088 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5090 TnyHeader *header = NULL;
5091 header = modest_msg_view_window_get_header
5092 (MODEST_MSG_VIEW_WINDOW (user_data));
5093 if (!TNY_IS_HEADER(header))
5094 g_warning ("%s: could not get source header", __FUNCTION__);
5096 src_folder = tny_header_get_folder (header);
5099 g_object_unref (header);
5102 TNY_FOLDER (modest_folder_view_get_selected
5103 (MODEST_FOLDER_VIEW (folder_view)));
5106 if (TNY_IS_FOLDER(src_folder)) {
5107 /* Do not allow to move the msg to the same folder */
5108 /* Do not allow to move the msg to an account */
5109 if ((gpointer) src_folder == (gpointer) folder_store ||
5110 TNY_IS_ACCOUNT (folder_store))
5111 ok_sensitive = FALSE;
5112 g_object_unref (src_folder);
5114 g_warning ("%s: could not get source folder", __FUNCTION__);
5118 /* Set sensitivity of the OK and NEW button */
5119 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5120 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5125 on_move_to_dialog_response (GtkDialog *dialog,
5129 GtkWidget *parent_win;
5130 MoveToInfo *helper = NULL;
5131 ModestFolderView *folder_view;
5132 gboolean unset_edit_mode = FALSE;
5134 helper = (MoveToInfo *) user_data;
5136 parent_win = (GtkWidget *) helper->win;
5137 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5138 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5140 TnyFolderStore *dst_folder;
5141 TnyFolderStore *selected;
5143 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5144 selected = modest_folder_view_get_selected (folder_view);
5145 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5146 g_object_unref (selected);
5148 case GTK_RESPONSE_NONE:
5149 case GTK_RESPONSE_CANCEL:
5150 case GTK_RESPONSE_DELETE_EVENT:
5152 case GTK_RESPONSE_OK:
5153 dst_folder = modest_folder_view_get_selected (folder_view);
5155 #ifndef MODEST_TOOLKIT_HILDON2
5156 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5157 /* Clean list to move used for filtering */
5158 modest_folder_view_set_list_to_move (folder_view, NULL);
5160 modest_ui_actions_on_main_window_move_to (NULL,
5161 GTK_WIDGET (folder_view),
5163 MODEST_MAIN_WINDOW (parent_win));
5165 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5166 /* Clean list to move used for filtering */
5167 modest_folder_view_set_list_to_move (folder_view, NULL);
5169 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5172 GTK_WINDOW (parent_win));
5175 /* if the user selected a root folder
5176 (account) then do not perform any action */
5177 if (TNY_IS_ACCOUNT (dst_folder)) {
5178 g_signal_stop_emission_by_name (dialog, "response");
5182 /* Clean list to move used for filtering */
5183 modest_folder_view_set_list_to_move (folder_view, NULL);
5185 /* Moving from headers window in edit mode */
5186 modest_ui_actions_on_window_move_to (NULL, helper->list,
5188 MODEST_WINDOW (parent_win));
5192 g_object_unref (dst_folder);
5194 unset_edit_mode = TRUE;
5197 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5200 /* Free the helper and exit */
5202 g_object_unref (helper->list);
5203 if (unset_edit_mode) {
5204 #ifdef MODEST_TOOLKIT_HILDON2
5205 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5208 g_slice_free (MoveToInfo, helper);
5209 gtk_widget_destroy (GTK_WIDGET (dialog));
5213 create_move_to_dialog (GtkWindow *win,
5214 GtkWidget *folder_view,
5215 TnyList *list_to_move)
5217 GtkWidget *dialog, *tree_view = NULL;
5219 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5221 #ifndef MODEST_TOOLKIT_HILDON2
5222 /* Track changes in the selection to
5223 * disable the OK button whenever "Move to" is not possible
5224 * disbale NEW button whenever New is not possible */
5225 g_signal_connect (tree_view,
5226 "folder_selection_changed",
5227 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5231 /* It could happen that we're trying to move a message from a
5232 window (msg window for example) after the main window was
5233 closed, so we can not just get the model of the folder
5235 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5236 const gchar *visible_id = NULL;
5238 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5239 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5240 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5241 MODEST_FOLDER_VIEW(tree_view));
5244 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5246 /* Show the same account than the one that is shown in the main window */
5247 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5250 const gchar *active_account_name = NULL;
5251 ModestAccountMgr *mgr = NULL;
5252 ModestAccountSettings *settings = NULL;
5253 ModestServerAccountSettings *store_settings = NULL;
5255 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5256 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5257 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5258 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5260 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5261 mgr = modest_runtime_get_account_mgr ();
5262 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5265 const gchar *store_account_name;
5266 store_settings = modest_account_settings_get_store_settings (settings);
5267 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5269 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5270 store_account_name);
5271 g_object_unref (store_settings);
5272 g_object_unref (settings);
5276 /* we keep a pointer to the embedded folder view, so we can
5277 * retrieve it with get_folder_view_from_move_to_dialog (see
5278 * above) later (needed for focus handling)
5280 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5282 /* Hide special folders */
5283 #ifndef MODEST_TOOLKIT_HILDON2
5284 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5287 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5288 #ifndef MODEST_TOOLKIT_HILDON2
5289 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5292 gtk_widget_show (GTK_WIDGET (tree_view));
5298 * Shows a confirmation dialog to the user when we're moving messages
5299 * from a remote server to the local storage. Returns the dialog
5300 * response. If it's other kind of movement then it always returns
5303 * This one is used by the next functions:
5304 * modest_ui_actions_on_paste - commented out
5305 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5308 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5309 TnyFolder *dest_folder,
5313 gint response = GTK_RESPONSE_OK;
5314 TnyAccount *account = NULL;
5315 TnyFolder *src_folder = NULL;
5316 TnyIterator *iter = NULL;
5317 TnyHeader *header = NULL;
5319 /* return with OK if the destination is a remote folder */
5320 if (modest_tny_folder_is_remote_folder (dest_folder))
5321 return GTK_RESPONSE_OK;
5323 /* Get source folder */
5324 iter = tny_list_create_iterator (headers);
5325 header = TNY_HEADER (tny_iterator_get_current (iter));
5327 src_folder = tny_header_get_folder (header);
5328 g_object_unref (header);
5330 g_object_unref (iter);
5332 /* if no src_folder, message may be an attahcment */
5333 if (src_folder == NULL)
5334 return GTK_RESPONSE_CANCEL;
5336 /* If the source is a local or MMC folder */
5337 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5338 g_object_unref (src_folder);
5339 return GTK_RESPONSE_OK;
5342 /* Get the account */
5343 account = tny_folder_get_account (src_folder);
5345 /* now if offline we ask the user */
5346 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5347 response = GTK_RESPONSE_OK;
5349 response = GTK_RESPONSE_CANCEL;
5352 g_object_unref (src_folder);
5353 g_object_unref (account);
5359 move_to_helper_destroyer (gpointer user_data)
5361 MoveToHelper *helper = (MoveToHelper *) user_data;
5363 /* Close the "Pasting" information banner */
5364 if (helper->banner) {
5365 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5366 g_object_unref (helper->banner);
5368 if (gtk_tree_row_reference_valid (helper->reference)) {
5369 gtk_tree_row_reference_free (helper->reference);
5370 helper->reference = NULL;
5376 move_to_cb (ModestMailOperation *mail_op,
5379 MoveToHelper *helper = (MoveToHelper *) user_data;
5380 GObject *object = modest_mail_operation_get_source (mail_op);
5382 /* Note that the operation could have failed, in that case do
5384 if (modest_mail_operation_get_status (mail_op) !=
5385 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5388 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5389 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5391 if (!modest_msg_view_window_select_next_message (self) &&
5392 !modest_msg_view_window_select_previous_message (self)) {
5393 /* No more messages to view, so close this window */
5394 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5396 #ifndef MODEST_TOOLKIT_HILDON2
5397 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5398 gtk_tree_row_reference_valid (helper->reference)) {
5399 GtkWidget *header_view;
5401 GtkTreeSelection *sel;
5403 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5404 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5405 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5406 path = gtk_tree_row_reference_get_path (helper->reference);
5407 /* We need to unselect the previous one
5408 because we could be copying instead of
5410 gtk_tree_selection_unselect_all (sel);
5411 gtk_tree_selection_select_path (sel, path);
5412 gtk_tree_path_free (path);
5415 g_object_unref (object);
5418 /* Destroy the helper */
5419 move_to_helper_destroyer (helper);
5423 folder_move_to_cb (ModestMailOperation *mail_op,
5424 TnyFolder *new_folder,
5429 object = modest_mail_operation_get_source (mail_op);
5430 #ifndef MODEST_TOOLKIT_HILDON2
5431 if (MODEST_IS_MAIN_WINDOW (object)) {
5432 GtkWidget *folder_view;
5433 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5434 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5435 g_object_ref (folder_view);
5436 g_object_unref (object);
5437 move_to_cb (mail_op, user_data);
5438 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5439 g_object_unref (folder_view);
5444 move_to_cb (mail_op, user_data);
5449 msgs_move_to_cb (ModestMailOperation *mail_op,
5452 move_to_cb (mail_op, user_data);
5456 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5459 GObject *win = NULL;
5460 const GError *error;
5461 TnyAccount *account = NULL;
5463 #ifndef MODEST_TOOLKIT_HILDON2
5464 ModestWindow *main_window = NULL;
5466 /* Disable next automatic folder selection */
5467 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5468 FALSE); /* don't create */
5470 /* Show notification dialog only if the main window exists */
5472 GtkWidget *folder_view = NULL;
5474 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5475 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5476 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5478 if (user_data && TNY_IS_FOLDER (user_data)) {
5479 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5480 TNY_FOLDER (user_data), FALSE);
5484 win = modest_mail_operation_get_source (mail_op);
5485 error = modest_mail_operation_get_error (mail_op);
5487 if (TNY_IS_FOLDER (user_data))
5488 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5489 else if (TNY_IS_ACCOUNT (user_data))
5490 account = g_object_ref (user_data);
5492 /* If it's not a disk full error then show a generic error */
5493 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5494 (GtkWidget *) win, (GError *) error,
5496 modest_platform_run_information_dialog ((GtkWindow *) win,
5497 _("mail_in_ui_folder_move_target_error"),
5500 g_object_unref (account);
5502 g_object_unref (win);
5505 #ifndef MODEST_TOOLKIT_HILDON2
5507 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5516 gint pending_purges = 0;
5517 gboolean some_purged = FALSE;
5518 ModestWindow *win = MODEST_WINDOW (user_data);
5519 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5521 /* If there was any error */
5522 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5523 modest_window_mgr_unregister_header (mgr, header);
5527 /* Once the message has been retrieved for purging, we check if
5528 * it's all ok for purging */
5530 parts = tny_simple_list_new ();
5531 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5532 iter = tny_list_create_iterator (parts);
5534 while (!tny_iterator_is_done (iter)) {
5536 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5537 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5538 if (tny_mime_part_is_purged (part))
5545 g_object_unref (part);
5547 tny_iterator_next (iter);
5549 g_object_unref (iter);
5552 if (pending_purges>0) {
5554 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5556 if (response == GTK_RESPONSE_OK) {
5559 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5560 iter = tny_list_create_iterator (parts);
5561 while (!tny_iterator_is_done (iter)) {
5564 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5565 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5566 tny_mime_part_set_purged (part);
5569 g_object_unref (part);
5571 tny_iterator_next (iter);
5573 g_object_unref (iter);
5575 tny_msg_rewrite_cache (msg);
5577 gtk_widget_destroy (info);
5581 modest_window_mgr_unregister_header (mgr, header);
5583 g_object_unref (parts);
5587 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5588 ModestMainWindow *win)
5590 GtkWidget *header_view;
5591 TnyList *header_list;
5593 TnyHeaderFlags flags;
5594 ModestWindow *msg_view_window = NULL;
5597 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5599 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5600 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5602 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5604 g_warning ("%s: no header selected", __FUNCTION__);
5608 if (tny_list_get_length (header_list) == 1) {
5609 TnyIterator *iter = tny_list_create_iterator (header_list);
5610 header = TNY_HEADER (tny_iterator_get_current (iter));
5611 g_object_unref (iter);
5615 if (!header || !TNY_IS_HEADER(header)) {
5616 g_warning ("%s: header is not valid", __FUNCTION__);
5620 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5621 header, &msg_view_window);
5622 flags = tny_header_get_flags (header);
5623 if (!(flags & TNY_HEADER_FLAG_CACHED))
5626 if (msg_view_window != NULL)
5627 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5629 /* do nothing; uid was registered before, so window is probably on it's way */
5630 g_debug ("header %p has already been registered", header);
5633 ModestMailOperation *mail_op = NULL;
5634 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5635 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5636 modest_ui_actions_disk_operations_error_handler,
5638 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5639 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5641 g_object_unref (mail_op);
5644 g_object_unref (header);
5646 g_object_unref (header_list);
5651 * Checks if we need a connection to do the transfer and if the user
5652 * wants to connect to complete it
5655 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5656 TnyFolderStore *src_folder,
5658 TnyFolder *dst_folder,
5659 gboolean delete_originals,
5660 gboolean *need_connection,
5663 TnyAccount *src_account;
5664 gint uncached_msgs = 0;
5666 /* We don't need any further check if
5668 * 1- the source folder is local OR
5669 * 2- the device is already online
5671 if (!modest_tny_folder_store_is_remote (src_folder) ||
5672 tny_device_is_online (modest_runtime_get_device())) {
5673 *need_connection = FALSE;
5678 /* We must ask for a connection when
5680 * - the message(s) is not already cached OR
5681 * - the message(s) is cached but the leave_on_server setting
5682 * is FALSE (because we need to sync the source folder to
5683 * delete the message from the server (for IMAP we could do it
5684 * offline, it'll take place the next time we get a
5687 uncached_msgs = header_list_count_uncached_msgs (headers);
5688 src_account = get_account_from_folder_store (src_folder);
5689 if (uncached_msgs > 0) {
5693 *need_connection = TRUE;
5694 num_headers = tny_list_get_length (headers);
5695 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5697 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5698 GTK_RESPONSE_CANCEL) {
5704 /* The transfer is possible and the user wants to */
5707 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5708 const gchar *account_name;
5709 gboolean leave_on_server;
5711 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5712 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5715 if (leave_on_server == TRUE) {
5716 *need_connection = FALSE;
5718 *need_connection = TRUE;
5721 *need_connection = FALSE;
5726 g_object_unref (src_account);
5730 xfer_messages_error_handler (ModestMailOperation *mail_op,
5734 const GError *error;
5735 TnyAccount *account;
5737 win = modest_mail_operation_get_source (mail_op);
5738 error = modest_mail_operation_get_error (mail_op);
5740 /* We cannot get the account from the mail op as that is the
5741 source account and for checking memory full conditions we
5742 need the destination one */
5743 account = TNY_ACCOUNT (user_data);
5746 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5747 (GtkWidget *) win, (GError*) error,
5748 account, _KR("cerm_memory_card_full"))) {
5749 modest_platform_run_information_dialog ((GtkWindow *) win,
5750 _("mail_in_ui_folder_move_target_error"),
5754 g_object_unref (win);
5758 TnyFolderStore *dst_folder;
5763 * Utility function that transfer messages from both the main window
5764 * and the msg view window when using the "Move to" dialog
5767 xfer_messages_performer (gboolean canceled,
5769 GtkWindow *parent_window,
5770 TnyAccount *account,
5773 ModestWindow *win = MODEST_WINDOW (parent_window);
5774 TnyAccount *dst_account = NULL;
5775 gboolean dst_forbids_message_add = FALSE;
5776 XferMsgsHelper *helper;
5777 MoveToHelper *movehelper;
5778 ModestMailOperation *mail_op;
5780 helper = (XferMsgsHelper *) user_data;
5782 if (canceled || err) {
5783 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5784 (GtkWidget *) parent_window, err,
5786 /* Show the proper error message */
5787 modest_ui_actions_on_account_connection_error (parent_window, account);
5792 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5794 /* tinymail will return NULL for local folders it seems */
5795 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5796 modest_tny_account_get_protocol_type (dst_account),
5797 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5799 if (dst_forbids_message_add) {
5800 modest_platform_information_banner (GTK_WIDGET (win),
5802 ngettext("mail_in_ui_folder_move_target_error",
5803 "mail_in_ui_folder_move_targets_error",
5804 tny_list_get_length (helper->headers)));
5808 movehelper = g_new0 (MoveToHelper, 1);
5810 #ifndef MODEST_TOOLKIT_HILDON2
5811 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5812 _CS("ckct_nw_pasting"));
5813 if (movehelper->banner != NULL) {
5814 g_object_ref (movehelper->banner);
5815 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5818 if (MODEST_IS_MAIN_WINDOW (win)) {
5819 GtkWidget *header_view =
5820 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5821 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5822 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5826 /* Perform the mail operation */
5827 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5828 xfer_messages_error_handler,
5829 g_object_ref (dst_account),
5831 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5834 modest_mail_operation_xfer_msgs (mail_op,
5836 TNY_FOLDER (helper->dst_folder),
5841 g_object_unref (G_OBJECT (mail_op));
5844 g_object_unref (dst_account);
5845 g_object_unref (helper->dst_folder);
5846 g_object_unref (helper->headers);
5847 g_slice_free (XferMsgsHelper, helper);
5851 TnyFolder *src_folder;
5852 TnyFolderStore *dst_folder;
5853 gboolean delete_original;
5854 GtkWidget *folder_view;
5858 on_move_folder_cb (gboolean canceled,
5860 GtkWindow *parent_window,
5861 TnyAccount *account,
5864 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5865 GtkTreeSelection *sel;
5866 ModestMailOperation *mail_op = NULL;
5868 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5869 /* Note that the connection process can fail due to
5870 memory low conditions as it can not successfully
5871 store the summary */
5872 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5873 (GtkWidget*) parent_window, err,
5875 g_debug ("Error connecting when trying to move a folder");
5877 g_object_unref (G_OBJECT (info->src_folder));
5878 g_object_unref (G_OBJECT (info->dst_folder));
5883 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5884 #ifndef MODEST_TOOLKIT_HILDON2
5885 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5886 _CS("ckct_nw_pasting"));
5887 if (helper->banner != NULL) {
5888 g_object_ref (helper->banner);
5889 gtk_widget_show (GTK_WIDGET(helper->banner));
5892 /* Clean folder on header view before moving it */
5893 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5894 gtk_tree_selection_unselect_all (sel);
5896 /* Let gtk events run. We need that the folder
5897 view frees its reference to the source
5898 folder *before* issuing the mail operation
5899 so we need the signal handler of selection
5900 changed to happen before the mail
5902 while (gtk_events_pending ())
5903 gtk_main_iteration (); */
5906 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5907 modest_ui_actions_move_folder_error_handler,
5908 g_object_ref (info->dst_folder), g_object_unref);
5909 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5912 #ifndef MODEST_TOOLKIT_HILDON2
5913 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5914 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5915 TNY_FOLDER (info->dst_folder), TRUE);
5918 modest_mail_operation_xfer_folder (mail_op,
5919 TNY_FOLDER (info->src_folder),
5921 info->delete_original,
5924 g_object_unref (G_OBJECT (info->src_folder));
5926 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5929 /* Unref mail operation */
5930 g_object_unref (G_OBJECT (mail_op));
5931 g_object_unref (G_OBJECT (info->dst_folder));
5936 get_account_from_folder_store (TnyFolderStore *folder_store)
5938 if (TNY_IS_ACCOUNT (folder_store))
5939 return g_object_ref (folder_store);
5941 return tny_folder_get_account (TNY_FOLDER (folder_store));
5944 #ifndef MODEST_TOOLKIT_HILDON2
5946 * UI handler for the "Move to" action when invoked from the
5950 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5951 GtkWidget *folder_view,
5952 TnyFolderStore *dst_folder,
5953 ModestMainWindow *win)
5955 ModestHeaderView *header_view = NULL;
5956 TnyFolderStore *src_folder = NULL;
5958 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5960 /* Get the source folder */
5961 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5963 /* Get header view */
5964 header_view = (ModestHeaderView *)
5965 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5967 /* Get folder or messages to transfer */
5968 if (gtk_widget_is_focus (folder_view)) {
5969 gboolean do_xfer = TRUE;
5971 /* Allow only to transfer folders to the local root folder */
5972 if (TNY_IS_ACCOUNT (dst_folder) &&
5973 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5974 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5976 } else if (!TNY_IS_FOLDER (src_folder)) {
5977 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5982 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5983 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5985 info->src_folder = g_object_ref (src_folder);
5986 info->dst_folder = g_object_ref (dst_folder);
5987 info->delete_original = TRUE;
5988 info->folder_view = folder_view;
5990 connect_info->callback = on_move_folder_cb;
5991 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5992 connect_info->data = info;
5994 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5995 TNY_FOLDER_STORE (src_folder),
5998 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6001 headers = modest_header_view_get_selected_headers(header_view);
6003 /* Transfer the messages */
6004 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6005 headers, TNY_FOLDER (dst_folder));
6007 g_object_unref (headers);
6011 g_object_unref (src_folder);
6015 #ifdef MODEST_TOOLKIT_HILDON2
6017 * UI handler for the "Move to" action when invoked from the
6018 * ModestFolderWindow
6021 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6022 TnyFolderStore *dst_folder,
6026 TnyFolderStore *src_folder = NULL;
6027 TnyIterator *iterator;
6029 if (tny_list_get_length (selection) != 1)
6032 iterator = tny_list_create_iterator (selection);
6033 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6034 g_object_unref (iterator);
6037 gboolean do_xfer = TRUE;
6039 /* Allow only to transfer folders to the local root folder */
6040 if (TNY_IS_ACCOUNT (dst_folder) &&
6041 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6042 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6045 modest_platform_run_information_dialog (win,
6046 _("mail_in_ui_folder_move_target_error"),
6048 } else if (!TNY_IS_FOLDER (src_folder)) {
6049 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6054 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6055 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6057 info->src_folder = g_object_ref (src_folder);
6058 info->dst_folder = g_object_ref (dst_folder);
6059 info->delete_original = TRUE;
6060 info->folder_view = folder_view;
6062 connect_info->callback = on_move_folder_cb;
6063 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6064 connect_info->data = info;
6066 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6067 TNY_FOLDER_STORE (src_folder),
6072 g_object_unref (src_folder);
6078 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6079 TnyFolder *src_folder,
6081 TnyFolder *dst_folder)
6083 gboolean need_connection = TRUE;
6084 gboolean do_xfer = TRUE;
6085 XferMsgsHelper *helper;
6087 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6088 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6089 g_return_if_fail (TNY_IS_LIST (headers));
6091 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6092 headers, TNY_FOLDER (dst_folder),
6093 TRUE, &need_connection,
6096 /* If we don't want to transfer just return */
6100 /* Create the helper */
6101 helper = g_slice_new (XferMsgsHelper);
6102 helper->dst_folder = g_object_ref (dst_folder);
6103 helper->headers = g_object_ref (headers);
6105 if (need_connection) {
6106 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6107 connect_info->callback = xfer_messages_performer;
6108 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6109 connect_info->data = helper;
6111 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6112 TNY_FOLDER_STORE (src_folder),
6115 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6116 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6117 src_account, helper);
6118 g_object_unref (src_account);
6123 * UI handler for the "Move to" action when invoked from the
6124 * ModestMsgViewWindow
6127 modest_ui_actions_on_window_move_to (GtkAction *action,
6129 TnyFolderStore *dst_folder,
6132 TnyFolder *src_folder = NULL;
6134 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6137 TnyHeader *header = NULL;
6140 iter = tny_list_create_iterator (headers);
6141 header = (TnyHeader *) tny_iterator_get_current (iter);
6142 src_folder = tny_header_get_folder (header);
6144 /* Transfer the messages */
6145 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6147 TNY_FOLDER (dst_folder));
6150 g_object_unref (header);
6151 g_object_unref (iter);
6152 g_object_unref (src_folder);
6157 modest_ui_actions_on_move_to (GtkAction *action,
6160 modest_ui_actions_on_edit_mode_move_to (win);
6164 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6166 GtkWidget *dialog = NULL;
6167 MoveToInfo *helper = NULL;
6168 TnyList *list_to_move;
6170 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6172 #ifndef MODEST_TOOLKIT_HILDON2
6173 /* Get the main window if exists */
6174 ModestMainWindow *main_window;
6175 if (MODEST_IS_MAIN_WINDOW (win))
6176 main_window = MODEST_MAIN_WINDOW (win);
6179 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6180 FALSE)); /* don't create */
6183 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6188 if (tny_list_get_length (list_to_move) < 1) {
6189 g_object_unref (list_to_move);
6193 /* Create and run the dialog */
6194 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6195 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6196 GTK_WINDOW (dialog),
6200 helper = g_slice_new0 (MoveToInfo);
6201 helper->list = list_to_move;
6204 /* Listen to response signal */
6205 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6207 /* Show the dialog */
6208 gtk_widget_show (dialog);
6214 * Calls #HeadersFunc for each header already selected in the main
6215 * window or the message currently being shown in the msg view window
6218 do_headers_action (ModestWindow *win,
6222 TnyList *headers_list = NULL;
6223 TnyIterator *iter = NULL;
6224 TnyHeader *header = NULL;
6225 TnyFolder *folder = NULL;
6228 headers_list = get_selected_headers (win);
6232 /* Get the folder */
6233 iter = tny_list_create_iterator (headers_list);
6234 header = TNY_HEADER (tny_iterator_get_current (iter));
6236 folder = tny_header_get_folder (header);
6237 g_object_unref (header);
6240 /* Call the function for each header */
6241 while (!tny_iterator_is_done (iter)) {
6242 header = TNY_HEADER (tny_iterator_get_current (iter));
6243 func (header, win, user_data);
6244 g_object_unref (header);
6245 tny_iterator_next (iter);
6248 /* Trick: do a poke status in order to speed up the signaling
6251 tny_folder_poke_status (folder);
6252 g_object_unref (folder);
6256 g_object_unref (iter);
6257 g_object_unref (headers_list);
6261 modest_ui_actions_view_attachment (GtkAction *action,
6262 ModestWindow *window)
6264 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6265 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6267 /* not supported window for this action */
6268 g_return_if_reached ();
6273 modest_ui_actions_save_attachments (GtkAction *action,
6274 ModestWindow *window)
6276 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6278 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6281 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6283 /* not supported window for this action */
6284 g_return_if_reached ();
6289 modest_ui_actions_remove_attachments (GtkAction *action,
6290 ModestWindow *window)
6292 #ifndef MODEST_TOOLKIT_HILDON2
6293 if (MODEST_IS_MAIN_WINDOW (window)) {
6294 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6295 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6297 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6299 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6301 /* not supported window for this action */
6302 g_return_if_reached ();
6307 modest_ui_actions_on_settings (GtkAction *action,
6312 dialog = modest_platform_get_global_settings_dialog ();
6313 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6314 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6315 gtk_widget_show_all (dialog);
6317 gtk_dialog_run (GTK_DIALOG (dialog));
6319 gtk_widget_destroy (dialog);
6323 modest_ui_actions_on_help (GtkAction *action,
6326 /* Help app is not available at all in fremantle */
6327 #ifndef MODEST_TOOLKIT_HILDON2
6328 const gchar *help_id;
6330 g_return_if_fail (win && GTK_IS_WINDOW(win));
6332 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6335 modest_platform_show_help (GTK_WINDOW (win), help_id);
6340 modest_ui_actions_on_csm_help (GtkAction *action,
6343 /* Help app is not available at all in fremantle */
6344 #ifndef MODEST_TOOLKIT_HILDON2
6346 const gchar* help_id = NULL;
6347 GtkWidget *folder_view;
6348 TnyFolderStore *folder_store;
6350 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6352 /* Get selected folder */
6353 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6354 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6355 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6357 /* Switch help_id */
6358 if (folder_store && TNY_IS_FOLDER (folder_store))
6359 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6362 g_object_unref (folder_store);
6365 modest_platform_show_help (GTK_WINDOW (win), help_id);
6367 modest_ui_actions_on_help (action, win);
6372 retrieve_contents_cb (ModestMailOperation *mail_op,
6379 /* We only need this callback to show an error in case of
6380 memory low condition */
6381 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6382 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6387 retrieve_msg_contents_performer (gboolean canceled,
6389 GtkWindow *parent_window,
6390 TnyAccount *account,
6393 ModestMailOperation *mail_op;
6394 TnyList *headers = TNY_LIST (user_data);
6396 if (err || canceled) {
6397 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6398 (GtkWidget *) parent_window, err,
6403 /* Create mail operation */
6404 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6405 modest_ui_actions_disk_operations_error_handler,
6407 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6408 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6411 g_object_unref (mail_op);
6413 g_object_unref (headers);
6414 g_object_unref (account);
6418 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6419 ModestWindow *window)
6421 TnyList *headers = NULL;
6422 TnyAccount *account = NULL;
6423 TnyIterator *iter = NULL;
6424 TnyHeader *header = NULL;
6425 TnyFolder *folder = NULL;
6428 headers = get_selected_headers (window);
6432 /* Pick the account */
6433 iter = tny_list_create_iterator (headers);
6434 header = TNY_HEADER (tny_iterator_get_current (iter));
6435 folder = tny_header_get_folder (header);
6436 account = tny_folder_get_account (folder);
6437 g_object_unref (folder);
6438 g_object_unref (header);
6439 g_object_unref (iter);
6441 /* Connect and perform the message retrieval */
6442 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6443 g_object_ref (account),
6444 retrieve_msg_contents_performer,
6445 g_object_ref (headers));
6448 g_object_unref (account);
6449 g_object_unref (headers);
6453 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6455 g_return_if_fail (MODEST_IS_WINDOW (window));
6458 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6462 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6464 g_return_if_fail (MODEST_IS_WINDOW (window));
6467 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6471 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6472 ModestWindow *window)
6474 g_return_if_fail (MODEST_IS_WINDOW (window));
6477 modest_ui_actions_check_menu_dimming_rules (window);
6481 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6482 ModestWindow *window)
6484 g_return_if_fail (MODEST_IS_WINDOW (window));
6487 modest_ui_actions_check_menu_dimming_rules (window);
6491 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6492 ModestWindow *window)
6494 g_return_if_fail (MODEST_IS_WINDOW (window));
6497 modest_ui_actions_check_menu_dimming_rules (window);
6501 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6502 ModestWindow *window)
6504 g_return_if_fail (MODEST_IS_WINDOW (window));
6507 modest_ui_actions_check_menu_dimming_rules (window);
6511 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6512 ModestWindow *window)
6514 g_return_if_fail (MODEST_IS_WINDOW (window));
6517 modest_ui_actions_check_menu_dimming_rules (window);
6521 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6522 ModestWindow *window)
6524 g_return_if_fail (MODEST_IS_WINDOW (window));
6527 modest_ui_actions_check_menu_dimming_rules (window);
6531 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6532 ModestWindow *window)
6534 g_return_if_fail (MODEST_IS_WINDOW (window));
6537 modest_ui_actions_check_menu_dimming_rules (window);
6541 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6542 ModestWindow *window)
6544 g_return_if_fail (MODEST_IS_WINDOW (window));
6547 modest_ui_actions_check_menu_dimming_rules (window);
6551 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6552 ModestWindow *window)
6554 g_return_if_fail (MODEST_IS_WINDOW (window));
6557 modest_ui_actions_check_menu_dimming_rules (window);
6561 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6563 g_return_if_fail (MODEST_IS_WINDOW (window));
6565 /* we check for low-mem; in that case, show a warning, and don't allow
6568 if (modest_platform_check_memory_low (window, TRUE))
6571 modest_platform_show_search_messages (GTK_WINDOW (window));
6575 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6577 g_return_if_fail (MODEST_IS_WINDOW (win));
6580 /* we check for low-mem; in that case, show a warning, and don't allow
6581 * for the addressbook
6583 if (modest_platform_check_memory_low (win, TRUE))
6587 modest_platform_show_addressbook (GTK_WINDOW (win));
6592 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6593 ModestWindow *window)
6596 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6598 if (GTK_IS_TOGGLE_ACTION (action))
6599 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6603 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6607 #ifndef MODEST_TOOLKIT_HILDON2
6609 on_send_receive_finished (ModestMailOperation *mail_op,
6612 GtkWidget *header_view, *folder_view;
6613 TnyFolderStore *folder_store;
6614 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6616 /* Set send/receive operation finished */
6617 modest_main_window_notify_send_receive_completed (main_win);
6619 /* Don't refresh the current folder if there were any errors */
6620 if (modest_mail_operation_get_status (mail_op) !=
6621 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6624 /* Refresh the current folder if we're viewing a window. We do
6625 this because the user won't be able to see the new mails in
6626 the selected folder after a Send&Receive because it only
6627 performs a poke_status, i.e, only the number of read/unread
6628 messages is updated, but the new headers are not
6630 folder_view = modest_main_window_get_child_widget (main_win,
6631 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6635 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6637 /* Do not need to refresh INBOX again because the
6638 update_account does it always automatically */
6639 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6640 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6641 ModestMailOperation *refresh_op;
6643 header_view = modest_main_window_get_child_widget (main_win,
6644 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6646 /* We do not need to set the contents style
6647 because it hasn't changed. We also do not
6648 need to save the widget status. Just force
6650 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6651 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6652 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6653 folder_refreshed_cb, main_win);
6654 g_object_unref (refresh_op);
6658 g_object_unref (folder_store);
6663 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6669 const gchar* server_name = NULL;
6670 TnyTransportAccount *transport;
6671 gchar *message = NULL;
6672 ModestProtocol *protocol;
6674 /* Don't show anything if the user cancelled something or the
6675 * send receive request is not interactive. Authentication
6676 * errors are managed by the account store so no need to show
6677 * a dialog here again */
6678 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6679 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6680 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6684 /* Get the server name. Note that we could be using a
6685 connection specific transport account */
6686 transport = (TnyTransportAccount *)
6687 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6689 ModestTnyAccountStore *acc_store;
6690 const gchar *acc_name;
6691 TnyTransportAccount *conn_specific;
6693 acc_store = modest_runtime_get_account_store();
6694 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6695 conn_specific = (TnyTransportAccount *)
6696 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6697 if (conn_specific) {
6698 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6699 g_object_unref (conn_specific);
6701 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6703 g_object_unref (transport);
6707 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6708 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6709 tny_account_get_proto (TNY_ACCOUNT (transport)));
6711 g_warning ("%s: Account with no proto", __FUNCTION__);
6715 /* Show the appropriate message text for the GError: */
6716 switch (err->code) {
6717 case TNY_SERVICE_ERROR_CONNECT:
6718 message = modest_protocol_get_translation (protocol,
6719 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6722 case TNY_SERVICE_ERROR_SEND:
6723 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6725 case TNY_SERVICE_ERROR_UNAVAILABLE:
6726 message = modest_protocol_get_translation (protocol,
6727 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6731 g_warning ("%s: unexpected ERROR %d",
6732 __FUNCTION__, err->code);
6733 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6737 modest_platform_run_information_dialog (NULL, message, FALSE);
6742 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6747 ModestWindow *top_window = NULL;
6748 ModestWindowMgr *mgr = NULL;
6749 GtkWidget *header_view = NULL;
6750 TnyFolder *selected_folder = NULL;
6751 TnyFolderType folder_type;
6753 mgr = modest_runtime_get_window_mgr ();
6754 top_window = modest_window_mgr_get_current_top (mgr);
6759 #ifndef MODEST_TOOLKIT_HILDON2
6760 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6761 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6762 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6765 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6766 header_view = (GtkWidget *)
6767 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6771 /* Get selected folder */
6773 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6774 if (!selected_folder)
6777 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6778 #if GTK_CHECK_VERSION(2, 8, 0)
6779 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6780 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6781 GtkTreeViewColumn *tree_column;
6783 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6784 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6786 gtk_tree_view_column_queue_resize (tree_column);
6788 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6789 gtk_widget_queue_draw (header_view);
6792 #ifndef MODEST_TOOLKIT_HILDON2
6793 /* Rerun dimming rules, because the message could become deletable for example */
6794 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6795 MODEST_DIMMING_RULES_TOOLBAR);
6796 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6797 MODEST_DIMMING_RULES_MENU);
6801 g_object_unref (selected_folder);
6805 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6806 TnyAccount *account)
6808 ModestProtocolType protocol_type;
6809 ModestProtocol *protocol;
6810 gchar *error_note = NULL;
6812 protocol_type = modest_tny_account_get_protocol_type (account);
6813 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6816 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6817 if (error_note == NULL) {
6818 g_warning ("%s: This should not be reached", __FUNCTION__);
6820 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6821 g_free (error_note);
6826 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6830 TnyFolderStore *folder = NULL;
6831 TnyAccount *account = NULL;
6832 ModestProtocolType proto;
6833 ModestProtocol *protocol;
6834 TnyHeader *header = NULL;
6836 #ifndef MODEST_TOOLKIT_HILDON2
6837 if (MODEST_IS_MAIN_WINDOW (win)) {
6838 GtkWidget *header_view;
6839 TnyList* headers = NULL;
6841 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6842 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6843 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6844 if (!headers || tny_list_get_length (headers) == 0) {
6846 g_object_unref (headers);
6849 iter = tny_list_create_iterator (headers);
6850 header = TNY_HEADER (tny_iterator_get_current (iter));
6851 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6852 g_object_unref (iter);
6853 g_object_unref (headers);
6855 if (MODEST_IS_HEADER_WINDOW (win)) {
6856 GtkWidget *header_view;
6857 TnyList* headers = NULL;
6859 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6860 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6861 if (!headers || tny_list_get_length (headers) == 0) {
6863 g_object_unref (headers);
6866 iter = tny_list_create_iterator (headers);
6867 header = TNY_HEADER (tny_iterator_get_current (iter));
6869 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6871 g_warning ("List should contain headers");
6873 g_object_unref (iter);
6874 g_object_unref (headers);
6876 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6877 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6879 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6882 if (!header || !folder)
6885 /* Get the account type */
6886 account = tny_folder_get_account (TNY_FOLDER (folder));
6887 proto = modest_tny_account_get_protocol_type (account);
6888 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6891 subject = tny_header_dup_subject (header);
6892 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6896 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6902 g_object_unref (account);
6904 g_object_unref (folder);
6906 g_object_unref (header);
6912 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6913 const gchar *account_name,
6914 const gchar *account_title)
6916 ModestAccountMgr *account_mgr;
6919 ModestProtocol *protocol;
6920 gboolean removed = FALSE;
6922 g_return_val_if_fail (account_name, FALSE);
6923 g_return_val_if_fail (account_title, FALSE);
6925 account_mgr = modest_runtime_get_account_mgr();
6927 /* The warning text depends on the account type: */
6928 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6929 modest_account_mgr_get_store_protocol (account_mgr,
6931 txt = modest_protocol_get_translation (protocol,
6932 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6935 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6937 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6941 if (response == GTK_RESPONSE_OK) {
6942 /* Remove account. If it succeeds then it also removes
6943 the account from the ModestAccountView: */
6944 gboolean is_default = FALSE;
6945 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6946 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6948 g_free (default_account_name);
6950 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6952 /* Close all email notifications, we cannot
6953 distinguish if the notification belongs to
6954 this account or not, so for safety reasons
6955 we remove them all */
6956 modest_platform_remove_new_mail_notifications (FALSE);
6958 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6965 on_fetch_images_performer (gboolean canceled,
6967 GtkWindow *parent_window,
6968 TnyAccount *account,
6971 if (err || canceled) {
6972 /* Show an unable to retrieve images ??? */
6976 /* Note that the user could have closed the window while connecting */
6977 if (GTK_WIDGET_VISIBLE (parent_window))
6978 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6979 g_object_unref ((GObject *) user_data);
6983 modest_ui_actions_on_fetch_images (GtkAction *action,
6984 ModestWindow *window)
6986 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6988 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6990 on_fetch_images_performer,
6991 g_object_ref (window));
6995 modest_ui_actions_on_reload_message (const gchar *msg_id)
6997 ModestWindow *window = NULL;
6999 g_return_if_fail (msg_id && msg_id[0] != '\0');
7000 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7006 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7009 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7012 /** Check whether any connections are active, and cancel them if
7014 * Returns TRUE is there was no problem,
7015 * or if an operation was cancelled so we can continue.
7016 * Returns FALSE if the user chose to cancel his request instead.
7020 modest_ui_actions_check_for_active_account (ModestWindow *self,
7021 const gchar* account_name)
7023 ModestTnySendQueue *send_queue;
7024 ModestTnyAccountStore *acc_store;
7025 ModestMailOperationQueue* queue;
7026 TnyConnectionStatus store_conn_status;
7027 TnyAccount *store_account = NULL, *transport_account = NULL;
7028 gboolean retval = TRUE, sending = FALSE;
7030 acc_store = modest_runtime_get_account_store ();
7031 queue = modest_runtime_get_mail_operation_queue ();
7034 modest_tny_account_store_get_server_account (acc_store,
7036 TNY_ACCOUNT_TYPE_STORE);
7038 /* This could happen if the account was deleted before the
7039 call to this function */
7044 modest_tny_account_store_get_server_account (acc_store,
7046 TNY_ACCOUNT_TYPE_TRANSPORT);
7048 /* This could happen if the account was deleted before the
7049 call to this function */
7050 if (!transport_account) {
7051 g_object_unref (store_account);
7055 /* If the transport account was not used yet, then the send
7056 queue could not exist (it's created on demand) */
7057 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7058 if (TNY_IS_SEND_QUEUE (send_queue))
7059 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7061 store_conn_status = tny_account_get_connection_status (store_account);
7062 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7065 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7066 _("emev_nc_disconnect_account"));
7067 if (response == GTK_RESPONSE_OK) {
7076 /* FIXME: We should only cancel those of this account */
7077 modest_mail_operation_queue_cancel_all (queue);
7079 /* Also disconnect the account */
7080 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7081 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7082 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7086 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7092 g_object_unref (store_account);
7093 g_object_unref (transport_account);