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) {
1014 format = modest_protocol_get_translation (protocol,
1015 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1018 format = modest_protocol_get_translation (protocol,
1019 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1022 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1023 tny_account_get_hostname (account));
1026 g_object_unref (account);
1031 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1033 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1037 msg = g_strdup_printf (format, subject);
1038 modest_platform_run_information_dialog (NULL, msg, FALSE);
1044 /* Remove the header from the preregistered uids */
1045 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1058 } OpenMsgBannerInfo;
1061 GtkTreeModel *model;
1063 ModestWindow *caller_window;
1064 OpenMsgBannerInfo *banner_info;
1065 GtkTreeRowReference *rowref;
1069 open_msg_banner_idle (gpointer userdata)
1071 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1073 gdk_threads_enter ();
1074 banner_info->idle_handler = 0;
1075 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1076 if (banner_info->banner)
1077 g_object_ref (banner_info->banner);
1079 gdk_threads_leave ();
1085 get_header_view_from_window (ModestWindow *window)
1087 GtkWidget *header_view;
1089 #ifndef MODEST_TOOLKIT_HILDON2
1090 if (MODEST_IS_MAIN_WINDOW (window)) {
1091 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1092 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1094 if (MODEST_IS_HEADER_WINDOW (window)){
1095 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1105 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1108 gchar *account = NULL;
1109 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1114 folder = tny_header_get_folder (header);
1115 /* Gets folder type (OUTBOX headers will be opened in edit window */
1116 if (modest_tny_folder_is_local_folder (folder)) {
1117 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1118 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1119 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1122 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1123 TnyTransportAccount *traccount = NULL;
1124 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1125 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1127 ModestTnySendQueue *send_queue = NULL;
1128 ModestTnySendQueueStatus status;
1130 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1131 TNY_ACCOUNT(traccount)));
1132 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1133 if (TNY_IS_SEND_QUEUE (send_queue)) {
1134 msg_id = modest_tny_send_queue_get_msg_id (header);
1135 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1137 /* Only open messages in outbox with the editor if they are in Failed state */
1138 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1141 #ifdef MODEST_TOOLKIT_HILDON2
1143 /* In Fremantle we can not
1144 open any message from
1145 outbox which is not in
1151 g_object_unref(traccount);
1153 g_warning("Cannot get transport account for message in outbox!!");
1155 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1156 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1160 TnyAccount *acc = tny_folder_get_account (folder);
1163 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1164 g_object_unref (acc);
1168 g_object_unref (folder);
1174 open_msg_cb (ModestMailOperation *mail_op,
1181 ModestWindowMgr *mgr = NULL;
1182 ModestWindow *parent_win = NULL;
1183 ModestWindow *win = NULL;
1184 gchar *account = NULL;
1185 gboolean open_in_editor = FALSE;
1187 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1189 /* Do nothing if there was any problem with the mail
1190 operation. The error will be shown by the error_handler of
1191 the mail operation */
1192 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1195 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1197 /* Mark header as read */
1198 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1200 account = get_info_from_header (header, &open_in_editor, &can_open);
1204 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1206 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1208 if (open_in_editor) {
1209 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1210 gchar *from_header = NULL, *acc_name;
1211 gchar *mailbox = NULL;
1213 from_header = tny_header_dup_from (header);
1215 /* we cannot edit without a valid account... */
1216 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1217 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1218 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1220 g_free (from_header);
1225 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1226 g_free (from_header);
1232 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1236 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1237 const gchar *mailbox = NULL;
1239 if (parent_win && MODEST_IS_WINDOW (parent_win))
1240 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1242 if (helper->rowref && helper->model) {
1243 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1244 helper->model, helper->rowref);
1246 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1251 /* Register and show new window */
1253 mgr = modest_runtime_get_window_mgr ();
1254 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1255 gtk_widget_destroy (GTK_WIDGET (win));
1258 gtk_widget_show_all (GTK_WIDGET(win));
1261 #ifndef MODEST_TOOLKIT_HILDON2
1262 /* Update toolbar dimming state */
1263 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1264 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1271 g_object_unref (parent_win);
1275 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1278 const GError *error;
1279 GObject *win = NULL;
1280 ModestMailOperationStatus status;
1282 win = modest_mail_operation_get_source (mail_op);
1283 error = modest_mail_operation_get_error (mail_op);
1284 status = modest_mail_operation_get_status (mail_op);
1286 /* If the mail op has been cancelled then it's not an error:
1287 don't show any message */
1288 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1289 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1290 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1291 (GError *) error, account)) {
1292 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1293 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1295 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1296 modest_platform_information_banner ((GtkWidget *) win,
1297 NULL, _("emev_ui_imap_inbox_select_error"));
1298 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1299 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1300 modest_platform_information_banner ((GtkWidget *) win,
1301 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1302 } else if (user_data) {
1303 modest_platform_information_banner ((GtkWidget *) win,
1307 g_object_unref (account);
1311 g_object_unref (win);
1315 * Returns the account a list of headers belongs to. It returns a
1316 * *new* reference so don't forget to unref it
1319 get_account_from_header_list (TnyList *headers)
1321 TnyAccount *account = NULL;
1323 if (tny_list_get_length (headers) > 0) {
1324 TnyIterator *iter = tny_list_create_iterator (headers);
1325 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1326 TnyFolder *folder = tny_header_get_folder (header);
1329 g_object_unref (header);
1331 while (!tny_iterator_is_done (iter)) {
1332 header = TNY_HEADER (tny_iterator_get_current (iter));
1333 folder = tny_header_get_folder (header);
1336 g_object_unref (header);
1338 tny_iterator_next (iter);
1343 account = tny_folder_get_account (folder);
1344 g_object_unref (folder);
1348 g_object_unref (header);
1350 g_object_unref (iter);
1356 get_account_from_header (TnyHeader *header)
1358 TnyAccount *account = NULL;
1361 folder = tny_header_get_folder (header);
1364 account = tny_folder_get_account (folder);
1365 g_object_unref (folder);
1371 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1373 if (helper->caller_window)
1374 helper->caller_window = NULL;
1378 open_msg_helper_destroyer (gpointer user_data)
1380 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1382 if (helper->caller_window) {
1383 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1384 helper->caller_window = NULL;
1387 if (helper->banner_info) {
1388 g_free (helper->banner_info->message);
1389 if (helper->banner_info->idle_handler > 0) {
1390 g_source_remove (helper->banner_info->idle_handler);
1391 helper->banner_info->idle_handler = 0;
1393 if (helper->banner_info->banner != NULL) {
1394 gtk_widget_destroy (helper->banner_info->banner);
1395 g_object_unref (helper->banner_info->banner);
1396 helper->banner_info->banner = NULL;
1398 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1399 helper->banner_info = NULL;
1401 g_object_unref (helper->model);
1402 g_object_unref (helper->header);
1403 gtk_tree_row_reference_free (helper->rowref);
1404 g_slice_free (OpenMsgHelper, helper);
1408 open_msg_performer(gboolean canceled,
1410 GtkWindow *parent_window,
1411 TnyAccount *account,
1414 ModestMailOperation *mail_op = NULL;
1415 gchar *error_msg = NULL;
1416 ModestProtocolType proto;
1417 TnyConnectionStatus status;
1418 OpenMsgHelper *helper = NULL;
1419 ModestProtocol *protocol;
1420 ModestProtocolRegistry *protocol_registry;
1423 helper = (OpenMsgHelper *) user_data;
1425 status = tny_account_get_connection_status (account);
1426 if (err || canceled || helper->caller_window == NULL) {
1427 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1428 /* Free the helper */
1429 open_msg_helper_destroyer (helper);
1431 /* In disk full conditions we could get this error here */
1432 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1433 (GtkWidget *) parent_window, err,
1439 /* Get the error message depending on the protocol */
1440 proto = modest_tny_account_get_protocol_type (account);
1441 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1442 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1445 protocol_registry = modest_runtime_get_protocol_registry ();
1446 subject = tny_header_dup_subject (helper->header);
1448 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1449 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1453 if (error_msg == NULL) {
1454 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1457 #ifndef MODEST_TOOLKIT_HILDON2
1458 gboolean show_open_draft = FALSE;
1459 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1461 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1463 TnyFolderType folder_type;
1465 folder = tny_header_get_folder (helper->header);
1466 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1467 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1468 g_object_unref (folder);
1472 #ifdef MODEST_TOOLKIT_HILDON2
1475 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1478 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1479 g_free (account_name);
1480 open_msg_helper_destroyer (helper);
1485 ModestWindow *window;
1486 GtkWidget *header_view;
1489 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1490 uid = modest_tny_folder_get_header_unique_id (helper->header);
1492 const gchar *mailbox = NULL;
1493 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1494 window = modest_msg_view_window_new_from_header_view
1495 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1496 if (window != NULL) {
1497 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1499 gtk_widget_destroy (GTK_WIDGET (window));
1501 gtk_widget_show_all (GTK_WIDGET(window));
1505 g_free (account_name);
1507 open_msg_helper_destroyer (helper);
1510 g_free (account_name);
1512 /* Create the mail operation */
1514 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1515 modest_ui_actions_disk_operations_error_handler,
1516 g_strdup (error_msg), g_free);
1517 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1521 #ifndef MODEST_TOOLKIT_HILDON2
1522 if (show_open_draft) {
1523 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1524 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1525 helper->banner_info->banner = NULL;
1526 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1527 helper->banner_info);
1533 headers = TNY_LIST (tny_simple_list_new ());
1534 tny_list_prepend (headers, G_OBJECT (helper->header));
1535 modest_mail_operation_get_msgs_full (mail_op,
1539 open_msg_helper_destroyer);
1540 g_object_unref (headers);
1547 g_object_unref (mail_op);
1548 g_object_unref (account);
1552 * This function is used by both modest_ui_actions_on_open and
1553 * modest_ui_actions_on_header_activated. This way we always do the
1554 * same when trying to open messages.
1557 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1559 ModestWindowMgr *mgr = NULL;
1560 TnyAccount *account;
1561 gboolean cached = FALSE;
1563 GtkWidget *header_view = NULL;
1564 OpenMsgHelper *helper;
1565 ModestWindow *window;
1567 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1569 mgr = modest_runtime_get_window_mgr ();
1572 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1573 if (header_view == NULL)
1576 /* Get the account */
1577 account = get_account_from_header (header);
1582 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1584 /* Do not open again the message and present the
1585 window to the user */
1588 #ifndef MODEST_TOOLKIT_HILDON2
1589 gtk_window_present (GTK_WINDOW (window));
1592 /* the header has been registered already, we don't do
1593 * anything but wait for the window to come up*/
1594 g_debug ("header %p already registered, waiting for window", header);
1599 /* Open each message */
1600 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1602 /* Allways download if we are online. */
1603 if (!tny_device_is_online (modest_runtime_get_device ())) {
1606 /* If ask for user permission to download the messages */
1607 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1608 _("mcen_nc_get_msg"));
1610 /* End if the user does not want to continue */
1611 if (response == GTK_RESPONSE_CANCEL) {
1617 /* We register the window for opening */
1618 modest_window_mgr_register_header (mgr, header, NULL);
1620 /* Create the helper. We need to get a reference to the model
1621 here because it could change while the message is readed
1622 (the user could switch between folders) */
1623 helper = g_slice_new (OpenMsgHelper);
1624 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1625 helper->caller_window = win;
1626 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1627 helper->header = g_object_ref (header);
1628 helper->rowref = gtk_tree_row_reference_copy (rowref);
1629 helper->banner_info = NULL;
1631 /* Connect to the account and perform */
1633 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1634 open_msg_performer, helper);
1636 /* Call directly the performer, do not need to connect */
1637 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1638 g_object_ref (account), helper);
1643 g_object_unref (account);
1647 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1654 /* we check for low-mem; in that case, show a warning, and don't allow
1657 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1661 headers = get_selected_headers (win);
1665 headers_count = tny_list_get_length (headers);
1666 if (headers_count != 1) {
1667 if (headers_count > 1) {
1668 /* Don't allow activation if there are more than one message selected */
1669 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1672 g_object_unref (headers);
1676 iter = tny_list_create_iterator (headers);
1677 header = TNY_HEADER (tny_iterator_get_current (iter));
1678 g_object_unref (iter);
1682 open_msg_from_header (header, NULL, win);
1683 g_object_unref (header);
1686 g_object_unref(headers);
1690 rf_helper_window_closed (gpointer data,
1693 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1695 helper->parent_window = NULL;
1698 static ReplyForwardHelper*
1699 create_reply_forward_helper (ReplyForwardAction action,
1701 guint reply_forward_type,
1704 ReplyForwardHelper *rf_helper = NULL;
1705 const gchar *active_acc = modest_window_get_active_account (win);
1706 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1708 rf_helper = g_slice_new0 (ReplyForwardHelper);
1709 rf_helper->reply_forward_type = reply_forward_type;
1710 rf_helper->action = action;
1711 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1712 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1713 rf_helper->account_name = (active_acc) ?
1714 g_strdup (active_acc) :
1715 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1716 rf_helper->mailbox = g_strdup (active_mailbox);
1718 /* Note that window could be destroyed just AFTER calling
1719 register_window so we must ensure that this pointer does
1720 not hold invalid references */
1721 if (rf_helper->parent_window)
1722 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1723 rf_helper_window_closed, rf_helper);
1729 free_reply_forward_helper (gpointer data)
1731 ReplyForwardHelper *helper;
1733 helper = (ReplyForwardHelper *) data;
1734 g_free (helper->account_name);
1735 g_free (helper->mailbox);
1737 g_object_unref (helper->header);
1738 if (helper->parent_window)
1739 g_object_weak_unref (G_OBJECT (helper->parent_window),
1740 rf_helper_window_closed, helper);
1741 g_slice_free (ReplyForwardHelper, helper);
1745 reply_forward_cb (ModestMailOperation *mail_op,
1752 TnyMsg *new_msg = NULL;
1753 ReplyForwardHelper *rf_helper;
1754 ModestWindow *msg_win = NULL;
1755 ModestEditType edit_type;
1757 TnyAccount *account = NULL;
1758 ModestWindowMgr *mgr = NULL;
1759 gchar *signature = NULL;
1760 gboolean use_signature;
1763 /* If there was any error. The mail operation could be NULL,
1764 this means that we already have the message downloaded and
1765 that we didn't do a mail operation to retrieve it */
1766 rf_helper = (ReplyForwardHelper *) user_data;
1767 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1770 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1771 rf_helper->account_name, rf_helper->mailbox);
1772 recipient = modest_text_utils_get_email_address (from);
1773 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1778 /* Create reply mail */
1779 switch (rf_helper->action) {
1780 /* Use the msg_header to ensure that we have all the
1781 information. The summary can lack some data */
1782 TnyHeader *msg_header;
1784 msg_header = tny_msg_get_header (msg);
1786 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1787 (use_signature) ? signature : NULL,
1788 rf_helper->reply_forward_type,
1789 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1790 g_object_unref (msg_header);
1792 case ACTION_REPLY_TO_ALL:
1793 msg_header = tny_msg_get_header (msg);
1795 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1796 (use_signature) ? signature : NULL,
1797 rf_helper->reply_forward_type,
1798 MODEST_TNY_MSG_REPLY_MODE_ALL);
1799 edit_type = MODEST_EDIT_TYPE_REPLY;
1800 g_object_unref (msg_header);
1802 case ACTION_FORWARD:
1804 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1805 rf_helper->reply_forward_type);
1806 edit_type = MODEST_EDIT_TYPE_FORWARD;
1809 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1811 g_return_if_reached ();
1819 g_warning ("%s: failed to create message\n", __FUNCTION__);
1823 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1824 rf_helper->account_name,
1825 TNY_ACCOUNT_TYPE_STORE);
1827 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1831 /* Create and register the windows */
1832 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1833 mgr = modest_runtime_get_window_mgr ();
1834 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1836 /* Note that register_window could have deleted the account */
1837 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1838 gdouble parent_zoom;
1840 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1841 modest_window_set_zoom (msg_win, parent_zoom);
1844 /* Show edit window */
1845 gtk_widget_show_all (GTK_WIDGET (msg_win));
1848 /* We always unregister the header because the message is
1849 forwarded or replied so the original one is no longer
1851 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1854 g_object_unref (G_OBJECT (new_msg));
1856 g_object_unref (G_OBJECT (account));
1857 free_reply_forward_helper (rf_helper);
1860 /* Checks a list of headers. If any of them are not currently
1861 * downloaded (CACHED) then returns TRUE else returns FALSE.
1864 header_list_count_uncached_msgs (TnyList *header_list)
1867 gint uncached_messages = 0;
1869 iter = tny_list_create_iterator (header_list);
1870 while (!tny_iterator_is_done (iter)) {
1873 header = TNY_HEADER (tny_iterator_get_current (iter));
1875 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1876 uncached_messages ++;
1877 g_object_unref (header);
1880 tny_iterator_next (iter);
1882 g_object_unref (iter);
1884 return uncached_messages;
1887 /* Returns FALSE if the user does not want to download the
1888 * messages. Returns TRUE if the user allowed the download.
1891 connect_to_get_msg (ModestWindow *win,
1892 gint num_of_uncached_msgs,
1893 TnyAccount *account)
1895 GtkResponseType response;
1897 /* Allways download if we are online. */
1898 if (tny_device_is_online (modest_runtime_get_device ()))
1901 /* If offline, then ask for user permission to download the messages */
1902 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1903 ngettext("mcen_nc_get_msg",
1905 num_of_uncached_msgs));
1907 if (response == GTK_RESPONSE_CANCEL)
1910 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1914 reply_forward_performer (gboolean canceled,
1916 GtkWindow *parent_window,
1917 TnyAccount *account,
1920 ReplyForwardHelper *rf_helper = NULL;
1921 ModestMailOperation *mail_op;
1923 rf_helper = (ReplyForwardHelper *) user_data;
1925 if (canceled || err) {
1926 free_reply_forward_helper (rf_helper);
1930 /* Retrieve the message */
1931 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1932 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1933 modest_ui_actions_disk_operations_error_handler,
1935 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1936 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1939 g_object_unref(mail_op);
1943 * Common code for the reply and forward actions
1946 reply_forward (ReplyForwardAction action, ModestWindow *win)
1948 ReplyForwardHelper *rf_helper = NULL;
1949 guint reply_forward_type;
1951 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1953 /* we check for low-mem; in that case, show a warning, and don't allow
1954 * reply/forward (because it could potentially require a lot of memory */
1955 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1959 /* we need an account when editing */
1960 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1961 if (!modest_ui_actions_run_account_setup_wizard (win))
1965 reply_forward_type =
1966 modest_conf_get_int (modest_runtime_get_conf (),
1967 (action == ACTION_FORWARD) ?
1968 MODEST_CONF_FORWARD_TYPE :
1969 MODEST_CONF_REPLY_TYPE,
1972 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1974 TnyHeader *header = NULL;
1975 /* Get header and message. Do not free them here, the
1976 reply_forward_cb must do it */
1977 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1978 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1980 if (msg && header) {
1982 rf_helper = create_reply_forward_helper (action, win,
1983 reply_forward_type, header);
1984 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1986 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1990 g_object_unref (msg);
1992 g_object_unref (header);
1994 TnyHeader *header = NULL;
1996 gboolean do_retrieve = TRUE;
1997 TnyList *header_list = NULL;
1999 header_list = get_selected_headers (win);
2002 /* Check that only one message is selected for replying */
2003 if (tny_list_get_length (header_list) != 1) {
2004 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2005 NULL, _("mcen_ib_select_one_message"));
2006 g_object_unref (header_list);
2010 /* Only reply/forward to one message */
2011 iter = tny_list_create_iterator (header_list);
2012 header = TNY_HEADER (tny_iterator_get_current (iter));
2013 g_object_unref (iter);
2015 /* Retrieve messages */
2016 do_retrieve = (action == ACTION_FORWARD) ||
2017 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2020 TnyAccount *account = NULL;
2021 TnyFolder *folder = NULL;
2022 gdouble download = TRUE;
2023 guint uncached_msgs = 0;
2025 folder = tny_header_get_folder (header);
2027 goto do_retrieve_frees;
2028 account = tny_folder_get_account (folder);
2030 goto do_retrieve_frees;
2032 uncached_msgs = header_list_count_uncached_msgs (header_list);
2034 if (uncached_msgs > 0) {
2035 /* Allways download if we are online. */
2036 if (!tny_device_is_online (modest_runtime_get_device ())) {
2039 /* If ask for user permission to download the messages */
2040 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2041 ngettext("mcen_nc_get_msg",
2045 /* End if the user does not want to continue */
2046 if (response == GTK_RESPONSE_CANCEL)
2053 rf_helper = create_reply_forward_helper (action, win,
2054 reply_forward_type, header);
2055 if (uncached_msgs > 0) {
2056 modest_platform_connect_and_perform (GTK_WINDOW (win),
2058 reply_forward_performer,
2061 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2062 account, rf_helper);
2067 g_object_unref (account);
2069 g_object_unref (folder);
2071 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2074 g_object_unref (header_list);
2075 g_object_unref (header);
2080 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2082 g_return_if_fail (MODEST_IS_WINDOW(win));
2084 reply_forward (ACTION_REPLY, win);
2088 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2090 g_return_if_fail (MODEST_IS_WINDOW(win));
2092 reply_forward (ACTION_FORWARD, win);
2096 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2098 g_return_if_fail (MODEST_IS_WINDOW(win));
2100 reply_forward (ACTION_REPLY_TO_ALL, win);
2104 modest_ui_actions_on_next (GtkAction *action,
2105 ModestWindow *window)
2107 #ifndef MODEST_TOOLKIT_HILDON2
2108 if (MODEST_IS_MAIN_WINDOW (window)) {
2109 GtkWidget *header_view;
2111 header_view = modest_main_window_get_child_widget (
2112 MODEST_MAIN_WINDOW(window),
2113 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2117 modest_header_view_select_next (
2118 MODEST_HEADER_VIEW(header_view));
2120 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2121 modest_msg_view_window_select_next_message (
2122 MODEST_MSG_VIEW_WINDOW (window));
2125 g_return_if_reached ();
2130 modest_ui_actions_on_prev (GtkAction *action,
2131 ModestWindow *window)
2133 g_return_if_fail (MODEST_IS_WINDOW(window));
2135 #ifndef MODEST_TOOLKIT_HILDON2
2136 if (MODEST_IS_MAIN_WINDOW (window)) {
2137 GtkWidget *header_view;
2138 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2139 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2143 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2145 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2146 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2149 g_return_if_reached ();
2154 modest_ui_actions_on_sort (GtkAction *action,
2155 ModestWindow *window)
2157 GtkWidget *header_view = NULL;
2159 g_return_if_fail (MODEST_IS_WINDOW(window));
2161 #ifndef MODEST_TOOLKIT_HILDON2
2162 if (MODEST_IS_MAIN_WINDOW (window)) {
2163 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2164 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2166 if (MODEST_IS_HEADER_WINDOW (window)) {
2167 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2172 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2177 /* Show sorting dialog */
2178 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2182 sync_folder_cb (ModestMailOperation *mail_op,
2186 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2188 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2189 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2191 /* We must clear first, because otherwise set_folder will ignore */
2192 /* the change as the folders are the same */
2193 modest_header_view_clear (header_view);
2194 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2196 g_object_unref (parent);
2199 g_object_unref (header_view);
2203 idle_refresh_folder (gpointer source)
2205 ModestHeaderView *header_view = NULL;
2207 /* If the window still exists */
2208 if (!GTK_IS_WIDGET (source) ||
2209 !GTK_WIDGET_VISIBLE (source))
2212 /* Refresh the current view */
2213 #ifdef MODEST_TOOLKIT_HILDON2
2214 if (MODEST_IS_HEADER_WINDOW (source))
2215 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2217 if (MODEST_IS_MAIN_WINDOW (source))
2218 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2219 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2222 TnyFolder *folder = modest_header_view_get_folder (header_view);
2224 /* Sync the folder status */
2225 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2226 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2227 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2228 g_object_unref (folder);
2229 g_object_unref (mail_op);
2237 update_account_cb (ModestMailOperation *self,
2238 TnyList *new_headers,
2242 gboolean show_visual_notifications;
2244 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2245 show_visual_notifications = (top) ? FALSE : TRUE;
2247 /* Notify new messages have been downloaded. If the
2248 send&receive was invoked by the user then do not show any
2249 visual notification, only play a sound and activate the LED
2250 (for the Maemo version) */
2251 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2253 /* We only notify about really new messages (not seen) we get */
2254 TnyList *actually_new_list;
2255 TnyIterator *iterator;
2256 actually_new_list = TNY_LIST (tny_simple_list_new ());
2257 for (iterator = tny_list_create_iterator (new_headers);
2258 !tny_iterator_is_done (iterator);
2259 tny_iterator_next (iterator)) {
2261 TnyHeaderFlags flags;
2262 header = TNY_HEADER (tny_iterator_get_current (iterator));
2263 flags = tny_header_get_flags (header);
2265 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2266 /* Messages are ordered from most
2267 recent to oldest. But we want to
2268 show notifications starting from
2269 the oldest message. That's why we
2271 tny_list_prepend (actually_new_list, G_OBJECT (header));
2273 g_object_unref (header);
2275 g_object_unref (iterator);
2277 if (tny_list_get_length (actually_new_list) > 0) {
2278 GList *new_headers_list = NULL;
2280 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2282 /* Send notifications */
2283 if (new_headers_list) {
2284 modest_platform_on_new_headers_received (new_headers_list,
2285 show_visual_notifications);
2287 modest_utils_free_notification_list (new_headers_list);
2290 g_object_unref (actually_new_list);
2294 /* Refresh the current folder in an idle. We do this
2295 in order to avoid refresh cancelations if the
2296 currently viewed folder is the inbox */
2297 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2298 idle_refresh_folder,
2305 TnyAccount *account;
2307 gchar *account_name;
2308 gboolean poke_status;
2309 gboolean interactive;
2310 ModestMailOperation *mail_op;
2314 do_send_receive_performer (gboolean canceled,
2316 GtkWindow *parent_window,
2317 TnyAccount *account,
2320 SendReceiveInfo *info;
2322 info = (SendReceiveInfo *) user_data;
2324 if (err || canceled) {
2325 /* In disk full conditions we could get this error here */
2326 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2327 (GtkWidget *) parent_window, err,
2330 if (info->mail_op) {
2331 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2337 #ifndef MODEST_TOOLKIT_HILDON2
2338 /* Set send/receive operation in progress */
2339 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2340 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2343 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2344 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2345 G_CALLBACK (on_send_receive_finished),
2349 /* Send & receive. */
2350 modest_mail_operation_update_account (info->mail_op, info->account_name,
2351 info->poke_status, info->interactive,
2352 update_account_cb, info->win);
2357 g_object_unref (G_OBJECT (info->mail_op));
2358 if (info->account_name)
2359 g_free (info->account_name);
2361 g_object_unref (info->win);
2363 g_object_unref (info->account);
2364 g_slice_free (SendReceiveInfo, info);
2368 * This function performs the send & receive required actions. The
2369 * window is used to create the mail operation. Typically it should
2370 * always be the main window, but we pass it as argument in order to
2374 modest_ui_actions_do_send_receive (const gchar *account_name,
2375 gboolean force_connection,
2376 gboolean poke_status,
2377 gboolean interactive,
2380 gchar *acc_name = NULL;
2381 SendReceiveInfo *info;
2382 ModestTnyAccountStore *acc_store;
2383 TnyAccount *account;
2385 /* If no account name was provided then get the current account, and if
2386 there is no current account then pick the default one: */
2387 if (!account_name) {
2389 acc_name = g_strdup (modest_window_get_active_account (win));
2391 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2393 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2397 acc_name = g_strdup (account_name);
2400 acc_store = modest_runtime_get_account_store ();
2401 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2405 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2409 /* Do not automatically refresh accounts that are flagged as
2410 NO_AUTO_UPDATE. This could be useful for accounts that
2411 handle their own update times */
2413 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2414 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2415 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2416 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2418 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2419 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2420 g_object_unref (account);
2427 /* Create the info for the connect and perform */
2428 info = g_slice_new (SendReceiveInfo);
2429 info->account_name = acc_name;
2430 info->win = (win) ? g_object_ref (win) : NULL;
2431 info->poke_status = poke_status;
2432 info->interactive = interactive;
2433 info->account = account;
2434 /* We need to create the operation here, because otherwise it
2435 could happen that the queue emits the queue-empty signal
2436 while we're trying to connect the account */
2437 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2438 modest_ui_actions_disk_operations_error_handler,
2440 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2442 /* Invoke the connect and perform */
2443 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2444 force_connection, info->account,
2445 do_send_receive_performer, info);
2450 modest_ui_actions_do_cancel_send (const gchar *account_name,
2453 TnyTransportAccount *transport_account;
2454 TnySendQueue *send_queue = NULL;
2455 GError *error = NULL;
2457 /* Get transport account */
2459 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2460 (modest_runtime_get_account_store(),
2462 TNY_ACCOUNT_TYPE_TRANSPORT));
2463 if (!transport_account) {
2464 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2469 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2470 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2471 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2472 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2473 "modest: could not find send queue for account\n");
2475 /* Cancel the current send */
2476 tny_account_cancel (TNY_ACCOUNT (transport_account));
2478 /* Suspend all pending messages */
2479 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2483 if (transport_account != NULL)
2484 g_object_unref (G_OBJECT (transport_account));
2488 modest_ui_actions_cancel_send_all (ModestWindow *win)
2490 GSList *account_names, *iter;
2492 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2495 iter = account_names;
2497 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2498 iter = g_slist_next (iter);
2501 modest_account_mgr_free_account_names (account_names);
2502 account_names = NULL;
2506 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2509 /* Check if accounts exist */
2510 gboolean accounts_exist =
2511 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2513 /* If not, allow the user to create an account before trying to send/receive. */
2514 if (!accounts_exist)
2515 modest_ui_actions_on_accounts (NULL, win);
2517 /* Cancel all sending operaitons */
2518 modest_ui_actions_cancel_send_all (win);
2522 * Refreshes all accounts. This function will be used by automatic
2526 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2527 gboolean force_connection,
2528 gboolean poke_status,
2529 gboolean interactive)
2531 GSList *account_names, *iter;
2533 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2536 iter = account_names;
2538 modest_ui_actions_do_send_receive ((const char*) iter->data,
2540 poke_status, interactive, win);
2541 iter = g_slist_next (iter);
2544 modest_account_mgr_free_account_names (account_names);
2545 account_names = NULL;
2549 * Handler of the click on Send&Receive button in the main toolbar
2552 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2554 /* Check if accounts exist */
2555 gboolean accounts_exist;
2558 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2560 /* If not, allow the user to create an account before trying to send/receive. */
2561 if (!accounts_exist)
2562 modest_ui_actions_on_accounts (NULL, win);
2564 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2565 #ifndef MODEST_TOOLKIT_HILDON2
2566 if (MODEST_IS_MAIN_WINDOW (win)) {
2567 GtkWidget *folder_view;
2568 TnyFolderStore *folder_store;
2571 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2572 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2576 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2579 g_object_unref (folder_store);
2580 /* Refresh the active account. Force the connection if needed
2581 and poke the status of all folders */
2582 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2584 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2585 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2588 const gchar *active_account;
2589 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2591 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2596 #ifndef MODEST_TOOLKIT_HILDON2
2598 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2601 GtkWidget *header_view;
2603 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2605 header_view = modest_main_window_get_child_widget (main_window,
2606 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2610 conf = modest_runtime_get_conf ();
2612 /* what is saved/restored is depending on the style; thus; we save with
2613 * old style, then update the style, and restore for this new style
2615 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2617 if (modest_header_view_get_style
2618 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2619 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2620 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2622 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2623 MODEST_HEADER_VIEW_STYLE_DETAILS);
2625 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2626 MODEST_CONF_HEADER_VIEW_KEY);
2630 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2632 ModestMainWindow *main_window)
2634 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2635 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2637 /* in the case the folder is empty, show the empty folder message and focus
2639 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2640 if (modest_header_view_is_empty (header_view)) {
2641 TnyFolder *folder = modest_header_view_get_folder (header_view);
2642 GtkWidget *folder_view =
2643 modest_main_window_get_child_widget (main_window,
2644 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2645 if (folder != NULL) {
2646 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2647 g_object_unref (folder);
2649 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2653 /* If no header has been selected then exit */
2658 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2659 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2661 /* Update toolbar dimming state */
2662 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2663 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2668 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2671 ModestWindow *window)
2673 GtkTreeRowReference *rowref;
2675 g_return_if_fail (MODEST_IS_WINDOW(window));
2676 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2677 g_return_if_fail (TNY_IS_HEADER (header));
2679 if (modest_header_view_count_selected_headers (header_view) > 1) {
2680 /* Don't allow activation if there are more than one message selected */
2681 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2685 /* we check for low-mem; in that case, show a warning, and don't allow
2686 * activating headers
2688 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2691 #ifndef MODEST_TOOLKIT_HILDON2
2692 GtkWidget *open_widget;
2693 if (MODEST_IS_MAIN_WINDOW (window)) {
2694 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2695 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2696 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2701 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2702 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2703 gtk_tree_row_reference_free (rowref);
2706 #ifndef MODEST_TOOLKIT_HILDON2
2708 set_active_account_from_tny_account (TnyAccount *account,
2709 ModestWindow *window)
2711 const gchar *server_acc_name = tny_account_get_id (account);
2713 /* We need the TnyAccount provided by the
2714 account store because that is the one that
2715 knows the name of the Modest account */
2716 TnyAccount *modest_server_account =
2717 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2718 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2720 if (!modest_server_account) {
2721 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2725 /* Update active account, but only if it's not a pseudo-account */
2726 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2727 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2728 const gchar *modest_acc_name =
2729 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2730 if (modest_acc_name)
2731 modest_window_set_active_account (window, modest_acc_name);
2734 g_object_unref (modest_server_account);
2738 folder_refreshed_cb (ModestMailOperation *mail_op,
2742 ModestMainWindow *win = NULL;
2743 GtkWidget *folder_view, *header_view;
2744 const GError *error;
2746 g_return_if_fail (TNY_IS_FOLDER (folder));
2748 win = MODEST_MAIN_WINDOW (user_data);
2750 /* Check if the operation failed due to memory low conditions */
2751 error = modest_mail_operation_get_error (mail_op);
2752 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2753 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2754 modest_platform_run_information_dialog (GTK_WINDOW (win),
2755 _KR("memr_ib_operation_disabled"),
2761 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2763 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2766 TnyFolderStore *current_folder;
2768 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2769 if (current_folder) {
2770 gboolean different = ((TnyFolderStore *) folder != current_folder);
2771 g_object_unref (current_folder);
2777 /* Check if folder is empty and set headers view contents style */
2778 if ((tny_folder_get_all_count (folder) == 0) ||
2779 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2780 modest_main_window_set_contents_style (win,
2781 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2785 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2786 TnyFolderStore *folder_store,
2788 ModestMainWindow *main_window)
2790 GtkWidget *header_view;
2792 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2794 header_view = modest_main_window_get_child_widget(main_window,
2795 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2800 if (TNY_IS_ACCOUNT (folder_store)) {
2802 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2804 /* Show account details */
2805 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2808 if (TNY_IS_FOLDER (folder_store) && selected) {
2809 TnyAccount *account;
2811 /* Update the active account */
2812 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2814 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2815 g_object_unref (account);
2819 /* Set the header style by default, it could
2820 be changed later by the refresh callback to
2822 modest_main_window_set_contents_style (main_window,
2823 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2825 /* Set folder on header view. This function
2826 will call tny_folder_refresh_async so we
2827 pass a callback that will be called when
2828 finished. We use that callback to set the
2829 empty view if there are no messages */
2830 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2831 TNY_FOLDER (folder_store),
2833 MODEST_WINDOW (main_window),
2834 folder_refreshed_cb,
2837 /* Restore configuration. We need to do this
2838 *after* the set_folder because the widget
2839 memory asks the header view about its
2841 modest_widget_memory_restore (modest_runtime_get_conf (),
2842 G_OBJECT(header_view),
2843 MODEST_CONF_HEADER_VIEW_KEY);
2845 /* No need to save the header view
2846 configuration for Maemo because it only
2847 saves the sorting stuff and that it's
2848 already being done by the sort
2849 dialog. Remove it when the GNOME version
2850 has the same behaviour */
2851 #ifdef MODEST_TOOLKIT_GTK
2852 if (modest_main_window_get_contents_style (main_window) ==
2853 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2854 modest_widget_memory_save (modest_runtime_get_conf (),
2855 G_OBJECT (header_view),
2856 MODEST_CONF_HEADER_VIEW_KEY);
2858 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2862 /* Update dimming state */
2863 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2864 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2869 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2876 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2878 online = tny_device_is_online (modest_runtime_get_device());
2881 /* already online -- the item is simply not there... */
2882 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2884 GTK_MESSAGE_WARNING,
2886 _("The %s you selected cannot be found"),
2888 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2889 gtk_dialog_run (GTK_DIALOG(dialog));
2891 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2894 _("mcen_bd_dialog_cancel"),
2895 GTK_RESPONSE_REJECT,
2896 _("mcen_bd_dialog_ok"),
2897 GTK_RESPONSE_ACCEPT,
2899 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2900 "Do you want to get online?"), item);
2901 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2902 gtk_label_new (txt), FALSE, FALSE, 0);
2903 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2906 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2907 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2908 /* TODO: Comment about why is this commented out: */
2909 /* modest_platform_connect_and_wait (); */
2912 gtk_widget_destroy (dialog);
2916 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2919 /* g_debug ("%s %s", __FUNCTION__, link); */
2924 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2927 modest_platform_activate_uri (link);
2931 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2934 modest_platform_show_uri_popup (link);
2938 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2941 /* we check for low-mem; in that case, show a warning, and don't allow
2942 * viewing attachments
2944 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2947 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2951 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2952 const gchar *address,
2955 /* g_debug ("%s %s", __FUNCTION__, address); */
2959 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2960 TnyMsg *saved_draft,
2963 ModestMsgEditWindow *edit_window;
2965 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2966 #ifndef MODEST_TOOLKIT_HILDON2
2967 ModestMainWindow *win;
2969 /* FIXME. Make the header view sensitive again. This is a
2970 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2972 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2973 modest_runtime_get_window_mgr(), FALSE));
2975 GtkWidget *hdrview = modest_main_window_get_child_widget(
2976 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2977 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2981 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2983 /* Set draft is there was no error */
2984 if (!modest_mail_operation_get_error (mail_op))
2985 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2987 g_object_unref(edit_window);
2991 enough_space_for_message (ModestMsgEditWindow *edit_window,
2994 guint64 available_disk, expected_size;
2999 available_disk = modest_utils_get_available_space (NULL);
3000 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3001 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3006 /* Double check: disk full condition or message too big */
3007 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3008 expected_size > available_disk) {
3009 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3010 modest_platform_information_banner (NULL, NULL, msg);
3017 * djcb: if we're in low-memory state, we only allow for
3018 * saving messages smaller than
3019 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3020 * should still allow for sending anything critical...
3022 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3023 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3027 * djcb: we also make sure that the attachments are smaller than the max size
3028 * this is for the case where we'd try to forward a message with attachments
3029 * bigger than our max allowed size, or sending an message from drafts which
3030 * somehow got past our checks when attaching.
3032 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3033 modest_platform_run_information_dialog (
3034 GTK_WINDOW(edit_window),
3035 _("mail_ib_error_attachment_size"),
3044 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3046 TnyTransportAccount *transport_account;
3047 ModestMailOperation *mail_operation;
3049 gchar *account_name;
3050 ModestAccountMgr *account_mgr;
3051 gboolean had_error = FALSE;
3053 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3055 data = modest_msg_edit_window_get_msg_data (edit_window);
3058 if (!enough_space_for_message (edit_window, data)) {
3059 modest_msg_edit_window_free_msg_data (edit_window, data);
3063 account_name = g_strdup (data->account_name);
3064 account_mgr = modest_runtime_get_account_mgr();
3066 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3068 account_name = modest_account_mgr_get_default_account (account_mgr);
3069 if (!account_name) {
3070 g_printerr ("modest: no account found\n");
3071 modest_msg_edit_window_free_msg_data (edit_window, data);
3075 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3076 account_name = g_strdup (data->account_name);
3080 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3081 (modest_runtime_get_account_store (),
3083 TNY_ACCOUNT_TYPE_TRANSPORT));
3084 if (!transport_account) {
3085 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3086 g_free (account_name);
3087 modest_msg_edit_window_free_msg_data (edit_window, data);
3091 /* Create the mail operation */
3092 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3094 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3096 modest_mail_operation_save_to_drafts (mail_operation,
3108 data->priority_flags,
3111 on_save_to_drafts_cb,
3112 g_object_ref(edit_window));
3114 #ifdef MODEST_TOOLKIT_HILDON2
3115 /* In hildon2 we always show the information banner on saving to drafts.
3116 * It will be a system information banner in this case.
3118 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3119 modest_platform_information_banner (NULL, NULL, text);
3122 ModestMainWindow *win = NULL;
3124 /* Use the main window as the parent of the banner, if the
3125 main window does not exist it won't be shown, if the parent
3126 window exists then it's properly shown. We don't use the
3127 editor window because it could be closed (save to drafts
3128 could happen after closing the window */
3129 win = (ModestMainWindow *)
3130 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3132 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3133 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3137 modest_msg_edit_window_set_modified (edit_window, FALSE);
3140 g_free (account_name);
3141 g_object_unref (G_OBJECT (transport_account));
3142 g_object_unref (G_OBJECT (mail_operation));
3144 modest_msg_edit_window_free_msg_data (edit_window, data);
3146 #ifndef MODEST_TOOLKIT_HILDON2
3148 * If the drafts folder is selected then make the header view
3149 * insensitive while the message is being saved to drafts
3150 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3151 * is not very clean but it avoids letting the drafts folder
3152 * in an inconsistent state: the user could edit the message
3153 * being saved and undesirable things would happen.
3154 * In the average case the user won't notice anything at
3155 * all. In the worst case (the user is editing a really big
3156 * file from Drafts) the header view will be insensitive
3157 * during the saving process (10 or 20 seconds, depending on
3158 * the message). Anyway this is just a quick workaround: once
3159 * we find a better solution it should be removed
3160 * See NB#65125 (commend #18) for details.
3162 if (!had_error && win != NULL) {
3163 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3164 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3166 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3168 if (modest_tny_folder_is_local_folder(folder)) {
3169 TnyFolderType folder_type;
3170 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3171 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3172 GtkWidget *hdrview = modest_main_window_get_child_widget(
3173 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3174 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3178 if (folder != NULL) g_object_unref(folder);
3186 /* For instance, when clicking the Send toolbar button when editing a message: */
3188 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3190 TnyTransportAccount *transport_account = NULL;
3191 gboolean had_error = FALSE;
3193 ModestAccountMgr *account_mgr;
3194 gchar *account_name;
3195 ModestMailOperation *mail_operation;
3198 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3200 /* Check names but do not automatically add them to addressbook */
3201 if (!modest_msg_edit_window_check_names (edit_window, FALSE))
3204 data = modest_msg_edit_window_get_msg_data (edit_window);
3206 recipients = g_strconcat (data->to?data->to:"",
3207 data->cc?data->cc:"",
3208 data->bcc?data->bcc:"",
3210 if (recipients == NULL || recipients[0] == '\0') {
3211 /* Empty subject -> no send */
3212 g_free (recipients);
3213 modest_msg_edit_window_free_msg_data (edit_window, data);
3216 g_free (recipients);
3219 if (!enough_space_for_message (edit_window, data)) {
3220 modest_msg_edit_window_free_msg_data (edit_window, data);
3224 account_mgr = modest_runtime_get_account_mgr();
3225 account_name = g_strdup (data->account_name);
3227 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3230 account_name = modest_account_mgr_get_default_account (account_mgr);
3232 if (!account_name) {
3233 modest_msg_edit_window_free_msg_data (edit_window, data);
3234 /* Run account setup wizard */
3235 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3240 /* Get the currently-active transport account for this modest account: */
3241 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3243 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3244 (modest_runtime_get_account_store (),
3245 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3248 if (!transport_account) {
3249 modest_msg_edit_window_free_msg_data (edit_window, data);
3250 /* Run account setup wizard */
3251 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3256 /* Create the mail operation */
3257 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3258 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3260 modest_mail_operation_send_new_mail (mail_operation,
3274 data->priority_flags);
3276 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3277 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3279 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3280 const GError *error = modest_mail_operation_get_error (mail_operation);
3281 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3282 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3283 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3284 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3290 g_free (account_name);
3291 g_object_unref (G_OBJECT (transport_account));
3292 g_object_unref (G_OBJECT (mail_operation));
3294 modest_msg_edit_window_free_msg_data (edit_window, data);
3297 modest_msg_edit_window_set_sent (edit_window, TRUE);
3299 /* Save settings and close the window: */
3300 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3307 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3308 ModestMsgEditWindow *window)
3310 ModestMsgEditFormatState *format_state = NULL;
3312 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3313 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3315 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3318 format_state = modest_msg_edit_window_get_format_state (window);
3319 g_return_if_fail (format_state != NULL);
3321 format_state->bold = gtk_toggle_action_get_active (action);
3322 modest_msg_edit_window_set_format_state (window, format_state);
3323 g_free (format_state);
3328 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3329 ModestMsgEditWindow *window)
3331 ModestMsgEditFormatState *format_state = NULL;
3333 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3334 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3336 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3339 format_state = modest_msg_edit_window_get_format_state (window);
3340 g_return_if_fail (format_state != NULL);
3342 format_state->italics = gtk_toggle_action_get_active (action);
3343 modest_msg_edit_window_set_format_state (window, format_state);
3344 g_free (format_state);
3349 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3350 ModestMsgEditWindow *window)
3352 ModestMsgEditFormatState *format_state = NULL;
3354 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3355 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3357 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3360 format_state = modest_msg_edit_window_get_format_state (window);
3361 g_return_if_fail (format_state != NULL);
3363 format_state->bullet = gtk_toggle_action_get_active (action);
3364 modest_msg_edit_window_set_format_state (window, format_state);
3365 g_free (format_state);
3370 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3371 GtkRadioAction *selected,
3372 ModestMsgEditWindow *window)
3374 ModestMsgEditFormatState *format_state = NULL;
3375 GtkJustification value;
3377 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3379 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3382 value = gtk_radio_action_get_current_value (selected);
3384 format_state = modest_msg_edit_window_get_format_state (window);
3385 g_return_if_fail (format_state != NULL);
3387 format_state->justification = value;
3388 modest_msg_edit_window_set_format_state (window, format_state);
3389 g_free (format_state);
3393 modest_ui_actions_on_select_editor_color (GtkAction *action,
3394 ModestMsgEditWindow *window)
3396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3397 g_return_if_fail (GTK_IS_ACTION (action));
3399 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3402 modest_msg_edit_window_select_color (window);
3406 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3407 ModestMsgEditWindow *window)
3409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3410 g_return_if_fail (GTK_IS_ACTION (action));
3412 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3415 modest_msg_edit_window_select_background_color (window);
3419 modest_ui_actions_on_insert_image (GObject *object,
3420 ModestMsgEditWindow *window)
3422 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3425 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3428 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3431 modest_msg_edit_window_insert_image (window);
3435 modest_ui_actions_on_attach_file (GtkAction *action,
3436 ModestMsgEditWindow *window)
3438 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3439 g_return_if_fail (GTK_IS_ACTION (action));
3441 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3444 modest_msg_edit_window_offer_attach_file (window);
3448 modest_ui_actions_on_remove_attachments (GtkAction *action,
3449 ModestMsgEditWindow *window)
3451 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3453 modest_msg_edit_window_remove_attachments (window, NULL);
3457 do_create_folder_cb (ModestMailOperation *mail_op,
3458 TnyFolderStore *parent_folder,
3459 TnyFolder *new_folder,
3462 gchar *suggested_name = (gchar *) user_data;
3463 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3464 const GError *error;
3466 error = modest_mail_operation_get_error (mail_op);
3468 gboolean disk_full = FALSE;
3469 TnyAccount *account;
3470 /* Show an error. If there was some problem writing to
3471 disk, show it, otherwise show the generic folder
3472 create error. We do it here and not in an error
3473 handler because the call to do_create_folder will
3474 stop the main loop in a gtk_dialog_run and then,
3475 the message won't be shown until that dialog is
3477 account = modest_mail_operation_get_account (mail_op);
3480 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3481 (GtkWidget *) source_win,
3484 _("mail_in_ui_folder_create_error_memory"));
3485 g_object_unref (account);
3488 /* Show an error and try again if there is no
3489 full memory condition */
3490 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3491 _("mail_in_ui_folder_create_error"));
3492 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3496 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3497 * FIXME: any other? */
3498 GtkWidget *folder_view;
3500 #ifndef MODEST_TOOLKIT_HILDON2
3501 if (MODEST_IS_MAIN_WINDOW(source_win))
3503 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3504 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3507 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3508 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3510 /* Select the newly created folder. It could happen
3511 that the widget is no longer there (i.e. the window
3512 has been destroyed, so we need to check this */
3514 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3516 g_object_unref (new_folder);
3518 /* Free. Note that the first time it'll be NULL so noop */
3519 g_free (suggested_name);
3520 g_object_unref (source_win);
3525 TnyFolderStore *parent;
3526 } CreateFolderConnect;
3529 do_create_folder_performer (gboolean canceled,
3531 GtkWindow *parent_window,
3532 TnyAccount *account,
3535 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3536 ModestMailOperation *mail_op;
3538 if (canceled || err) {
3539 /* In disk full conditions we could get this error here */
3540 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3541 (GtkWidget *) parent_window, err,
3542 NULL, _("mail_in_ui_folder_create_error_memory"));
3544 /* This happens if we have selected the outbox folder
3546 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3547 TNY_IS_MERGE_FOLDER (helper->parent)) {
3548 /* Show an error and retry */
3549 modest_platform_information_banner ((GtkWidget *) parent_window,
3551 _("mail_in_ui_folder_create_error"));
3553 do_create_folder (parent_window, helper->parent, helper->folder_name);
3559 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3560 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3562 modest_mail_operation_create_folder (mail_op,
3564 (const gchar *) helper->folder_name,
3565 do_create_folder_cb,
3566 g_strdup (helper->folder_name));
3567 g_object_unref (mail_op);
3571 g_object_unref (helper->parent);
3572 if (helper->folder_name)
3573 g_free (helper->folder_name);
3574 g_slice_free (CreateFolderConnect, helper);
3579 do_create_folder (GtkWindow *parent_window,
3580 TnyFolderStore *suggested_parent,
3581 const gchar *suggested_name)
3584 gchar *folder_name = NULL;
3585 TnyFolderStore *parent_folder = NULL;
3587 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3589 (gchar *) suggested_name,
3593 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3594 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3595 helper->folder_name = g_strdup (folder_name);
3596 helper->parent = g_object_ref (parent_folder);
3598 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3601 do_create_folder_performer,
3606 g_free (folder_name);
3608 g_object_unref (parent_folder);
3612 modest_ui_actions_create_folder(GtkWidget *parent_window,
3613 GtkWidget *folder_view,
3614 TnyFolderStore *parent_folder)
3616 if (!parent_folder) {
3617 #ifdef MODEST_TOOLKIT_HILDON2
3618 ModestTnyAccountStore *acc_store;
3620 acc_store = modest_runtime_get_account_store ();
3622 parent_folder = (TnyFolderStore *)
3623 modest_tny_account_store_get_local_folders_account (acc_store);
3625 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3629 if (parent_folder) {
3630 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3631 g_object_unref (parent_folder);
3636 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3639 g_return_if_fail (MODEST_IS_WINDOW(window));
3641 #ifndef MODEST_TOOLKIT_HILDON2
3642 if (MODEST_IS_MAIN_WINDOW (window)) {
3643 GtkWidget *folder_view;
3645 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3646 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3650 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3652 if (MODEST_IS_FOLDER_WINDOW (window)) {
3653 GtkWidget *folder_view;
3655 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3656 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3659 g_assert_not_reached ();
3664 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3667 const GError *error = NULL;
3668 gchar *message = NULL;
3670 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3672 /* Get error message */
3673 error = modest_mail_operation_get_error (mail_op);
3675 g_return_if_reached ();
3677 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3678 (GError *) error, account);
3680 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3681 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3682 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3683 message = _CS("ckdg_ib_folder_already_exists");
3684 } else if (error->domain == TNY_ERROR_DOMAIN &&
3685 error->code == TNY_SERVICE_ERROR_STATE) {
3686 /* This means that the folder is already in use (a
3687 message is opened for example */
3688 message = _("emev_ni_internal_error");
3690 message = _CS("ckdg_ib_unable_to_rename");
3693 /* We don't set a parent for the dialog because the dialog
3694 will be destroyed so the banner won't appear */
3695 modest_platform_information_banner (NULL, NULL, message);
3698 g_object_unref (account);
3704 TnyFolderStore *folder;
3709 on_rename_folder_cb (ModestMailOperation *mail_op,
3710 TnyFolder *new_folder,
3713 ModestFolderView *folder_view;
3715 /* If the window was closed when renaming a folder, or if
3716 * it's not a main window this will happen */
3717 if (!MODEST_IS_FOLDER_VIEW (user_data))
3720 folder_view = MODEST_FOLDER_VIEW (user_data);
3721 /* Note that if the rename fails new_folder will be NULL */
3723 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3724 #ifndef MODEST_TOOLKIT_HILDON2
3726 modest_folder_view_select_first_inbox_or_local (folder_view);
3729 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3733 on_rename_folder_performer (gboolean canceled,
3735 GtkWindow *parent_window,
3736 TnyAccount *account,
3739 ModestMailOperation *mail_op = NULL;
3740 GtkTreeSelection *sel = NULL;
3741 GtkWidget *folder_view = NULL;
3742 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3744 if (canceled || err) {
3745 /* In disk full conditions we could get this error here */
3746 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3747 (GtkWidget *) parent_window, err,
3752 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3753 modest_ui_actions_rename_folder_error_handler,
3754 parent_window, NULL);
3756 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3758 #ifndef MODEST_TOOLKIT_HILDON2
3759 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3761 folder_view = modest_main_window_get_child_widget (
3762 MODEST_MAIN_WINDOW (parent_window),
3763 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3766 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3767 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3768 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3772 /* Clear the folders view */
3773 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3774 gtk_tree_selection_unselect_all (sel);
3776 /* Actually rename the folder */
3777 modest_mail_operation_rename_folder (mail_op,
3778 TNY_FOLDER (data->folder),
3779 (const gchar *) (data->new_name),
3780 on_rename_folder_cb,
3782 g_object_unref (mail_op);
3785 g_object_unref (data->folder);
3786 g_free (data->new_name);
3791 modest_ui_actions_on_rename_folder (GtkAction *action,
3792 ModestWindow *window)
3794 modest_ui_actions_on_edit_mode_rename_folder (window);
3798 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3800 TnyFolderStore *folder;
3801 GtkWidget *folder_view;
3802 gboolean do_rename = TRUE;
3804 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3806 #ifndef MODEST_TOOLKIT_HILDON2
3807 if (MODEST_IS_MAIN_WINDOW (window)) {
3808 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3809 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3813 if (MODEST_IS_FOLDER_WINDOW (window)) {
3814 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3820 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3825 if (TNY_IS_FOLDER (folder)) {
3826 gchar *folder_name = NULL;
3828 const gchar *current_name;
3829 TnyFolderStore *parent;
3831 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3832 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3833 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3834 parent, current_name,
3836 g_object_unref (parent);
3838 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3841 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3842 rename_folder_data->folder = g_object_ref (folder);
3843 rename_folder_data->new_name = folder_name;
3844 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3845 folder, on_rename_folder_performer, rename_folder_data);
3848 g_object_unref (folder);
3853 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3856 GObject *win = modest_mail_operation_get_source (mail_op);
3858 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3859 _("mail_in_ui_folder_delete_error"),
3861 g_object_unref (win);
3865 TnyFolderStore *folder;
3866 gboolean move_to_trash;
3870 on_delete_folder_cb (gboolean canceled,
3872 GtkWindow *parent_window,
3873 TnyAccount *account,
3876 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3877 GtkWidget *folder_view;
3878 ModestMailOperation *mail_op;
3879 GtkTreeSelection *sel;
3881 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3882 /* Note that the connection process can fail due to
3883 memory low conditions as it can not successfully
3884 store the summary */
3885 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3886 (GtkWidget*) parent_window, err,
3888 g_debug ("Error connecting when trying to delete a folder");
3889 g_object_unref (G_OBJECT (info->folder));
3894 #ifndef MODEST_TOOLKIT_HILDON2
3895 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3896 folder_view = modest_main_window_get_child_widget (
3897 MODEST_MAIN_WINDOW (parent_window),
3898 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3900 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3901 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3904 g_object_unref (G_OBJECT (info->folder));
3909 /* Unselect the folder before deleting it to free the headers */
3910 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3911 gtk_tree_selection_unselect_all (sel);
3913 /* Create the mail operation */
3915 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3916 modest_ui_actions_delete_folder_error_handler,
3919 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3921 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3923 #ifndef MODEST_TOOLKIT_HILDON2
3924 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3927 g_object_unref (mail_op);
3928 g_object_unref (info->folder);
3933 delete_folder (ModestWindow *window, gboolean move_to_trash)
3935 TnyFolderStore *folder;
3936 GtkWidget *folder_view;
3940 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3942 #ifndef MODEST_TOOLKIT_HILDON2
3943 if (MODEST_IS_MAIN_WINDOW (window)) {
3945 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3946 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3948 if (MODEST_IS_FOLDER_WINDOW (window)) {
3949 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3957 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3962 /* Show an error if it's an account */
3963 if (!TNY_IS_FOLDER (folder)) {
3964 modest_platform_run_information_dialog (GTK_WINDOW (window),
3965 _("mail_in_ui_folder_delete_error"),
3967 g_object_unref (G_OBJECT (folder));
3972 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3973 tny_folder_get_name (TNY_FOLDER (folder)));
3974 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3975 (const gchar *) message);
3978 if (response == GTK_RESPONSE_OK) {
3979 TnyAccount *account = NULL;
3980 DeleteFolderInfo *info = NULL;
3981 info = g_new0(DeleteFolderInfo, 1);
3982 info->folder = g_object_ref (folder);
3983 info->move_to_trash = move_to_trash;
3985 account = tny_folder_get_account (TNY_FOLDER (folder));
3986 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3988 TNY_FOLDER_STORE (account),
3989 on_delete_folder_cb, info);
3990 g_object_unref (account);
3991 g_object_unref (folder);
3999 modest_ui_actions_on_delete_folder (GtkAction *action,
4000 ModestWindow *window)
4002 modest_ui_actions_on_edit_mode_delete_folder (window);
4006 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4008 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4010 return delete_folder (window, FALSE);
4013 #ifndef MODEST_TOOLKIT_HILDON2
4015 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4017 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4019 delete_folder (MODEST_WINDOW (main_window), TRUE);
4023 typedef struct _PasswordDialogFields {
4024 GtkWidget *username;
4025 GtkWidget *password;
4027 } PasswordDialogFields;
4030 password_dialog_check_field (GtkEditable *editable,
4031 PasswordDialogFields *fields)
4034 gboolean any_value_empty = FALSE;
4036 value = modest_entry_get_text (fields->username);
4037 if ((value == NULL) || value[0] == '\0') {
4038 any_value_empty = TRUE;
4040 value = modest_entry_get_text (fields->password);
4041 if ((value == NULL) || value[0] == '\0') {
4042 any_value_empty = TRUE;
4044 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4048 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4049 const gchar* server_account_name,
4054 ModestMainWindow *main_window)
4056 g_return_if_fail(server_account_name);
4057 gboolean completed = FALSE;
4058 PasswordDialogFields *fields = NULL;
4060 /* Initalize output parameters: */
4067 #ifndef MODEST_TOOLKIT_GTK
4068 /* Maemo uses a different (awkward) button order,
4069 * It should probably just use gtk_alternative_dialog_button_order ().
4071 #ifdef MODEST_TOOLKIT_HILDON2
4073 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4076 _HL("wdgt_bd_done"),
4077 GTK_RESPONSE_ACCEPT,
4079 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4080 HILDON_MARGIN_DOUBLE);
4083 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4086 _("mcen_bd_dialog_ok"),
4087 GTK_RESPONSE_ACCEPT,
4088 _("mcen_bd_dialog_cancel"),
4089 GTK_RESPONSE_REJECT,
4091 #endif /* MODEST_TOOLKIT_HILDON2 */
4094 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4098 GTK_RESPONSE_REJECT,
4100 GTK_RESPONSE_ACCEPT,
4102 #endif /* MODEST_TOOLKIT_GTK */
4104 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4106 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4107 modest_runtime_get_account_mgr(), server_account_name);
4108 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4109 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4112 gtk_widget_destroy (dialog);
4116 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4117 GtkWidget *label = gtk_label_new (txt);
4118 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4120 g_free (server_name);
4121 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4126 gchar *initial_username = modest_account_mgr_get_server_account_username (
4127 modest_runtime_get_account_mgr(), server_account_name);
4129 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
4130 if (initial_username)
4131 modest_entry_set_text (entry_username, initial_username);
4133 /* Dim this if a connection has ever succeeded with this username,
4134 * as per the UI spec: */
4135 /* const gboolean username_known = */
4136 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4137 /* modest_runtime_get_account_mgr(), server_account_name); */
4138 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4140 /* We drop the username sensitive code and disallow changing it here
4141 * as tinymail does not support really changing the username in the callback
4143 gtk_widget_set_sensitive (entry_username, FALSE);
4145 #ifndef MODEST_TOOLKIT_GTK
4146 /* Auto-capitalization is the default, so let's turn it off: */
4147 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4149 /* Create a size group to be used by all captions.
4150 * Note that HildonCaption does not create a default size group if we do not specify one.
4151 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4152 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4154 #ifdef MODEST_TOOLKIT_HILDON2
4155 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4156 _("mail_fi_username"), FALSE,
4159 GtkWidget *caption = hildon_caption_new (sizegroup,
4160 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4162 gtk_widget_show (entry_username);
4163 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4164 FALSE, FALSE, MODEST_MARGIN_HALF);
4165 gtk_widget_show (caption);
4167 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4169 #endif /* !MODEST_TOOLKIT_GTK */
4172 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
4173 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4174 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4176 #ifndef MODEST_TOOLKIT_GTK
4177 /* Auto-capitalization is the default, so let's turn it off: */
4178 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4179 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4181 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4182 _("mail_fi_password"), FALSE,
4184 gtk_widget_show (entry_password);
4185 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4186 FALSE, FALSE, MODEST_MARGIN_HALF);
4187 gtk_widget_show (caption);
4188 g_object_unref (sizegroup);
4190 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4192 #endif /* !MODEST_TOOLKIT_GTK */
4194 if (initial_username != NULL)
4195 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4197 /* This is not in the Maemo UI spec:
4198 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4199 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4203 fields = g_slice_new0 (PasswordDialogFields);
4204 fields->username = entry_username;
4205 fields->password = entry_password;
4206 fields->dialog = dialog;
4208 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4209 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4210 password_dialog_check_field (NULL, fields);
4212 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4214 while (!completed) {
4216 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4218 *username = g_strdup (modest_entry_get_text (entry_username));
4220 /* Note that an empty field becomes the "" string */
4221 if (*username && strlen (*username) > 0) {
4222 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4223 server_account_name,
4227 const gboolean username_was_changed =
4228 (strcmp (*username, initial_username) != 0);
4229 if (username_was_changed) {
4230 g_warning ("%s: tinymail does not yet support changing the "
4231 "username in the get_password() callback.\n", __FUNCTION__);
4237 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4238 _("mcen_ib_username_pw_incorrect"));
4244 *password = g_strdup (modest_entry_get_text (entry_password));
4246 /* We do not save the password in the configuration,
4247 * because this function is only called for passwords that should
4248 * not be remembered:
4249 modest_server_account_set_password (
4250 modest_runtime_get_account_mgr(), server_account_name,
4257 #ifndef MODEST_TOOLKIT_HILDON2
4258 /* Set parent to NULL or the banner will disappear with its parent dialog */
4259 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4271 /* This is not in the Maemo UI spec:
4272 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4278 g_free (initial_username);
4279 gtk_widget_destroy (dialog);
4280 g_slice_free (PasswordDialogFields, fields);
4282 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4286 modest_ui_actions_on_cut (GtkAction *action,
4287 ModestWindow *window)
4289 GtkWidget *focused_widget;
4290 GtkClipboard *clipboard;
4292 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4293 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4294 if (GTK_IS_EDITABLE (focused_widget)) {
4295 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4296 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4297 gtk_clipboard_store (clipboard);
4298 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4299 GtkTextBuffer *buffer;
4301 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4302 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4303 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4304 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4305 gtk_clipboard_store (clipboard);
4307 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4308 TnyList *header_list = modest_header_view_get_selected_headers (
4309 MODEST_HEADER_VIEW (focused_widget));
4310 gboolean continue_download = FALSE;
4311 gint num_of_unc_msgs;
4313 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4315 if (num_of_unc_msgs) {
4316 TnyAccount *account = get_account_from_header_list (header_list);
4318 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4319 g_object_unref (account);
4323 if (num_of_unc_msgs == 0 || continue_download) {
4324 /* modest_platform_information_banner (
4325 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4326 modest_header_view_cut_selection (
4327 MODEST_HEADER_VIEW (focused_widget));
4330 g_object_unref (header_list);
4331 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4332 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4337 modest_ui_actions_on_copy (GtkAction *action,
4338 ModestWindow *window)
4340 GtkClipboard *clipboard;
4341 GtkWidget *focused_widget;
4342 gboolean copied = TRUE;
4344 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4345 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4347 if (GTK_IS_LABEL (focused_widget)) {
4349 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4350 gtk_clipboard_set_text (clipboard, selection, -1);
4352 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4353 gtk_clipboard_store (clipboard);
4354 } else if (GTK_IS_EDITABLE (focused_widget)) {
4355 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4356 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4357 gtk_clipboard_store (clipboard);
4358 } else if (GTK_IS_HTML (focused_widget)) {
4361 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4362 if ((sel == NULL) || (sel[0] == '\0')) {
4365 gtk_html_copy (GTK_HTML (focused_widget));
4366 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4367 gtk_clipboard_store (clipboard);
4369 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4370 GtkTextBuffer *buffer;
4371 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4372 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4373 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4374 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4375 gtk_clipboard_store (clipboard);
4377 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4378 TnyList *header_list = modest_header_view_get_selected_headers (
4379 MODEST_HEADER_VIEW (focused_widget));
4380 gboolean continue_download = FALSE;
4381 gint num_of_unc_msgs;
4383 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4385 if (num_of_unc_msgs) {
4386 TnyAccount *account = get_account_from_header_list (header_list);
4388 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4389 g_object_unref (account);
4393 if (num_of_unc_msgs == 0 || continue_download) {
4394 modest_platform_information_banner (
4395 NULL, NULL, _CS("mcen_ib_getting_items"));
4396 modest_header_view_copy_selection (
4397 MODEST_HEADER_VIEW (focused_widget));
4401 g_object_unref (header_list);
4403 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4404 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4407 /* Show information banner if there was a copy to clipboard */
4409 modest_platform_information_banner (
4410 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4414 modest_ui_actions_on_undo (GtkAction *action,
4415 ModestWindow *window)
4417 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4418 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4419 #ifndef MODEST_TOOLKIT_HILDON2
4420 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4421 ModestEmailClipboard *clipboard = NULL;
4422 /* Clear clipboard source */
4423 clipboard = modest_runtime_get_email_clipboard ();
4424 modest_email_clipboard_clear (clipboard);
4427 g_return_if_reached ();
4432 modest_ui_actions_on_redo (GtkAction *action,
4433 ModestWindow *window)
4435 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4436 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4439 g_return_if_reached ();
4445 destroy_information_note (ModestMailOperation *mail_op,
4448 /* destroy information note */
4449 gtk_widget_destroy (GTK_WIDGET(user_data));
4453 destroy_folder_information_note (ModestMailOperation *mail_op,
4454 TnyFolder *new_folder,
4457 /* destroy information note */
4458 gtk_widget_destroy (GTK_WIDGET(user_data));
4463 paste_as_attachment_free (gpointer data)
4465 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4467 if (helper->banner) {
4468 gtk_widget_destroy (helper->banner);
4469 g_object_unref (helper->banner);
4475 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4480 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4481 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4486 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4491 modest_ui_actions_on_paste (GtkAction *action,
4492 ModestWindow *window)
4494 GtkWidget *focused_widget = NULL;
4495 GtkWidget *inf_note = NULL;
4496 ModestMailOperation *mail_op = NULL;
4498 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4499 if (GTK_IS_EDITABLE (focused_widget)) {
4500 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4501 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4502 ModestEmailClipboard *e_clipboard = NULL;
4503 e_clipboard = modest_runtime_get_email_clipboard ();
4504 if (modest_email_clipboard_cleared (e_clipboard)) {
4505 GtkTextBuffer *buffer;
4506 GtkClipboard *clipboard;
4508 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4509 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4510 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4511 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4512 ModestMailOperation *mail_op;
4513 TnyFolder *src_folder = NULL;
4514 TnyList *data = NULL;
4516 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4517 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4518 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4519 _CS("ckct_nw_pasting"));
4520 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4521 mail_op = modest_mail_operation_new (G_OBJECT (window));
4522 if (helper->banner != NULL) {
4523 g_object_ref (G_OBJECT (helper->banner));
4524 gtk_widget_show (GTK_WIDGET (helper->banner));
4528 modest_mail_operation_get_msgs_full (mail_op,
4530 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4532 paste_as_attachment_free);
4536 g_object_unref (data);
4538 g_object_unref (src_folder);
4541 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4542 ModestEmailClipboard *clipboard = NULL;
4543 TnyFolder *src_folder = NULL;
4544 TnyFolderStore *folder_store = NULL;
4545 TnyList *data = NULL;
4546 gboolean delete = FALSE;
4548 /* Check clipboard source */
4549 clipboard = modest_runtime_get_email_clipboard ();
4550 if (modest_email_clipboard_cleared (clipboard))
4553 /* Get elements to paste */
4554 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4556 /* Create a new mail operation */
4557 mail_op = modest_mail_operation_new (G_OBJECT(window));
4559 /* Get destination folder */
4560 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4562 /* transfer messages */
4566 /* Ask for user confirmation */
4568 modest_ui_actions_msgs_move_to_confirmation (window,
4569 TNY_FOLDER (folder_store),
4573 if (response == GTK_RESPONSE_OK) {
4574 /* Launch notification */
4575 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4576 _CS("ckct_nw_pasting"));
4577 if (inf_note != NULL) {
4578 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4579 gtk_widget_show (GTK_WIDGET(inf_note));
4582 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4583 modest_mail_operation_xfer_msgs (mail_op,
4585 TNY_FOLDER (folder_store),
4587 destroy_information_note,
4590 g_object_unref (mail_op);
4593 } else if (src_folder != NULL) {
4594 /* Launch notification */
4595 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4596 _CS("ckct_nw_pasting"));
4597 if (inf_note != NULL) {
4598 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4599 gtk_widget_show (GTK_WIDGET(inf_note));
4602 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4603 modest_mail_operation_xfer_folder (mail_op,
4607 destroy_folder_information_note,
4613 g_object_unref (data);
4614 if (src_folder != NULL)
4615 g_object_unref (src_folder);
4616 if (folder_store != NULL)
4617 g_object_unref (folder_store);
4623 modest_ui_actions_on_select_all (GtkAction *action,
4624 ModestWindow *window)
4626 GtkWidget *focused_widget;
4628 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4629 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4630 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4631 } else if (GTK_IS_LABEL (focused_widget)) {
4632 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4633 } else if (GTK_IS_EDITABLE (focused_widget)) {
4634 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4635 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4636 GtkTextBuffer *buffer;
4637 GtkTextIter start, end;
4639 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4640 gtk_text_buffer_get_start_iter (buffer, &start);
4641 gtk_text_buffer_get_end_iter (buffer, &end);
4642 gtk_text_buffer_select_range (buffer, &start, &end);
4643 } else if (GTK_IS_HTML (focused_widget)) {
4644 gtk_html_select_all (GTK_HTML (focused_widget));
4645 #ifndef MODEST_TOOLKIT_HILDON2
4646 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4647 GtkWidget *header_view = focused_widget;
4648 GtkTreeSelection *selection = NULL;
4650 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4651 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4652 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4655 /* Disable window dimming management */
4656 modest_window_disable_dimming (MODEST_WINDOW(window));
4658 /* Select all messages */
4659 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4660 gtk_tree_selection_select_all (selection);
4662 /* Set focuse on header view */
4663 gtk_widget_grab_focus (header_view);
4665 /* Enable window dimming management */
4666 modest_window_enable_dimming (MODEST_WINDOW(window));
4667 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4668 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4675 modest_ui_actions_on_mark_as_read (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_read, NULL);
4685 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4686 ModestWindow *window)
4688 g_return_if_fail (MODEST_IS_WINDOW(window));
4690 /* Mark each header as read */
4691 do_headers_action (window, headers_action_mark_as_unread, NULL);
4695 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4696 GtkRadioAction *selected,
4697 ModestWindow *window)
4701 value = gtk_radio_action_get_current_value (selected);
4702 if (MODEST_IS_WINDOW (window)) {
4703 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4708 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4709 GtkRadioAction *selected,
4710 ModestWindow *window)
4712 TnyHeaderFlags flags;
4713 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4715 flags = gtk_radio_action_get_current_value (selected);
4716 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4720 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4721 GtkRadioAction *selected,
4722 ModestWindow *window)
4726 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4728 file_format = gtk_radio_action_get_current_value (selected);
4729 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4734 modest_ui_actions_on_zoom_plus (GtkAction *action,
4735 ModestWindow *window)
4737 g_return_if_fail (MODEST_IS_WINDOW (window));
4739 modest_window_zoom_plus (MODEST_WINDOW (window));
4743 modest_ui_actions_on_zoom_minus (GtkAction *action,
4744 ModestWindow *window)
4746 g_return_if_fail (MODEST_IS_WINDOW (window));
4748 modest_window_zoom_minus (MODEST_WINDOW (window));
4752 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4753 ModestWindow *window)
4755 ModestWindowMgr *mgr;
4756 gboolean fullscreen, active;
4757 g_return_if_fail (MODEST_IS_WINDOW (window));
4759 mgr = modest_runtime_get_window_mgr ();
4761 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4762 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4764 if (active != fullscreen) {
4765 modest_window_mgr_set_fullscreen_mode (mgr, active);
4766 #ifndef MODEST_TOOLKIT_HILDON2
4767 gtk_window_present (GTK_WINDOW (window));
4773 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4774 ModestWindow *window)
4776 ModestWindowMgr *mgr;
4777 gboolean fullscreen;
4779 g_return_if_fail (MODEST_IS_WINDOW (window));
4781 mgr = modest_runtime_get_window_mgr ();
4782 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4783 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4785 #ifndef MODEST_TOOLKIT_HILDON2
4786 gtk_window_present (GTK_WINDOW (window));
4791 * Used by modest_ui_actions_on_details to call do_headers_action
4794 headers_action_show_details (TnyHeader *header,
4795 ModestWindow *window,
4799 gboolean async_retrieval;
4802 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4803 async_retrieval = TRUE;
4804 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4806 async_retrieval = FALSE;
4808 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4810 g_object_unref (msg);
4814 * Show the header details in a ModestDetailsDialog widget
4817 modest_ui_actions_on_details (GtkAction *action,
4820 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4824 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4828 header = tny_msg_get_header (msg);
4830 headers_action_show_details (header, win, NULL);
4831 g_object_unref (header);
4833 g_object_unref (msg);
4834 #ifndef MODEST_TOOLKIT_HILDON2
4835 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4836 GtkWidget *folder_view, *header_view;
4838 /* Check which widget has the focus */
4839 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4840 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4841 if (gtk_widget_is_focus (folder_view)) {
4842 TnyFolderStore *folder_store
4843 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4844 if (!folder_store) {
4845 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4848 /* Show only when it's a folder */
4849 /* This function should not be called for account items,
4850 * because we dim the menu item for them. */
4851 if (TNY_IS_FOLDER (folder_store)) {
4852 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4853 TNY_FOLDER (folder_store));
4856 g_object_unref (folder_store);
4859 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4860 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4861 /* Show details of each header */
4862 do_headers_action (win, headers_action_show_details, header_view);
4865 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4867 GtkWidget *header_view;
4869 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4870 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4872 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4874 g_object_unref (folder);
4881 modest_ui_actions_on_limit_error (GtkAction *action,
4884 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4886 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4891 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4892 ModestMsgEditWindow *window)
4894 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4896 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4900 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4901 ModestMsgEditWindow *window)
4903 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4905 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4908 #ifndef MODEST_TOOLKIT_HILDON2
4910 modest_ui_actions_toggle_folders_view (GtkAction *action,
4911 ModestMainWindow *main_window)
4913 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4915 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4916 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4918 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4923 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4924 ModestWindow *window)
4926 gboolean active, fullscreen = FALSE;
4927 ModestWindowMgr *mgr;
4929 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4931 /* Check if we want to toggle the toolbar view in fullscreen
4933 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4934 "ViewShowToolbarFullScreen")) {
4938 /* Toggle toolbar */
4939 mgr = modest_runtime_get_window_mgr ();
4940 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4944 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4945 ModestMsgEditWindow *window)
4947 modest_msg_edit_window_select_font (window);
4952 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4953 const gchar *display_name,
4956 /* don't update the display name if it was already set;
4957 * updating the display name apparently is expensive */
4958 const gchar* old_name = gtk_window_get_title (window);
4960 if (display_name == NULL)
4963 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4964 return; /* don't do anything */
4966 /* This is usually used to change the title of the main window, which
4967 * is the one that holds the folder view. Note that this change can
4968 * happen even when the widget doesn't have the focus. */
4969 gtk_window_set_title (window, display_name);
4974 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4976 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4977 modest_msg_edit_window_select_contacts (window);
4981 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4983 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4984 modest_msg_edit_window_check_names (window, FALSE);
4987 #ifndef MODEST_TOOLKIT_HILDON2
4989 * This function is used to track changes in the selection of the
4990 * folder view that is inside the "move to" dialog to enable/disable
4991 * the OK button because we do not want the user to select a disallowed
4992 * destination for a folder.
4993 * The user also not desired to be able to use NEW button on items where
4994 * folder creation is not possibel.
4997 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4998 TnyFolderStore *folder_store,
5002 GtkWidget *dialog = NULL;
5003 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5004 gboolean moving_folder = FALSE;
5005 gboolean is_local_account = TRUE;
5006 GtkWidget *folder_view = NULL;
5007 ModestTnyFolderRules rules;
5009 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5014 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5018 /* check if folder_store is an remote account */
5019 if (TNY_IS_ACCOUNT (folder_store)) {
5020 TnyAccount *local_account = NULL;
5021 TnyAccount *mmc_account = NULL;
5022 ModestTnyAccountStore *account_store = NULL;
5024 account_store = modest_runtime_get_account_store ();
5025 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5026 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5028 if ((gpointer) local_account != (gpointer) folder_store &&
5029 (gpointer) mmc_account != (gpointer) folder_store) {
5030 ModestProtocolType proto;
5031 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5032 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5033 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5035 is_local_account = FALSE;
5036 /* New button should be dimmed on remote
5038 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5040 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5042 g_object_unref (local_account);
5044 /* It could not exist */
5046 g_object_unref (mmc_account);
5049 /* Check the target folder rules */
5050 if (TNY_IS_FOLDER (folder_store)) {
5051 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5052 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5053 ok_sensitive = FALSE;
5054 new_sensitive = FALSE;
5059 /* Check if we're moving a folder */
5060 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5061 /* Get the widgets */
5062 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5063 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5064 if (gtk_widget_is_focus (folder_view))
5065 moving_folder = TRUE;
5068 if (moving_folder) {
5069 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5071 /* Get the folder to move */
5072 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5074 /* Check that we're not moving to the same folder */
5075 if (TNY_IS_FOLDER (moved_folder)) {
5076 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5077 if (parent == folder_store)
5078 ok_sensitive = FALSE;
5079 g_object_unref (parent);
5082 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5083 /* Do not allow to move to an account unless it's the
5084 local folders account */
5085 if (!is_local_account)
5086 ok_sensitive = FALSE;
5089 if (ok_sensitive && (moved_folder == folder_store)) {
5090 /* Do not allow to move to itself */
5091 ok_sensitive = FALSE;
5093 g_object_unref (moved_folder);
5095 TnyFolder *src_folder = NULL;
5097 /* Moving a message */
5098 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5100 TnyHeader *header = NULL;
5101 header = modest_msg_view_window_get_header
5102 (MODEST_MSG_VIEW_WINDOW (user_data));
5103 if (!TNY_IS_HEADER(header))
5104 g_warning ("%s: could not get source header", __FUNCTION__);
5106 src_folder = tny_header_get_folder (header);
5109 g_object_unref (header);
5112 TNY_FOLDER (modest_folder_view_get_selected
5113 (MODEST_FOLDER_VIEW (folder_view)));
5116 if (TNY_IS_FOLDER(src_folder)) {
5117 /* Do not allow to move the msg to the same folder */
5118 /* Do not allow to move the msg to an account */
5119 if ((gpointer) src_folder == (gpointer) folder_store ||
5120 TNY_IS_ACCOUNT (folder_store))
5121 ok_sensitive = FALSE;
5122 g_object_unref (src_folder);
5124 g_warning ("%s: could not get source folder", __FUNCTION__);
5128 /* Set sensitivity of the OK and NEW button */
5129 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5130 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5135 on_move_to_dialog_response (GtkDialog *dialog,
5139 GtkWidget *parent_win;
5140 MoveToInfo *helper = NULL;
5141 ModestFolderView *folder_view;
5142 gboolean unset_edit_mode = FALSE;
5144 helper = (MoveToInfo *) user_data;
5146 parent_win = (GtkWidget *) helper->win;
5147 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5148 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5150 TnyFolderStore *dst_folder;
5151 TnyFolderStore *selected;
5153 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5154 selected = modest_folder_view_get_selected (folder_view);
5155 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5156 g_object_unref (selected);
5158 case GTK_RESPONSE_NONE:
5159 case GTK_RESPONSE_CANCEL:
5160 case GTK_RESPONSE_DELETE_EVENT:
5162 case GTK_RESPONSE_OK:
5163 dst_folder = modest_folder_view_get_selected (folder_view);
5165 #ifndef MODEST_TOOLKIT_HILDON2
5166 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5167 /* Clean list to move used for filtering */
5168 modest_folder_view_set_list_to_move (folder_view, NULL);
5170 modest_ui_actions_on_main_window_move_to (NULL,
5171 GTK_WIDGET (folder_view),
5173 MODEST_MAIN_WINDOW (parent_win));
5175 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5176 /* Clean list to move used for filtering */
5177 modest_folder_view_set_list_to_move (folder_view, NULL);
5179 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5182 GTK_WINDOW (parent_win));
5185 /* if the user selected a root folder
5186 (account) then do not perform any action */
5187 if (TNY_IS_ACCOUNT (dst_folder)) {
5188 g_signal_stop_emission_by_name (dialog, "response");
5192 /* Clean list to move used for filtering */
5193 modest_folder_view_set_list_to_move (folder_view, NULL);
5195 /* Moving from headers window in edit mode */
5196 modest_ui_actions_on_window_move_to (NULL, helper->list,
5198 MODEST_WINDOW (parent_win));
5202 g_object_unref (dst_folder);
5204 unset_edit_mode = TRUE;
5207 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5210 /* Free the helper and exit */
5212 g_object_unref (helper->list);
5213 if (unset_edit_mode) {
5214 #ifdef MODEST_TOOLKIT_HILDON2
5215 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5218 g_slice_free (MoveToInfo, helper);
5219 gtk_widget_destroy (GTK_WIDGET (dialog));
5223 create_move_to_dialog (GtkWindow *win,
5224 GtkWidget *folder_view,
5225 TnyList *list_to_move)
5227 GtkWidget *dialog, *tree_view = NULL;
5229 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5231 #ifndef MODEST_TOOLKIT_HILDON2
5232 /* Track changes in the selection to
5233 * disable the OK button whenever "Move to" is not possible
5234 * disbale NEW button whenever New is not possible */
5235 g_signal_connect (tree_view,
5236 "folder_selection_changed",
5237 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5241 /* It could happen that we're trying to move a message from a
5242 window (msg window for example) after the main window was
5243 closed, so we can not just get the model of the folder
5245 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5246 const gchar *visible_id = NULL;
5248 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5249 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5250 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5251 MODEST_FOLDER_VIEW(tree_view));
5254 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5256 /* Show the same account than the one that is shown in the main window */
5257 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5260 const gchar *active_account_name = NULL;
5261 ModestAccountMgr *mgr = NULL;
5262 ModestAccountSettings *settings = NULL;
5263 ModestServerAccountSettings *store_settings = NULL;
5265 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5266 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5267 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5268 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5270 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5271 mgr = modest_runtime_get_account_mgr ();
5272 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5275 const gchar *store_account_name;
5276 store_settings = modest_account_settings_get_store_settings (settings);
5277 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5279 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5280 store_account_name);
5281 g_object_unref (store_settings);
5282 g_object_unref (settings);
5286 /* we keep a pointer to the embedded folder view, so we can
5287 * retrieve it with get_folder_view_from_move_to_dialog (see
5288 * above) later (needed for focus handling)
5290 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5292 /* Hide special folders */
5293 #ifndef MODEST_TOOLKIT_HILDON2
5294 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5297 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5298 #ifndef MODEST_TOOLKIT_HILDON2
5299 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5302 gtk_widget_show (GTK_WIDGET (tree_view));
5308 * Shows a confirmation dialog to the user when we're moving messages
5309 * from a remote server to the local storage. Returns the dialog
5310 * response. If it's other kind of movement then it always returns
5313 * This one is used by the next functions:
5314 * modest_ui_actions_on_paste - commented out
5315 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5318 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5319 TnyFolder *dest_folder,
5323 gint response = GTK_RESPONSE_OK;
5324 TnyAccount *account = NULL;
5325 TnyFolder *src_folder = NULL;
5326 TnyIterator *iter = NULL;
5327 TnyHeader *header = NULL;
5329 /* return with OK if the destination is a remote folder */
5330 if (modest_tny_folder_is_remote_folder (dest_folder))
5331 return GTK_RESPONSE_OK;
5333 /* Get source folder */
5334 iter = tny_list_create_iterator (headers);
5335 header = TNY_HEADER (tny_iterator_get_current (iter));
5337 src_folder = tny_header_get_folder (header);
5338 g_object_unref (header);
5340 g_object_unref (iter);
5342 /* if no src_folder, message may be an attahcment */
5343 if (src_folder == NULL)
5344 return GTK_RESPONSE_CANCEL;
5346 /* If the source is a local or MMC folder */
5347 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5348 g_object_unref (src_folder);
5349 return GTK_RESPONSE_OK;
5352 /* Get the account */
5353 account = tny_folder_get_account (src_folder);
5355 /* now if offline we ask the user */
5356 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5357 response = GTK_RESPONSE_OK;
5359 response = GTK_RESPONSE_CANCEL;
5362 g_object_unref (src_folder);
5363 g_object_unref (account);
5369 move_to_helper_destroyer (gpointer user_data)
5371 MoveToHelper *helper = (MoveToHelper *) user_data;
5373 /* Close the "Pasting" information banner */
5374 if (helper->banner) {
5375 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5376 g_object_unref (helper->banner);
5378 if (gtk_tree_row_reference_valid (helper->reference)) {
5379 gtk_tree_row_reference_free (helper->reference);
5380 helper->reference = NULL;
5386 move_to_cb (ModestMailOperation *mail_op,
5389 MoveToHelper *helper = (MoveToHelper *) user_data;
5390 GObject *object = modest_mail_operation_get_source (mail_op);
5392 /* Note that the operation could have failed, in that case do
5394 if (modest_mail_operation_get_status (mail_op) !=
5395 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5398 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5399 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5401 if (!modest_msg_view_window_select_next_message (self) &&
5402 !modest_msg_view_window_select_previous_message (self)) {
5403 /* No more messages to view, so close this window */
5404 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5406 #ifndef MODEST_TOOLKIT_HILDON2
5407 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5408 gtk_tree_row_reference_valid (helper->reference)) {
5409 GtkWidget *header_view;
5411 GtkTreeSelection *sel;
5413 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5414 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5415 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5416 path = gtk_tree_row_reference_get_path (helper->reference);
5417 /* We need to unselect the previous one
5418 because we could be copying instead of
5420 gtk_tree_selection_unselect_all (sel);
5421 gtk_tree_selection_select_path (sel, path);
5422 gtk_tree_path_free (path);
5425 g_object_unref (object);
5428 /* Destroy the helper */
5429 move_to_helper_destroyer (helper);
5433 folder_move_to_cb (ModestMailOperation *mail_op,
5434 TnyFolder *new_folder,
5439 object = modest_mail_operation_get_source (mail_op);
5440 #ifndef MODEST_TOOLKIT_HILDON2
5441 if (MODEST_IS_MAIN_WINDOW (object)) {
5442 GtkWidget *folder_view;
5443 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5444 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5445 g_object_ref (folder_view);
5446 g_object_unref (object);
5447 move_to_cb (mail_op, user_data);
5448 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5449 g_object_unref (folder_view);
5454 move_to_cb (mail_op, user_data);
5459 msgs_move_to_cb (ModestMailOperation *mail_op,
5462 move_to_cb (mail_op, user_data);
5466 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5469 GObject *win = NULL;
5470 const GError *error;
5471 TnyAccount *account = NULL;
5473 #ifndef MODEST_TOOLKIT_HILDON2
5474 ModestWindow *main_window = NULL;
5476 /* Disable next automatic folder selection */
5477 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5478 FALSE); /* don't create */
5480 /* Show notification dialog only if the main window exists */
5482 GtkWidget *folder_view = NULL;
5484 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5485 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5486 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5488 if (user_data && TNY_IS_FOLDER (user_data)) {
5489 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5490 TNY_FOLDER (user_data), FALSE);
5494 win = modest_mail_operation_get_source (mail_op);
5495 error = modest_mail_operation_get_error (mail_op);
5497 if (TNY_IS_FOLDER (user_data))
5498 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5499 else if (TNY_IS_ACCOUNT (user_data))
5500 account = g_object_ref (user_data);
5502 /* If it's not a disk full error then show a generic error */
5503 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5504 (GtkWidget *) win, (GError *) error,
5506 modest_platform_run_information_dialog ((GtkWindow *) win,
5507 _("mail_in_ui_folder_move_target_error"),
5510 g_object_unref (account);
5512 g_object_unref (win);
5515 #ifndef MODEST_TOOLKIT_HILDON2
5517 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5526 gint pending_purges = 0;
5527 gboolean some_purged = FALSE;
5528 ModestWindow *win = MODEST_WINDOW (user_data);
5529 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5531 /* If there was any error */
5532 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5533 modest_window_mgr_unregister_header (mgr, header);
5537 /* Once the message has been retrieved for purging, we check if
5538 * it's all ok for purging */
5540 parts = tny_simple_list_new ();
5541 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5542 iter = tny_list_create_iterator (parts);
5544 while (!tny_iterator_is_done (iter)) {
5546 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5547 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5548 if (tny_mime_part_is_purged (part))
5555 g_object_unref (part);
5557 tny_iterator_next (iter);
5559 g_object_unref (iter);
5562 if (pending_purges>0) {
5564 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5566 if (response == GTK_RESPONSE_OK) {
5569 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5570 iter = tny_list_create_iterator (parts);
5571 while (!tny_iterator_is_done (iter)) {
5574 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5575 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5576 tny_mime_part_set_purged (part);
5579 g_object_unref (part);
5581 tny_iterator_next (iter);
5583 g_object_unref (iter);
5585 tny_msg_rewrite_cache (msg);
5587 gtk_widget_destroy (info);
5591 modest_window_mgr_unregister_header (mgr, header);
5593 g_object_unref (parts);
5597 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5598 ModestMainWindow *win)
5600 GtkWidget *header_view;
5601 TnyList *header_list;
5603 TnyHeaderFlags flags;
5604 ModestWindow *msg_view_window = NULL;
5607 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5609 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5610 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5612 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5614 g_warning ("%s: no header selected", __FUNCTION__);
5618 if (tny_list_get_length (header_list) == 1) {
5619 TnyIterator *iter = tny_list_create_iterator (header_list);
5620 header = TNY_HEADER (tny_iterator_get_current (iter));
5621 g_object_unref (iter);
5625 if (!header || !TNY_IS_HEADER(header)) {
5626 g_warning ("%s: header is not valid", __FUNCTION__);
5630 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5631 header, &msg_view_window);
5632 flags = tny_header_get_flags (header);
5633 if (!(flags & TNY_HEADER_FLAG_CACHED))
5636 if (msg_view_window != NULL)
5637 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5639 /* do nothing; uid was registered before, so window is probably on it's way */
5640 g_debug ("header %p has already been registered", header);
5643 ModestMailOperation *mail_op = NULL;
5644 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5645 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5646 modest_ui_actions_disk_operations_error_handler,
5648 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5649 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5651 g_object_unref (mail_op);
5654 g_object_unref (header);
5656 g_object_unref (header_list);
5661 * Checks if we need a connection to do the transfer and if the user
5662 * wants to connect to complete it
5665 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5666 TnyFolderStore *src_folder,
5668 TnyFolder *dst_folder,
5669 gboolean delete_originals,
5670 gboolean *need_connection,
5673 TnyAccount *src_account;
5674 gint uncached_msgs = 0;
5676 /* We don't need any further check if
5678 * 1- the source folder is local OR
5679 * 2- the device is already online
5681 if (!modest_tny_folder_store_is_remote (src_folder) ||
5682 tny_device_is_online (modest_runtime_get_device())) {
5683 *need_connection = FALSE;
5688 /* We must ask for a connection when
5690 * - the message(s) is not already cached OR
5691 * - the message(s) is cached but the leave_on_server setting
5692 * is FALSE (because we need to sync the source folder to
5693 * delete the message from the server (for IMAP we could do it
5694 * offline, it'll take place the next time we get a
5697 uncached_msgs = header_list_count_uncached_msgs (headers);
5698 src_account = get_account_from_folder_store (src_folder);
5699 if (uncached_msgs > 0) {
5703 *need_connection = TRUE;
5704 num_headers = tny_list_get_length (headers);
5705 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5707 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5708 GTK_RESPONSE_CANCEL) {
5714 /* The transfer is possible and the user wants to */
5717 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5718 const gchar *account_name;
5719 gboolean leave_on_server;
5721 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5722 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5725 if (leave_on_server == TRUE) {
5726 *need_connection = FALSE;
5728 *need_connection = TRUE;
5731 *need_connection = FALSE;
5736 g_object_unref (src_account);
5740 xfer_messages_error_handler (ModestMailOperation *mail_op,
5744 const GError *error;
5745 TnyAccount *account;
5747 win = modest_mail_operation_get_source (mail_op);
5748 error = modest_mail_operation_get_error (mail_op);
5750 /* We cannot get the account from the mail op as that is the
5751 source account and for checking memory full conditions we
5752 need the destination one */
5753 account = TNY_ACCOUNT (user_data);
5756 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5757 (GtkWidget *) win, (GError*) error,
5758 account, _KR("cerm_memory_card_full"))) {
5759 modest_platform_run_information_dialog ((GtkWindow *) win,
5760 _("mail_in_ui_folder_move_target_error"),
5764 g_object_unref (win);
5768 TnyFolderStore *dst_folder;
5773 * Utility function that transfer messages from both the main window
5774 * and the msg view window when using the "Move to" dialog
5777 xfer_messages_performer (gboolean canceled,
5779 GtkWindow *parent_window,
5780 TnyAccount *account,
5783 ModestWindow *win = MODEST_WINDOW (parent_window);
5784 TnyAccount *dst_account = NULL;
5785 gboolean dst_forbids_message_add = FALSE;
5786 XferMsgsHelper *helper;
5787 MoveToHelper *movehelper;
5788 ModestMailOperation *mail_op;
5790 helper = (XferMsgsHelper *) user_data;
5792 if (canceled || err) {
5793 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5794 (GtkWidget *) parent_window, err,
5796 /* Show the proper error message */
5797 modest_ui_actions_on_account_connection_error (parent_window, account);
5802 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5804 /* tinymail will return NULL for local folders it seems */
5805 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5806 modest_tny_account_get_protocol_type (dst_account),
5807 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5809 if (dst_forbids_message_add) {
5810 modest_platform_information_banner (GTK_WIDGET (win),
5812 ngettext("mail_in_ui_folder_move_target_error",
5813 "mail_in_ui_folder_move_targets_error",
5814 tny_list_get_length (helper->headers)));
5818 movehelper = g_new0 (MoveToHelper, 1);
5820 #ifndef MODEST_TOOLKIT_HILDON2
5821 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5822 _CS("ckct_nw_pasting"));
5823 if (movehelper->banner != NULL) {
5824 g_object_ref (movehelper->banner);
5825 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5828 if (MODEST_IS_MAIN_WINDOW (win)) {
5829 GtkWidget *header_view =
5830 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5831 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5832 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5836 /* Perform the mail operation */
5837 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5838 xfer_messages_error_handler,
5839 g_object_ref (dst_account),
5841 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5844 modest_mail_operation_xfer_msgs (mail_op,
5846 TNY_FOLDER (helper->dst_folder),
5851 g_object_unref (G_OBJECT (mail_op));
5854 g_object_unref (dst_account);
5855 g_object_unref (helper->dst_folder);
5856 g_object_unref (helper->headers);
5857 g_slice_free (XferMsgsHelper, helper);
5861 TnyFolder *src_folder;
5862 TnyFolderStore *dst_folder;
5863 gboolean delete_original;
5864 GtkWidget *folder_view;
5868 on_move_folder_cb (gboolean canceled,
5870 GtkWindow *parent_window,
5871 TnyAccount *account,
5874 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5875 GtkTreeSelection *sel;
5876 ModestMailOperation *mail_op = NULL;
5878 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5879 /* Note that the connection process can fail due to
5880 memory low conditions as it can not successfully
5881 store the summary */
5882 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5883 (GtkWidget*) parent_window, err,
5885 g_debug ("Error connecting when trying to move a folder");
5887 g_object_unref (G_OBJECT (info->src_folder));
5888 g_object_unref (G_OBJECT (info->dst_folder));
5893 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5894 #ifndef MODEST_TOOLKIT_HILDON2
5895 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5896 _CS("ckct_nw_pasting"));
5897 if (helper->banner != NULL) {
5898 g_object_ref (helper->banner);
5899 gtk_widget_show (GTK_WIDGET(helper->banner));
5902 /* Clean folder on header view before moving it */
5903 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5904 gtk_tree_selection_unselect_all (sel);
5906 /* Let gtk events run. We need that the folder
5907 view frees its reference to the source
5908 folder *before* issuing the mail operation
5909 so we need the signal handler of selection
5910 changed to happen before the mail
5912 while (gtk_events_pending ())
5913 gtk_main_iteration (); */
5916 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5917 modest_ui_actions_move_folder_error_handler,
5918 g_object_ref (info->dst_folder), g_object_unref);
5919 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5922 #ifndef MODEST_TOOLKIT_HILDON2
5923 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5924 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5925 TNY_FOLDER (info->dst_folder), TRUE);
5928 modest_mail_operation_xfer_folder (mail_op,
5929 TNY_FOLDER (info->src_folder),
5931 info->delete_original,
5934 g_object_unref (G_OBJECT (info->src_folder));
5936 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5939 /* Unref mail operation */
5940 g_object_unref (G_OBJECT (mail_op));
5941 g_object_unref (G_OBJECT (info->dst_folder));
5946 get_account_from_folder_store (TnyFolderStore *folder_store)
5948 if (TNY_IS_ACCOUNT (folder_store))
5949 return g_object_ref (folder_store);
5951 return tny_folder_get_account (TNY_FOLDER (folder_store));
5954 #ifndef MODEST_TOOLKIT_HILDON2
5956 * UI handler for the "Move to" action when invoked from the
5960 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5961 GtkWidget *folder_view,
5962 TnyFolderStore *dst_folder,
5963 ModestMainWindow *win)
5965 ModestHeaderView *header_view = NULL;
5966 TnyFolderStore *src_folder = NULL;
5968 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5970 /* Get the source folder */
5971 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5973 /* Get header view */
5974 header_view = (ModestHeaderView *)
5975 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5977 /* Get folder or messages to transfer */
5978 if (gtk_widget_is_focus (folder_view)) {
5979 gboolean do_xfer = TRUE;
5981 /* Allow only to transfer folders to the local root folder */
5982 if (TNY_IS_ACCOUNT (dst_folder) &&
5983 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5984 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5986 } else if (!TNY_IS_FOLDER (src_folder)) {
5987 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5992 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5993 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5995 info->src_folder = g_object_ref (src_folder);
5996 info->dst_folder = g_object_ref (dst_folder);
5997 info->delete_original = TRUE;
5998 info->folder_view = folder_view;
6000 connect_info->callback = on_move_folder_cb;
6001 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6002 connect_info->data = info;
6004 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6005 TNY_FOLDER_STORE (src_folder),
6008 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6011 headers = modest_header_view_get_selected_headers(header_view);
6013 /* Transfer the messages */
6014 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6015 headers, TNY_FOLDER (dst_folder));
6017 g_object_unref (headers);
6021 g_object_unref (src_folder);
6025 #ifdef MODEST_TOOLKIT_HILDON2
6027 * UI handler for the "Move to" action when invoked from the
6028 * ModestFolderWindow
6031 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6032 TnyFolderStore *dst_folder,
6036 TnyFolderStore *src_folder = NULL;
6037 TnyIterator *iterator;
6039 if (tny_list_get_length (selection) != 1)
6042 iterator = tny_list_create_iterator (selection);
6043 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6044 g_object_unref (iterator);
6047 gboolean do_xfer = TRUE;
6049 /* Allow only to transfer folders to the local root folder */
6050 if (TNY_IS_ACCOUNT (dst_folder) &&
6051 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6052 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6055 modest_platform_run_information_dialog (win,
6056 _("mail_in_ui_folder_move_target_error"),
6058 } else if (!TNY_IS_FOLDER (src_folder)) {
6059 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6064 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6065 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6067 info->src_folder = g_object_ref (src_folder);
6068 info->dst_folder = g_object_ref (dst_folder);
6069 info->delete_original = TRUE;
6070 info->folder_view = folder_view;
6072 connect_info->callback = on_move_folder_cb;
6073 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6074 connect_info->data = info;
6076 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6077 TNY_FOLDER_STORE (src_folder),
6082 g_object_unref (src_folder);
6088 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6089 TnyFolder *src_folder,
6091 TnyFolder *dst_folder)
6093 gboolean need_connection = TRUE;
6094 gboolean do_xfer = TRUE;
6095 XferMsgsHelper *helper;
6097 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6098 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6099 g_return_if_fail (TNY_IS_LIST (headers));
6101 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6102 headers, TNY_FOLDER (dst_folder),
6103 TRUE, &need_connection,
6106 /* If we don't want to transfer just return */
6110 /* Create the helper */
6111 helper = g_slice_new (XferMsgsHelper);
6112 helper->dst_folder = g_object_ref (dst_folder);
6113 helper->headers = g_object_ref (headers);
6115 if (need_connection) {
6116 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6117 connect_info->callback = xfer_messages_performer;
6118 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6119 connect_info->data = helper;
6121 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6122 TNY_FOLDER_STORE (src_folder),
6125 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6126 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6127 src_account, helper);
6128 g_object_unref (src_account);
6133 * UI handler for the "Move to" action when invoked from the
6134 * ModestMsgViewWindow
6137 modest_ui_actions_on_window_move_to (GtkAction *action,
6139 TnyFolderStore *dst_folder,
6142 TnyFolder *src_folder = NULL;
6144 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6147 TnyHeader *header = NULL;
6150 iter = tny_list_create_iterator (headers);
6151 header = (TnyHeader *) tny_iterator_get_current (iter);
6152 src_folder = tny_header_get_folder (header);
6154 /* Transfer the messages */
6155 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6157 TNY_FOLDER (dst_folder));
6160 g_object_unref (header);
6161 g_object_unref (iter);
6162 g_object_unref (src_folder);
6167 modest_ui_actions_on_move_to (GtkAction *action,
6170 modest_ui_actions_on_edit_mode_move_to (win);
6174 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6176 GtkWidget *dialog = NULL;
6177 MoveToInfo *helper = NULL;
6178 TnyList *list_to_move;
6180 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6182 #ifndef MODEST_TOOLKIT_HILDON2
6183 /* Get the main window if exists */
6184 ModestMainWindow *main_window;
6185 if (MODEST_IS_MAIN_WINDOW (win))
6186 main_window = MODEST_MAIN_WINDOW (win);
6189 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6190 FALSE)); /* don't create */
6193 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6198 if (tny_list_get_length (list_to_move) < 1) {
6199 g_object_unref (list_to_move);
6203 /* Create and run the dialog */
6204 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6205 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6206 GTK_WINDOW (dialog),
6210 helper = g_slice_new0 (MoveToInfo);
6211 helper->list = list_to_move;
6214 /* Listen to response signal */
6215 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6217 /* Show the dialog */
6218 gtk_widget_show (dialog);
6224 * Calls #HeadersFunc for each header already selected in the main
6225 * window or the message currently being shown in the msg view window
6228 do_headers_action (ModestWindow *win,
6232 TnyList *headers_list = NULL;
6233 TnyIterator *iter = NULL;
6234 TnyHeader *header = NULL;
6235 TnyFolder *folder = NULL;
6238 headers_list = get_selected_headers (win);
6242 /* Get the folder */
6243 iter = tny_list_create_iterator (headers_list);
6244 header = TNY_HEADER (tny_iterator_get_current (iter));
6246 folder = tny_header_get_folder (header);
6247 g_object_unref (header);
6250 /* Call the function for each header */
6251 while (!tny_iterator_is_done (iter)) {
6252 header = TNY_HEADER (tny_iterator_get_current (iter));
6253 func (header, win, user_data);
6254 g_object_unref (header);
6255 tny_iterator_next (iter);
6258 /* Trick: do a poke status in order to speed up the signaling
6261 tny_folder_poke_status (folder);
6262 g_object_unref (folder);
6266 g_object_unref (iter);
6267 g_object_unref (headers_list);
6271 modest_ui_actions_view_attachment (GtkAction *action,
6272 ModestWindow *window)
6274 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6275 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6277 /* not supported window for this action */
6278 g_return_if_reached ();
6283 modest_ui_actions_save_attachments (GtkAction *action,
6284 ModestWindow *window)
6286 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6288 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6291 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6293 /* not supported window for this action */
6294 g_return_if_reached ();
6299 modest_ui_actions_remove_attachments (GtkAction *action,
6300 ModestWindow *window)
6302 #ifndef MODEST_TOOLKIT_HILDON2
6303 if (MODEST_IS_MAIN_WINDOW (window)) {
6304 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6305 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6307 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6309 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6311 /* not supported window for this action */
6312 g_return_if_reached ();
6317 modest_ui_actions_on_settings (GtkAction *action,
6322 dialog = modest_platform_get_global_settings_dialog ();
6323 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6324 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6325 gtk_widget_show_all (dialog);
6327 gtk_dialog_run (GTK_DIALOG (dialog));
6329 gtk_widget_destroy (dialog);
6333 modest_ui_actions_on_help (GtkAction *action,
6336 /* Help app is not available at all in fremantle */
6337 #ifndef MODEST_TOOLKIT_HILDON2
6338 const gchar *help_id;
6340 g_return_if_fail (win && GTK_IS_WINDOW(win));
6342 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6345 modest_platform_show_help (GTK_WINDOW (win), help_id);
6350 modest_ui_actions_on_csm_help (GtkAction *action,
6353 /* Help app is not available at all in fremantle */
6354 #ifndef MODEST_TOOLKIT_HILDON2
6356 const gchar* help_id = NULL;
6357 GtkWidget *folder_view;
6358 TnyFolderStore *folder_store;
6360 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6362 /* Get selected folder */
6363 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6364 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6365 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6367 /* Switch help_id */
6368 if (folder_store && TNY_IS_FOLDER (folder_store))
6369 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6372 g_object_unref (folder_store);
6375 modest_platform_show_help (GTK_WINDOW (win), help_id);
6377 modest_ui_actions_on_help (action, win);
6382 retrieve_contents_cb (ModestMailOperation *mail_op,
6389 /* We only need this callback to show an error in case of
6390 memory low condition */
6391 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6392 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6397 retrieve_msg_contents_performer (gboolean canceled,
6399 GtkWindow *parent_window,
6400 TnyAccount *account,
6403 ModestMailOperation *mail_op;
6404 TnyList *headers = TNY_LIST (user_data);
6406 if (err || canceled) {
6407 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6408 (GtkWidget *) parent_window, err,
6413 /* Create mail operation */
6414 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6415 modest_ui_actions_disk_operations_error_handler,
6417 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6418 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6421 g_object_unref (mail_op);
6423 g_object_unref (headers);
6424 g_object_unref (account);
6428 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6429 ModestWindow *window)
6431 TnyList *headers = NULL;
6432 TnyAccount *account = NULL;
6433 TnyIterator *iter = NULL;
6434 TnyHeader *header = NULL;
6435 TnyFolder *folder = NULL;
6438 headers = get_selected_headers (window);
6442 /* Pick the account */
6443 iter = tny_list_create_iterator (headers);
6444 header = TNY_HEADER (tny_iterator_get_current (iter));
6445 folder = tny_header_get_folder (header);
6446 account = tny_folder_get_account (folder);
6447 g_object_unref (folder);
6448 g_object_unref (header);
6449 g_object_unref (iter);
6451 /* Connect and perform the message retrieval */
6452 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6453 g_object_ref (account),
6454 retrieve_msg_contents_performer,
6455 g_object_ref (headers));
6458 g_object_unref (account);
6459 g_object_unref (headers);
6463 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6465 g_return_if_fail (MODEST_IS_WINDOW (window));
6468 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6472 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6474 g_return_if_fail (MODEST_IS_WINDOW (window));
6477 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6481 modest_ui_actions_on_email_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_edit_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_view_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_format_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_tools_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_attachment_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_toolbar_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_folder_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_header_view_csm_menu_activated (GtkAction *action,
6562 ModestWindow *window)
6564 g_return_if_fail (MODEST_IS_WINDOW (window));
6567 modest_ui_actions_check_menu_dimming_rules (window);
6571 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6573 g_return_if_fail (MODEST_IS_WINDOW (window));
6575 /* we check for low-mem; in that case, show a warning, and don't allow
6578 if (modest_platform_check_memory_low (window, TRUE))
6581 modest_platform_show_search_messages (GTK_WINDOW (window));
6585 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6587 g_return_if_fail (MODEST_IS_WINDOW (win));
6590 /* we check for low-mem; in that case, show a warning, and don't allow
6591 * for the addressbook
6593 if (modest_platform_check_memory_low (win, TRUE))
6597 modest_platform_show_addressbook (GTK_WINDOW (win));
6602 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6603 ModestWindow *window)
6606 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6608 if (GTK_IS_TOGGLE_ACTION (action))
6609 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6613 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6617 #ifndef MODEST_TOOLKIT_HILDON2
6619 on_send_receive_finished (ModestMailOperation *mail_op,
6622 GtkWidget *header_view, *folder_view;
6623 TnyFolderStore *folder_store;
6624 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6626 /* Set send/receive operation finished */
6627 modest_main_window_notify_send_receive_completed (main_win);
6629 /* Don't refresh the current folder if there were any errors */
6630 if (modest_mail_operation_get_status (mail_op) !=
6631 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6634 /* Refresh the current folder if we're viewing a window. We do
6635 this because the user won't be able to see the new mails in
6636 the selected folder after a Send&Receive because it only
6637 performs a poke_status, i.e, only the number of read/unread
6638 messages is updated, but the new headers are not
6640 folder_view = modest_main_window_get_child_widget (main_win,
6641 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6645 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6647 /* Do not need to refresh INBOX again because the
6648 update_account does it always automatically */
6649 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6650 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6651 ModestMailOperation *refresh_op;
6653 header_view = modest_main_window_get_child_widget (main_win,
6654 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6656 /* We do not need to set the contents style
6657 because it hasn't changed. We also do not
6658 need to save the widget status. Just force
6660 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6661 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6662 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6663 folder_refreshed_cb, main_win);
6664 g_object_unref (refresh_op);
6668 g_object_unref (folder_store);
6673 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6679 const gchar* server_name = NULL;
6680 TnyTransportAccount *transport;
6681 gchar *message = NULL;
6682 ModestProtocol *protocol;
6684 /* Don't show anything if the user cancelled something or the
6685 * send receive request is not interactive. Authentication
6686 * errors are managed by the account store so no need to show
6687 * a dialog here again */
6688 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6689 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6690 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6694 /* Get the server name. Note that we could be using a
6695 connection specific transport account */
6696 transport = (TnyTransportAccount *)
6697 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6699 ModestTnyAccountStore *acc_store;
6700 const gchar *acc_name;
6701 TnyTransportAccount *conn_specific;
6703 acc_store = modest_runtime_get_account_store();
6704 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6705 conn_specific = (TnyTransportAccount *)
6706 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6707 if (conn_specific) {
6708 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6709 g_object_unref (conn_specific);
6711 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6713 g_object_unref (transport);
6717 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6718 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6719 tny_account_get_proto (TNY_ACCOUNT (transport)));
6721 g_warning ("%s: Account with no proto", __FUNCTION__);
6725 /* Show the appropriate message text for the GError: */
6726 switch (err->code) {
6727 case TNY_SERVICE_ERROR_CONNECT:
6728 message = modest_protocol_get_translation (protocol,
6729 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6732 case TNY_SERVICE_ERROR_SEND:
6733 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6735 case TNY_SERVICE_ERROR_UNAVAILABLE:
6736 message = modest_protocol_get_translation (protocol,
6737 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6741 g_warning ("%s: unexpected ERROR %d",
6742 __FUNCTION__, err->code);
6743 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6747 modest_platform_run_information_dialog (NULL, message, FALSE);
6752 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6757 ModestWindow *top_window = NULL;
6758 ModestWindowMgr *mgr = NULL;
6759 GtkWidget *header_view = NULL;
6760 TnyFolder *selected_folder = NULL;
6761 TnyFolderType folder_type;
6763 mgr = modest_runtime_get_window_mgr ();
6764 top_window = modest_window_mgr_get_current_top (mgr);
6769 #ifndef MODEST_TOOLKIT_HILDON2
6770 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6771 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6772 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6775 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6776 header_view = (GtkWidget *)
6777 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6781 /* Get selected folder */
6783 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6784 if (!selected_folder)
6787 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6788 #if GTK_CHECK_VERSION(2, 8, 0)
6789 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6790 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6791 GtkTreeViewColumn *tree_column;
6793 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6794 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6796 gtk_tree_view_column_queue_resize (tree_column);
6798 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6799 gtk_widget_queue_draw (header_view);
6802 #ifndef MODEST_TOOLKIT_HILDON2
6803 /* Rerun dimming rules, because the message could become deletable for example */
6804 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6805 MODEST_DIMMING_RULES_TOOLBAR);
6806 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6807 MODEST_DIMMING_RULES_MENU);
6811 g_object_unref (selected_folder);
6815 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6816 TnyAccount *account)
6818 ModestProtocolType protocol_type;
6819 ModestProtocol *protocol;
6820 gchar *error_note = NULL;
6822 protocol_type = modest_tny_account_get_protocol_type (account);
6823 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6826 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6827 if (error_note == NULL) {
6828 g_warning ("%s: This should not be reached", __FUNCTION__);
6830 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6831 g_free (error_note);
6836 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6840 TnyFolderStore *folder = NULL;
6841 TnyAccount *account = NULL;
6842 ModestProtocolType proto;
6843 ModestProtocol *protocol;
6844 TnyHeader *header = NULL;
6846 #ifndef MODEST_TOOLKIT_HILDON2
6847 if (MODEST_IS_MAIN_WINDOW (win)) {
6848 GtkWidget *header_view;
6849 TnyList* headers = NULL;
6851 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6852 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6853 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6854 if (!headers || tny_list_get_length (headers) == 0) {
6856 g_object_unref (headers);
6859 iter = tny_list_create_iterator (headers);
6860 header = TNY_HEADER (tny_iterator_get_current (iter));
6861 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6862 g_object_unref (iter);
6863 g_object_unref (headers);
6865 if (MODEST_IS_HEADER_WINDOW (win)) {
6866 GtkWidget *header_view;
6867 TnyList* headers = NULL;
6869 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6870 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6871 if (!headers || tny_list_get_length (headers) == 0) {
6873 g_object_unref (headers);
6876 iter = tny_list_create_iterator (headers);
6877 header = TNY_HEADER (tny_iterator_get_current (iter));
6879 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6881 g_warning ("List should contain headers");
6883 g_object_unref (iter);
6884 g_object_unref (headers);
6886 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6887 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6889 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6892 if (!header || !folder)
6895 /* Get the account type */
6896 account = tny_folder_get_account (TNY_FOLDER (folder));
6897 proto = modest_tny_account_get_protocol_type (account);
6898 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6901 subject = tny_header_dup_subject (header);
6902 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6906 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6912 g_object_unref (account);
6914 g_object_unref (folder);
6916 g_object_unref (header);
6922 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6923 const gchar *account_name,
6924 const gchar *account_title)
6926 ModestAccountMgr *account_mgr;
6929 ModestProtocol *protocol;
6930 gboolean removed = FALSE;
6932 g_return_val_if_fail (account_name, FALSE);
6933 g_return_val_if_fail (account_title, FALSE);
6935 account_mgr = modest_runtime_get_account_mgr();
6937 /* The warning text depends on the account type: */
6938 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6939 modest_account_mgr_get_store_protocol (account_mgr,
6941 txt = modest_protocol_get_translation (protocol,
6942 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6945 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6947 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6951 if (response == GTK_RESPONSE_OK) {
6952 /* Remove account. If it succeeds then it also removes
6953 the account from the ModestAccountView: */
6954 gboolean is_default = FALSE;
6955 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6956 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6958 g_free (default_account_name);
6960 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6962 /* Close all email notifications, we cannot
6963 distinguish if the notification belongs to
6964 this account or not, so for safety reasons
6965 we remove them all */
6966 modest_platform_remove_new_mail_notifications (FALSE);
6968 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6975 on_fetch_images_performer (gboolean canceled,
6977 GtkWindow *parent_window,
6978 TnyAccount *account,
6981 if (err || canceled) {
6982 /* Show an unable to retrieve images ??? */
6986 /* Note that the user could have closed the window while connecting */
6987 if (GTK_WIDGET_VISIBLE (parent_window))
6988 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6989 g_object_unref ((GObject *) user_data);
6993 modest_ui_actions_on_fetch_images (GtkAction *action,
6994 ModestWindow *window)
6996 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6998 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7000 on_fetch_images_performer,
7001 g_object_ref (window));
7005 modest_ui_actions_on_reload_message (const gchar *msg_id)
7007 ModestWindow *window = NULL;
7009 g_return_if_fail (msg_id && msg_id[0] != '\0');
7010 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7016 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7019 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7022 /** Check whether any connections are active, and cancel them if
7024 * Returns TRUE is there was no problem,
7025 * or if an operation was cancelled so we can continue.
7026 * Returns FALSE if the user chose to cancel his request instead.
7030 modest_ui_actions_check_for_active_account (ModestWindow *self,
7031 const gchar* account_name)
7033 ModestTnySendQueue *send_queue;
7034 ModestTnyAccountStore *acc_store;
7035 ModestMailOperationQueue* queue;
7036 TnyConnectionStatus store_conn_status;
7037 TnyAccount *store_account = NULL, *transport_account = NULL;
7038 gboolean retval = TRUE, sending = FALSE;
7040 acc_store = modest_runtime_get_account_store ();
7041 queue = modest_runtime_get_mail_operation_queue ();
7044 modest_tny_account_store_get_server_account (acc_store,
7046 TNY_ACCOUNT_TYPE_STORE);
7048 /* This could happen if the account was deleted before the
7049 call to this function */
7054 modest_tny_account_store_get_server_account (acc_store,
7056 TNY_ACCOUNT_TYPE_TRANSPORT);
7058 /* This could happen if the account was deleted before the
7059 call to this function */
7060 if (!transport_account) {
7061 g_object_unref (store_account);
7065 /* If the transport account was not used yet, then the send
7066 queue could not exist (it's created on demand) */
7067 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7068 if (TNY_IS_SEND_QUEUE (send_queue))
7069 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7071 store_conn_status = tny_account_get_connection_status (store_account);
7072 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7075 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7076 _("emev_nc_disconnect_account"));
7077 if (response == GTK_RESPONSE_OK) {
7086 /* FIXME: We should only cancel those of this account */
7087 modest_mail_operation_queue_cancel_all (queue);
7089 /* Also disconnect the account */
7090 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7091 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7092 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7096 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7102 g_object_unref (store_account);
7103 g_object_unref (transport_account);