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);
1030 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1032 msg = g_strdup_printf (format, subject);
1033 modest_platform_run_information_dialog (NULL, msg, FALSE);
1039 /* Remove the header from the preregistered uids */
1040 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1053 } OpenMsgBannerInfo;
1056 GtkTreeModel *model;
1058 ModestWindow *caller_window;
1059 OpenMsgBannerInfo *banner_info;
1060 GtkTreeRowReference *rowref;
1064 open_msg_banner_idle (gpointer userdata)
1066 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1068 gdk_threads_enter ();
1069 banner_info->idle_handler = 0;
1070 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1071 if (banner_info->banner)
1072 g_object_ref (banner_info->banner);
1074 gdk_threads_leave ();
1080 get_header_view_from_window (ModestWindow *window)
1082 GtkWidget *header_view;
1084 #ifndef MODEST_TOOLKIT_HILDON2
1085 if (MODEST_IS_MAIN_WINDOW (window)) {
1086 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1087 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1089 if (MODEST_IS_HEADER_WINDOW (window)){
1090 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1100 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1103 gchar *account = NULL;
1104 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1109 folder = tny_header_get_folder (header);
1110 /* Gets folder type (OUTBOX headers will be opened in edit window */
1111 if (modest_tny_folder_is_local_folder (folder)) {
1112 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1113 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1114 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1117 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1118 TnyTransportAccount *traccount = NULL;
1119 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1120 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1122 ModestTnySendQueue *send_queue = NULL;
1123 ModestTnySendQueueStatus status;
1125 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1126 TNY_ACCOUNT(traccount)));
1127 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1128 if (TNY_IS_SEND_QUEUE (send_queue)) {
1129 msg_id = modest_tny_send_queue_get_msg_id (header);
1130 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1132 /* Only open messages in outbox with the editor if they are in Failed state */
1133 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1136 #ifdef MODEST_TOOLKIT_HILDON2
1138 /* In Fremantle we can not
1139 open any message from
1140 outbox which is not in
1146 g_object_unref(traccount);
1148 g_warning("Cannot get transport account for message in outbox!!");
1150 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1151 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1155 TnyAccount *acc = tny_folder_get_account (folder);
1158 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1159 g_object_unref (acc);
1163 g_object_unref (folder);
1169 open_msg_cb (ModestMailOperation *mail_op,
1176 ModestWindowMgr *mgr = NULL;
1177 ModestWindow *parent_win = NULL;
1178 ModestWindow *win = NULL;
1179 gchar *account = NULL;
1180 gboolean open_in_editor = FALSE;
1182 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1184 /* Do nothing if there was any problem with the mail
1185 operation. The error will be shown by the error_handler of
1186 the mail operation */
1187 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1190 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1192 /* Mark header as read */
1193 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1195 account = get_info_from_header (header, &open_in_editor, &can_open);
1199 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1201 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1203 if (open_in_editor) {
1204 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1205 gchar *from_header = NULL, *acc_name;
1206 gchar *mailbox = NULL;
1208 from_header = tny_header_dup_from (header);
1210 /* we cannot edit without a valid account... */
1211 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1212 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1213 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1215 g_free (from_header);
1220 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1221 g_free (from_header);
1227 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1231 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1232 const gchar *mailbox = NULL;
1234 if (parent_win && MODEST_IS_WINDOW (parent_win))
1235 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1237 if (helper->rowref && helper->model) {
1238 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1239 helper->model, helper->rowref);
1241 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1246 /* Register and show new window */
1248 mgr = modest_runtime_get_window_mgr ();
1249 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1250 gtk_widget_destroy (GTK_WIDGET (win));
1253 gtk_widget_show_all (GTK_WIDGET(win));
1256 #ifndef MODEST_TOOLKIT_HILDON2
1257 /* Update toolbar dimming state */
1258 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1259 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1266 g_object_unref (parent_win);
1270 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1273 const GError *error;
1274 GObject *win = NULL;
1275 ModestMailOperationStatus status;
1277 win = modest_mail_operation_get_source (mail_op);
1278 error = modest_mail_operation_get_error (mail_op);
1279 status = modest_mail_operation_get_status (mail_op);
1281 /* If the mail op has been cancelled then it's not an error:
1282 don't show any message */
1283 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1284 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1285 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1286 (GError *) error, account)) {
1287 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1288 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1290 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1291 modest_platform_information_banner ((GtkWidget *) win,
1292 NULL, _("emev_ui_imap_inbox_select_error"));
1293 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1294 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1295 modest_platform_information_banner ((GtkWidget *) win,
1296 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1297 } else if (user_data) {
1298 modest_platform_information_banner ((GtkWidget *) win,
1302 g_object_unref (account);
1306 g_object_unref (win);
1310 * Returns the account a list of headers belongs to. It returns a
1311 * *new* reference so don't forget to unref it
1314 get_account_from_header_list (TnyList *headers)
1316 TnyAccount *account = NULL;
1318 if (tny_list_get_length (headers) > 0) {
1319 TnyIterator *iter = tny_list_create_iterator (headers);
1320 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1321 TnyFolder *folder = tny_header_get_folder (header);
1324 g_object_unref (header);
1326 while (!tny_iterator_is_done (iter)) {
1327 header = TNY_HEADER (tny_iterator_get_current (iter));
1328 folder = tny_header_get_folder (header);
1331 g_object_unref (header);
1333 tny_iterator_next (iter);
1338 account = tny_folder_get_account (folder);
1339 g_object_unref (folder);
1343 g_object_unref (header);
1345 g_object_unref (iter);
1351 get_account_from_header (TnyHeader *header)
1353 TnyAccount *account = NULL;
1356 folder = tny_header_get_folder (header);
1359 account = tny_folder_get_account (folder);
1360 g_object_unref (folder);
1366 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1368 if (helper->caller_window)
1369 helper->caller_window = NULL;
1373 open_msg_helper_destroyer (gpointer user_data)
1375 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1377 if (helper->caller_window) {
1378 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1379 helper->caller_window = NULL;
1382 if (helper->banner_info) {
1383 g_free (helper->banner_info->message);
1384 if (helper->banner_info->idle_handler > 0) {
1385 g_source_remove (helper->banner_info->idle_handler);
1386 helper->banner_info->idle_handler = 0;
1388 if (helper->banner_info->banner != NULL) {
1389 gtk_widget_destroy (helper->banner_info->banner);
1390 g_object_unref (helper->banner_info->banner);
1391 helper->banner_info->banner = NULL;
1393 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1394 helper->banner_info = NULL;
1396 g_object_unref (helper->model);
1397 g_object_unref (helper->header);
1398 gtk_tree_row_reference_free (helper->rowref);
1399 g_slice_free (OpenMsgHelper, helper);
1403 open_msg_performer(gboolean canceled,
1405 GtkWindow *parent_window,
1406 TnyAccount *account,
1409 ModestMailOperation *mail_op = NULL;
1410 gchar *error_msg = NULL;
1411 ModestProtocolType proto;
1412 TnyConnectionStatus status;
1413 OpenMsgHelper *helper = NULL;
1414 ModestProtocol *protocol;
1415 ModestProtocolRegistry *protocol_registry;
1418 helper = (OpenMsgHelper *) user_data;
1420 status = tny_account_get_connection_status (account);
1421 if (err || canceled || helper->caller_window == NULL) {
1422 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1423 /* Free the helper */
1424 open_msg_helper_destroyer (helper);
1426 /* In disk full conditions we could get this error here */
1427 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1428 (GtkWidget *) parent_window, err,
1434 /* Get the error message depending on the protocol */
1435 proto = modest_tny_account_get_protocol_type (account);
1436 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1437 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1440 protocol_registry = modest_runtime_get_protocol_registry ();
1441 subject = tny_header_dup_subject (helper->header);
1443 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1444 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1448 if (error_msg == NULL) {
1449 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1452 #ifndef MODEST_TOOLKIT_HILDON2
1453 gboolean show_open_draft = FALSE;
1454 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1456 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1458 TnyFolderType folder_type;
1460 folder = tny_header_get_folder (helper->header);
1461 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1462 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1463 g_object_unref (folder);
1467 #ifdef MODEST_TOOLKIT_HILDON2
1470 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1473 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1474 g_free (account_name);
1475 open_msg_helper_destroyer (helper);
1480 ModestWindow *window;
1481 GtkWidget *header_view;
1484 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1485 uid = modest_tny_folder_get_header_unique_id (helper->header);
1487 const gchar *mailbox = NULL;
1488 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1489 window = modest_msg_view_window_new_from_header_view
1490 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1491 if (window != NULL) {
1492 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1494 gtk_widget_destroy (GTK_WIDGET (window));
1496 gtk_widget_show_all (GTK_WIDGET(window));
1500 g_free (account_name);
1502 open_msg_helper_destroyer (helper);
1505 g_free (account_name);
1507 /* Create the mail operation */
1509 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1510 modest_ui_actions_disk_operations_error_handler,
1511 g_strdup (error_msg), g_free);
1512 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1516 #ifndef MODEST_TOOLKIT_HILDON2
1517 if (show_open_draft) {
1518 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1519 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1520 helper->banner_info->banner = NULL;
1521 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1522 helper->banner_info);
1528 headers = TNY_LIST (tny_simple_list_new ());
1529 tny_list_prepend (headers, G_OBJECT (helper->header));
1530 modest_mail_operation_get_msgs_full (mail_op,
1534 open_msg_helper_destroyer);
1535 g_object_unref (headers);
1542 g_object_unref (mail_op);
1543 g_object_unref (account);
1547 * This function is used by both modest_ui_actions_on_open and
1548 * modest_ui_actions_on_header_activated. This way we always do the
1549 * same when trying to open messages.
1552 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1554 ModestWindowMgr *mgr = NULL;
1555 TnyAccount *account;
1556 gboolean cached = FALSE;
1558 GtkWidget *header_view = NULL;
1559 OpenMsgHelper *helper;
1560 ModestWindow *window;
1562 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1564 mgr = modest_runtime_get_window_mgr ();
1567 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1568 if (header_view == NULL)
1571 /* Get the account */
1572 account = get_account_from_header (header);
1577 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1579 /* Do not open again the message and present the
1580 window to the user */
1583 #ifndef MODEST_TOOLKIT_HILDON2
1584 gtk_window_present (GTK_WINDOW (window));
1587 /* the header has been registered already, we don't do
1588 * anything but wait for the window to come up*/
1589 g_debug ("header %p already registered, waiting for window", header);
1594 /* Open each message */
1595 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1597 /* Allways download if we are online. */
1598 if (!tny_device_is_online (modest_runtime_get_device ())) {
1601 /* If ask for user permission to download the messages */
1602 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1603 _("mcen_nc_get_msg"));
1605 /* End if the user does not want to continue */
1606 if (response == GTK_RESPONSE_CANCEL) {
1612 /* We register the window for opening */
1613 modest_window_mgr_register_header (mgr, header, NULL);
1615 /* Create the helper. We need to get a reference to the model
1616 here because it could change while the message is readed
1617 (the user could switch between folders) */
1618 helper = g_slice_new (OpenMsgHelper);
1619 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1620 helper->caller_window = win;
1621 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1622 helper->header = g_object_ref (header);
1623 helper->rowref = gtk_tree_row_reference_copy (rowref);
1624 helper->banner_info = NULL;
1626 /* Connect to the account and perform */
1628 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1629 open_msg_performer, helper);
1631 /* Call directly the performer, do not need to connect */
1632 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1633 g_object_ref (account), helper);
1638 g_object_unref (account);
1642 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1649 /* we check for low-mem; in that case, show a warning, and don't allow
1652 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1656 headers = get_selected_headers (win);
1660 headers_count = tny_list_get_length (headers);
1661 if (headers_count != 1) {
1662 if (headers_count > 1) {
1663 /* Don't allow activation if there are more than one message selected */
1664 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1667 g_object_unref (headers);
1671 iter = tny_list_create_iterator (headers);
1672 header = TNY_HEADER (tny_iterator_get_current (iter));
1673 g_object_unref (iter);
1677 open_msg_from_header (header, NULL, win);
1678 g_object_unref (header);
1681 g_object_unref(headers);
1685 rf_helper_window_closed (gpointer data,
1688 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1690 helper->parent_window = NULL;
1693 static ReplyForwardHelper*
1694 create_reply_forward_helper (ReplyForwardAction action,
1696 guint reply_forward_type,
1699 ReplyForwardHelper *rf_helper = NULL;
1700 const gchar *active_acc = modest_window_get_active_account (win);
1701 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1703 rf_helper = g_slice_new0 (ReplyForwardHelper);
1704 rf_helper->reply_forward_type = reply_forward_type;
1705 rf_helper->action = action;
1706 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1707 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1708 rf_helper->account_name = (active_acc) ?
1709 g_strdup (active_acc) :
1710 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1711 rf_helper->mailbox = g_strdup (active_mailbox);
1713 /* Note that window could be destroyed just AFTER calling
1714 register_window so we must ensure that this pointer does
1715 not hold invalid references */
1716 if (rf_helper->parent_window)
1717 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1718 rf_helper_window_closed, rf_helper);
1724 free_reply_forward_helper (gpointer data)
1726 ReplyForwardHelper *helper;
1728 helper = (ReplyForwardHelper *) data;
1729 g_free (helper->account_name);
1730 g_free (helper->mailbox);
1732 g_object_unref (helper->header);
1733 if (helper->parent_window)
1734 g_object_weak_unref (G_OBJECT (helper->parent_window),
1735 rf_helper_window_closed, helper);
1736 g_slice_free (ReplyForwardHelper, helper);
1740 reply_forward_cb (ModestMailOperation *mail_op,
1747 TnyMsg *new_msg = NULL;
1748 ReplyForwardHelper *rf_helper;
1749 ModestWindow *msg_win = NULL;
1750 ModestEditType edit_type;
1752 TnyAccount *account = NULL;
1753 ModestWindowMgr *mgr = NULL;
1754 gchar *signature = NULL;
1755 gboolean use_signature;
1758 /* If there was any error. The mail operation could be NULL,
1759 this means that we already have the message downloaded and
1760 that we didn't do a mail operation to retrieve it */
1761 rf_helper = (ReplyForwardHelper *) user_data;
1762 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1765 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1766 rf_helper->account_name, rf_helper->mailbox);
1767 recipient = modest_text_utils_get_email_address (from);
1768 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1773 /* Create reply mail */
1774 switch (rf_helper->action) {
1775 /* Use the msg_header to ensure that we have all the
1776 information. The summary can lack some data */
1777 TnyHeader *msg_header;
1779 msg_header = tny_msg_get_header (msg);
1781 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1782 (use_signature) ? signature : NULL,
1783 rf_helper->reply_forward_type,
1784 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1785 g_object_unref (msg_header);
1787 case ACTION_REPLY_TO_ALL:
1788 msg_header = tny_msg_get_header (msg);
1790 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1791 (use_signature) ? signature : NULL,
1792 rf_helper->reply_forward_type,
1793 MODEST_TNY_MSG_REPLY_MODE_ALL);
1794 edit_type = MODEST_EDIT_TYPE_REPLY;
1795 g_object_unref (msg_header);
1797 case ACTION_FORWARD:
1799 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1800 rf_helper->reply_forward_type);
1801 edit_type = MODEST_EDIT_TYPE_FORWARD;
1804 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1806 g_return_if_reached ();
1814 g_warning ("%s: failed to create message\n", __FUNCTION__);
1818 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1819 rf_helper->account_name,
1820 TNY_ACCOUNT_TYPE_STORE);
1822 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1826 /* Create and register the windows */
1827 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1828 mgr = modest_runtime_get_window_mgr ();
1829 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1831 /* Note that register_window could have deleted the account */
1832 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1833 gdouble parent_zoom;
1835 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1836 modest_window_set_zoom (msg_win, parent_zoom);
1839 /* Show edit window */
1840 gtk_widget_show_all (GTK_WIDGET (msg_win));
1843 /* We always unregister the header because the message is
1844 forwarded or replied so the original one is no longer
1846 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1849 g_object_unref (G_OBJECT (new_msg));
1851 g_object_unref (G_OBJECT (account));
1852 free_reply_forward_helper (rf_helper);
1855 /* Checks a list of headers. If any of them are not currently
1856 * downloaded (CACHED) then returns TRUE else returns FALSE.
1859 header_list_count_uncached_msgs (TnyList *header_list)
1862 gint uncached_messages = 0;
1864 iter = tny_list_create_iterator (header_list);
1865 while (!tny_iterator_is_done (iter)) {
1868 header = TNY_HEADER (tny_iterator_get_current (iter));
1870 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1871 uncached_messages ++;
1872 g_object_unref (header);
1875 tny_iterator_next (iter);
1877 g_object_unref (iter);
1879 return uncached_messages;
1882 /* Returns FALSE if the user does not want to download the
1883 * messages. Returns TRUE if the user allowed the download.
1886 connect_to_get_msg (ModestWindow *win,
1887 gint num_of_uncached_msgs,
1888 TnyAccount *account)
1890 GtkResponseType response;
1892 /* Allways download if we are online. */
1893 if (tny_device_is_online (modest_runtime_get_device ()))
1896 /* If offline, then ask for user permission to download the messages */
1897 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1898 ngettext("mcen_nc_get_msg",
1900 num_of_uncached_msgs));
1902 if (response == GTK_RESPONSE_CANCEL)
1905 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1909 reply_forward_performer (gboolean canceled,
1911 GtkWindow *parent_window,
1912 TnyAccount *account,
1915 ReplyForwardHelper *rf_helper = NULL;
1916 ModestMailOperation *mail_op;
1918 rf_helper = (ReplyForwardHelper *) user_data;
1920 if (canceled || err) {
1921 free_reply_forward_helper (rf_helper);
1925 /* Retrieve the message */
1926 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1927 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1928 modest_ui_actions_disk_operations_error_handler,
1930 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1931 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1934 g_object_unref(mail_op);
1938 * Common code for the reply and forward actions
1941 reply_forward (ReplyForwardAction action, ModestWindow *win)
1943 ReplyForwardHelper *rf_helper = NULL;
1944 guint reply_forward_type;
1946 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1948 /* we check for low-mem; in that case, show a warning, and don't allow
1949 * reply/forward (because it could potentially require a lot of memory */
1950 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1954 /* we need an account when editing */
1955 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1956 if (!modest_ui_actions_run_account_setup_wizard (win))
1960 reply_forward_type =
1961 modest_conf_get_int (modest_runtime_get_conf (),
1962 (action == ACTION_FORWARD) ?
1963 MODEST_CONF_FORWARD_TYPE :
1964 MODEST_CONF_REPLY_TYPE,
1967 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1969 TnyHeader *header = NULL;
1970 /* Get header and message. Do not free them here, the
1971 reply_forward_cb must do it */
1972 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1973 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1975 if (msg && header) {
1977 rf_helper = create_reply_forward_helper (action, win,
1978 reply_forward_type, header);
1979 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1981 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1985 g_object_unref (msg);
1987 g_object_unref (header);
1989 TnyHeader *header = NULL;
1991 gboolean do_retrieve = TRUE;
1992 TnyList *header_list = NULL;
1994 header_list = get_selected_headers (win);
1997 /* Check that only one message is selected for replying */
1998 if (tny_list_get_length (header_list) != 1) {
1999 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2000 NULL, _("mcen_ib_select_one_message"));
2001 g_object_unref (header_list);
2005 /* Only reply/forward to one message */
2006 iter = tny_list_create_iterator (header_list);
2007 header = TNY_HEADER (tny_iterator_get_current (iter));
2008 g_object_unref (iter);
2010 /* Retrieve messages */
2011 do_retrieve = (action == ACTION_FORWARD) ||
2012 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2015 TnyAccount *account = NULL;
2016 TnyFolder *folder = NULL;
2017 gdouble download = TRUE;
2018 guint uncached_msgs = 0;
2020 folder = tny_header_get_folder (header);
2022 goto do_retrieve_frees;
2023 account = tny_folder_get_account (folder);
2025 goto do_retrieve_frees;
2027 uncached_msgs = header_list_count_uncached_msgs (header_list);
2029 if (uncached_msgs > 0) {
2030 /* Allways download if we are online. */
2031 if (!tny_device_is_online (modest_runtime_get_device ())) {
2034 /* If ask for user permission to download the messages */
2035 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2036 ngettext("mcen_nc_get_msg",
2040 /* End if the user does not want to continue */
2041 if (response == GTK_RESPONSE_CANCEL)
2048 rf_helper = create_reply_forward_helper (action, win,
2049 reply_forward_type, header);
2050 if (uncached_msgs > 0) {
2051 modest_platform_connect_and_perform (GTK_WINDOW (win),
2053 reply_forward_performer,
2056 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2057 account, rf_helper);
2062 g_object_unref (account);
2064 g_object_unref (folder);
2066 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2069 g_object_unref (header_list);
2070 g_object_unref (header);
2075 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2077 g_return_if_fail (MODEST_IS_WINDOW(win));
2079 reply_forward (ACTION_REPLY, win);
2083 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2085 g_return_if_fail (MODEST_IS_WINDOW(win));
2087 reply_forward (ACTION_FORWARD, win);
2091 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2093 g_return_if_fail (MODEST_IS_WINDOW(win));
2095 reply_forward (ACTION_REPLY_TO_ALL, win);
2099 modest_ui_actions_on_next (GtkAction *action,
2100 ModestWindow *window)
2102 #ifndef MODEST_TOOLKIT_HILDON2
2103 if (MODEST_IS_MAIN_WINDOW (window)) {
2104 GtkWidget *header_view;
2106 header_view = modest_main_window_get_child_widget (
2107 MODEST_MAIN_WINDOW(window),
2108 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2112 modest_header_view_select_next (
2113 MODEST_HEADER_VIEW(header_view));
2115 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2116 modest_msg_view_window_select_next_message (
2117 MODEST_MSG_VIEW_WINDOW (window));
2120 g_return_if_reached ();
2125 modest_ui_actions_on_prev (GtkAction *action,
2126 ModestWindow *window)
2128 g_return_if_fail (MODEST_IS_WINDOW(window));
2130 #ifndef MODEST_TOOLKIT_HILDON2
2131 if (MODEST_IS_MAIN_WINDOW (window)) {
2132 GtkWidget *header_view;
2133 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2134 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2138 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2140 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2141 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2144 g_return_if_reached ();
2149 modest_ui_actions_on_sort (GtkAction *action,
2150 ModestWindow *window)
2152 GtkWidget *header_view = NULL;
2154 g_return_if_fail (MODEST_IS_WINDOW(window));
2156 #ifndef MODEST_TOOLKIT_HILDON2
2157 if (MODEST_IS_MAIN_WINDOW (window)) {
2158 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2159 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2161 if (MODEST_IS_HEADER_WINDOW (window)) {
2162 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2167 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2172 /* Show sorting dialog */
2173 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2177 sync_folder_cb (ModestMailOperation *mail_op,
2181 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2183 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2184 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2186 /* We must clear first, because otherwise set_folder will ignore */
2187 /* the change as the folders are the same */
2188 modest_header_view_clear (header_view);
2189 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2191 g_object_unref (parent);
2194 g_object_unref (header_view);
2198 idle_refresh_folder (gpointer source)
2200 ModestHeaderView *header_view = NULL;
2202 /* If the window still exists */
2203 if (!GTK_IS_WIDGET (source) ||
2204 !GTK_WIDGET_VISIBLE (source))
2207 /* Refresh the current view */
2208 #ifdef MODEST_TOOLKIT_HILDON2
2209 if (MODEST_IS_HEADER_WINDOW (source))
2210 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2212 if (MODEST_IS_MAIN_WINDOW (source))
2213 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2214 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2217 TnyFolder *folder = modest_header_view_get_folder (header_view);
2219 /* Sync the folder status */
2220 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2221 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2222 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2223 g_object_unref (folder);
2224 g_object_unref (mail_op);
2232 update_account_cb (ModestMailOperation *self,
2233 TnyList *new_headers,
2237 gboolean show_visual_notifications;
2239 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2240 show_visual_notifications = (top) ? FALSE : TRUE;
2242 /* Notify new messages have been downloaded. If the
2243 send&receive was invoked by the user then do not show any
2244 visual notification, only play a sound and activate the LED
2245 (for the Maemo version) */
2246 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2248 /* We only notify about really new messages (not seen) we get */
2249 TnyList *actually_new_list;
2250 TnyIterator *iterator;
2251 actually_new_list = TNY_LIST (tny_simple_list_new ());
2252 for (iterator = tny_list_create_iterator (new_headers);
2253 !tny_iterator_is_done (iterator);
2254 tny_iterator_next (iterator)) {
2256 TnyHeaderFlags flags;
2257 header = TNY_HEADER (tny_iterator_get_current (iterator));
2258 flags = tny_header_get_flags (header);
2260 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2261 /* Messages are ordered from most
2262 recent to oldest. But we want to
2263 show notifications starting from
2264 the oldest message. That's why we
2266 tny_list_prepend (actually_new_list, G_OBJECT (header));
2268 g_object_unref (header);
2270 g_object_unref (iterator);
2272 if (tny_list_get_length (actually_new_list) > 0) {
2273 GList *new_headers_list = NULL;
2275 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2277 /* Send notifications */
2278 if (new_headers_list) {
2279 modest_platform_on_new_headers_received (new_headers_list,
2280 show_visual_notifications);
2282 modest_utils_free_notification_list (new_headers_list);
2285 g_object_unref (actually_new_list);
2289 /* Refresh the current folder in an idle. We do this
2290 in order to avoid refresh cancelations if the
2291 currently viewed folder is the inbox */
2292 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2293 idle_refresh_folder,
2300 TnyAccount *account;
2302 gchar *account_name;
2303 gboolean poke_status;
2304 gboolean interactive;
2305 ModestMailOperation *mail_op;
2309 do_send_receive_performer (gboolean canceled,
2311 GtkWindow *parent_window,
2312 TnyAccount *account,
2315 SendReceiveInfo *info;
2317 info = (SendReceiveInfo *) user_data;
2319 if (err || canceled) {
2320 /* In disk full conditions we could get this error here */
2321 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2322 (GtkWidget *) parent_window, err,
2325 if (info->mail_op) {
2326 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2332 #ifndef MODEST_TOOLKIT_HILDON2
2333 /* Set send/receive operation in progress */
2334 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2335 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2338 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2339 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2340 G_CALLBACK (on_send_receive_finished),
2344 /* Send & receive. */
2345 modest_mail_operation_update_account (info->mail_op, info->account_name,
2346 info->poke_status, info->interactive,
2347 update_account_cb, info->win);
2352 g_object_unref (G_OBJECT (info->mail_op));
2353 if (info->account_name)
2354 g_free (info->account_name);
2356 g_object_unref (info->win);
2358 g_object_unref (info->account);
2359 g_slice_free (SendReceiveInfo, info);
2363 * This function performs the send & receive required actions. The
2364 * window is used to create the mail operation. Typically it should
2365 * always be the main window, but we pass it as argument in order to
2369 modest_ui_actions_do_send_receive (const gchar *account_name,
2370 gboolean force_connection,
2371 gboolean poke_status,
2372 gboolean interactive,
2375 gchar *acc_name = NULL;
2376 SendReceiveInfo *info;
2377 ModestTnyAccountStore *acc_store;
2378 TnyAccount *account;
2380 /* If no account name was provided then get the current account, and if
2381 there is no current account then pick the default one: */
2382 if (!account_name) {
2384 acc_name = g_strdup (modest_window_get_active_account (win));
2386 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2388 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2392 acc_name = g_strdup (account_name);
2395 acc_store = modest_runtime_get_account_store ();
2396 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2400 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2404 /* Do not automatically refresh accounts that are flagged as
2405 NO_AUTO_UPDATE. This could be useful for accounts that
2406 handle their own update times */
2408 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2409 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2410 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2411 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2413 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2414 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2415 g_object_unref (account);
2422 /* Create the info for the connect and perform */
2423 info = g_slice_new (SendReceiveInfo);
2424 info->account_name = acc_name;
2425 info->win = (win) ? g_object_ref (win) : NULL;
2426 info->poke_status = poke_status;
2427 info->interactive = interactive;
2428 info->account = account;
2429 /* We need to create the operation here, because otherwise it
2430 could happen that the queue emits the queue-empty signal
2431 while we're trying to connect the account */
2432 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2433 modest_ui_actions_disk_operations_error_handler,
2435 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2437 /* Invoke the connect and perform */
2438 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2439 force_connection, info->account,
2440 do_send_receive_performer, info);
2445 modest_ui_actions_do_cancel_send (const gchar *account_name,
2448 TnyTransportAccount *transport_account;
2449 TnySendQueue *send_queue = NULL;
2450 GError *error = NULL;
2452 /* Get transport account */
2454 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2455 (modest_runtime_get_account_store(),
2457 TNY_ACCOUNT_TYPE_TRANSPORT));
2458 if (!transport_account) {
2459 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2464 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2465 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2466 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2467 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2468 "modest: could not find send queue for account\n");
2470 /* Cancel the current send */
2471 tny_account_cancel (TNY_ACCOUNT (transport_account));
2473 /* Suspend all pending messages */
2474 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2478 if (transport_account != NULL)
2479 g_object_unref (G_OBJECT (transport_account));
2483 modest_ui_actions_cancel_send_all (ModestWindow *win)
2485 GSList *account_names, *iter;
2487 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2490 iter = account_names;
2492 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2493 iter = g_slist_next (iter);
2496 modest_account_mgr_free_account_names (account_names);
2497 account_names = NULL;
2501 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2504 /* Check if accounts exist */
2505 gboolean accounts_exist =
2506 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2508 /* If not, allow the user to create an account before trying to send/receive. */
2509 if (!accounts_exist)
2510 modest_ui_actions_on_accounts (NULL, win);
2512 /* Cancel all sending operaitons */
2513 modest_ui_actions_cancel_send_all (win);
2517 * Refreshes all accounts. This function will be used by automatic
2521 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2522 gboolean force_connection,
2523 gboolean poke_status,
2524 gboolean interactive)
2526 GSList *account_names, *iter;
2528 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2531 iter = account_names;
2533 modest_ui_actions_do_send_receive ((const char*) iter->data,
2535 poke_status, interactive, win);
2536 iter = g_slist_next (iter);
2539 modest_account_mgr_free_account_names (account_names);
2540 account_names = NULL;
2544 * Handler of the click on Send&Receive button in the main toolbar
2547 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2549 /* Check if accounts exist */
2550 gboolean accounts_exist;
2553 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2555 /* If not, allow the user to create an account before trying to send/receive. */
2556 if (!accounts_exist)
2557 modest_ui_actions_on_accounts (NULL, win);
2559 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2560 #ifndef MODEST_TOOLKIT_HILDON2
2561 if (MODEST_IS_MAIN_WINDOW (win)) {
2562 GtkWidget *folder_view;
2563 TnyFolderStore *folder_store;
2566 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2567 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2571 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2574 g_object_unref (folder_store);
2575 /* Refresh the active account. Force the connection if needed
2576 and poke the status of all folders */
2577 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2579 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2580 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2583 const gchar *active_account;
2584 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2586 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2591 #ifndef MODEST_TOOLKIT_HILDON2
2593 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2596 GtkWidget *header_view;
2598 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2600 header_view = modest_main_window_get_child_widget (main_window,
2601 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2605 conf = modest_runtime_get_conf ();
2607 /* what is saved/restored is depending on the style; thus; we save with
2608 * old style, then update the style, and restore for this new style
2610 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2612 if (modest_header_view_get_style
2613 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2614 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2615 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2617 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2618 MODEST_HEADER_VIEW_STYLE_DETAILS);
2620 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2621 MODEST_CONF_HEADER_VIEW_KEY);
2625 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2627 ModestMainWindow *main_window)
2629 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2630 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2632 /* in the case the folder is empty, show the empty folder message and focus
2634 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2635 if (modest_header_view_is_empty (header_view)) {
2636 TnyFolder *folder = modest_header_view_get_folder (header_view);
2637 GtkWidget *folder_view =
2638 modest_main_window_get_child_widget (main_window,
2639 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2640 if (folder != NULL) {
2641 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2642 g_object_unref (folder);
2644 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2648 /* If no header has been selected then exit */
2653 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2654 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2656 /* Update toolbar dimming state */
2657 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2658 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2663 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2666 ModestWindow *window)
2668 GtkTreeRowReference *rowref;
2670 g_return_if_fail (MODEST_IS_WINDOW(window));
2671 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2672 g_return_if_fail (TNY_IS_HEADER (header));
2674 if (modest_header_view_count_selected_headers (header_view) > 1) {
2675 /* Don't allow activation if there are more than one message selected */
2676 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2680 /* we check for low-mem; in that case, show a warning, and don't allow
2681 * activating headers
2683 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2686 #ifndef MODEST_TOOLKIT_HILDON2
2687 GtkWidget *open_widget;
2688 if (MODEST_IS_MAIN_WINDOW (window)) {
2689 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2690 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2691 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2696 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2697 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2698 gtk_tree_row_reference_free (rowref);
2701 #ifndef MODEST_TOOLKIT_HILDON2
2703 set_active_account_from_tny_account (TnyAccount *account,
2704 ModestWindow *window)
2706 const gchar *server_acc_name = tny_account_get_id (account);
2708 /* We need the TnyAccount provided by the
2709 account store because that is the one that
2710 knows the name of the Modest account */
2711 TnyAccount *modest_server_account =
2712 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2713 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2715 if (!modest_server_account) {
2716 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2720 /* Update active account, but only if it's not a pseudo-account */
2721 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2722 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2723 const gchar *modest_acc_name =
2724 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2725 if (modest_acc_name)
2726 modest_window_set_active_account (window, modest_acc_name);
2729 g_object_unref (modest_server_account);
2733 folder_refreshed_cb (ModestMailOperation *mail_op,
2737 ModestMainWindow *win = NULL;
2738 GtkWidget *folder_view, *header_view;
2739 const GError *error;
2741 g_return_if_fail (TNY_IS_FOLDER (folder));
2743 win = MODEST_MAIN_WINDOW (user_data);
2745 /* Check if the operation failed due to memory low conditions */
2746 error = modest_mail_operation_get_error (mail_op);
2747 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2748 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2749 modest_platform_run_information_dialog (GTK_WINDOW (win),
2750 _KR("memr_ib_operation_disabled"),
2756 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2758 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2761 TnyFolderStore *current_folder;
2763 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2764 if (current_folder) {
2765 gboolean different = ((TnyFolderStore *) folder != current_folder);
2766 g_object_unref (current_folder);
2772 /* Check if folder is empty and set headers view contents style */
2773 if ((tny_folder_get_all_count (folder) == 0) ||
2774 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2775 modest_main_window_set_contents_style (win,
2776 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2780 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2781 TnyFolderStore *folder_store,
2783 ModestMainWindow *main_window)
2785 GtkWidget *header_view;
2787 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2789 header_view = modest_main_window_get_child_widget(main_window,
2790 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2795 if (TNY_IS_ACCOUNT (folder_store)) {
2797 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2799 /* Show account details */
2800 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2803 if (TNY_IS_FOLDER (folder_store) && selected) {
2804 TnyAccount *account;
2806 /* Update the active account */
2807 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2809 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2810 g_object_unref (account);
2814 /* Set the header style by default, it could
2815 be changed later by the refresh callback to
2817 modest_main_window_set_contents_style (main_window,
2818 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2820 /* Set folder on header view. This function
2821 will call tny_folder_refresh_async so we
2822 pass a callback that will be called when
2823 finished. We use that callback to set the
2824 empty view if there are no messages */
2825 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2826 TNY_FOLDER (folder_store),
2828 MODEST_WINDOW (main_window),
2829 folder_refreshed_cb,
2832 /* Restore configuration. We need to do this
2833 *after* the set_folder because the widget
2834 memory asks the header view about its
2836 modest_widget_memory_restore (modest_runtime_get_conf (),
2837 G_OBJECT(header_view),
2838 MODEST_CONF_HEADER_VIEW_KEY);
2840 /* No need to save the header view
2841 configuration for Maemo because it only
2842 saves the sorting stuff and that it's
2843 already being done by the sort
2844 dialog. Remove it when the GNOME version
2845 has the same behaviour */
2846 #ifdef MODEST_TOOLKIT_GTK
2847 if (modest_main_window_get_contents_style (main_window) ==
2848 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2849 modest_widget_memory_save (modest_runtime_get_conf (),
2850 G_OBJECT (header_view),
2851 MODEST_CONF_HEADER_VIEW_KEY);
2853 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2857 /* Update dimming state */
2858 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2859 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2864 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2871 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2873 online = tny_device_is_online (modest_runtime_get_device());
2876 /* already online -- the item is simply not there... */
2877 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2879 GTK_MESSAGE_WARNING,
2881 _("The %s you selected cannot be found"),
2883 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2884 gtk_dialog_run (GTK_DIALOG(dialog));
2886 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2889 _("mcen_bd_dialog_cancel"),
2890 GTK_RESPONSE_REJECT,
2891 _("mcen_bd_dialog_ok"),
2892 GTK_RESPONSE_ACCEPT,
2894 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2895 "Do you want to get online?"), item);
2896 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2897 gtk_label_new (txt), FALSE, FALSE, 0);
2898 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2901 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2902 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2903 /* TODO: Comment about why is this commented out: */
2904 /* modest_platform_connect_and_wait (); */
2907 gtk_widget_destroy (dialog);
2911 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2914 /* g_debug ("%s %s", __FUNCTION__, link); */
2919 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2922 modest_platform_activate_uri (link);
2926 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2929 modest_platform_show_uri_popup (link);
2933 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2936 /* we check for low-mem; in that case, show a warning, and don't allow
2937 * viewing attachments
2939 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2942 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2946 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2947 const gchar *address,
2950 /* g_debug ("%s %s", __FUNCTION__, address); */
2954 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2955 TnyMsg *saved_draft,
2958 ModestMsgEditWindow *edit_window;
2960 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2961 #ifndef MODEST_TOOLKIT_HILDON2
2962 ModestMainWindow *win;
2964 /* FIXME. Make the header view sensitive again. This is a
2965 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2967 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2968 modest_runtime_get_window_mgr(), FALSE));
2970 GtkWidget *hdrview = modest_main_window_get_child_widget(
2971 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2972 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2976 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2978 /* Set draft is there was no error */
2979 if (!modest_mail_operation_get_error (mail_op))
2980 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2982 g_object_unref(edit_window);
2986 enough_space_for_message (ModestMsgEditWindow *edit_window,
2989 guint64 available_disk, expected_size;
2994 available_disk = modest_utils_get_available_space (NULL);
2995 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2996 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3001 /* Double check: disk full condition or message too big */
3002 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3003 expected_size > available_disk) {
3004 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3005 modest_platform_information_banner (NULL, NULL, msg);
3012 * djcb: if we're in low-memory state, we only allow for
3013 * saving messages smaller than
3014 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3015 * should still allow for sending anything critical...
3017 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3018 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3022 * djcb: we also make sure that the attachments are smaller than the max size
3023 * this is for the case where we'd try to forward a message with attachments
3024 * bigger than our max allowed size, or sending an message from drafts which
3025 * somehow got past our checks when attaching.
3027 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3028 modest_platform_run_information_dialog (
3029 GTK_WINDOW(edit_window),
3030 _("mail_ib_error_attachment_size"),
3039 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3041 TnyTransportAccount *transport_account;
3042 ModestMailOperation *mail_operation;
3044 gchar *account_name;
3045 ModestAccountMgr *account_mgr;
3046 gboolean had_error = FALSE;
3048 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3050 data = modest_msg_edit_window_get_msg_data (edit_window);
3053 if (!enough_space_for_message (edit_window, data)) {
3054 modest_msg_edit_window_free_msg_data (edit_window, data);
3058 account_name = g_strdup (data->account_name);
3059 account_mgr = modest_runtime_get_account_mgr();
3061 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3063 account_name = modest_account_mgr_get_default_account (account_mgr);
3064 if (!account_name) {
3065 g_printerr ("modest: no account found\n");
3066 modest_msg_edit_window_free_msg_data (edit_window, data);
3070 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3071 account_name = g_strdup (data->account_name);
3075 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3076 (modest_runtime_get_account_store (),
3078 TNY_ACCOUNT_TYPE_TRANSPORT));
3079 if (!transport_account) {
3080 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3081 g_free (account_name);
3082 modest_msg_edit_window_free_msg_data (edit_window, data);
3086 /* Create the mail operation */
3087 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3089 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3091 modest_mail_operation_save_to_drafts (mail_operation,
3103 data->priority_flags,
3106 on_save_to_drafts_cb,
3107 g_object_ref(edit_window));
3109 #ifdef MODEST_TOOLKIT_HILDON2
3110 /* In hildon2 we always show the information banner on saving to drafts.
3111 * It will be a system information banner in this case.
3113 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3114 modest_platform_information_banner (NULL, NULL, text);
3117 ModestMainWindow *win = NULL;
3119 /* Use the main window as the parent of the banner, if the
3120 main window does not exist it won't be shown, if the parent
3121 window exists then it's properly shown. We don't use the
3122 editor window because it could be closed (save to drafts
3123 could happen after closing the window */
3124 win = (ModestMainWindow *)
3125 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3127 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3128 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3132 modest_msg_edit_window_set_modified (edit_window, FALSE);
3135 g_free (account_name);
3136 g_object_unref (G_OBJECT (transport_account));
3137 g_object_unref (G_OBJECT (mail_operation));
3139 modest_msg_edit_window_free_msg_data (edit_window, data);
3141 #ifndef MODEST_TOOLKIT_HILDON2
3143 * If the drafts folder is selected then make the header view
3144 * insensitive while the message is being saved to drafts
3145 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3146 * is not very clean but it avoids letting the drafts folder
3147 * in an inconsistent state: the user could edit the message
3148 * being saved and undesirable things would happen.
3149 * In the average case the user won't notice anything at
3150 * all. In the worst case (the user is editing a really big
3151 * file from Drafts) the header view will be insensitive
3152 * during the saving process (10 or 20 seconds, depending on
3153 * the message). Anyway this is just a quick workaround: once
3154 * we find a better solution it should be removed
3155 * See NB#65125 (commend #18) for details.
3157 if (!had_error && win != NULL) {
3158 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3159 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3161 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3163 if (modest_tny_folder_is_local_folder(folder)) {
3164 TnyFolderType folder_type;
3165 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3166 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3167 GtkWidget *hdrview = modest_main_window_get_child_widget(
3168 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3169 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3173 if (folder != NULL) g_object_unref(folder);
3181 /* For instance, when clicking the Send toolbar button when editing a message: */
3183 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3185 TnyTransportAccount *transport_account = NULL;
3186 gboolean had_error = FALSE;
3188 ModestAccountMgr *account_mgr;
3189 gchar *account_name;
3190 ModestMailOperation *mail_operation;
3193 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3195 /* Check names but do not automatically add them to addressbook */
3196 if (!modest_msg_edit_window_check_names (edit_window, FALSE))
3199 data = modest_msg_edit_window_get_msg_data (edit_window);
3201 recipients = g_strconcat (data->to?data->to:"",
3202 data->cc?data->cc:"",
3203 data->bcc?data->bcc:"",
3205 if (recipients == NULL || recipients[0] == '\0') {
3206 /* Empty subject -> no send */
3207 g_free (recipients);
3208 modest_msg_edit_window_free_msg_data (edit_window, data);
3211 g_free (recipients);
3214 if (!enough_space_for_message (edit_window, data)) {
3215 modest_msg_edit_window_free_msg_data (edit_window, data);
3219 account_mgr = modest_runtime_get_account_mgr();
3220 account_name = g_strdup (data->account_name);
3222 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3225 account_name = modest_account_mgr_get_default_account (account_mgr);
3227 if (!account_name) {
3228 modest_msg_edit_window_free_msg_data (edit_window, data);
3229 /* Run account setup wizard */
3230 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3235 /* Get the currently-active transport account for this modest account: */
3236 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3238 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3239 (modest_runtime_get_account_store (),
3240 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3243 if (!transport_account) {
3244 modest_msg_edit_window_free_msg_data (edit_window, data);
3245 /* Run account setup wizard */
3246 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3251 /* Create the mail operation */
3252 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3253 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3255 modest_mail_operation_send_new_mail (mail_operation,
3269 data->priority_flags);
3271 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3272 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3274 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3275 const GError *error = modest_mail_operation_get_error (mail_operation);
3276 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3277 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3278 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3279 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3285 g_free (account_name);
3286 g_object_unref (G_OBJECT (transport_account));
3287 g_object_unref (G_OBJECT (mail_operation));
3289 modest_msg_edit_window_free_msg_data (edit_window, data);
3292 modest_msg_edit_window_set_sent (edit_window, TRUE);
3294 /* Save settings and close the window: */
3295 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3302 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3303 ModestMsgEditWindow *window)
3305 ModestMsgEditFormatState *format_state = NULL;
3307 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3308 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3310 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3313 format_state = modest_msg_edit_window_get_format_state (window);
3314 g_return_if_fail (format_state != NULL);
3316 format_state->bold = gtk_toggle_action_get_active (action);
3317 modest_msg_edit_window_set_format_state (window, format_state);
3318 g_free (format_state);
3323 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3324 ModestMsgEditWindow *window)
3326 ModestMsgEditFormatState *format_state = NULL;
3328 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3329 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3331 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3334 format_state = modest_msg_edit_window_get_format_state (window);
3335 g_return_if_fail (format_state != NULL);
3337 format_state->italics = gtk_toggle_action_get_active (action);
3338 modest_msg_edit_window_set_format_state (window, format_state);
3339 g_free (format_state);
3344 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3345 ModestMsgEditWindow *window)
3347 ModestMsgEditFormatState *format_state = NULL;
3349 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3350 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3352 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3355 format_state = modest_msg_edit_window_get_format_state (window);
3356 g_return_if_fail (format_state != NULL);
3358 format_state->bullet = gtk_toggle_action_get_active (action);
3359 modest_msg_edit_window_set_format_state (window, format_state);
3360 g_free (format_state);
3365 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3366 GtkRadioAction *selected,
3367 ModestMsgEditWindow *window)
3369 ModestMsgEditFormatState *format_state = NULL;
3370 GtkJustification value;
3372 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3374 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3377 value = gtk_radio_action_get_current_value (selected);
3379 format_state = modest_msg_edit_window_get_format_state (window);
3380 g_return_if_fail (format_state != NULL);
3382 format_state->justification = value;
3383 modest_msg_edit_window_set_format_state (window, format_state);
3384 g_free (format_state);
3388 modest_ui_actions_on_select_editor_color (GtkAction *action,
3389 ModestMsgEditWindow *window)
3391 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3392 g_return_if_fail (GTK_IS_ACTION (action));
3394 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3397 modest_msg_edit_window_select_color (window);
3401 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3402 ModestMsgEditWindow *window)
3404 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3405 g_return_if_fail (GTK_IS_ACTION (action));
3407 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3410 modest_msg_edit_window_select_background_color (window);
3414 modest_ui_actions_on_insert_image (GObject *object,
3415 ModestMsgEditWindow *window)
3417 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3420 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3423 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3426 modest_msg_edit_window_insert_image (window);
3430 modest_ui_actions_on_attach_file (GtkAction *action,
3431 ModestMsgEditWindow *window)
3433 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3434 g_return_if_fail (GTK_IS_ACTION (action));
3436 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3439 modest_msg_edit_window_offer_attach_file (window);
3443 modest_ui_actions_on_remove_attachments (GtkAction *action,
3444 ModestMsgEditWindow *window)
3446 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3448 modest_msg_edit_window_remove_attachments (window, NULL);
3452 do_create_folder_cb (ModestMailOperation *mail_op,
3453 TnyFolderStore *parent_folder,
3454 TnyFolder *new_folder,
3457 gchar *suggested_name = (gchar *) user_data;
3458 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3459 const GError *error;
3461 error = modest_mail_operation_get_error (mail_op);
3463 gboolean disk_full = FALSE;
3464 TnyAccount *account;
3465 /* Show an error. If there was some problem writing to
3466 disk, show it, otherwise show the generic folder
3467 create error. We do it here and not in an error
3468 handler because the call to do_create_folder will
3469 stop the main loop in a gtk_dialog_run and then,
3470 the message won't be shown until that dialog is
3472 account = modest_mail_operation_get_account (mail_op);
3475 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3476 (GtkWidget *) source_win,
3479 _("mail_in_ui_folder_create_error_memory"));
3480 g_object_unref (account);
3483 /* Show an error and try again if there is no
3484 full memory condition */
3485 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3486 _("mail_in_ui_folder_create_error"));
3487 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3491 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3492 * FIXME: any other? */
3493 GtkWidget *folder_view;
3495 #ifndef MODEST_TOOLKIT_HILDON2
3496 if (MODEST_IS_MAIN_WINDOW(source_win))
3498 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3499 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3502 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3503 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3505 /* Select the newly created folder. It could happen
3506 that the widget is no longer there (i.e. the window
3507 has been destroyed, so we need to check this */
3509 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3511 g_object_unref (new_folder);
3513 /* Free. Note that the first time it'll be NULL so noop */
3514 g_free (suggested_name);
3515 g_object_unref (source_win);
3520 TnyFolderStore *parent;
3521 } CreateFolderConnect;
3524 do_create_folder_performer (gboolean canceled,
3526 GtkWindow *parent_window,
3527 TnyAccount *account,
3530 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3531 ModestMailOperation *mail_op;
3533 if (canceled || err) {
3534 /* In disk full conditions we could get this error here */
3535 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3536 (GtkWidget *) parent_window, err,
3537 NULL, _("mail_in_ui_folder_create_error_memory"));
3539 /* This happens if we have selected the outbox folder
3541 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3542 TNY_IS_MERGE_FOLDER (helper->parent)) {
3543 /* Show an error and retry */
3544 modest_platform_information_banner ((GtkWidget *) parent_window,
3546 _("mail_in_ui_folder_create_error"));
3548 do_create_folder (parent_window, helper->parent, helper->folder_name);
3554 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3555 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3557 modest_mail_operation_create_folder (mail_op,
3559 (const gchar *) helper->folder_name,
3560 do_create_folder_cb,
3561 g_strdup (helper->folder_name));
3562 g_object_unref (mail_op);
3566 g_object_unref (helper->parent);
3567 if (helper->folder_name)
3568 g_free (helper->folder_name);
3569 g_slice_free (CreateFolderConnect, helper);
3574 do_create_folder (GtkWindow *parent_window,
3575 TnyFolderStore *suggested_parent,
3576 const gchar *suggested_name)
3579 gchar *folder_name = NULL;
3580 TnyFolderStore *parent_folder = NULL;
3582 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3584 (gchar *) suggested_name,
3588 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3589 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3590 helper->folder_name = g_strdup (folder_name);
3591 helper->parent = g_object_ref (parent_folder);
3593 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3596 do_create_folder_performer,
3601 g_free (folder_name);
3603 g_object_unref (parent_folder);
3607 modest_ui_actions_create_folder(GtkWidget *parent_window,
3608 GtkWidget *folder_view,
3609 TnyFolderStore *parent_folder)
3611 if (!parent_folder) {
3612 #ifdef MODEST_TOOLKIT_HILDON2
3613 ModestTnyAccountStore *acc_store;
3615 acc_store = modest_runtime_get_account_store ();
3617 parent_folder = (TnyFolderStore *)
3618 modest_tny_account_store_get_local_folders_account (acc_store);
3620 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3624 if (parent_folder) {
3625 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3626 g_object_unref (parent_folder);
3631 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3634 g_return_if_fail (MODEST_IS_WINDOW(window));
3636 #ifndef MODEST_TOOLKIT_HILDON2
3637 if (MODEST_IS_MAIN_WINDOW (window)) {
3638 GtkWidget *folder_view;
3640 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3641 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3645 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3647 if (MODEST_IS_FOLDER_WINDOW (window)) {
3648 GtkWidget *folder_view;
3650 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3651 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3654 g_assert_not_reached ();
3659 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3662 const GError *error = NULL;
3663 gchar *message = NULL;
3665 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3667 /* Get error message */
3668 error = modest_mail_operation_get_error (mail_op);
3670 g_return_if_reached ();
3672 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3673 (GError *) error, account);
3675 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3676 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3677 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3678 message = _CS("ckdg_ib_folder_already_exists");
3679 } else if (error->domain == TNY_ERROR_DOMAIN &&
3680 error->code == TNY_SERVICE_ERROR_STATE) {
3681 /* This means that the folder is already in use (a
3682 message is opened for example */
3683 message = _("emev_ni_internal_error");
3685 message = _CS("ckdg_ib_unable_to_rename");
3688 /* We don't set a parent for the dialog because the dialog
3689 will be destroyed so the banner won't appear */
3690 modest_platform_information_banner (NULL, NULL, message);
3693 g_object_unref (account);
3699 TnyFolderStore *folder;
3704 on_rename_folder_cb (ModestMailOperation *mail_op,
3705 TnyFolder *new_folder,
3708 ModestFolderView *folder_view;
3710 /* If the window was closed when renaming a folder, or if
3711 * it's not a main window this will happen */
3712 if (!MODEST_IS_FOLDER_VIEW (user_data))
3715 folder_view = MODEST_FOLDER_VIEW (user_data);
3716 /* Note that if the rename fails new_folder will be NULL */
3718 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3719 #ifndef MODEST_TOOLKIT_HILDON2
3721 modest_folder_view_select_first_inbox_or_local (folder_view);
3724 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3728 on_rename_folder_performer (gboolean canceled,
3730 GtkWindow *parent_window,
3731 TnyAccount *account,
3734 ModestMailOperation *mail_op = NULL;
3735 GtkTreeSelection *sel = NULL;
3736 GtkWidget *folder_view = NULL;
3737 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3739 if (canceled || err) {
3740 /* In disk full conditions we could get this error here */
3741 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3742 (GtkWidget *) parent_window, err,
3747 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3748 modest_ui_actions_rename_folder_error_handler,
3749 parent_window, NULL);
3751 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3753 #ifndef MODEST_TOOLKIT_HILDON2
3754 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3756 folder_view = modest_main_window_get_child_widget (
3757 MODEST_MAIN_WINDOW (parent_window),
3758 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3761 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3762 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3763 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3767 /* Clear the folders view */
3768 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3769 gtk_tree_selection_unselect_all (sel);
3771 /* Actually rename the folder */
3772 modest_mail_operation_rename_folder (mail_op,
3773 TNY_FOLDER (data->folder),
3774 (const gchar *) (data->new_name),
3775 on_rename_folder_cb,
3777 g_object_unref (mail_op);
3780 g_object_unref (data->folder);
3781 g_free (data->new_name);
3786 modest_ui_actions_on_rename_folder (GtkAction *action,
3787 ModestWindow *window)
3789 modest_ui_actions_on_edit_mode_rename_folder (window);
3793 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3795 TnyFolderStore *folder;
3796 GtkWidget *folder_view;
3797 gboolean do_rename = TRUE;
3799 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3801 #ifndef MODEST_TOOLKIT_HILDON2
3802 if (MODEST_IS_MAIN_WINDOW (window)) {
3803 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3804 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3808 if (MODEST_IS_FOLDER_WINDOW (window)) {
3809 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3815 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3820 if (TNY_IS_FOLDER (folder)) {
3821 gchar *folder_name = NULL;
3823 const gchar *current_name;
3824 TnyFolderStore *parent;
3826 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3827 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3828 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3829 parent, current_name,
3831 g_object_unref (parent);
3833 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3836 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3837 rename_folder_data->folder = g_object_ref (folder);
3838 rename_folder_data->new_name = folder_name;
3839 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3840 folder, on_rename_folder_performer, rename_folder_data);
3843 g_object_unref (folder);
3848 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3851 GObject *win = modest_mail_operation_get_source (mail_op);
3853 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3854 _("mail_in_ui_folder_delete_error"),
3856 g_object_unref (win);
3860 TnyFolderStore *folder;
3861 gboolean move_to_trash;
3865 on_delete_folder_cb (gboolean canceled,
3867 GtkWindow *parent_window,
3868 TnyAccount *account,
3871 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3872 GtkWidget *folder_view;
3873 ModestMailOperation *mail_op;
3874 GtkTreeSelection *sel;
3876 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3877 /* Note that the connection process can fail due to
3878 memory low conditions as it can not successfully
3879 store the summary */
3880 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3881 (GtkWidget*) parent_window, err,
3883 g_debug ("Error connecting when trying to delete a folder");
3884 g_object_unref (G_OBJECT (info->folder));
3889 #ifndef MODEST_TOOLKIT_HILDON2
3890 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3891 folder_view = modest_main_window_get_child_widget (
3892 MODEST_MAIN_WINDOW (parent_window),
3893 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3895 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3896 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3899 g_object_unref (G_OBJECT (info->folder));
3904 /* Unselect the folder before deleting it to free the headers */
3905 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3906 gtk_tree_selection_unselect_all (sel);
3908 /* Create the mail operation */
3910 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3911 modest_ui_actions_delete_folder_error_handler,
3914 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3916 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3918 #ifndef MODEST_TOOLKIT_HILDON2
3919 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3922 g_object_unref (mail_op);
3923 g_object_unref (info->folder);
3928 delete_folder (ModestWindow *window, gboolean move_to_trash)
3930 TnyFolderStore *folder;
3931 GtkWidget *folder_view;
3935 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3937 #ifndef MODEST_TOOLKIT_HILDON2
3938 if (MODEST_IS_MAIN_WINDOW (window)) {
3940 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3941 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3943 if (MODEST_IS_FOLDER_WINDOW (window)) {
3944 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3952 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3957 /* Show an error if it's an account */
3958 if (!TNY_IS_FOLDER (folder)) {
3959 modest_platform_run_information_dialog (GTK_WINDOW (window),
3960 _("mail_in_ui_folder_delete_error"),
3962 g_object_unref (G_OBJECT (folder));
3967 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3968 tny_folder_get_name (TNY_FOLDER (folder)));
3969 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3970 (const gchar *) message);
3973 if (response == GTK_RESPONSE_OK) {
3974 TnyAccount *account = NULL;
3975 DeleteFolderInfo *info = NULL;
3976 info = g_new0(DeleteFolderInfo, 1);
3977 info->folder = g_object_ref (folder);
3978 info->move_to_trash = move_to_trash;
3980 account = tny_folder_get_account (TNY_FOLDER (folder));
3981 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3983 TNY_FOLDER_STORE (account),
3984 on_delete_folder_cb, info);
3985 g_object_unref (account);
3986 g_object_unref (folder);
3994 modest_ui_actions_on_delete_folder (GtkAction *action,
3995 ModestWindow *window)
3997 modest_ui_actions_on_edit_mode_delete_folder (window);
4001 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4003 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4005 return delete_folder (window, FALSE);
4008 #ifndef MODEST_TOOLKIT_HILDON2
4010 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4012 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4014 delete_folder (MODEST_WINDOW (main_window), TRUE);
4018 typedef struct _PasswordDialogFields {
4019 GtkWidget *username;
4020 GtkWidget *password;
4022 } PasswordDialogFields;
4025 password_dialog_check_field (GtkEditable *editable,
4026 PasswordDialogFields *fields)
4029 gboolean any_value_empty = FALSE;
4031 value = modest_entry_get_text (fields->username);
4032 if ((value == NULL) || value[0] == '\0') {
4033 any_value_empty = TRUE;
4035 value = modest_entry_get_text (fields->password);
4036 if ((value == NULL) || value[0] == '\0') {
4037 any_value_empty = TRUE;
4039 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4043 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4044 const gchar* server_account_name,
4049 ModestMainWindow *main_window)
4051 g_return_if_fail(server_account_name);
4052 gboolean completed = FALSE;
4053 PasswordDialogFields *fields = NULL;
4055 /* Initalize output parameters: */
4062 #ifndef MODEST_TOOLKIT_GTK
4063 /* Maemo uses a different (awkward) button order,
4064 * It should probably just use gtk_alternative_dialog_button_order ().
4066 #ifdef MODEST_TOOLKIT_HILDON2
4068 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4071 _HL("wdgt_bd_done"),
4072 GTK_RESPONSE_ACCEPT,
4074 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4075 HILDON_MARGIN_DOUBLE);
4078 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4081 _("mcen_bd_dialog_ok"),
4082 GTK_RESPONSE_ACCEPT,
4083 _("mcen_bd_dialog_cancel"),
4084 GTK_RESPONSE_REJECT,
4086 #endif /* MODEST_TOOLKIT_HILDON2 */
4089 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4093 GTK_RESPONSE_REJECT,
4095 GTK_RESPONSE_ACCEPT,
4097 #endif /* MODEST_TOOLKIT_GTK */
4099 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4101 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4102 modest_runtime_get_account_mgr(), server_account_name);
4103 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4104 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4107 gtk_widget_destroy (dialog);
4111 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4112 GtkWidget *label = gtk_label_new (txt);
4113 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4115 g_free (server_name);
4116 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4121 gchar *initial_username = modest_account_mgr_get_server_account_username (
4122 modest_runtime_get_account_mgr(), server_account_name);
4124 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
4125 if (initial_username)
4126 modest_entry_set_text (entry_username, initial_username);
4128 /* Dim this if a connection has ever succeeded with this username,
4129 * as per the UI spec: */
4130 /* const gboolean username_known = */
4131 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4132 /* modest_runtime_get_account_mgr(), server_account_name); */
4133 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4135 /* We drop the username sensitive code and disallow changing it here
4136 * as tinymail does not support really changing the username in the callback
4138 gtk_widget_set_sensitive (entry_username, FALSE);
4140 #ifndef MODEST_TOOLKIT_GTK
4141 /* Auto-capitalization is the default, so let's turn it off: */
4142 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4144 /* Create a size group to be used by all captions.
4145 * Note that HildonCaption does not create a default size group if we do not specify one.
4146 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4147 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4149 #ifdef MODEST_TOOLKIT_HILDON2
4150 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4151 _("mail_fi_username"), FALSE,
4154 GtkWidget *caption = hildon_caption_new (sizegroup,
4155 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4157 gtk_widget_show (entry_username);
4158 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4159 FALSE, FALSE, MODEST_MARGIN_HALF);
4160 gtk_widget_show (caption);
4162 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4164 #endif /* !MODEST_TOOLKIT_GTK */
4167 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
4168 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4169 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4171 #ifndef MODEST_TOOLKIT_GTK
4172 /* Auto-capitalization is the default, so let's turn it off: */
4173 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4174 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4176 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4177 _("mail_fi_password"), FALSE,
4179 gtk_widget_show (entry_password);
4180 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4181 FALSE, FALSE, MODEST_MARGIN_HALF);
4182 gtk_widget_show (caption);
4183 g_object_unref (sizegroup);
4185 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4187 #endif /* !MODEST_TOOLKIT_GTK */
4189 if (initial_username != NULL)
4190 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4192 /* This is not in the Maemo UI spec:
4193 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4194 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4198 fields = g_slice_new0 (PasswordDialogFields);
4199 fields->username = entry_username;
4200 fields->password = entry_password;
4201 fields->dialog = dialog;
4203 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4204 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4205 password_dialog_check_field (NULL, fields);
4207 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4209 while (!completed) {
4211 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4213 *username = g_strdup (modest_entry_get_text (entry_username));
4215 /* Note that an empty field becomes the "" string */
4216 if (*username && strlen (*username) > 0) {
4217 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4218 server_account_name,
4222 const gboolean username_was_changed =
4223 (strcmp (*username, initial_username) != 0);
4224 if (username_was_changed) {
4225 g_warning ("%s: tinymail does not yet support changing the "
4226 "username in the get_password() callback.\n", __FUNCTION__);
4232 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4233 _("mcen_ib_username_pw_incorrect"));
4239 *password = g_strdup (modest_entry_get_text (entry_password));
4241 /* We do not save the password in the configuration,
4242 * because this function is only called for passwords that should
4243 * not be remembered:
4244 modest_server_account_set_password (
4245 modest_runtime_get_account_mgr(), server_account_name,
4252 #ifndef MODEST_TOOLKIT_HILDON2
4253 /* Set parent to NULL or the banner will disappear with its parent dialog */
4254 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4266 /* This is not in the Maemo UI spec:
4267 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4273 g_free (initial_username);
4274 gtk_widget_destroy (dialog);
4275 g_slice_free (PasswordDialogFields, fields);
4277 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4281 modest_ui_actions_on_cut (GtkAction *action,
4282 ModestWindow *window)
4284 GtkWidget *focused_widget;
4285 GtkClipboard *clipboard;
4287 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4288 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4289 if (GTK_IS_EDITABLE (focused_widget)) {
4290 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4291 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4292 gtk_clipboard_store (clipboard);
4293 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4294 GtkTextBuffer *buffer;
4296 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4297 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4298 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4299 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4300 gtk_clipboard_store (clipboard);
4302 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4303 TnyList *header_list = modest_header_view_get_selected_headers (
4304 MODEST_HEADER_VIEW (focused_widget));
4305 gboolean continue_download = FALSE;
4306 gint num_of_unc_msgs;
4308 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4310 if (num_of_unc_msgs) {
4311 TnyAccount *account = get_account_from_header_list (header_list);
4313 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4314 g_object_unref (account);
4318 if (num_of_unc_msgs == 0 || continue_download) {
4319 /* modest_platform_information_banner (
4320 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4321 modest_header_view_cut_selection (
4322 MODEST_HEADER_VIEW (focused_widget));
4325 g_object_unref (header_list);
4326 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4327 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4332 modest_ui_actions_on_copy (GtkAction *action,
4333 ModestWindow *window)
4335 GtkClipboard *clipboard;
4336 GtkWidget *focused_widget;
4337 gboolean copied = TRUE;
4339 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4340 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4342 if (GTK_IS_LABEL (focused_widget)) {
4344 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4345 gtk_clipboard_set_text (clipboard, selection, -1);
4347 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4348 gtk_clipboard_store (clipboard);
4349 } else if (GTK_IS_EDITABLE (focused_widget)) {
4350 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4351 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4352 gtk_clipboard_store (clipboard);
4353 } else if (GTK_IS_HTML (focused_widget)) {
4356 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4357 if ((sel == NULL) || (sel[0] == '\0')) {
4360 gtk_html_copy (GTK_HTML (focused_widget));
4361 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4362 gtk_clipboard_store (clipboard);
4364 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4365 GtkTextBuffer *buffer;
4366 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4367 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4368 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4369 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4370 gtk_clipboard_store (clipboard);
4372 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4373 TnyList *header_list = modest_header_view_get_selected_headers (
4374 MODEST_HEADER_VIEW (focused_widget));
4375 gboolean continue_download = FALSE;
4376 gint num_of_unc_msgs;
4378 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4380 if (num_of_unc_msgs) {
4381 TnyAccount *account = get_account_from_header_list (header_list);
4383 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4384 g_object_unref (account);
4388 if (num_of_unc_msgs == 0 || continue_download) {
4389 modest_platform_information_banner (
4390 NULL, NULL, _CS("mcen_ib_getting_items"));
4391 modest_header_view_copy_selection (
4392 MODEST_HEADER_VIEW (focused_widget));
4396 g_object_unref (header_list);
4398 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4399 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4402 /* Show information banner if there was a copy to clipboard */
4404 modest_platform_information_banner (
4405 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4409 modest_ui_actions_on_undo (GtkAction *action,
4410 ModestWindow *window)
4412 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4413 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4414 #ifndef MODEST_TOOLKIT_HILDON2
4415 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4416 ModestEmailClipboard *clipboard = NULL;
4417 /* Clear clipboard source */
4418 clipboard = modest_runtime_get_email_clipboard ();
4419 modest_email_clipboard_clear (clipboard);
4422 g_return_if_reached ();
4427 modest_ui_actions_on_redo (GtkAction *action,
4428 ModestWindow *window)
4430 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4431 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4434 g_return_if_reached ();
4440 destroy_information_note (ModestMailOperation *mail_op,
4443 /* destroy information note */
4444 gtk_widget_destroy (GTK_WIDGET(user_data));
4448 destroy_folder_information_note (ModestMailOperation *mail_op,
4449 TnyFolder *new_folder,
4452 /* destroy information note */
4453 gtk_widget_destroy (GTK_WIDGET(user_data));
4458 paste_as_attachment_free (gpointer data)
4460 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4462 if (helper->banner) {
4463 gtk_widget_destroy (helper->banner);
4464 g_object_unref (helper->banner);
4470 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4475 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4476 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4481 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4486 modest_ui_actions_on_paste (GtkAction *action,
4487 ModestWindow *window)
4489 GtkWidget *focused_widget = NULL;
4490 GtkWidget *inf_note = NULL;
4491 ModestMailOperation *mail_op = NULL;
4493 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4494 if (GTK_IS_EDITABLE (focused_widget)) {
4495 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4496 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4497 ModestEmailClipboard *e_clipboard = NULL;
4498 e_clipboard = modest_runtime_get_email_clipboard ();
4499 if (modest_email_clipboard_cleared (e_clipboard)) {
4500 GtkTextBuffer *buffer;
4501 GtkClipboard *clipboard;
4503 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4504 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4505 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4506 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4507 ModestMailOperation *mail_op;
4508 TnyFolder *src_folder = NULL;
4509 TnyList *data = NULL;
4511 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4512 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4513 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4514 _CS("ckct_nw_pasting"));
4515 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4516 mail_op = modest_mail_operation_new (G_OBJECT (window));
4517 if (helper->banner != NULL) {
4518 g_object_ref (G_OBJECT (helper->banner));
4519 gtk_widget_show (GTK_WIDGET (helper->banner));
4523 modest_mail_operation_get_msgs_full (mail_op,
4525 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4527 paste_as_attachment_free);
4531 g_object_unref (data);
4533 g_object_unref (src_folder);
4536 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4537 ModestEmailClipboard *clipboard = NULL;
4538 TnyFolder *src_folder = NULL;
4539 TnyFolderStore *folder_store = NULL;
4540 TnyList *data = NULL;
4541 gboolean delete = FALSE;
4543 /* Check clipboard source */
4544 clipboard = modest_runtime_get_email_clipboard ();
4545 if (modest_email_clipboard_cleared (clipboard))
4548 /* Get elements to paste */
4549 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4551 /* Create a new mail operation */
4552 mail_op = modest_mail_operation_new (G_OBJECT(window));
4554 /* Get destination folder */
4555 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4557 /* transfer messages */
4561 /* Ask for user confirmation */
4563 modest_ui_actions_msgs_move_to_confirmation (window,
4564 TNY_FOLDER (folder_store),
4568 if (response == GTK_RESPONSE_OK) {
4569 /* Launch notification */
4570 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4571 _CS("ckct_nw_pasting"));
4572 if (inf_note != NULL) {
4573 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4574 gtk_widget_show (GTK_WIDGET(inf_note));
4577 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4578 modest_mail_operation_xfer_msgs (mail_op,
4580 TNY_FOLDER (folder_store),
4582 destroy_information_note,
4585 g_object_unref (mail_op);
4588 } else if (src_folder != NULL) {
4589 /* Launch notification */
4590 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4591 _CS("ckct_nw_pasting"));
4592 if (inf_note != NULL) {
4593 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4594 gtk_widget_show (GTK_WIDGET(inf_note));
4597 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4598 modest_mail_operation_xfer_folder (mail_op,
4602 destroy_folder_information_note,
4608 g_object_unref (data);
4609 if (src_folder != NULL)
4610 g_object_unref (src_folder);
4611 if (folder_store != NULL)
4612 g_object_unref (folder_store);
4618 modest_ui_actions_on_select_all (GtkAction *action,
4619 ModestWindow *window)
4621 GtkWidget *focused_widget;
4623 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4624 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4625 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4626 } else if (GTK_IS_LABEL (focused_widget)) {
4627 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4628 } else if (GTK_IS_EDITABLE (focused_widget)) {
4629 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4630 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4631 GtkTextBuffer *buffer;
4632 GtkTextIter start, end;
4634 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4635 gtk_text_buffer_get_start_iter (buffer, &start);
4636 gtk_text_buffer_get_end_iter (buffer, &end);
4637 gtk_text_buffer_select_range (buffer, &start, &end);
4638 } else if (GTK_IS_HTML (focused_widget)) {
4639 gtk_html_select_all (GTK_HTML (focused_widget));
4640 #ifndef MODEST_TOOLKIT_HILDON2
4641 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4642 GtkWidget *header_view = focused_widget;
4643 GtkTreeSelection *selection = NULL;
4645 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4646 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4647 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4650 /* Disable window dimming management */
4651 modest_window_disable_dimming (MODEST_WINDOW(window));
4653 /* Select all messages */
4654 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4655 gtk_tree_selection_select_all (selection);
4657 /* Set focuse on header view */
4658 gtk_widget_grab_focus (header_view);
4660 /* Enable window dimming management */
4661 modest_window_enable_dimming (MODEST_WINDOW(window));
4662 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4663 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4670 modest_ui_actions_on_mark_as_read (GtkAction *action,
4671 ModestWindow *window)
4673 g_return_if_fail (MODEST_IS_WINDOW(window));
4675 /* Mark each header as read */
4676 do_headers_action (window, headers_action_mark_as_read, NULL);
4680 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4681 ModestWindow *window)
4683 g_return_if_fail (MODEST_IS_WINDOW(window));
4685 /* Mark each header as read */
4686 do_headers_action (window, headers_action_mark_as_unread, NULL);
4690 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4691 GtkRadioAction *selected,
4692 ModestWindow *window)
4696 value = gtk_radio_action_get_current_value (selected);
4697 if (MODEST_IS_WINDOW (window)) {
4698 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4703 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4704 GtkRadioAction *selected,
4705 ModestWindow *window)
4707 TnyHeaderFlags flags;
4708 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4710 flags = gtk_radio_action_get_current_value (selected);
4711 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4715 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4716 GtkRadioAction *selected,
4717 ModestWindow *window)
4721 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4723 file_format = gtk_radio_action_get_current_value (selected);
4724 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4729 modest_ui_actions_on_zoom_plus (GtkAction *action,
4730 ModestWindow *window)
4732 g_return_if_fail (MODEST_IS_WINDOW (window));
4734 modest_window_zoom_plus (MODEST_WINDOW (window));
4738 modest_ui_actions_on_zoom_minus (GtkAction *action,
4739 ModestWindow *window)
4741 g_return_if_fail (MODEST_IS_WINDOW (window));
4743 modest_window_zoom_minus (MODEST_WINDOW (window));
4747 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4748 ModestWindow *window)
4750 ModestWindowMgr *mgr;
4751 gboolean fullscreen, active;
4752 g_return_if_fail (MODEST_IS_WINDOW (window));
4754 mgr = modest_runtime_get_window_mgr ();
4756 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4757 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4759 if (active != fullscreen) {
4760 modest_window_mgr_set_fullscreen_mode (mgr, active);
4761 #ifndef MODEST_TOOLKIT_HILDON2
4762 gtk_window_present (GTK_WINDOW (window));
4768 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4769 ModestWindow *window)
4771 ModestWindowMgr *mgr;
4772 gboolean fullscreen;
4774 g_return_if_fail (MODEST_IS_WINDOW (window));
4776 mgr = modest_runtime_get_window_mgr ();
4777 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4778 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4780 #ifndef MODEST_TOOLKIT_HILDON2
4781 gtk_window_present (GTK_WINDOW (window));
4786 * Used by modest_ui_actions_on_details to call do_headers_action
4789 headers_action_show_details (TnyHeader *header,
4790 ModestWindow *window,
4794 gboolean async_retrieval;
4797 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4798 async_retrieval = TRUE;
4799 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4801 async_retrieval = FALSE;
4803 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4805 g_object_unref (msg);
4809 * Show the header details in a ModestDetailsDialog widget
4812 modest_ui_actions_on_details (GtkAction *action,
4815 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4819 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4823 header = tny_msg_get_header (msg);
4825 headers_action_show_details (header, win, NULL);
4826 g_object_unref (header);
4828 g_object_unref (msg);
4829 #ifndef MODEST_TOOLKIT_HILDON2
4830 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4831 GtkWidget *folder_view, *header_view;
4833 /* Check which widget has the focus */
4834 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4835 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4836 if (gtk_widget_is_focus (folder_view)) {
4837 TnyFolderStore *folder_store
4838 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4839 if (!folder_store) {
4840 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4843 /* Show only when it's a folder */
4844 /* This function should not be called for account items,
4845 * because we dim the menu item for them. */
4846 if (TNY_IS_FOLDER (folder_store)) {
4847 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4848 TNY_FOLDER (folder_store));
4851 g_object_unref (folder_store);
4854 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4855 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4856 /* Show details of each header */
4857 do_headers_action (win, headers_action_show_details, header_view);
4860 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4862 GtkWidget *header_view;
4864 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4865 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4867 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4869 g_object_unref (folder);
4876 modest_ui_actions_on_limit_error (GtkAction *action,
4879 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4881 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4886 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4887 ModestMsgEditWindow *window)
4889 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4891 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4895 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4896 ModestMsgEditWindow *window)
4898 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4900 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4903 #ifndef MODEST_TOOLKIT_HILDON2
4905 modest_ui_actions_toggle_folders_view (GtkAction *action,
4906 ModestMainWindow *main_window)
4908 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4910 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4911 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4913 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4918 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4919 ModestWindow *window)
4921 gboolean active, fullscreen = FALSE;
4922 ModestWindowMgr *mgr;
4924 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4926 /* Check if we want to toggle the toolbar view in fullscreen
4928 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4929 "ViewShowToolbarFullScreen")) {
4933 /* Toggle toolbar */
4934 mgr = modest_runtime_get_window_mgr ();
4935 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4939 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4940 ModestMsgEditWindow *window)
4942 modest_msg_edit_window_select_font (window);
4947 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4948 const gchar *display_name,
4951 /* don't update the display name if it was already set;
4952 * updating the display name apparently is expensive */
4953 const gchar* old_name = gtk_window_get_title (window);
4955 if (display_name == NULL)
4958 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4959 return; /* don't do anything */
4961 /* This is usually used to change the title of the main window, which
4962 * is the one that holds the folder view. Note that this change can
4963 * happen even when the widget doesn't have the focus. */
4964 gtk_window_set_title (window, display_name);
4969 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4971 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4972 modest_msg_edit_window_select_contacts (window);
4976 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4978 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4979 modest_msg_edit_window_check_names (window, FALSE);
4982 #ifndef MODEST_TOOLKIT_HILDON2
4984 * This function is used to track changes in the selection of the
4985 * folder view that is inside the "move to" dialog to enable/disable
4986 * the OK button because we do not want the user to select a disallowed
4987 * destination for a folder.
4988 * The user also not desired to be able to use NEW button on items where
4989 * folder creation is not possibel.
4992 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4993 TnyFolderStore *folder_store,
4997 GtkWidget *dialog = NULL;
4998 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4999 gboolean moving_folder = FALSE;
5000 gboolean is_local_account = TRUE;
5001 GtkWidget *folder_view = NULL;
5002 ModestTnyFolderRules rules;
5004 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5009 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5013 /* check if folder_store is an remote account */
5014 if (TNY_IS_ACCOUNT (folder_store)) {
5015 TnyAccount *local_account = NULL;
5016 TnyAccount *mmc_account = NULL;
5017 ModestTnyAccountStore *account_store = NULL;
5019 account_store = modest_runtime_get_account_store ();
5020 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5021 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5023 if ((gpointer) local_account != (gpointer) folder_store &&
5024 (gpointer) mmc_account != (gpointer) folder_store) {
5025 ModestProtocolType proto;
5026 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5027 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5028 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5030 is_local_account = FALSE;
5031 /* New button should be dimmed on remote
5033 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5035 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5037 g_object_unref (local_account);
5039 /* It could not exist */
5041 g_object_unref (mmc_account);
5044 /* Check the target folder rules */
5045 if (TNY_IS_FOLDER (folder_store)) {
5046 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5047 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5048 ok_sensitive = FALSE;
5049 new_sensitive = FALSE;
5054 /* Check if we're moving a folder */
5055 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5056 /* Get the widgets */
5057 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5058 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5059 if (gtk_widget_is_focus (folder_view))
5060 moving_folder = TRUE;
5063 if (moving_folder) {
5064 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5066 /* Get the folder to move */
5067 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5069 /* Check that we're not moving to the same folder */
5070 if (TNY_IS_FOLDER (moved_folder)) {
5071 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5072 if (parent == folder_store)
5073 ok_sensitive = FALSE;
5074 g_object_unref (parent);
5077 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5078 /* Do not allow to move to an account unless it's the
5079 local folders account */
5080 if (!is_local_account)
5081 ok_sensitive = FALSE;
5084 if (ok_sensitive && (moved_folder == folder_store)) {
5085 /* Do not allow to move to itself */
5086 ok_sensitive = FALSE;
5088 g_object_unref (moved_folder);
5090 TnyFolder *src_folder = NULL;
5092 /* Moving a message */
5093 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5095 TnyHeader *header = NULL;
5096 header = modest_msg_view_window_get_header
5097 (MODEST_MSG_VIEW_WINDOW (user_data));
5098 if (!TNY_IS_HEADER(header))
5099 g_warning ("%s: could not get source header", __FUNCTION__);
5101 src_folder = tny_header_get_folder (header);
5104 g_object_unref (header);
5107 TNY_FOLDER (modest_folder_view_get_selected
5108 (MODEST_FOLDER_VIEW (folder_view)));
5111 if (TNY_IS_FOLDER(src_folder)) {
5112 /* Do not allow to move the msg to the same folder */
5113 /* Do not allow to move the msg to an account */
5114 if ((gpointer) src_folder == (gpointer) folder_store ||
5115 TNY_IS_ACCOUNT (folder_store))
5116 ok_sensitive = FALSE;
5117 g_object_unref (src_folder);
5119 g_warning ("%s: could not get source folder", __FUNCTION__);
5123 /* Set sensitivity of the OK and NEW button */
5124 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5125 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5130 on_move_to_dialog_response (GtkDialog *dialog,
5134 GtkWidget *parent_win;
5135 MoveToInfo *helper = NULL;
5136 ModestFolderView *folder_view;
5137 gboolean unset_edit_mode = FALSE;
5139 helper = (MoveToInfo *) user_data;
5141 parent_win = (GtkWidget *) helper->win;
5142 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5143 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5145 TnyFolderStore *dst_folder;
5146 TnyFolderStore *selected;
5148 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5149 selected = modest_folder_view_get_selected (folder_view);
5150 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5151 g_object_unref (selected);
5153 case GTK_RESPONSE_NONE:
5154 case GTK_RESPONSE_CANCEL:
5155 case GTK_RESPONSE_DELETE_EVENT:
5157 case GTK_RESPONSE_OK:
5158 dst_folder = modest_folder_view_get_selected (folder_view);
5160 #ifndef MODEST_TOOLKIT_HILDON2
5161 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5162 /* Clean list to move used for filtering */
5163 modest_folder_view_set_list_to_move (folder_view, NULL);
5165 modest_ui_actions_on_main_window_move_to (NULL,
5166 GTK_WIDGET (folder_view),
5168 MODEST_MAIN_WINDOW (parent_win));
5170 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5171 /* Clean list to move used for filtering */
5172 modest_folder_view_set_list_to_move (folder_view, NULL);
5174 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5177 GTK_WINDOW (parent_win));
5180 /* if the user selected a root folder
5181 (account) then do not perform any action */
5182 if (TNY_IS_ACCOUNT (dst_folder)) {
5183 g_signal_stop_emission_by_name (dialog, "response");
5187 /* Clean list to move used for filtering */
5188 modest_folder_view_set_list_to_move (folder_view, NULL);
5190 /* Moving from headers window in edit mode */
5191 modest_ui_actions_on_window_move_to (NULL, helper->list,
5193 MODEST_WINDOW (parent_win));
5197 g_object_unref (dst_folder);
5199 unset_edit_mode = TRUE;
5202 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5205 /* Free the helper and exit */
5207 g_object_unref (helper->list);
5208 if (unset_edit_mode) {
5209 #ifdef MODEST_TOOLKIT_HILDON2
5210 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5213 g_slice_free (MoveToInfo, helper);
5214 gtk_widget_destroy (GTK_WIDGET (dialog));
5218 create_move_to_dialog (GtkWindow *win,
5219 GtkWidget *folder_view,
5220 TnyList *list_to_move)
5222 GtkWidget *dialog, *tree_view = NULL;
5224 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5226 #ifndef MODEST_TOOLKIT_HILDON2
5227 /* Track changes in the selection to
5228 * disable the OK button whenever "Move to" is not possible
5229 * disbale NEW button whenever New is not possible */
5230 g_signal_connect (tree_view,
5231 "folder_selection_changed",
5232 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5236 /* It could happen that we're trying to move a message from a
5237 window (msg window for example) after the main window was
5238 closed, so we can not just get the model of the folder
5240 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5241 const gchar *visible_id = NULL;
5243 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5244 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5245 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5246 MODEST_FOLDER_VIEW(tree_view));
5249 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5251 /* Show the same account than the one that is shown in the main window */
5252 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5255 const gchar *active_account_name = NULL;
5256 ModestAccountMgr *mgr = NULL;
5257 ModestAccountSettings *settings = NULL;
5258 ModestServerAccountSettings *store_settings = NULL;
5260 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5261 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5262 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5263 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5265 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5266 mgr = modest_runtime_get_account_mgr ();
5267 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5270 const gchar *store_account_name;
5271 store_settings = modest_account_settings_get_store_settings (settings);
5272 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5274 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5275 store_account_name);
5276 g_object_unref (store_settings);
5277 g_object_unref (settings);
5281 /* we keep a pointer to the embedded folder view, so we can
5282 * retrieve it with get_folder_view_from_move_to_dialog (see
5283 * above) later (needed for focus handling)
5285 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5287 /* Hide special folders */
5288 #ifndef MODEST_TOOLKIT_HILDON2
5289 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5292 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5293 #ifndef MODEST_TOOLKIT_HILDON2
5294 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5297 gtk_widget_show (GTK_WIDGET (tree_view));
5303 * Shows a confirmation dialog to the user when we're moving messages
5304 * from a remote server to the local storage. Returns the dialog
5305 * response. If it's other kind of movement then it always returns
5308 * This one is used by the next functions:
5309 * modest_ui_actions_on_paste - commented out
5310 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5313 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5314 TnyFolder *dest_folder,
5318 gint response = GTK_RESPONSE_OK;
5319 TnyAccount *account = NULL;
5320 TnyFolder *src_folder = NULL;
5321 TnyIterator *iter = NULL;
5322 TnyHeader *header = NULL;
5324 /* return with OK if the destination is a remote folder */
5325 if (modest_tny_folder_is_remote_folder (dest_folder))
5326 return GTK_RESPONSE_OK;
5328 /* Get source folder */
5329 iter = tny_list_create_iterator (headers);
5330 header = TNY_HEADER (tny_iterator_get_current (iter));
5332 src_folder = tny_header_get_folder (header);
5333 g_object_unref (header);
5335 g_object_unref (iter);
5337 /* if no src_folder, message may be an attahcment */
5338 if (src_folder == NULL)
5339 return GTK_RESPONSE_CANCEL;
5341 /* If the source is a local or MMC folder */
5342 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5343 g_object_unref (src_folder);
5344 return GTK_RESPONSE_OK;
5347 /* Get the account */
5348 account = tny_folder_get_account (src_folder);
5350 /* now if offline we ask the user */
5351 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5352 response = GTK_RESPONSE_OK;
5354 response = GTK_RESPONSE_CANCEL;
5357 g_object_unref (src_folder);
5358 g_object_unref (account);
5364 move_to_helper_destroyer (gpointer user_data)
5366 MoveToHelper *helper = (MoveToHelper *) user_data;
5368 /* Close the "Pasting" information banner */
5369 if (helper->banner) {
5370 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5371 g_object_unref (helper->banner);
5373 if (gtk_tree_row_reference_valid (helper->reference)) {
5374 gtk_tree_row_reference_free (helper->reference);
5375 helper->reference = NULL;
5381 move_to_cb (ModestMailOperation *mail_op,
5384 MoveToHelper *helper = (MoveToHelper *) user_data;
5385 GObject *object = modest_mail_operation_get_source (mail_op);
5387 /* Note that the operation could have failed, in that case do
5389 if (modest_mail_operation_get_status (mail_op) !=
5390 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5393 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5394 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5396 if (!modest_msg_view_window_select_next_message (self) &&
5397 !modest_msg_view_window_select_previous_message (self)) {
5398 /* No more messages to view, so close this window */
5399 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5401 #ifndef MODEST_TOOLKIT_HILDON2
5402 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5403 gtk_tree_row_reference_valid (helper->reference)) {
5404 GtkWidget *header_view;
5406 GtkTreeSelection *sel;
5408 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5409 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5410 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5411 path = gtk_tree_row_reference_get_path (helper->reference);
5412 /* We need to unselect the previous one
5413 because we could be copying instead of
5415 gtk_tree_selection_unselect_all (sel);
5416 gtk_tree_selection_select_path (sel, path);
5417 gtk_tree_path_free (path);
5420 g_object_unref (object);
5423 /* Destroy the helper */
5424 move_to_helper_destroyer (helper);
5428 folder_move_to_cb (ModestMailOperation *mail_op,
5429 TnyFolder *new_folder,
5434 object = modest_mail_operation_get_source (mail_op);
5435 #ifndef MODEST_TOOLKIT_HILDON2
5436 if (MODEST_IS_MAIN_WINDOW (object)) {
5437 GtkWidget *folder_view;
5438 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5439 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5440 g_object_ref (folder_view);
5441 g_object_unref (object);
5442 move_to_cb (mail_op, user_data);
5443 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5444 g_object_unref (folder_view);
5449 move_to_cb (mail_op, user_data);
5454 msgs_move_to_cb (ModestMailOperation *mail_op,
5457 move_to_cb (mail_op, user_data);
5461 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5464 GObject *win = NULL;
5465 const GError *error;
5466 TnyAccount *account = NULL;
5468 #ifndef MODEST_TOOLKIT_HILDON2
5469 ModestWindow *main_window = NULL;
5471 /* Disable next automatic folder selection */
5472 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5473 FALSE); /* don't create */
5475 /* Show notification dialog only if the main window exists */
5477 GtkWidget *folder_view = NULL;
5479 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5480 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5481 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5483 if (user_data && TNY_IS_FOLDER (user_data)) {
5484 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5485 TNY_FOLDER (user_data), FALSE);
5489 win = modest_mail_operation_get_source (mail_op);
5490 error = modest_mail_operation_get_error (mail_op);
5492 if (TNY_IS_FOLDER (user_data))
5493 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5494 else if (TNY_IS_ACCOUNT (user_data))
5495 account = g_object_ref (user_data);
5497 /* If it's not a disk full error then show a generic error */
5498 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5499 (GtkWidget *) win, (GError *) error,
5501 modest_platform_run_information_dialog ((GtkWindow *) win,
5502 _("mail_in_ui_folder_move_target_error"),
5505 g_object_unref (account);
5507 g_object_unref (win);
5510 #ifndef MODEST_TOOLKIT_HILDON2
5512 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5521 gint pending_purges = 0;
5522 gboolean some_purged = FALSE;
5523 ModestWindow *win = MODEST_WINDOW (user_data);
5524 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5526 /* If there was any error */
5527 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5528 modest_window_mgr_unregister_header (mgr, header);
5532 /* Once the message has been retrieved for purging, we check if
5533 * it's all ok for purging */
5535 parts = tny_simple_list_new ();
5536 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5537 iter = tny_list_create_iterator (parts);
5539 while (!tny_iterator_is_done (iter)) {
5541 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5542 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5543 if (tny_mime_part_is_purged (part))
5550 g_object_unref (part);
5552 tny_iterator_next (iter);
5554 g_object_unref (iter);
5557 if (pending_purges>0) {
5559 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5561 if (response == GTK_RESPONSE_OK) {
5564 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5565 iter = tny_list_create_iterator (parts);
5566 while (!tny_iterator_is_done (iter)) {
5569 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5570 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5571 tny_mime_part_set_purged (part);
5574 g_object_unref (part);
5576 tny_iterator_next (iter);
5578 g_object_unref (iter);
5580 tny_msg_rewrite_cache (msg);
5582 gtk_widget_destroy (info);
5586 modest_window_mgr_unregister_header (mgr, header);
5588 g_object_unref (parts);
5592 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5593 ModestMainWindow *win)
5595 GtkWidget *header_view;
5596 TnyList *header_list;
5598 TnyHeaderFlags flags;
5599 ModestWindow *msg_view_window = NULL;
5602 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5604 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5605 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5607 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5609 g_warning ("%s: no header selected", __FUNCTION__);
5613 if (tny_list_get_length (header_list) == 1) {
5614 TnyIterator *iter = tny_list_create_iterator (header_list);
5615 header = TNY_HEADER (tny_iterator_get_current (iter));
5616 g_object_unref (iter);
5620 if (!header || !TNY_IS_HEADER(header)) {
5621 g_warning ("%s: header is not valid", __FUNCTION__);
5625 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5626 header, &msg_view_window);
5627 flags = tny_header_get_flags (header);
5628 if (!(flags & TNY_HEADER_FLAG_CACHED))
5631 if (msg_view_window != NULL)
5632 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5634 /* do nothing; uid was registered before, so window is probably on it's way */
5635 g_debug ("header %p has already been registered", header);
5638 ModestMailOperation *mail_op = NULL;
5639 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5640 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5641 modest_ui_actions_disk_operations_error_handler,
5643 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5644 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5646 g_object_unref (mail_op);
5649 g_object_unref (header);
5651 g_object_unref (header_list);
5656 * Checks if we need a connection to do the transfer and if the user
5657 * wants to connect to complete it
5660 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5661 TnyFolderStore *src_folder,
5663 TnyFolder *dst_folder,
5664 gboolean delete_originals,
5665 gboolean *need_connection,
5668 TnyAccount *src_account;
5669 gint uncached_msgs = 0;
5671 /* We don't need any further check if
5673 * 1- the source folder is local OR
5674 * 2- the device is already online
5676 if (!modest_tny_folder_store_is_remote (src_folder) ||
5677 tny_device_is_online (modest_runtime_get_device())) {
5678 *need_connection = FALSE;
5683 /* We must ask for a connection when
5685 * - the message(s) is not already cached OR
5686 * - the message(s) is cached but the leave_on_server setting
5687 * is FALSE (because we need to sync the source folder to
5688 * delete the message from the server (for IMAP we could do it
5689 * offline, it'll take place the next time we get a
5692 uncached_msgs = header_list_count_uncached_msgs (headers);
5693 src_account = get_account_from_folder_store (src_folder);
5694 if (uncached_msgs > 0) {
5698 *need_connection = TRUE;
5699 num_headers = tny_list_get_length (headers);
5700 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5702 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5703 GTK_RESPONSE_CANCEL) {
5709 /* The transfer is possible and the user wants to */
5712 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5713 const gchar *account_name;
5714 gboolean leave_on_server;
5716 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5717 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5720 if (leave_on_server == TRUE) {
5721 *need_connection = FALSE;
5723 *need_connection = TRUE;
5726 *need_connection = FALSE;
5731 g_object_unref (src_account);
5735 xfer_messages_error_handler (ModestMailOperation *mail_op,
5739 const GError *error;
5740 TnyAccount *account;
5742 win = modest_mail_operation_get_source (mail_op);
5743 error = modest_mail_operation_get_error (mail_op);
5745 /* We cannot get the account from the mail op as that is the
5746 source account and for checking memory full conditions we
5747 need the destination one */
5748 account = TNY_ACCOUNT (user_data);
5751 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5752 (GtkWidget *) win, (GError*) error,
5753 account, _KR("cerm_memory_card_full"))) {
5754 modest_platform_run_information_dialog ((GtkWindow *) win,
5755 _("mail_in_ui_folder_move_target_error"),
5759 g_object_unref (win);
5763 TnyFolderStore *dst_folder;
5768 * Utility function that transfer messages from both the main window
5769 * and the msg view window when using the "Move to" dialog
5772 xfer_messages_performer (gboolean canceled,
5774 GtkWindow *parent_window,
5775 TnyAccount *account,
5778 ModestWindow *win = MODEST_WINDOW (parent_window);
5779 TnyAccount *dst_account = NULL;
5780 gboolean dst_forbids_message_add = FALSE;
5781 XferMsgsHelper *helper;
5782 MoveToHelper *movehelper;
5783 ModestMailOperation *mail_op;
5785 helper = (XferMsgsHelper *) user_data;
5787 if (canceled || err) {
5788 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5789 (GtkWidget *) parent_window, err,
5791 /* Show the proper error message */
5792 modest_ui_actions_on_account_connection_error (parent_window, account);
5797 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5799 /* tinymail will return NULL for local folders it seems */
5800 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5801 modest_tny_account_get_protocol_type (dst_account),
5802 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5804 if (dst_forbids_message_add) {
5805 modest_platform_information_banner (GTK_WIDGET (win),
5807 ngettext("mail_in_ui_folder_move_target_error",
5808 "mail_in_ui_folder_move_targets_error",
5809 tny_list_get_length (helper->headers)));
5813 movehelper = g_new0 (MoveToHelper, 1);
5815 #ifndef MODEST_TOOLKIT_HILDON2
5816 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5817 _CS("ckct_nw_pasting"));
5818 if (movehelper->banner != NULL) {
5819 g_object_ref (movehelper->banner);
5820 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5823 if (MODEST_IS_MAIN_WINDOW (win)) {
5824 GtkWidget *header_view =
5825 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5826 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5827 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5831 /* Perform the mail operation */
5832 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5833 xfer_messages_error_handler,
5834 g_object_ref (dst_account),
5836 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5839 modest_mail_operation_xfer_msgs (mail_op,
5841 TNY_FOLDER (helper->dst_folder),
5846 g_object_unref (G_OBJECT (mail_op));
5849 g_object_unref (dst_account);
5850 g_object_unref (helper->dst_folder);
5851 g_object_unref (helper->headers);
5852 g_slice_free (XferMsgsHelper, helper);
5856 TnyFolder *src_folder;
5857 TnyFolderStore *dst_folder;
5858 gboolean delete_original;
5859 GtkWidget *folder_view;
5863 on_move_folder_cb (gboolean canceled,
5865 GtkWindow *parent_window,
5866 TnyAccount *account,
5869 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5870 GtkTreeSelection *sel;
5871 ModestMailOperation *mail_op = NULL;
5873 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5874 /* Note that the connection process can fail due to
5875 memory low conditions as it can not successfully
5876 store the summary */
5877 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5878 (GtkWidget*) parent_window, err,
5880 g_debug ("Error connecting when trying to move a folder");
5882 g_object_unref (G_OBJECT (info->src_folder));
5883 g_object_unref (G_OBJECT (info->dst_folder));
5888 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5889 #ifndef MODEST_TOOLKIT_HILDON2
5890 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5891 _CS("ckct_nw_pasting"));
5892 if (helper->banner != NULL) {
5893 g_object_ref (helper->banner);
5894 gtk_widget_show (GTK_WIDGET(helper->banner));
5897 /* Clean folder on header view before moving it */
5898 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5899 gtk_tree_selection_unselect_all (sel);
5901 /* Let gtk events run. We need that the folder
5902 view frees its reference to the source
5903 folder *before* issuing the mail operation
5904 so we need the signal handler of selection
5905 changed to happen before the mail
5907 while (gtk_events_pending ())
5908 gtk_main_iteration (); */
5911 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5912 modest_ui_actions_move_folder_error_handler,
5913 g_object_ref (info->dst_folder), g_object_unref);
5914 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5917 #ifndef MODEST_TOOLKIT_HILDON2
5918 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5919 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5920 TNY_FOLDER (info->dst_folder), TRUE);
5923 modest_mail_operation_xfer_folder (mail_op,
5924 TNY_FOLDER (info->src_folder),
5926 info->delete_original,
5929 g_object_unref (G_OBJECT (info->src_folder));
5931 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5934 /* Unref mail operation */
5935 g_object_unref (G_OBJECT (mail_op));
5936 g_object_unref (G_OBJECT (info->dst_folder));
5941 get_account_from_folder_store (TnyFolderStore *folder_store)
5943 if (TNY_IS_ACCOUNT (folder_store))
5944 return g_object_ref (folder_store);
5946 return tny_folder_get_account (TNY_FOLDER (folder_store));
5949 #ifndef MODEST_TOOLKIT_HILDON2
5951 * UI handler for the "Move to" action when invoked from the
5955 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5956 GtkWidget *folder_view,
5957 TnyFolderStore *dst_folder,
5958 ModestMainWindow *win)
5960 ModestHeaderView *header_view = NULL;
5961 TnyFolderStore *src_folder = NULL;
5963 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5965 /* Get the source folder */
5966 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5968 /* Get header view */
5969 header_view = (ModestHeaderView *)
5970 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5972 /* Get folder or messages to transfer */
5973 if (gtk_widget_is_focus (folder_view)) {
5974 gboolean do_xfer = TRUE;
5976 /* Allow only to transfer folders to the local root folder */
5977 if (TNY_IS_ACCOUNT (dst_folder) &&
5978 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5979 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5981 } else if (!TNY_IS_FOLDER (src_folder)) {
5982 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5987 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5988 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5990 info->src_folder = g_object_ref (src_folder);
5991 info->dst_folder = g_object_ref (dst_folder);
5992 info->delete_original = TRUE;
5993 info->folder_view = folder_view;
5995 connect_info->callback = on_move_folder_cb;
5996 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5997 connect_info->data = info;
5999 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6000 TNY_FOLDER_STORE (src_folder),
6003 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6006 headers = modest_header_view_get_selected_headers(header_view);
6008 /* Transfer the messages */
6009 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6010 headers, TNY_FOLDER (dst_folder));
6012 g_object_unref (headers);
6016 g_object_unref (src_folder);
6020 #ifdef MODEST_TOOLKIT_HILDON2
6022 * UI handler for the "Move to" action when invoked from the
6023 * ModestFolderWindow
6026 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6027 TnyFolderStore *dst_folder,
6031 TnyFolderStore *src_folder = NULL;
6032 TnyIterator *iterator;
6034 if (tny_list_get_length (selection) != 1)
6037 iterator = tny_list_create_iterator (selection);
6038 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6039 g_object_unref (iterator);
6042 gboolean do_xfer = TRUE;
6044 /* Allow only to transfer folders to the local root folder */
6045 if (TNY_IS_ACCOUNT (dst_folder) &&
6046 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6047 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6050 modest_platform_run_information_dialog (win,
6051 _("mail_in_ui_folder_move_target_error"),
6053 } else if (!TNY_IS_FOLDER (src_folder)) {
6054 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6059 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6060 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6062 info->src_folder = g_object_ref (src_folder);
6063 info->dst_folder = g_object_ref (dst_folder);
6064 info->delete_original = TRUE;
6065 info->folder_view = folder_view;
6067 connect_info->callback = on_move_folder_cb;
6068 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6069 connect_info->data = info;
6071 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6072 TNY_FOLDER_STORE (src_folder),
6077 g_object_unref (src_folder);
6083 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6084 TnyFolder *src_folder,
6086 TnyFolder *dst_folder)
6088 gboolean need_connection = TRUE;
6089 gboolean do_xfer = TRUE;
6090 XferMsgsHelper *helper;
6092 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6093 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6094 g_return_if_fail (TNY_IS_LIST (headers));
6096 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6097 headers, TNY_FOLDER (dst_folder),
6098 TRUE, &need_connection,
6101 /* If we don't want to transfer just return */
6105 /* Create the helper */
6106 helper = g_slice_new (XferMsgsHelper);
6107 helper->dst_folder = g_object_ref (dst_folder);
6108 helper->headers = g_object_ref (headers);
6110 if (need_connection) {
6111 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6112 connect_info->callback = xfer_messages_performer;
6113 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6114 connect_info->data = helper;
6116 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6117 TNY_FOLDER_STORE (src_folder),
6120 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6121 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6122 src_account, helper);
6123 g_object_unref (src_account);
6128 * UI handler for the "Move to" action when invoked from the
6129 * ModestMsgViewWindow
6132 modest_ui_actions_on_window_move_to (GtkAction *action,
6134 TnyFolderStore *dst_folder,
6137 TnyFolder *src_folder = NULL;
6139 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6142 TnyHeader *header = NULL;
6145 iter = tny_list_create_iterator (headers);
6146 header = (TnyHeader *) tny_iterator_get_current (iter);
6147 src_folder = tny_header_get_folder (header);
6149 /* Transfer the messages */
6150 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6152 TNY_FOLDER (dst_folder));
6155 g_object_unref (header);
6156 g_object_unref (iter);
6157 g_object_unref (src_folder);
6162 modest_ui_actions_on_move_to (GtkAction *action,
6165 modest_ui_actions_on_edit_mode_move_to (win);
6169 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6171 GtkWidget *dialog = NULL;
6172 MoveToInfo *helper = NULL;
6173 TnyList *list_to_move;
6175 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6177 #ifndef MODEST_TOOLKIT_HILDON2
6178 /* Get the main window if exists */
6179 ModestMainWindow *main_window;
6180 if (MODEST_IS_MAIN_WINDOW (win))
6181 main_window = MODEST_MAIN_WINDOW (win);
6184 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6185 FALSE)); /* don't create */
6188 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6193 if (tny_list_get_length (list_to_move) < 1) {
6194 g_object_unref (list_to_move);
6198 /* Create and run the dialog */
6199 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6200 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6201 GTK_WINDOW (dialog),
6205 helper = g_slice_new0 (MoveToInfo);
6206 helper->list = list_to_move;
6209 /* Listen to response signal */
6210 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6212 /* Show the dialog */
6213 gtk_widget_show (dialog);
6219 * Calls #HeadersFunc for each header already selected in the main
6220 * window or the message currently being shown in the msg view window
6223 do_headers_action (ModestWindow *win,
6227 TnyList *headers_list = NULL;
6228 TnyIterator *iter = NULL;
6229 TnyHeader *header = NULL;
6230 TnyFolder *folder = NULL;
6233 headers_list = get_selected_headers (win);
6237 /* Get the folder */
6238 iter = tny_list_create_iterator (headers_list);
6239 header = TNY_HEADER (tny_iterator_get_current (iter));
6241 folder = tny_header_get_folder (header);
6242 g_object_unref (header);
6245 /* Call the function for each header */
6246 while (!tny_iterator_is_done (iter)) {
6247 header = TNY_HEADER (tny_iterator_get_current (iter));
6248 func (header, win, user_data);
6249 g_object_unref (header);
6250 tny_iterator_next (iter);
6253 /* Trick: do a poke status in order to speed up the signaling
6256 tny_folder_poke_status (folder);
6257 g_object_unref (folder);
6261 g_object_unref (iter);
6262 g_object_unref (headers_list);
6266 modest_ui_actions_view_attachment (GtkAction *action,
6267 ModestWindow *window)
6269 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6270 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6272 /* not supported window for this action */
6273 g_return_if_reached ();
6278 modest_ui_actions_save_attachments (GtkAction *action,
6279 ModestWindow *window)
6281 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6283 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6286 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6288 /* not supported window for this action */
6289 g_return_if_reached ();
6294 modest_ui_actions_remove_attachments (GtkAction *action,
6295 ModestWindow *window)
6297 #ifndef MODEST_TOOLKIT_HILDON2
6298 if (MODEST_IS_MAIN_WINDOW (window)) {
6299 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6300 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6302 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6304 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6306 /* not supported window for this action */
6307 g_return_if_reached ();
6312 modest_ui_actions_on_settings (GtkAction *action,
6317 dialog = modest_platform_get_global_settings_dialog ();
6318 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6319 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6320 gtk_widget_show_all (dialog);
6322 gtk_dialog_run (GTK_DIALOG (dialog));
6324 gtk_widget_destroy (dialog);
6328 modest_ui_actions_on_help (GtkAction *action,
6331 /* Help app is not available at all in fremantle */
6332 #ifndef MODEST_TOOLKIT_HILDON2
6333 const gchar *help_id;
6335 g_return_if_fail (win && GTK_IS_WINDOW(win));
6337 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6340 modest_platform_show_help (GTK_WINDOW (win), help_id);
6345 modest_ui_actions_on_csm_help (GtkAction *action,
6348 /* Help app is not available at all in fremantle */
6349 #ifndef MODEST_TOOLKIT_HILDON2
6351 const gchar* help_id = NULL;
6352 GtkWidget *folder_view;
6353 TnyFolderStore *folder_store;
6355 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6357 /* Get selected folder */
6358 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6359 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6360 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6362 /* Switch help_id */
6363 if (folder_store && TNY_IS_FOLDER (folder_store))
6364 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6367 g_object_unref (folder_store);
6370 modest_platform_show_help (GTK_WINDOW (win), help_id);
6372 modest_ui_actions_on_help (action, win);
6377 retrieve_contents_cb (ModestMailOperation *mail_op,
6384 /* We only need this callback to show an error in case of
6385 memory low condition */
6386 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6387 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6392 retrieve_msg_contents_performer (gboolean canceled,
6394 GtkWindow *parent_window,
6395 TnyAccount *account,
6398 ModestMailOperation *mail_op;
6399 TnyList *headers = TNY_LIST (user_data);
6401 if (err || canceled) {
6402 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6403 (GtkWidget *) parent_window, err,
6408 /* Create mail operation */
6409 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6410 modest_ui_actions_disk_operations_error_handler,
6412 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6413 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6416 g_object_unref (mail_op);
6418 g_object_unref (headers);
6419 g_object_unref (account);
6423 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6424 ModestWindow *window)
6426 TnyList *headers = NULL;
6427 TnyAccount *account = NULL;
6428 TnyIterator *iter = NULL;
6429 TnyHeader *header = NULL;
6430 TnyFolder *folder = NULL;
6433 headers = get_selected_headers (window);
6437 /* Pick the account */
6438 iter = tny_list_create_iterator (headers);
6439 header = TNY_HEADER (tny_iterator_get_current (iter));
6440 folder = tny_header_get_folder (header);
6441 account = tny_folder_get_account (folder);
6442 g_object_unref (folder);
6443 g_object_unref (header);
6444 g_object_unref (iter);
6446 /* Connect and perform the message retrieval */
6447 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6448 g_object_ref (account),
6449 retrieve_msg_contents_performer,
6450 g_object_ref (headers));
6453 g_object_unref (account);
6454 g_object_unref (headers);
6458 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6460 g_return_if_fail (MODEST_IS_WINDOW (window));
6463 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6467 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6469 g_return_if_fail (MODEST_IS_WINDOW (window));
6472 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6476 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6477 ModestWindow *window)
6479 g_return_if_fail (MODEST_IS_WINDOW (window));
6482 modest_ui_actions_check_menu_dimming_rules (window);
6486 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6487 ModestWindow *window)
6489 g_return_if_fail (MODEST_IS_WINDOW (window));
6492 modest_ui_actions_check_menu_dimming_rules (window);
6496 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6497 ModestWindow *window)
6499 g_return_if_fail (MODEST_IS_WINDOW (window));
6502 modest_ui_actions_check_menu_dimming_rules (window);
6506 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6507 ModestWindow *window)
6509 g_return_if_fail (MODEST_IS_WINDOW (window));
6512 modest_ui_actions_check_menu_dimming_rules (window);
6516 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6517 ModestWindow *window)
6519 g_return_if_fail (MODEST_IS_WINDOW (window));
6522 modest_ui_actions_check_menu_dimming_rules (window);
6526 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6527 ModestWindow *window)
6529 g_return_if_fail (MODEST_IS_WINDOW (window));
6532 modest_ui_actions_check_menu_dimming_rules (window);
6536 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6537 ModestWindow *window)
6539 g_return_if_fail (MODEST_IS_WINDOW (window));
6542 modest_ui_actions_check_menu_dimming_rules (window);
6546 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6547 ModestWindow *window)
6549 g_return_if_fail (MODEST_IS_WINDOW (window));
6552 modest_ui_actions_check_menu_dimming_rules (window);
6556 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6557 ModestWindow *window)
6559 g_return_if_fail (MODEST_IS_WINDOW (window));
6562 modest_ui_actions_check_menu_dimming_rules (window);
6566 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6568 g_return_if_fail (MODEST_IS_WINDOW (window));
6570 /* we check for low-mem; in that case, show a warning, and don't allow
6573 if (modest_platform_check_memory_low (window, TRUE))
6576 modest_platform_show_search_messages (GTK_WINDOW (window));
6580 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6582 g_return_if_fail (MODEST_IS_WINDOW (win));
6585 /* we check for low-mem; in that case, show a warning, and don't allow
6586 * for the addressbook
6588 if (modest_platform_check_memory_low (win, TRUE))
6592 modest_platform_show_addressbook (GTK_WINDOW (win));
6597 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6598 ModestWindow *window)
6601 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6603 if (GTK_IS_TOGGLE_ACTION (action))
6604 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6608 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6612 #ifndef MODEST_TOOLKIT_HILDON2
6614 on_send_receive_finished (ModestMailOperation *mail_op,
6617 GtkWidget *header_view, *folder_view;
6618 TnyFolderStore *folder_store;
6619 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6621 /* Set send/receive operation finished */
6622 modest_main_window_notify_send_receive_completed (main_win);
6624 /* Don't refresh the current folder if there were any errors */
6625 if (modest_mail_operation_get_status (mail_op) !=
6626 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6629 /* Refresh the current folder if we're viewing a window. We do
6630 this because the user won't be able to see the new mails in
6631 the selected folder after a Send&Receive because it only
6632 performs a poke_status, i.e, only the number of read/unread
6633 messages is updated, but the new headers are not
6635 folder_view = modest_main_window_get_child_widget (main_win,
6636 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6640 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6642 /* Do not need to refresh INBOX again because the
6643 update_account does it always automatically */
6644 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6645 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6646 ModestMailOperation *refresh_op;
6648 header_view = modest_main_window_get_child_widget (main_win,
6649 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6651 /* We do not need to set the contents style
6652 because it hasn't changed. We also do not
6653 need to save the widget status. Just force
6655 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6656 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6657 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6658 folder_refreshed_cb, main_win);
6659 g_object_unref (refresh_op);
6663 g_object_unref (folder_store);
6668 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6674 const gchar* server_name = NULL;
6675 TnyTransportAccount *transport;
6676 gchar *message = NULL;
6677 ModestProtocol *protocol;
6679 /* Don't show anything if the user cancelled something or the
6680 * send receive request is not interactive. Authentication
6681 * errors are managed by the account store so no need to show
6682 * a dialog here again */
6683 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6684 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6685 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6689 /* Get the server name. Note that we could be using a
6690 connection specific transport account */
6691 transport = (TnyTransportAccount *)
6692 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6694 ModestTnyAccountStore *acc_store;
6695 const gchar *acc_name;
6696 TnyTransportAccount *conn_specific;
6698 acc_store = modest_runtime_get_account_store();
6699 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6700 conn_specific = (TnyTransportAccount *)
6701 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6702 if (conn_specific) {
6703 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6704 g_object_unref (conn_specific);
6706 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6708 g_object_unref (transport);
6712 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6713 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6714 tny_account_get_proto (TNY_ACCOUNT (transport)));
6716 g_warning ("%s: Account with no proto", __FUNCTION__);
6720 /* Show the appropriate message text for the GError: */
6721 switch (err->code) {
6722 case TNY_SERVICE_ERROR_CONNECT:
6723 message = modest_protocol_get_translation (protocol,
6724 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6727 case TNY_SERVICE_ERROR_SEND:
6728 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6730 case TNY_SERVICE_ERROR_UNAVAILABLE:
6731 message = modest_protocol_get_translation (protocol,
6732 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6736 g_warning ("%s: unexpected ERROR %d",
6737 __FUNCTION__, err->code);
6738 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6742 modest_platform_run_information_dialog (NULL, message, FALSE);
6747 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6752 ModestWindow *top_window = NULL;
6753 ModestWindowMgr *mgr = NULL;
6754 GtkWidget *header_view = NULL;
6755 TnyFolder *selected_folder = NULL;
6756 TnyFolderType folder_type;
6758 mgr = modest_runtime_get_window_mgr ();
6759 top_window = modest_window_mgr_get_current_top (mgr);
6764 #ifndef MODEST_TOOLKIT_HILDON2
6765 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6766 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6767 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6770 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6771 header_view = (GtkWidget *)
6772 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6776 /* Get selected folder */
6778 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6779 if (!selected_folder)
6782 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6783 #if GTK_CHECK_VERSION(2, 8, 0)
6784 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6785 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6786 GtkTreeViewColumn *tree_column;
6788 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6789 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6791 gtk_tree_view_column_queue_resize (tree_column);
6793 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6794 gtk_widget_queue_draw (header_view);
6797 #ifndef MODEST_TOOLKIT_HILDON2
6798 /* Rerun dimming rules, because the message could become deletable for example */
6799 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6800 MODEST_DIMMING_RULES_TOOLBAR);
6801 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6802 MODEST_DIMMING_RULES_MENU);
6806 g_object_unref (selected_folder);
6810 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6811 TnyAccount *account)
6813 ModestProtocolType protocol_type;
6814 ModestProtocol *protocol;
6815 gchar *error_note = NULL;
6817 protocol_type = modest_tny_account_get_protocol_type (account);
6818 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6821 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6822 if (error_note == NULL) {
6823 g_warning ("%s: This should not be reached", __FUNCTION__);
6825 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6826 g_free (error_note);
6831 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6835 TnyFolderStore *folder = NULL;
6836 TnyAccount *account = NULL;
6837 ModestProtocolType proto;
6838 ModestProtocol *protocol;
6839 TnyHeader *header = NULL;
6841 #ifndef MODEST_TOOLKIT_HILDON2
6842 if (MODEST_IS_MAIN_WINDOW (win)) {
6843 GtkWidget *header_view;
6844 TnyList* headers = NULL;
6846 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6847 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6848 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6849 if (!headers || tny_list_get_length (headers) == 0) {
6851 g_object_unref (headers);
6854 iter = tny_list_create_iterator (headers);
6855 header = TNY_HEADER (tny_iterator_get_current (iter));
6856 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6857 g_object_unref (iter);
6858 g_object_unref (headers);
6860 if (MODEST_IS_HEADER_WINDOW (win)) {
6861 GtkWidget *header_view;
6862 TnyList* headers = NULL;
6864 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6865 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6866 if (!headers || tny_list_get_length (headers) == 0) {
6868 g_object_unref (headers);
6871 iter = tny_list_create_iterator (headers);
6872 header = TNY_HEADER (tny_iterator_get_current (iter));
6874 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6876 g_warning ("List should contain headers");
6878 g_object_unref (iter);
6879 g_object_unref (headers);
6881 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6882 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6884 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6887 if (!header || !folder)
6890 /* Get the account type */
6891 account = tny_folder_get_account (TNY_FOLDER (folder));
6892 proto = modest_tny_account_get_protocol_type (account);
6893 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6896 subject = tny_header_dup_subject (header);
6897 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6901 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6907 g_object_unref (account);
6909 g_object_unref (folder);
6911 g_object_unref (header);
6917 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6918 const gchar *account_name,
6919 const gchar *account_title)
6921 ModestAccountMgr *account_mgr;
6924 ModestProtocol *protocol;
6925 gboolean removed = FALSE;
6927 g_return_val_if_fail (account_name, FALSE);
6928 g_return_val_if_fail (account_title, FALSE);
6930 account_mgr = modest_runtime_get_account_mgr();
6932 /* The warning text depends on the account type: */
6933 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6934 modest_account_mgr_get_store_protocol (account_mgr,
6936 txt = modest_protocol_get_translation (protocol,
6937 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6940 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6942 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6946 if (response == GTK_RESPONSE_OK) {
6947 /* Remove account. If it succeeds then it also removes
6948 the account from the ModestAccountView: */
6949 gboolean is_default = FALSE;
6950 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6951 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6953 g_free (default_account_name);
6955 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6957 /* Close all email notifications, we cannot
6958 distinguish if the notification belongs to
6959 this account or not, so for safety reasons
6960 we remove them all */
6961 modest_platform_remove_new_mail_notifications (FALSE);
6963 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6970 on_fetch_images_performer (gboolean canceled,
6972 GtkWindow *parent_window,
6973 TnyAccount *account,
6976 if (err || canceled) {
6977 /* Show an unable to retrieve images ??? */
6981 /* Note that the user could have closed the window while connecting */
6982 if (GTK_WIDGET_VISIBLE (parent_window))
6983 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6984 g_object_unref ((GObject *) user_data);
6988 modest_ui_actions_on_fetch_images (GtkAction *action,
6989 ModestWindow *window)
6991 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6993 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6995 on_fetch_images_performer,
6996 g_object_ref (window));
7000 modest_ui_actions_on_reload_message (const gchar *msg_id)
7002 ModestWindow *window = NULL;
7004 g_return_if_fail (msg_id && msg_id[0] != '\0');
7005 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7011 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7014 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7017 /** Check whether any connections are active, and cancel them if
7019 * Returns TRUE is there was no problem,
7020 * or if an operation was cancelled so we can continue.
7021 * Returns FALSE if the user chose to cancel his request instead.
7025 modest_ui_actions_check_for_active_account (ModestWindow *self,
7026 const gchar* account_name)
7028 ModestTnySendQueue *send_queue;
7029 ModestTnyAccountStore *acc_store;
7030 ModestMailOperationQueue* queue;
7031 TnyConnectionStatus store_conn_status;
7032 TnyAccount *store_account = NULL, *transport_account = NULL;
7033 gboolean retval = TRUE, sending = FALSE;
7035 acc_store = modest_runtime_get_account_store ();
7036 queue = modest_runtime_get_mail_operation_queue ();
7039 modest_tny_account_store_get_server_account (acc_store,
7041 TNY_ACCOUNT_TYPE_STORE);
7043 /* This could happen if the account was deleted before the
7044 call to this function */
7049 modest_tny_account_store_get_server_account (acc_store,
7051 TNY_ACCOUNT_TYPE_TRANSPORT);
7053 /* This could happen if the account was deleted before the
7054 call to this function */
7055 if (!transport_account) {
7056 g_object_unref (store_account);
7060 /* If the transport account was not used yet, then the send
7061 queue could not exist (it's created on demand) */
7062 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7063 if (TNY_IS_SEND_QUEUE (send_queue))
7064 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7066 store_conn_status = tny_account_get_connection_status (store_account);
7067 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7070 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7071 _("emev_nc_disconnect_account"));
7072 if (response == GTK_RESPONSE_OK) {
7081 /* FIXME: We should only cancel those of this account */
7082 modest_mail_operation_queue_cancel_all (queue);
7084 /* Also disconnect the account */
7085 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7086 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7087 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7091 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7097 g_object_unref (store_account);
7098 g_object_unref (transport_account);