1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #ifdef MODEST_PLATFORM_MAEMO
63 #include "maemo/modest-osso-state-saving.h"
64 #endif /* MODEST_PLATFORM_MAEMO */
65 #ifndef MODEST_TOOLKIT_GTK
66 #include "maemo/modest-hildon-includes.h"
67 #include "maemo/modest-connection-specific-smtp-window.h"
68 #endif /* !MODEST_TOOLKIT_GTK */
70 #include <modest-utils.h>
71 #include "widgets/modest-ui-constants.h"
72 #include <widgets/modest-main-window.h>
73 #include <widgets/modest-msg-view-window.h>
74 #include <widgets/modest-account-view-window.h>
75 #include <widgets/modest-details-dialog.h>
76 #include <widgets/modest-attachments-view.h>
77 #include "widgets/modest-folder-view.h"
78 #include "widgets/modest-global-settings-dialog.h"
79 #include "modest-account-mgr-helpers.h"
80 #include "modest-mail-operation.h"
81 #include "modest-text-utils.h"
82 #include <modest-widget-memory.h>
83 #include <tny-error.h>
84 #include <tny-simple-list.h>
85 #include <tny-msg-view.h>
86 #include <tny-device.h>
87 #include <tny-merge-folder.h>
88 #include <tny-camel-bs-msg.h>
89 #include <tny-camel-bs-mime-part.h>
92 #include <gtkhtml/gtkhtml.h>
94 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
96 typedef struct _GetMsgAsyncHelper {
98 ModestMailOperation *mail_op;
105 typedef enum _ReplyForwardAction {
109 } ReplyForwardAction;
111 typedef struct _ReplyForwardHelper {
112 guint reply_forward_type;
113 ReplyForwardAction action;
116 GtkWidget *parent_window;
118 TnyHeader *top_header;
121 } ReplyForwardHelper;
123 typedef struct _MoveToHelper {
124 GtkTreeRowReference *reference;
128 typedef struct _PasteAsAttachmentHelper {
129 ModestMsgEditWindow *window;
131 } PasteAsAttachmentHelper;
139 * The do_headers_action uses this kind of functions to perform some
140 * action to each member of a list of headers
142 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
144 static void do_headers_action (ModestWindow *win,
148 static void open_msg_cb (ModestMailOperation *mail_op,
155 static void reply_forward_cb (ModestMailOperation *mail_op,
162 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
164 static void folder_refreshed_cb (ModestMailOperation *mail_op,
168 static void on_send_receive_finished (ModestMailOperation *mail_op,
171 static gint header_list_count_uncached_msgs (TnyList *header_list);
173 static gboolean connect_to_get_msg (ModestWindow *win,
174 gint num_of_uncached_msgs,
175 TnyAccount *account);
177 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
179 static void do_create_folder (GtkWindow *window,
180 TnyFolderStore *parent_folder,
181 const gchar *suggested_name);
183 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
185 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
186 GtkWidget *folder_view,
187 TnyFolderStore *dst_folder,
188 ModestMainWindow *win);
189 #ifdef MODEST_TOOLKIT_HILDON2
190 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
191 TnyFolderStore *dst_folder,
196 static void modest_ui_actions_on_window_move_to (GtkAction *action,
197 TnyList *list_to_move,
198 TnyFolderStore *dst_folder,
202 * This function checks whether a TnyFolderStore is a pop account
205 remote_folder_has_leave_on_server (TnyFolderStore *folder)
210 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
212 account = get_account_from_folder_store (folder);
213 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
214 modest_tny_account_get_protocol_type (account)));
215 g_object_unref (account);
220 /* FIXME: this should be merged with the similar code in modest-account-view-window */
221 /* Show the account creation wizard dialog.
222 * returns: TRUE if an account was created. FALSE if the user cancelled.
225 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
227 gboolean result = FALSE;
229 gint dialog_response;
231 /* there is no such wizard yet */
232 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
233 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
235 #ifndef MODEST_TOOLKIT_HILDON2
236 /* always present a main window in the background
237 * we do it here, so we cannot end up with two wizards (as this
238 * function might be called in modest_window_mgr_get_main_window as well */
240 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
241 TRUE); /* create if not existent */
245 ModestWindowMgr *mgr;
247 mgr = modest_runtime_get_window_mgr ();
249 window_list = modest_window_mgr_get_window_list (mgr);
250 if (window_list == NULL) {
251 win = MODEST_WINDOW (modest_accounts_window_new ());
252 if (modest_window_mgr_register_window (mgr, win, NULL)) {
253 gtk_widget_show_all (GTK_WIDGET (win));
255 gtk_widget_destroy (GTK_WIDGET (win));
260 g_list_free (window_list);
266 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
268 /* make sure the mainwindow is visible. We need to present the
269 wizard again to give it the focus back. show_all are needed
270 in order to get the widgets properly drawn (MainWindow main
271 paned won't be in its right position and the dialog will be
273 #ifndef MODEST_TOOLKIT_HILDON2
274 gtk_widget_show_all (GTK_WIDGET (win));
275 gtk_widget_show_all (GTK_WIDGET (wizard));
276 gtk_window_present (GTK_WINDOW (win));
277 gtk_window_present (GTK_WINDOW (wizard));
280 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
281 gtk_widget_destroy (GTK_WIDGET (wizard));
282 if (gtk_events_pending ())
283 gtk_main_iteration ();
285 if (dialog_response == GTK_RESPONSE_CANCEL) {
288 /* Check whether an account was created: */
289 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
296 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
299 const gchar *authors[] = {
300 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
303 about = gtk_about_dialog_new ();
304 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
305 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
306 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
307 _("Copyright (c) 2006, Nokia Corporation\n"
308 "All rights reserved."));
309 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
310 _("a modest e-mail client\n\n"
311 "design and implementation: Dirk-Jan C. Binnema\n"
312 "contributions from the fine people at KC and Ig\n"
313 "uses the tinymail email framework written by Philip van Hoof"));
314 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
315 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
316 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
317 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
319 gtk_dialog_run (GTK_DIALOG (about));
320 gtk_widget_destroy(about);
324 * Gets the list of currently selected messages. If the win is the
325 * main window, then it returns a newly allocated list of the headers
326 * selected in the header view. If win is the msg view window, then
327 * the value returned is a list with just a single header.
329 * The caller of this funcion must free the list.
332 get_selected_headers (ModestWindow *win)
334 if (MODEST_IS_MAIN_WINDOW(win)) {
335 GtkWidget *header_view;
337 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
338 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
339 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
341 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
342 /* for MsgViewWindows, we simply return a list with one element */
344 TnyList *list = NULL;
346 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
347 if (header != NULL) {
348 list = tny_simple_list_new ();
349 tny_list_prepend (list, G_OBJECT(header));
350 g_object_unref (G_OBJECT(header));
355 #ifdef MODEST_TOOLKIT_HILDON2
356 } else if (MODEST_IS_HEADER_WINDOW (win)) {
357 GtkWidget *header_view;
359 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
360 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
366 static GtkTreeRowReference *
367 get_next_after_selected_headers (ModestHeaderView *header_view)
369 GtkTreeSelection *sel;
370 GList *selected_rows, *node;
372 GtkTreeRowReference *result;
375 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
376 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
377 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
379 if (selected_rows == NULL)
382 node = g_list_last (selected_rows);
383 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
384 gtk_tree_path_next (path);
386 result = gtk_tree_row_reference_new (model, path);
388 gtk_tree_path_free (path);
389 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
390 g_list_free (selected_rows);
396 headers_action_mark_as_read (TnyHeader *header,
400 TnyHeaderFlags flags;
402 g_return_if_fail (TNY_IS_HEADER(header));
404 flags = tny_header_get_flags (header);
405 if (flags & TNY_HEADER_FLAG_SEEN) return;
406 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
410 headers_action_mark_as_unread (TnyHeader *header,
414 TnyHeaderFlags flags;
416 g_return_if_fail (TNY_IS_HEADER(header));
418 flags = tny_header_get_flags (header);
419 if (flags & TNY_HEADER_FLAG_SEEN) {
420 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
424 /** After deleing a message that is currently visible in a window,
425 * show the next message from the list, or close the window if there are no more messages.
428 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
430 /* Close msg view window or select next */
431 if (!modest_msg_view_window_select_next_message (win) &&
432 !modest_msg_view_window_select_previous_message (win)) {
434 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
440 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
442 modest_ui_actions_on_edit_mode_delete_message (win);
446 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
448 TnyList *header_list = NULL;
449 TnyIterator *iter = NULL;
450 TnyHeader *header = NULL;
451 gchar *message = NULL;
454 ModestWindowMgr *mgr;
455 GtkWidget *header_view = NULL;
456 gboolean retval = TRUE;
458 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
460 /* Check first if the header view has the focus */
461 if (MODEST_IS_MAIN_WINDOW (win)) {
463 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
464 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
465 if (!gtk_widget_is_focus (header_view))
469 /* Get the headers, either from the header view (if win is the main window),
470 * or from the message view window: */
471 header_list = get_selected_headers (win);
472 if (!header_list) return FALSE;
474 /* Check if any of the headers are already opened, or in the process of being opened */
475 if (MODEST_IS_MAIN_WINDOW (win)) {
476 gint opened_headers = 0;
478 iter = tny_list_create_iterator (header_list);
479 mgr = modest_runtime_get_window_mgr ();
480 while (!tny_iterator_is_done (iter)) {
481 header = TNY_HEADER (tny_iterator_get_current (iter));
483 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
485 g_object_unref (header);
487 tny_iterator_next (iter);
489 g_object_unref (iter);
491 if (opened_headers > 0) {
494 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
497 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
500 g_object_unref (header_list);
506 if (tny_list_get_length(header_list) == 1) {
507 iter = tny_list_create_iterator (header_list);
508 header = TNY_HEADER (tny_iterator_get_current (iter));
511 subject = tny_header_dup_subject (header);
513 subject = g_strdup (_("mail_va_no_subject"));
514 desc = g_strdup_printf ("%s", subject);
516 g_object_unref (header);
519 g_object_unref (iter);
521 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
522 tny_list_get_length(header_list)), desc);
524 /* Confirmation dialog */
525 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
529 if (response == GTK_RESPONSE_OK) {
530 ModestWindowMgr *mgr = NULL;
531 GtkTreeModel *model = NULL;
532 GtkTreeSelection *sel = NULL;
533 GList *sel_list = NULL, *tmp = NULL;
534 GtkTreeRowReference *next_row_reference = NULL;
535 GtkTreeRowReference *prev_row_reference = NULL;
536 GtkTreePath *next_path = NULL;
537 GtkTreePath *prev_path = NULL;
538 ModestMailOperation *mail_op = NULL;
540 /* Find last selected row */
541 if (MODEST_IS_MAIN_WINDOW (win)) {
542 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
543 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
544 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
545 for (tmp=sel_list; tmp; tmp=tmp->next) {
546 if (tmp->next == NULL) {
547 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
548 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
550 gtk_tree_path_prev (prev_path);
551 gtk_tree_path_next (next_path);
553 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
554 next_row_reference = gtk_tree_row_reference_new (model, next_path);
559 /* Disable window dimming management */
560 modest_window_disable_dimming (win);
562 /* Remove each header. If it's a view window header_view == NULL */
563 mail_op = modest_mail_operation_new ((GObject *) win);
564 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
566 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
567 g_object_unref (mail_op);
569 /* Enable window dimming management */
571 gtk_tree_selection_unselect_all (sel);
573 modest_window_enable_dimming (win);
575 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
576 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
578 /* Get main window */
579 mgr = modest_runtime_get_window_mgr ();
580 } else if (MODEST_IS_MAIN_WINDOW (win)) {
581 /* Select next or previous row */
582 if (gtk_tree_row_reference_valid (next_row_reference)) {
583 gtk_tree_selection_select_path (sel, next_path);
585 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
586 gtk_tree_selection_select_path (sel, prev_path);
590 if (gtk_tree_row_reference_valid (next_row_reference))
591 gtk_tree_row_reference_free (next_row_reference);
592 if (next_path != NULL)
593 gtk_tree_path_free (next_path);
594 if (gtk_tree_row_reference_valid (prev_row_reference))
595 gtk_tree_row_reference_free (prev_row_reference);
596 if (prev_path != NULL)
597 gtk_tree_path_free (prev_path);
600 /* Update toolbar dimming state */
601 modest_ui_actions_check_menu_dimming_rules (win);
602 modest_ui_actions_check_toolbar_dimming_rules (win);
605 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
606 g_list_free (sel_list);
615 g_object_unref (header_list);
623 /* delete either message or folder, based on where we are */
625 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
627 g_return_if_fail (MODEST_IS_WINDOW(win));
629 /* Check first if the header view has the focus */
630 if (MODEST_IS_MAIN_WINDOW (win)) {
632 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
633 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
634 if (gtk_widget_is_focus (w)) {
635 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, *recipient = NULL, *tmp = NULL;
831 gboolean use_signature = FALSE;
832 ModestWindow *msg_win = NULL;
833 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
834 ModestTnyAccountStore *store = modest_runtime_get_account_store();
835 GnomeVFSFileSize total_size, allowed_size;
836 guint64 available_disk, expected_size, parts_size;
839 /* we check for low-mem */
840 if (modest_platform_check_memory_low (win, TRUE))
843 available_disk = modest_utils_get_available_space (NULL);
844 parts_count = g_slist_length (attachments);
845 parts_size = count_parts_size (attachments);
846 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
848 /* Double check: disk full condition or message too big */
849 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
850 expected_size > available_disk) {
851 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
852 modest_platform_system_banner (NULL, NULL, msg);
858 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
859 modest_platform_run_information_dialog (
861 _("mail_ib_error_attachment_size"),
867 #ifdef MODEST_TOOLKIT_HILDON2
869 account_name = g_strdup (modest_window_get_active_account(win));
872 account_name = modest_account_mgr_get_default_account(mgr);
875 g_printerr ("modest: no account found\n");
880 mailbox = modest_window_get_active_mailbox (win);
883 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
885 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
888 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
890 g_printerr ("modest: failed to find Drafts folder\n");
893 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
895 g_printerr ("modest: failed get from string for '%s'\n", account_name);
900 recipient = modest_text_utils_get_email_address (from_str);
901 tmp = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
904 signature = modest_text_utils_create_colored_signature (tmp);
908 body = use_signature ? g_strconcat ((body_str) ? body_str : "", signature, NULL) :
911 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
912 NULL, NULL, body, NULL, NULL, NULL, NULL, NULL);
914 g_printerr ("modest: failed to create new msg\n");
918 /* Create and register edit window */
919 /* This is destroyed by TODO. */
921 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
922 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
924 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
925 gtk_widget_destroy (GTK_WIDGET (msg_win));
928 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
929 gtk_widget_show_all (GTK_WIDGET (msg_win));
931 while (attachments) {
932 GnomeVFSFileSize att_size;
934 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
935 attachments->data, allowed_size);
936 total_size += att_size;
938 if (att_size > allowed_size) {
939 g_debug ("%s: total size: %u",
940 __FUNCTION__, (unsigned int)total_size);
943 allowed_size -= att_size;
945 attachments = g_slist_next(attachments);
952 g_free (account_name);
954 g_object_unref (G_OBJECT(account));
956 g_object_unref (G_OBJECT(folder));
958 g_object_unref (G_OBJECT(msg));
962 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
964 /* if there are no accounts yet, just show the wizard */
965 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
966 if (!modest_ui_actions_run_account_setup_wizard (win))
969 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
974 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
978 ModestMailOperationStatus status;
980 /* If there is no message or the operation was not successful */
981 status = modest_mail_operation_get_status (mail_op);
982 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
985 /* If it's a memory low issue, then show a banner */
986 error = modest_mail_operation_get_error (mail_op);
987 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
988 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
989 GObject *source = modest_mail_operation_get_source (mail_op);
990 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
991 _KR("memr_ib_operation_disabled"),
993 g_object_unref (source);
996 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
997 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
998 gchar *subject, *msg, *format = NULL;
1001 subject = (header) ? tny_header_dup_subject (header) : NULL;
1003 subject = g_strdup (_("mail_va_no_subject"));
1005 account = modest_mail_operation_get_account (mail_op);
1007 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1008 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1011 if (tny_account_get_connection_status (account) ==
1012 TNY_CONNECTION_STATUS_CONNECTED) {
1014 format = modest_protocol_get_translation (protocol,
1015 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1018 format = modest_protocol_get_translation (protocol,
1019 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1022 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1023 tny_account_get_hostname (account));
1026 g_object_unref (account);
1031 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1033 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1037 msg = g_strdup_printf (format, subject);
1038 modest_platform_run_information_dialog (NULL, msg, FALSE);
1044 /* Remove the header from the preregistered uids */
1045 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1058 } OpenMsgBannerInfo;
1061 GtkTreeModel *model;
1063 ModestWindow *caller_window;
1064 OpenMsgBannerInfo *banner_info;
1065 GtkTreeRowReference *rowref;
1069 open_msg_banner_idle (gpointer userdata)
1071 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1073 gdk_threads_enter ();
1074 banner_info->idle_handler = 0;
1075 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1076 if (banner_info->banner)
1077 g_object_ref (banner_info->banner);
1079 gdk_threads_leave ();
1085 get_header_view_from_window (ModestWindow *window)
1087 GtkWidget *header_view;
1089 if (MODEST_IS_MAIN_WINDOW (window)) {
1090 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1091 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1092 #ifdef MODEST_TOOLKIT_HILDON2
1093 } else if (MODEST_IS_HEADER_WINDOW (window)){
1094 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1104 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1107 gchar *account = NULL;
1108 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1113 folder = tny_header_get_folder (header);
1114 /* Gets folder type (OUTBOX headers will be opened in edit window */
1115 if (modest_tny_folder_is_local_folder (folder)) {
1116 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1117 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1118 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1121 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1122 TnyTransportAccount *traccount = NULL;
1123 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1124 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1126 ModestTnySendQueue *send_queue = NULL;
1127 ModestTnySendQueueStatus status;
1129 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1130 TNY_ACCOUNT(traccount)));
1131 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1132 if (TNY_IS_SEND_QUEUE (send_queue)) {
1133 msg_id = modest_tny_send_queue_get_msg_id (header);
1134 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1136 /* Only open messages in outbox with the editor if they are in Failed state */
1137 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1140 #ifdef MODEST_TOOLKIT_HILDON2
1142 /* In Fremantle we can not
1143 open any message from
1144 outbox which is not in
1150 g_object_unref(traccount);
1152 g_warning("Cannot get transport account for message in outbox!!");
1154 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1155 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1159 TnyAccount *acc = tny_folder_get_account (folder);
1162 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1163 g_object_unref (acc);
1167 g_object_unref (folder);
1173 open_msg_cb (ModestMailOperation *mail_op,
1180 ModestWindowMgr *mgr = NULL;
1181 ModestWindow *parent_win = NULL;
1182 ModestWindow *win = NULL;
1183 gchar *account = NULL;
1184 gboolean open_in_editor = FALSE;
1186 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1188 /* Do nothing if there was any problem with the mail
1189 operation. The error will be shown by the error_handler of
1190 the mail operation */
1191 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1194 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1196 /* Mark header as read */
1197 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1199 account = get_info_from_header (header, &open_in_editor, &can_open);
1203 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1205 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1207 if (open_in_editor) {
1208 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1209 gchar *from_header = NULL, *acc_name;
1210 gchar *mailbox = NULL;
1212 from_header = tny_header_dup_from (header);
1214 /* we cannot edit without a valid account... */
1215 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1216 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1217 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1219 g_free (from_header);
1224 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1225 g_free (from_header);
1231 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1235 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1236 const gchar *mailbox = NULL;
1238 if (parent_win && MODEST_IS_WINDOW (parent_win))
1239 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1241 if (helper->rowref && helper->model) {
1242 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1243 helper->model, helper->rowref);
1245 win = modest_msg_view_window_new_for_attachment (msg, NULL, account, mailbox, (const gchar*) uid);
1250 /* Register and show new window */
1252 mgr = modest_runtime_get_window_mgr ();
1253 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1254 gtk_widget_destroy (GTK_WIDGET (win));
1257 gtk_widget_show_all (GTK_WIDGET(win));
1260 /* Update toolbar dimming state */
1261 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1262 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1268 g_object_unref (parent_win);
1272 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1275 const GError *error;
1276 GObject *win = NULL;
1277 ModestMailOperationStatus status;
1279 win = modest_mail_operation_get_source (mail_op);
1280 error = modest_mail_operation_get_error (mail_op);
1281 status = modest_mail_operation_get_status (mail_op);
1283 /* If the mail op has been cancelled then it's not an error:
1284 don't show any message */
1285 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1286 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1287 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1288 (GError *) error, account)) {
1289 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1290 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1292 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1293 modest_platform_information_banner ((GtkWidget *) win,
1294 NULL, _("emev_ui_imap_inbox_select_error"));
1295 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1296 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1297 modest_platform_information_banner ((GtkWidget *) win,
1298 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1299 } else if (user_data) {
1300 modest_platform_information_banner ((GtkWidget *) win,
1304 g_object_unref (account);
1308 g_object_unref (win);
1312 * Returns the account a list of headers belongs to. It returns a
1313 * *new* reference so don't forget to unref it
1316 get_account_from_header_list (TnyList *headers)
1318 TnyAccount *account = NULL;
1320 if (tny_list_get_length (headers) > 0) {
1321 TnyIterator *iter = tny_list_create_iterator (headers);
1322 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1323 TnyFolder *folder = tny_header_get_folder (header);
1326 g_object_unref (header);
1328 while (!tny_iterator_is_done (iter)) {
1329 header = TNY_HEADER (tny_iterator_get_current (iter));
1330 folder = tny_header_get_folder (header);
1333 g_object_unref (header);
1335 tny_iterator_next (iter);
1340 account = tny_folder_get_account (folder);
1341 g_object_unref (folder);
1345 g_object_unref (header);
1347 g_object_unref (iter);
1353 get_account_from_header (TnyHeader *header)
1355 TnyAccount *account = NULL;
1358 folder = tny_header_get_folder (header);
1361 account = tny_folder_get_account (folder);
1362 g_object_unref (folder);
1368 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1370 if (helper->caller_window)
1371 helper->caller_window = NULL;
1375 open_msg_helper_destroyer (gpointer user_data)
1377 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1379 if (helper->caller_window) {
1380 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1381 helper->caller_window = NULL;
1384 if (helper->banner_info) {
1385 g_free (helper->banner_info->message);
1386 if (helper->banner_info->idle_handler > 0) {
1387 g_source_remove (helper->banner_info->idle_handler);
1388 helper->banner_info->idle_handler = 0;
1390 if (helper->banner_info->banner != NULL) {
1391 gtk_widget_destroy (helper->banner_info->banner);
1392 g_object_unref (helper->banner_info->banner);
1393 helper->banner_info->banner = NULL;
1395 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1396 helper->banner_info = NULL;
1398 g_object_unref (helper->model);
1399 g_object_unref (helper->header);
1400 gtk_tree_row_reference_free (helper->rowref);
1401 g_slice_free (OpenMsgHelper, helper);
1405 open_msg_performer(gboolean canceled,
1407 GtkWindow *parent_window,
1408 TnyAccount *account,
1411 ModestMailOperation *mail_op = NULL;
1412 gchar *error_msg = NULL;
1413 ModestProtocolType proto;
1414 TnyConnectionStatus status;
1415 OpenMsgHelper *helper = NULL;
1416 ModestProtocol *protocol;
1417 ModestProtocolRegistry *protocol_registry;
1420 helper = (OpenMsgHelper *) user_data;
1422 status = tny_account_get_connection_status (account);
1423 if (err || canceled || helper->caller_window == NULL) {
1424 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1425 /* Free the helper */
1426 open_msg_helper_destroyer (helper);
1428 /* In disk full conditions we could get this error here */
1429 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1430 (GtkWidget *) parent_window, err,
1436 /* Get the error message depending on the protocol */
1437 proto = modest_tny_account_get_protocol_type (account);
1438 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1439 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1442 protocol_registry = modest_runtime_get_protocol_registry ();
1443 subject = tny_header_dup_subject (helper->header);
1445 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1446 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1450 if (error_msg == NULL) {
1451 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1454 #ifndef MODEST_TOOLKIT_HILDON2
1455 gboolean show_open_draft = FALSE;
1456 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1458 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1460 TnyFolderType folder_type;
1462 folder = tny_header_get_folder (helper->header);
1463 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1464 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1465 g_object_unref (folder);
1469 #ifdef MODEST_TOOLKIT_HILDON2
1472 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1474 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
1475 !g_strcmp0 (account_name, MODEST_MMC_ACCOUNT_ID)) {
1476 g_free (account_name);
1477 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1481 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1482 g_free (account_name);
1483 open_msg_helper_destroyer (helper);
1488 ModestWindow *window;
1489 GtkWidget *header_view;
1492 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1493 uid = modest_tny_folder_get_header_unique_id (helper->header);
1495 const gchar *mailbox = NULL;
1496 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1497 window = modest_msg_view_window_new_from_header_view
1498 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1499 if (window != NULL) {
1500 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1502 gtk_widget_destroy (GTK_WIDGET (window));
1504 gtk_widget_show_all (GTK_WIDGET(window));
1508 g_free (account_name);
1510 open_msg_helper_destroyer (helper);
1513 g_free (account_name);
1515 /* Create the mail operation */
1517 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1518 modest_ui_actions_disk_operations_error_handler,
1519 g_strdup (error_msg), g_free);
1520 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1524 #ifndef MODEST_TOOLKIT_HILDON2
1525 if (show_open_draft) {
1526 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1527 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1528 helper->banner_info->banner = NULL;
1529 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1530 helper->banner_info);
1536 headers = TNY_LIST (tny_simple_list_new ());
1537 tny_list_prepend (headers, G_OBJECT (helper->header));
1538 modest_mail_operation_get_msgs_full (mail_op,
1542 open_msg_helper_destroyer);
1543 g_object_unref (headers);
1550 g_object_unref (mail_op);
1551 g_object_unref (account);
1555 * This function is used by both modest_ui_actions_on_open and
1556 * modest_ui_actions_on_header_activated. This way we always do the
1557 * same when trying to open messages.
1560 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1562 ModestWindowMgr *mgr = NULL;
1563 TnyAccount *account;
1564 gboolean cached = FALSE;
1566 GtkWidget *header_view = NULL;
1567 OpenMsgHelper *helper;
1568 ModestWindow *window;
1570 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1572 mgr = modest_runtime_get_window_mgr ();
1575 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1576 if (header_view == NULL)
1579 /* Get the account */
1580 account = get_account_from_header (header);
1585 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1587 /* Do not open again the message and present the
1588 window to the user */
1591 #ifndef MODEST_TOOLKIT_HILDON2
1592 gtk_window_present (GTK_WINDOW (window));
1595 /* the header has been registered already, we don't do
1596 * anything but wait for the window to come up*/
1597 g_debug ("header %p already registered, waiting for window", header);
1602 /* Open each message */
1603 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1605 /* Allways download if we are online. */
1606 if (!tny_device_is_online (modest_runtime_get_device ())) {
1609 /* If ask for user permission to download the messages */
1610 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1611 _("mcen_nc_get_msg"));
1613 /* End if the user does not want to continue */
1614 if (response == GTK_RESPONSE_CANCEL) {
1620 /* We register the window for opening */
1621 modest_window_mgr_register_header (mgr, header, NULL);
1623 /* Create the helper. We need to get a reference to the model
1624 here because it could change while the message is readed
1625 (the user could switch between folders) */
1626 helper = g_slice_new (OpenMsgHelper);
1627 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1628 helper->caller_window = win;
1629 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1630 helper->header = g_object_ref (header);
1631 helper->rowref = gtk_tree_row_reference_copy (rowref);
1632 helper->banner_info = NULL;
1634 /* Connect to the account and perform */
1636 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1637 open_msg_performer, helper);
1639 /* Call directly the performer, do not need to connect */
1640 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1641 g_object_ref (account), helper);
1646 g_object_unref (account);
1650 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1657 /* we check for low-mem; in that case, show a warning, and don't allow
1660 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1664 headers = get_selected_headers (win);
1668 headers_count = tny_list_get_length (headers);
1669 if (headers_count != 1) {
1670 if (headers_count > 1) {
1671 /* Don't allow activation if there are more than one message selected */
1672 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1675 g_object_unref (headers);
1679 iter = tny_list_create_iterator (headers);
1680 header = TNY_HEADER (tny_iterator_get_current (iter));
1681 g_object_unref (iter);
1685 open_msg_from_header (header, NULL, win);
1686 g_object_unref (header);
1689 g_object_unref(headers);
1693 rf_helper_window_closed (gpointer data,
1696 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1698 helper->parent_window = NULL;
1701 static ReplyForwardHelper*
1702 create_reply_forward_helper (ReplyForwardAction action,
1704 guint reply_forward_type,
1707 TnyHeader *top_header,
1710 ReplyForwardHelper *rf_helper = NULL;
1711 const gchar *active_acc = modest_window_get_active_account (win);
1712 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1714 rf_helper = g_slice_new0 (ReplyForwardHelper);
1715 rf_helper->reply_forward_type = reply_forward_type;
1716 rf_helper->action = action;
1717 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1718 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1719 rf_helper->top_header = (top_header) ? g_object_ref (top_header) : NULL;
1720 rf_helper->msg_part = (msg_part) ? g_object_ref (msg_part) : NULL;
1721 rf_helper->account_name = (active_acc) ?
1722 g_strdup (active_acc) :
1723 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1724 rf_helper->mailbox = g_strdup (active_mailbox);
1726 rf_helper->parts = g_object_ref (parts);
1728 rf_helper->parts = NULL;
1730 /* Note that window could be destroyed just AFTER calling
1731 register_window so we must ensure that this pointer does
1732 not hold invalid references */
1733 if (rf_helper->parent_window)
1734 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1735 rf_helper_window_closed, rf_helper);
1741 free_reply_forward_helper (gpointer data)
1743 ReplyForwardHelper *helper;
1745 helper = (ReplyForwardHelper *) data;
1746 g_free (helper->account_name);
1747 g_free (helper->mailbox);
1749 g_object_unref (helper->header);
1750 if (helper->top_header)
1751 g_object_unref (helper->top_header);
1752 if (helper->msg_part)
1753 g_object_unref (helper->msg_part);
1755 g_object_unref (helper->parts);
1756 if (helper->parent_window)
1757 g_object_weak_unref (G_OBJECT (helper->parent_window),
1758 rf_helper_window_closed, helper);
1759 g_slice_free (ReplyForwardHelper, helper);
1763 reply_forward_cb (ModestMailOperation *mail_op,
1770 TnyMsg *new_msg = NULL;
1771 ReplyForwardHelper *rf_helper;
1772 ModestWindow *msg_win = NULL;
1773 ModestEditType edit_type;
1775 TnyAccount *account = NULL;
1776 ModestWindowMgr *mgr = NULL;
1777 gchar *signature = NULL, *recipient = NULL;
1778 gboolean use_signature;
1780 /* If there was any error. The mail operation could be NULL,
1781 this means that we already have the message downloaded and
1782 that we didn't do a mail operation to retrieve it */
1783 rf_helper = (ReplyForwardHelper *) user_data;
1784 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1787 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1788 rf_helper->account_name, rf_helper->mailbox);
1790 recipient = modest_text_utils_get_email_address (from);
1791 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
1796 /* Create reply mail */
1797 switch (rf_helper->action) {
1798 /* Use the msg_header to ensure that we have all the
1799 information. The summary can lack some data */
1800 TnyHeader *msg_header;
1802 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1804 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1805 (use_signature) ? signature : NULL,
1806 rf_helper->reply_forward_type,
1807 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1808 g_object_unref (msg_header);
1810 case ACTION_REPLY_TO_ALL:
1811 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1813 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1814 (use_signature) ? signature : NULL,
1815 rf_helper->reply_forward_type,
1816 MODEST_TNY_MSG_REPLY_MODE_ALL);
1817 edit_type = MODEST_EDIT_TYPE_REPLY;
1818 g_object_unref (msg_header);
1820 case ACTION_FORWARD:
1822 modest_tny_msg_create_forward_msg (rf_helper->msg_part?rf_helper->msg_part:msg, from,
1823 (use_signature) ? signature : NULL,
1824 rf_helper->reply_forward_type);
1825 edit_type = MODEST_EDIT_TYPE_FORWARD;
1828 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1830 g_return_if_reached ();
1838 g_warning ("%s: failed to create message\n", __FUNCTION__);
1842 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1843 rf_helper->account_name,
1844 TNY_ACCOUNT_TYPE_STORE);
1846 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1850 /* Create and register the windows */
1851 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1852 mgr = modest_runtime_get_window_mgr ();
1853 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1855 /* Note that register_window could have deleted the account */
1856 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1857 gdouble parent_zoom;
1859 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1860 modest_window_set_zoom (msg_win, parent_zoom);
1863 /* Show edit window */
1864 gtk_widget_show_all (GTK_WIDGET (msg_win));
1867 /* We always unregister the header because the message is
1868 forwarded or replied so the original one is no longer
1870 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1873 g_object_unref (G_OBJECT (new_msg));
1875 g_object_unref (G_OBJECT (account));
1876 free_reply_forward_helper (rf_helper);
1879 /* Checks a list of headers. If any of them are not currently
1880 * downloaded (CACHED) then returns TRUE else returns FALSE.
1883 header_list_count_uncached_msgs (TnyList *header_list)
1886 gint uncached_messages = 0;
1888 iter = tny_list_create_iterator (header_list);
1889 while (!tny_iterator_is_done (iter)) {
1892 header = TNY_HEADER (tny_iterator_get_current (iter));
1894 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1895 uncached_messages ++;
1896 g_object_unref (header);
1899 tny_iterator_next (iter);
1901 g_object_unref (iter);
1903 return uncached_messages;
1906 /* Returns FALSE if the user does not want to download the
1907 * messages. Returns TRUE if the user allowed the download.
1910 connect_to_get_msg (ModestWindow *win,
1911 gint num_of_uncached_msgs,
1912 TnyAccount *account)
1914 GtkResponseType response;
1916 /* Allways download if we are online. */
1917 if (tny_device_is_online (modest_runtime_get_device ()))
1920 /* If offline, then ask for user permission to download the messages */
1921 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1922 ngettext("mcen_nc_get_msg",
1924 num_of_uncached_msgs));
1926 if (response == GTK_RESPONSE_CANCEL)
1929 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1933 reply_forward_performer (gboolean canceled,
1935 GtkWindow *parent_window,
1936 TnyAccount *account,
1939 ReplyForwardHelper *rf_helper = NULL;
1940 ModestMailOperation *mail_op;
1942 rf_helper = (ReplyForwardHelper *) user_data;
1944 if (canceled || err) {
1945 free_reply_forward_helper (rf_helper);
1949 /* Retrieve the message */
1950 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1951 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1952 modest_ui_actions_disk_operations_error_handler,
1954 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1955 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->top_header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1958 g_object_unref(mail_op);
1962 all_parts_retrieved (TnyMimePart *part)
1964 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1967 TnyList *pending_parts;
1968 TnyIterator *iterator;
1969 gboolean all_retrieved = TRUE;
1971 pending_parts = TNY_LIST (tny_simple_list_new ());
1972 tny_mime_part_get_parts (part, pending_parts);
1973 iterator = tny_list_create_iterator (pending_parts);
1974 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1977 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1979 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1980 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1982 all_retrieved = FALSE;
1985 g_object_unref (child);
1986 tny_iterator_next (iterator);
1988 g_object_unref (iterator);
1989 g_object_unref (pending_parts);
1990 return all_retrieved;
1995 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1998 TnyIterator *iterator;
2000 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2001 tny_list_append (list, G_OBJECT (part));
2003 parts = TNY_LIST (tny_simple_list_new ());
2004 tny_mime_part_get_parts (part, parts);
2005 for (iterator = tny_list_create_iterator (parts);
2006 !tny_iterator_is_done (iterator);
2007 tny_iterator_next (iterator)) {
2010 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2011 forward_pending_parts_helper (child, list);
2012 g_object_unref (child);
2014 g_object_unref (iterator);
2015 g_object_unref (parts);
2019 forward_pending_parts (TnyMsg *msg)
2021 TnyList *result = TNY_LIST (tny_simple_list_new ());
2022 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2023 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2030 * Common code for the reply and forward actions
2033 reply_forward (ReplyForwardAction action, ModestWindow *win)
2035 ReplyForwardHelper *rf_helper = NULL;
2036 guint reply_forward_type;
2038 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2040 /* we check for low-mem; in that case, show a warning, and don't allow
2041 * reply/forward (because it could potentially require a lot of memory */
2042 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2046 /* we need an account when editing */
2047 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2048 if (!modest_ui_actions_run_account_setup_wizard (win))
2052 reply_forward_type =
2053 modest_conf_get_int (modest_runtime_get_conf (),
2054 (action == ACTION_FORWARD) ?
2055 MODEST_CONF_FORWARD_TYPE :
2056 MODEST_CONF_REPLY_TYPE,
2059 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2061 TnyMsg *top_msg = NULL;
2062 TnyHeader *header = NULL;
2063 /* Get header and message. Do not free them here, the
2064 reply_forward_cb must do it */
2065 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2066 top_msg = modest_msg_view_window_get_top_message (MODEST_MSG_VIEW_WINDOW(win));
2067 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2069 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2071 rf_helper = create_reply_forward_helper (action, win,
2072 reply_forward_type, header, NULL, NULL, NULL);
2073 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2075 gboolean do_download = TRUE;
2077 if (msg && header && action == ACTION_FORWARD) {
2078 if (top_msg == NULL)
2079 top_msg = g_object_ref (msg);
2080 /* Not all parts retrieved. Then we have to retrieve them all before
2081 * creating the forward message */
2082 if (!tny_device_is_online (modest_runtime_get_device ())) {
2085 /* If ask for user permission to download the messages */
2086 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2087 ngettext("mcen_nc_get_msg",
2091 /* End if the user does not want to continue */
2092 if (response == GTK_RESPONSE_CANCEL)
2093 do_download = FALSE;
2097 TnyList *pending_parts;
2099 TnyAccount *account;
2100 TnyHeader *top_header;
2103 top_header = tny_msg_get_header (top_msg);
2104 pending_parts = forward_pending_parts (top_msg);
2105 rf_helper = create_reply_forward_helper (action, win,
2106 reply_forward_type, header, msg, top_header, pending_parts);
2107 g_object_unref (pending_parts);
2109 folder = tny_header_get_folder (top_header);
2110 account = tny_folder_get_account (folder);
2111 modest_platform_connect_and_perform (GTK_WINDOW (win),
2113 reply_forward_performer,
2115 if (folder) g_object_unref (folder);
2116 g_object_unref (account);
2117 if (top_header) g_object_unref (top_header);
2121 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2126 g_object_unref (msg);
2128 g_object_unref (top_msg);
2130 g_object_unref (header);
2132 TnyHeader *header = NULL;
2134 gboolean do_retrieve = TRUE;
2135 TnyList *header_list = NULL;
2137 header_list = get_selected_headers (win);
2140 /* Check that only one message is selected for replying */
2141 if (tny_list_get_length (header_list) != 1) {
2142 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2143 NULL, _("mcen_ib_select_one_message"));
2144 g_object_unref (header_list);
2148 /* Only reply/forward to one message */
2149 iter = tny_list_create_iterator (header_list);
2150 header = TNY_HEADER (tny_iterator_get_current (iter));
2151 g_object_unref (iter);
2153 /* Retrieve messages */
2154 do_retrieve = (action == ACTION_FORWARD) ||
2155 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2158 TnyAccount *account = NULL;
2159 TnyFolder *folder = NULL;
2160 gdouble download = TRUE;
2161 guint uncached_msgs = 0;
2163 folder = tny_header_get_folder (header);
2165 goto do_retrieve_frees;
2166 account = tny_folder_get_account (folder);
2168 goto do_retrieve_frees;
2170 uncached_msgs = header_list_count_uncached_msgs (header_list);
2172 if (uncached_msgs > 0) {
2173 /* Allways download if we are online. */
2174 if (!tny_device_is_online (modest_runtime_get_device ())) {
2177 /* If ask for user permission to download the messages */
2178 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2179 ngettext("mcen_nc_get_msg",
2183 /* End if the user does not want to continue */
2184 if (response == GTK_RESPONSE_CANCEL)
2191 rf_helper = create_reply_forward_helper (action, win,
2192 reply_forward_type, header, NULL, NULL, NULL);
2193 if (uncached_msgs > 0) {
2194 modest_platform_connect_and_perform (GTK_WINDOW (win),
2196 reply_forward_performer,
2199 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2200 account, rf_helper);
2205 g_object_unref (account);
2207 g_object_unref (folder);
2209 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2212 g_object_unref (header_list);
2213 g_object_unref (header);
2218 modest_ui_actions_reply_calendar (ModestWindow *win, TnyMsg *msg, TnyList *header_pairs)
2223 gboolean use_signature;
2226 gdouble parent_zoom;
2227 const gchar *account_name;
2228 const gchar *mailbox;
2229 TnyHeader *msg_header;
2230 ModestWindowMgr *mgr;
2232 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win));
2234 /* we check for low-mem; in that case, show a warning, and don't allow
2235 * reply/forward (because it could potentially require a lot of memory */
2236 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2239 account_name = modest_window_get_active_account (MODEST_WINDOW (win));
2240 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (win));
2241 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
2242 account_name, mailbox);
2243 recipient = modest_text_utils_get_email_address (from);
2244 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
2249 msg_header = tny_msg_get_header (msg);
2251 modest_tny_msg_create_reply_calendar_msg (msg, msg_header, from,
2252 (use_signature) ? signature : NULL,
2254 g_object_unref (msg_header);
2260 g_warning ("%s: failed to create message\n", __FUNCTION__);
2264 msg_win = (GtkWidget *) modest_msg_edit_window_new (new_msg, account_name, mailbox, FALSE);
2265 mgr = modest_runtime_get_window_mgr ();
2266 modest_window_mgr_register_window (mgr, MODEST_WINDOW (msg_win), (ModestWindow *) win);
2268 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (win));
2269 modest_window_set_zoom (MODEST_WINDOW (msg_win), parent_zoom);
2271 /* Show edit window */
2272 gtk_widget_show_all (GTK_WIDGET (msg_win));
2276 g_object_unref (G_OBJECT (new_msg));
2280 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2282 g_return_if_fail (MODEST_IS_WINDOW(win));
2284 reply_forward (ACTION_REPLY, win);
2288 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2290 g_return_if_fail (MODEST_IS_WINDOW(win));
2292 reply_forward (ACTION_FORWARD, win);
2296 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2298 g_return_if_fail (MODEST_IS_WINDOW(win));
2300 reply_forward (ACTION_REPLY_TO_ALL, win);
2304 modest_ui_actions_on_next (GtkAction *action,
2305 ModestWindow *window)
2307 if (MODEST_IS_MAIN_WINDOW (window)) {
2308 GtkWidget *header_view;
2310 header_view = modest_main_window_get_child_widget (
2311 MODEST_MAIN_WINDOW(window),
2312 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2316 modest_header_view_select_next (
2317 MODEST_HEADER_VIEW(header_view));
2318 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2319 modest_msg_view_window_select_next_message (
2320 MODEST_MSG_VIEW_WINDOW (window));
2322 g_return_if_reached ();
2327 modest_ui_actions_on_prev (GtkAction *action,
2328 ModestWindow *window)
2330 g_return_if_fail (MODEST_IS_WINDOW(window));
2332 if (MODEST_IS_MAIN_WINDOW (window)) {
2333 GtkWidget *header_view;
2334 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2335 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2339 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2340 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2341 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2343 g_return_if_reached ();
2348 modest_ui_actions_on_sort (GtkAction *action,
2349 ModestWindow *window)
2351 GtkWidget *header_view = NULL;
2353 g_return_if_fail (MODEST_IS_WINDOW(window));
2355 if (MODEST_IS_MAIN_WINDOW (window)) {
2356 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2357 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2358 #ifdef MODEST_TOOLKIT_HILDON2
2359 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2360 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2365 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2370 /* Show sorting dialog */
2371 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2375 sync_folder_cb (ModestMailOperation *mail_op,
2379 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2381 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2382 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2384 /* We must clear first, because otherwise set_folder will ignore */
2385 /* the change as the folders are the same */
2386 modest_header_view_clear (header_view);
2387 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2389 g_object_unref (parent);
2392 g_object_unref (header_view);
2396 idle_refresh_folder (gpointer source)
2398 ModestHeaderView *header_view = NULL;
2400 /* If the window still exists */
2401 if (!GTK_IS_WIDGET (source) ||
2402 !GTK_WIDGET_VISIBLE (source))
2405 /* Refresh the current view */
2406 #ifdef MODEST_TOOLKIT_HILDON2
2407 if (MODEST_IS_HEADER_WINDOW (source))
2408 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2410 if (MODEST_IS_MAIN_WINDOW (source))
2411 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2412 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2415 TnyFolder *folder = modest_header_view_get_folder (header_view);
2417 /* Sync the folder status */
2418 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2419 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2420 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2421 g_object_unref (folder);
2422 g_object_unref (mail_op);
2430 update_account_cb (ModestMailOperation *self,
2431 TnyList *new_headers,
2435 gboolean show_visual_notifications;
2437 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2438 show_visual_notifications = (top) ? FALSE : TRUE;
2440 /* Notify new messages have been downloaded. If the
2441 send&receive was invoked by the user then do not show any
2442 visual notification, only play a sound and activate the LED
2443 (for the Maemo version) */
2444 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2446 /* We only notify about really new messages (not seen) we get */
2447 TnyList *actually_new_list;
2448 TnyIterator *iterator;
2449 actually_new_list = TNY_LIST (tny_simple_list_new ());
2450 for (iterator = tny_list_create_iterator (new_headers);
2451 !tny_iterator_is_done (iterator);
2452 tny_iterator_next (iterator)) {
2454 TnyHeaderFlags flags;
2455 header = TNY_HEADER (tny_iterator_get_current (iterator));
2456 flags = tny_header_get_flags (header);
2458 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2459 /* Messages are ordered from most
2460 recent to oldest. But we want to
2461 show notifications starting from
2462 the oldest message. That's why we
2464 tny_list_prepend (actually_new_list, G_OBJECT (header));
2466 g_object_unref (header);
2468 g_object_unref (iterator);
2470 if (tny_list_get_length (actually_new_list) > 0) {
2471 GList *new_headers_list = NULL;
2473 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2475 /* Send notifications */
2476 if (new_headers_list) {
2477 modest_platform_on_new_headers_received (new_headers_list,
2478 show_visual_notifications);
2480 modest_utils_free_notification_list (new_headers_list);
2483 g_object_unref (actually_new_list);
2487 /* Refresh the current folder in an idle. We do this
2488 in order to avoid refresh cancelations if the
2489 currently viewed folder is the inbox */
2490 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2491 idle_refresh_folder,
2498 TnyAccount *account;
2500 gchar *account_name;
2501 gboolean poke_status;
2502 gboolean interactive;
2503 ModestMailOperation *mail_op;
2507 do_send_receive_performer (gboolean canceled,
2509 GtkWindow *parent_window,
2510 TnyAccount *account,
2513 SendReceiveInfo *info;
2515 info = (SendReceiveInfo *) user_data;
2517 if (err || canceled) {
2518 /* In disk full conditions we could get this error here */
2519 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2520 (GtkWidget *) parent_window, err,
2523 if (info->mail_op) {
2524 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2530 /* Set send/receive operation in progress */
2531 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2532 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2535 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2536 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2537 G_CALLBACK (on_send_receive_finished),
2540 /* Send & receive. */
2541 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2542 update_account_cb, info->win);
2547 g_object_unref (G_OBJECT (info->mail_op));
2548 if (info->account_name)
2549 g_free (info->account_name);
2551 g_object_unref (info->win);
2553 g_object_unref (info->account);
2554 g_slice_free (SendReceiveInfo, info);
2558 * This function performs the send & receive required actions. The
2559 * window is used to create the mail operation. Typically it should
2560 * always be the main window, but we pass it as argument in order to
2564 modest_ui_actions_do_send_receive (const gchar *account_name,
2565 gboolean force_connection,
2566 gboolean poke_status,
2567 gboolean interactive,
2570 gchar *acc_name = NULL;
2571 SendReceiveInfo *info;
2572 ModestTnyAccountStore *acc_store;
2573 TnyAccount *account;
2575 /* If no account name was provided then get the current account, and if
2576 there is no current account then pick the default one: */
2577 if (!account_name) {
2579 acc_name = g_strdup (modest_window_get_active_account (win));
2581 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2583 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2587 acc_name = g_strdup (account_name);
2590 acc_store = modest_runtime_get_account_store ();
2591 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2595 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2599 /* Do not automatically refresh accounts that are flagged as
2600 NO_AUTO_UPDATE. This could be useful for accounts that
2601 handle their own update times */
2603 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2604 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2605 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2606 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2608 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2609 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2610 g_object_unref (account);
2617 /* Create the info for the connect and perform */
2618 info = g_slice_new (SendReceiveInfo);
2619 info->account_name = acc_name;
2620 info->win = (win) ? g_object_ref (win) : NULL;
2621 info->poke_status = poke_status;
2622 info->interactive = interactive;
2623 info->account = account;
2624 /* We need to create the operation here, because otherwise it
2625 could happen that the queue emits the queue-empty signal
2626 while we're trying to connect the account */
2627 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2628 modest_ui_actions_disk_operations_error_handler,
2630 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2632 /* Invoke the connect and perform */
2633 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2634 force_connection, info->account,
2635 do_send_receive_performer, info);
2640 modest_ui_actions_do_cancel_send (const gchar *account_name,
2643 TnyTransportAccount *transport_account;
2644 TnySendQueue *send_queue = NULL;
2645 GError *error = NULL;
2647 /* Get transport account */
2649 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2650 (modest_runtime_get_account_store(),
2652 TNY_ACCOUNT_TYPE_TRANSPORT));
2653 if (!transport_account) {
2654 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2659 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2660 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2661 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2662 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2663 "modest: could not find send queue for account\n");
2665 /* Cancel the current send */
2666 tny_account_cancel (TNY_ACCOUNT (transport_account));
2668 /* Suspend all pending messages */
2669 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2673 if (transport_account != NULL)
2674 g_object_unref (G_OBJECT (transport_account));
2678 modest_ui_actions_cancel_send_all (ModestWindow *win)
2680 GSList *account_names, *iter;
2682 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2685 iter = account_names;
2687 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2688 iter = g_slist_next (iter);
2691 modest_account_mgr_free_account_names (account_names);
2692 account_names = NULL;
2696 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2699 /* Check if accounts exist */
2700 gboolean accounts_exist =
2701 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2703 /* If not, allow the user to create an account before trying to send/receive. */
2704 if (!accounts_exist)
2705 modest_ui_actions_on_accounts (NULL, win);
2707 /* Cancel all sending operaitons */
2708 modest_ui_actions_cancel_send_all (win);
2712 * Refreshes all accounts. This function will be used by automatic
2716 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2717 gboolean force_connection,
2718 gboolean poke_status,
2719 gboolean interactive)
2721 GSList *account_names, *iter;
2723 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2726 iter = account_names;
2728 modest_ui_actions_do_send_receive ((const char*) iter->data,
2730 poke_status, interactive, win);
2731 iter = g_slist_next (iter);
2734 modest_account_mgr_free_account_names (account_names);
2735 account_names = NULL;
2739 * Handler of the click on Send&Receive button in the main toolbar
2742 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2744 /* Check if accounts exist */
2745 gboolean accounts_exist;
2748 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2750 /* If not, allow the user to create an account before trying to send/receive. */
2751 if (!accounts_exist)
2752 modest_ui_actions_on_accounts (NULL, win);
2754 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2755 if (MODEST_IS_MAIN_WINDOW (win)) {
2756 GtkWidget *folder_view;
2757 TnyFolderStore *folder_store;
2760 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2761 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2765 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2768 g_object_unref (folder_store);
2769 /* Refresh the active account. Force the connection if needed
2770 and poke the status of all folders */
2771 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2772 #ifdef MODEST_TOOLKIT_HILDON2
2773 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2774 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2777 const gchar *active_account;
2778 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2780 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2787 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2790 GtkWidget *header_view;
2792 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2794 header_view = modest_main_window_get_child_widget (main_window,
2795 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2799 conf = modest_runtime_get_conf ();
2801 /* what is saved/restored is depending on the style; thus; we save with
2802 * old style, then update the style, and restore for this new style
2804 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2806 if (modest_header_view_get_style
2807 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2808 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2809 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2811 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2812 MODEST_HEADER_VIEW_STYLE_DETAILS);
2814 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2815 MODEST_CONF_HEADER_VIEW_KEY);
2820 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2822 ModestMainWindow *main_window)
2824 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2825 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2827 /* in the case the folder is empty, show the empty folder message and focus
2829 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2830 if (modest_header_view_is_empty (header_view)) {
2831 TnyFolder *folder = modest_header_view_get_folder (header_view);
2832 GtkWidget *folder_view =
2833 modest_main_window_get_child_widget (main_window,
2834 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2835 if (folder != NULL) {
2836 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2837 g_object_unref (folder);
2839 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2843 /* If no header has been selected then exit */
2848 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2849 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2851 /* Update toolbar dimming state */
2852 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2853 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2857 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2860 ModestWindow *window)
2862 GtkWidget *open_widget;
2863 GtkTreeRowReference *rowref;
2865 g_return_if_fail (MODEST_IS_WINDOW(window));
2866 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2867 g_return_if_fail (TNY_IS_HEADER (header));
2869 if (modest_header_view_count_selected_headers (header_view) > 1) {
2870 /* Don't allow activation if there are more than one message selected */
2871 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2875 /* we check for low-mem; in that case, show a warning, and don't allow
2876 * activating headers
2878 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2881 if (MODEST_IS_MAIN_WINDOW (window)) {
2882 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2883 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2884 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2888 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2889 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2890 gtk_tree_row_reference_free (rowref);
2894 set_active_account_from_tny_account (TnyAccount *account,
2895 ModestWindow *window)
2897 const gchar *server_acc_name = tny_account_get_id (account);
2899 /* We need the TnyAccount provided by the
2900 account store because that is the one that
2901 knows the name of the Modest account */
2902 TnyAccount *modest_server_account =
2903 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2904 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2906 if (!modest_server_account) {
2907 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2911 /* Update active account, but only if it's not a pseudo-account */
2912 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2913 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2914 const gchar *modest_acc_name =
2915 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2916 if (modest_acc_name)
2917 modest_window_set_active_account (window, modest_acc_name);
2920 g_object_unref (modest_server_account);
2925 folder_refreshed_cb (ModestMailOperation *mail_op,
2929 ModestMainWindow *win = NULL;
2930 GtkWidget *folder_view, *header_view;
2931 const GError *error;
2933 g_return_if_fail (TNY_IS_FOLDER (folder));
2935 win = MODEST_MAIN_WINDOW (user_data);
2937 /* Check if the operation failed due to memory low conditions */
2938 error = modest_mail_operation_get_error (mail_op);
2939 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2940 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2941 modest_platform_run_information_dialog (GTK_WINDOW (win),
2942 _KR("memr_ib_operation_disabled"),
2948 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2950 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2953 TnyFolderStore *current_folder;
2955 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2956 if (current_folder) {
2957 gboolean different = ((TnyFolderStore *) folder != current_folder);
2958 g_object_unref (current_folder);
2964 /* Check if folder is empty and set headers view contents style */
2965 if ((tny_folder_get_all_count (folder) == 0) ||
2966 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2967 modest_main_window_set_contents_style (win,
2968 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2972 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2973 TnyFolderStore *folder_store,
2975 ModestMainWindow *main_window)
2977 GtkWidget *header_view;
2979 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2981 header_view = modest_main_window_get_child_widget(main_window,
2982 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2987 if (TNY_IS_ACCOUNT (folder_store)) {
2989 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2991 /* Show account details */
2992 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2995 if (TNY_IS_FOLDER (folder_store) && selected) {
2996 TnyAccount *account;
2998 /* Update the active account */
2999 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
3001 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
3002 g_object_unref (account);
3006 /* Set the header style by default, it could
3007 be changed later by the refresh callback to
3009 modest_main_window_set_contents_style (main_window,
3010 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
3012 /* Set folder on header view. This function
3013 will call tny_folder_refresh_async so we
3014 pass a callback that will be called when
3015 finished. We use that callback to set the
3016 empty view if there are no messages */
3017 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
3018 TNY_FOLDER (folder_store),
3020 MODEST_WINDOW (main_window),
3021 folder_refreshed_cb,
3024 /* Restore configuration. We need to do this
3025 *after* the set_folder because the widget
3026 memory asks the header view about its
3028 modest_widget_memory_restore (modest_runtime_get_conf (),
3029 G_OBJECT(header_view),
3030 MODEST_CONF_HEADER_VIEW_KEY);
3032 /* No need to save the header view
3033 configuration for Maemo because it only
3034 saves the sorting stuff and that it's
3035 already being done by the sort
3036 dialog. Remove it when the GNOME version
3037 has the same behaviour */
3038 #ifdef MODEST_TOOLKIT_GTK
3039 if (modest_main_window_get_contents_style (main_window) ==
3040 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
3041 modest_widget_memory_save (modest_runtime_get_conf (),
3042 G_OBJECT (header_view),
3043 MODEST_CONF_HEADER_VIEW_KEY);
3045 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
3049 /* Update dimming state */
3050 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
3051 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
3055 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
3062 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
3064 online = tny_device_is_online (modest_runtime_get_device());
3067 /* already online -- the item is simply not there... */
3068 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
3070 GTK_MESSAGE_WARNING,
3072 _("The %s you selected cannot be found"),
3074 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3075 gtk_dialog_run (GTK_DIALOG(dialog));
3077 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3080 _("mcen_bd_dialog_cancel"),
3081 GTK_RESPONSE_REJECT,
3082 _("mcen_bd_dialog_ok"),
3083 GTK_RESPONSE_ACCEPT,
3085 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3086 "Do you want to get online?"), item);
3087 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3088 gtk_label_new (txt), FALSE, FALSE, 0);
3089 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3092 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3093 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3094 /* TODO: Comment about why is this commented out: */
3095 /* modest_platform_connect_and_wait (); */
3098 gtk_widget_destroy (dialog);
3102 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3105 /* g_debug ("%s %s", __FUNCTION__, link); */
3110 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3113 modest_platform_activate_uri (link);
3117 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3120 modest_platform_show_uri_popup (link);
3124 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3127 /* we check for low-mem; in that case, show a warning, and don't allow
3128 * viewing attachments
3130 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3133 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3137 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3138 const gchar *address,
3141 /* g_debug ("%s %s", __FUNCTION__, address); */
3145 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3146 TnyMsg *saved_draft,
3149 ModestMsgEditWindow *edit_window;
3151 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3152 #ifndef MODEST_TOOLKIT_HILDON2
3153 ModestMainWindow *win;
3155 /* FIXME. Make the header view sensitive again. This is a
3156 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3158 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3159 modest_runtime_get_window_mgr(), FALSE));
3161 GtkWidget *hdrview = modest_main_window_get_child_widget(
3162 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3163 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3167 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3169 /* Set draft is there was no error */
3170 if (!modest_mail_operation_get_error (mail_op))
3171 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3173 g_object_unref(edit_window);
3177 enough_space_for_message (ModestMsgEditWindow *edit_window,
3180 guint64 available_disk, expected_size;
3185 available_disk = modest_utils_get_available_space (NULL);
3186 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3187 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3192 /* Double check: disk full condition or message too big */
3193 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3194 expected_size > available_disk) {
3195 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3196 modest_platform_information_banner (NULL, NULL, msg);
3203 * djcb: if we're in low-memory state, we only allow for
3204 * saving messages smaller than
3205 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3206 * should still allow for sending anything critical...
3208 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3209 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3213 * djcb: we also make sure that the attachments are smaller than the max size
3214 * this is for the case where we'd try to forward a message with attachments
3215 * bigger than our max allowed size, or sending an message from drafts which
3216 * somehow got past our checks when attaching.
3218 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3219 modest_platform_run_information_dialog (
3220 GTK_WINDOW(edit_window),
3221 _("mail_ib_error_attachment_size"),
3230 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3232 TnyTransportAccount *transport_account;
3233 ModestMailOperation *mail_operation;
3235 gchar *account_name;
3236 ModestAccountMgr *account_mgr;
3237 gboolean had_error = FALSE;
3238 ModestMainWindow *win = NULL;
3240 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3242 data = modest_msg_edit_window_get_msg_data (edit_window);
3245 if (!enough_space_for_message (edit_window, data)) {
3246 modest_msg_edit_window_free_msg_data (edit_window, data);
3250 account_name = g_strdup (data->account_name);
3251 account_mgr = modest_runtime_get_account_mgr();
3253 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3255 account_name = modest_account_mgr_get_default_account (account_mgr);
3256 if (!account_name) {
3257 g_printerr ("modest: no account found\n");
3258 modest_msg_edit_window_free_msg_data (edit_window, data);
3262 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3263 account_name = g_strdup (data->account_name);
3267 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3268 (modest_runtime_get_account_store (),
3270 TNY_ACCOUNT_TYPE_TRANSPORT));
3271 if (!transport_account) {
3272 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3273 g_free (account_name);
3274 modest_msg_edit_window_free_msg_data (edit_window, data);
3278 /* Create the mail operation */
3279 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3281 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3283 modest_mail_operation_save_to_drafts (mail_operation,
3295 data->priority_flags,
3298 on_save_to_drafts_cb,
3299 g_object_ref(edit_window));
3301 #ifdef MODEST_TOOLKIT_HILDON2
3302 /* In hildon2 we always show the information banner on saving to drafts.
3303 * It will be a system information banner in this case.
3305 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3306 modest_platform_information_banner (NULL, NULL, text);
3309 /* Use the main window as the parent of the banner, if the
3310 main window does not exist it won't be shown, if the parent
3311 window exists then it's properly shown. We don't use the
3312 editor window because it could be closed (save to drafts
3313 could happen after closing the window */
3314 win = (ModestMainWindow *)
3315 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3317 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3318 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3322 modest_msg_edit_window_set_modified (edit_window, FALSE);
3325 g_free (account_name);
3326 g_object_unref (G_OBJECT (transport_account));
3327 g_object_unref (G_OBJECT (mail_operation));
3329 modest_msg_edit_window_free_msg_data (edit_window, data);
3332 * If the drafts folder is selected then make the header view
3333 * insensitive while the message is being saved to drafts
3334 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3335 * is not very clean but it avoids letting the drafts folder
3336 * in an inconsistent state: the user could edit the message
3337 * being saved and undesirable things would happen.
3338 * In the average case the user won't notice anything at
3339 * all. In the worst case (the user is editing a really big
3340 * file from Drafts) the header view will be insensitive
3341 * during the saving process (10 or 20 seconds, depending on
3342 * the message). Anyway this is just a quick workaround: once
3343 * we find a better solution it should be removed
3344 * See NB#65125 (commend #18) for details.
3346 if (!had_error && win != NULL) {
3347 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3348 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3350 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3352 if (modest_tny_folder_is_local_folder(folder)) {
3353 TnyFolderType folder_type;
3354 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3355 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3356 GtkWidget *hdrview = modest_main_window_get_child_widget(
3357 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3358 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3362 if (folder != NULL) g_object_unref(folder);
3369 /* For instance, when clicking the Send toolbar button when editing a message: */
3371 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3373 TnyTransportAccount *transport_account = NULL;
3374 gboolean had_error = FALSE, add_to_contacts;
3376 ModestAccountMgr *account_mgr;
3377 gchar *account_name;
3378 ModestMailOperation *mail_operation;
3381 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3383 /* Check whether to automatically add new contacts to addressbook or not */
3384 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3385 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3386 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3389 data = modest_msg_edit_window_get_msg_data (edit_window);
3391 recipients = g_strconcat (data->to?data->to:"",
3392 data->cc?data->cc:"",
3393 data->bcc?data->bcc:"",
3395 if (recipients == NULL || recipients[0] == '\0') {
3396 /* Empty subject -> no send */
3397 g_free (recipients);
3398 modest_msg_edit_window_free_msg_data (edit_window, data);
3401 g_free (recipients);
3404 if (!enough_space_for_message (edit_window, data)) {
3405 modest_msg_edit_window_free_msg_data (edit_window, data);
3409 account_mgr = modest_runtime_get_account_mgr();
3410 account_name = g_strdup (data->account_name);
3412 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3415 account_name = modest_account_mgr_get_default_account (account_mgr);
3417 if (!account_name) {
3418 modest_msg_edit_window_free_msg_data (edit_window, data);
3419 /* Run account setup wizard */
3420 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3425 /* Get the currently-active transport account for this modest account: */
3426 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3428 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3429 (modest_runtime_get_account_store (),
3430 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3433 if (!transport_account) {
3434 modest_msg_edit_window_free_msg_data (edit_window, data);
3435 /* Run account setup wizard */
3436 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3441 /* Create the mail operation */
3442 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3443 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3445 modest_mail_operation_send_new_mail (mail_operation,
3459 data->priority_flags);
3461 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3462 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3464 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3465 const GError *error = modest_mail_operation_get_error (mail_operation);
3466 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3467 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3468 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3469 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3475 g_free (account_name);
3476 g_object_unref (G_OBJECT (transport_account));
3477 g_object_unref (G_OBJECT (mail_operation));
3479 modest_msg_edit_window_free_msg_data (edit_window, data);
3482 modest_msg_edit_window_set_sent (edit_window, TRUE);
3484 /* Save settings and close the window: */
3485 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3492 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3493 ModestMsgEditWindow *window)
3495 ModestMsgEditFormatState *format_state = NULL;
3497 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3498 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3500 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3503 format_state = modest_msg_edit_window_get_format_state (window);
3504 g_return_if_fail (format_state != NULL);
3506 format_state->bold = gtk_toggle_action_get_active (action);
3507 modest_msg_edit_window_set_format_state (window, format_state);
3508 g_free (format_state);
3513 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3514 ModestMsgEditWindow *window)
3516 ModestMsgEditFormatState *format_state = NULL;
3518 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3519 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3521 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3524 format_state = modest_msg_edit_window_get_format_state (window);
3525 g_return_if_fail (format_state != NULL);
3527 format_state->italics = gtk_toggle_action_get_active (action);
3528 modest_msg_edit_window_set_format_state (window, format_state);
3529 g_free (format_state);
3534 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3535 ModestMsgEditWindow *window)
3537 ModestMsgEditFormatState *format_state = NULL;
3539 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3540 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3542 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3545 format_state = modest_msg_edit_window_get_format_state (window);
3546 g_return_if_fail (format_state != NULL);
3548 format_state->bullet = gtk_toggle_action_get_active (action);
3549 modest_msg_edit_window_set_format_state (window, format_state);
3550 g_free (format_state);
3555 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3556 GtkRadioAction *selected,
3557 ModestMsgEditWindow *window)
3559 ModestMsgEditFormatState *format_state = NULL;
3560 GtkJustification value;
3562 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3564 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3567 value = gtk_radio_action_get_current_value (selected);
3569 format_state = modest_msg_edit_window_get_format_state (window);
3570 g_return_if_fail (format_state != NULL);
3572 format_state->justification = value;
3573 modest_msg_edit_window_set_format_state (window, format_state);
3574 g_free (format_state);
3578 modest_ui_actions_on_select_editor_color (GtkAction *action,
3579 ModestMsgEditWindow *window)
3581 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3582 g_return_if_fail (GTK_IS_ACTION (action));
3584 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3587 modest_msg_edit_window_select_color (window);
3591 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3592 ModestMsgEditWindow *window)
3594 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3595 g_return_if_fail (GTK_IS_ACTION (action));
3597 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3600 modest_msg_edit_window_select_background_color (window);
3604 modest_ui_actions_on_insert_image (GObject *object,
3605 ModestMsgEditWindow *window)
3607 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3610 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3613 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3616 modest_msg_edit_window_insert_image (window);
3620 modest_ui_actions_on_attach_file (GtkAction *action,
3621 ModestMsgEditWindow *window)
3623 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3624 g_return_if_fail (GTK_IS_ACTION (action));
3626 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3629 modest_msg_edit_window_offer_attach_file (window);
3633 modest_ui_actions_on_remove_attachments (GtkAction *action,
3634 ModestMsgEditWindow *window)
3636 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3638 modest_msg_edit_window_remove_attachments (window, NULL);
3642 do_create_folder_cb (ModestMailOperation *mail_op,
3643 TnyFolderStore *parent_folder,
3644 TnyFolder *new_folder,
3647 gchar *suggested_name = (gchar *) user_data;
3648 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3649 const GError *error;
3651 error = modest_mail_operation_get_error (mail_op);
3653 gboolean disk_full = FALSE;
3654 TnyAccount *account;
3655 /* Show an error. If there was some problem writing to
3656 disk, show it, otherwise show the generic folder
3657 create error. We do it here and not in an error
3658 handler because the call to do_create_folder will
3659 stop the main loop in a gtk_dialog_run and then,
3660 the message won't be shown until that dialog is
3662 account = modest_mail_operation_get_account (mail_op);
3665 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3666 (GtkWidget *) source_win,
3669 _("mail_in_ui_folder_create_error_memory"));
3670 g_object_unref (account);
3673 /* Show an error and try again if there is no
3674 full memory condition */
3675 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3676 _("mail_in_ui_folder_create_error"));
3677 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3681 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3682 * FIXME: any other? */
3683 GtkWidget *folder_view;
3685 if (MODEST_IS_MAIN_WINDOW(source_win))
3687 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3688 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3690 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3691 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3693 /* Select the newly created folder. It could happen
3694 that the widget is no longer there (i.e. the window
3695 has been destroyed, so we need to check this */
3697 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3699 g_object_unref (new_folder);
3701 /* Free. Note that the first time it'll be NULL so noop */
3702 g_free (suggested_name);
3703 g_object_unref (source_win);
3708 TnyFolderStore *parent;
3709 } CreateFolderConnect;
3712 do_create_folder_performer (gboolean canceled,
3714 GtkWindow *parent_window,
3715 TnyAccount *account,
3718 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3719 ModestMailOperation *mail_op;
3721 if (canceled || err) {
3722 /* In disk full conditions we could get this error here */
3723 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3724 (GtkWidget *) parent_window, err,
3725 NULL, _("mail_in_ui_folder_create_error_memory"));
3727 /* This happens if we have selected the outbox folder
3729 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3730 TNY_IS_MERGE_FOLDER (helper->parent)) {
3731 /* Show an error and retry */
3732 modest_platform_information_banner ((GtkWidget *) parent_window,
3734 _("mail_in_ui_folder_create_error"));
3736 do_create_folder (parent_window, helper->parent, helper->folder_name);
3742 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3743 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3745 modest_mail_operation_create_folder (mail_op,
3747 (const gchar *) helper->folder_name,
3748 do_create_folder_cb,
3749 g_strdup (helper->folder_name));
3750 g_object_unref (mail_op);
3754 g_object_unref (helper->parent);
3755 if (helper->folder_name)
3756 g_free (helper->folder_name);
3757 g_slice_free (CreateFolderConnect, helper);
3762 do_create_folder (GtkWindow *parent_window,
3763 TnyFolderStore *suggested_parent,
3764 const gchar *suggested_name)
3767 gchar *folder_name = NULL;
3768 TnyFolderStore *parent_folder = NULL;
3770 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3772 (gchar *) suggested_name,
3776 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3777 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3778 helper->folder_name = g_strdup (folder_name);
3779 helper->parent = g_object_ref (parent_folder);
3781 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3784 do_create_folder_performer,
3789 g_free (folder_name);
3791 g_object_unref (parent_folder);
3795 modest_ui_actions_create_folder(GtkWidget *parent_window,
3796 GtkWidget *folder_view,
3797 TnyFolderStore *parent_folder)
3799 if (!parent_folder) {
3800 #ifdef MODEST_TOOLKIT_HILDON2
3801 ModestTnyAccountStore *acc_store;
3803 acc_store = modest_runtime_get_account_store ();
3805 parent_folder = (TnyFolderStore *)
3806 modest_tny_account_store_get_local_folders_account (acc_store);
3808 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3812 if (parent_folder) {
3813 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3814 g_object_unref (parent_folder);
3819 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3822 g_return_if_fail (MODEST_IS_WINDOW(window));
3824 if (MODEST_IS_MAIN_WINDOW (window)) {
3825 GtkWidget *folder_view;
3827 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3828 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3832 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3833 #ifdef MODEST_TOOLKIT_HILDON2
3834 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3835 GtkWidget *folder_view;
3837 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3838 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3841 g_assert_not_reached ();
3846 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3849 const GError *error = NULL;
3850 gchar *message = NULL;
3852 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3854 /* Get error message */
3855 error = modest_mail_operation_get_error (mail_op);
3857 g_return_if_reached ();
3859 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3860 (GError *) error, account);
3862 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3863 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3864 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3865 message = _CS("ckdg_ib_folder_already_exists");
3866 } else if (error->domain == TNY_ERROR_DOMAIN &&
3867 error->code == TNY_SERVICE_ERROR_STATE) {
3868 /* This means that the folder is already in use (a
3869 message is opened for example */
3870 message = _("emev_ni_internal_error");
3872 message = _CS("ckdg_ib_unable_to_rename");
3875 /* We don't set a parent for the dialog because the dialog
3876 will be destroyed so the banner won't appear */
3877 modest_platform_information_banner (NULL, NULL, message);
3880 g_object_unref (account);
3886 TnyFolderStore *folder;
3891 on_rename_folder_cb (ModestMailOperation *mail_op,
3892 TnyFolder *new_folder,
3895 ModestFolderView *folder_view;
3897 /* If the window was closed when renaming a folder, or if
3898 * it's not a main window this will happen */
3899 if (!MODEST_IS_FOLDER_VIEW (user_data))
3902 folder_view = MODEST_FOLDER_VIEW (user_data);
3903 /* Note that if the rename fails new_folder will be NULL */
3905 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3907 modest_folder_view_select_first_inbox_or_local (folder_view);
3909 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3913 on_rename_folder_performer (gboolean canceled,
3915 GtkWindow *parent_window,
3916 TnyAccount *account,
3919 ModestMailOperation *mail_op = NULL;
3920 GtkTreeSelection *sel = NULL;
3921 GtkWidget *folder_view = NULL;
3922 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3924 if (canceled || err) {
3925 /* In disk full conditions we could get this error here */
3926 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3927 (GtkWidget *) parent_window, err,
3932 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3933 modest_ui_actions_rename_folder_error_handler,
3934 parent_window, NULL);
3936 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3939 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3941 folder_view = modest_main_window_get_child_widget (
3942 MODEST_MAIN_WINDOW (parent_window),
3943 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3945 #ifdef MODEST_TOOLKIT_HILDON2
3946 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3947 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3948 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3952 /* Clear the folders view */
3953 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3954 gtk_tree_selection_unselect_all (sel);
3956 /* Actually rename the folder */
3957 modest_mail_operation_rename_folder (mail_op,
3958 TNY_FOLDER (data->folder),
3959 (const gchar *) (data->new_name),
3960 on_rename_folder_cb,
3962 g_object_unref (mail_op);
3965 g_object_unref (data->folder);
3966 g_free (data->new_name);
3971 modest_ui_actions_on_rename_folder (GtkAction *action,
3972 ModestWindow *window)
3974 modest_ui_actions_on_edit_mode_rename_folder (window);
3978 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3980 TnyFolderStore *folder;
3981 GtkWidget *folder_view;
3982 gboolean do_rename = TRUE;
3984 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3986 if (MODEST_IS_MAIN_WINDOW (window)) {
3987 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3988 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3992 #ifdef MODEST_TOOLKIT_HILDON2
3993 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3994 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4000 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
4005 if (TNY_IS_FOLDER (folder)) {
4006 gchar *folder_name = NULL;
4008 const gchar *current_name;
4009 TnyFolderStore *parent;
4011 current_name = tny_folder_get_name (TNY_FOLDER (folder));
4012 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
4013 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
4014 parent, current_name,
4016 g_object_unref (parent);
4018 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
4021 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
4022 rename_folder_data->folder = g_object_ref (folder);
4023 rename_folder_data->new_name = folder_name;
4024 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
4025 folder, on_rename_folder_performer, rename_folder_data);
4028 g_object_unref (folder);
4033 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
4036 GObject *win = modest_mail_operation_get_source (mail_op);
4038 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
4039 _("mail_in_ui_folder_delete_error"),
4041 g_object_unref (win);
4045 TnyFolderStore *folder;
4046 gboolean move_to_trash;
4050 on_delete_folder_cb (gboolean canceled,
4052 GtkWindow *parent_window,
4053 TnyAccount *account,
4056 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
4057 GtkWidget *folder_view;
4058 ModestMailOperation *mail_op;
4059 GtkTreeSelection *sel;
4061 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
4062 /* Note that the connection process can fail due to
4063 memory low conditions as it can not successfully
4064 store the summary */
4065 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4066 (GtkWidget*) parent_window, err,
4068 g_debug ("Error connecting when trying to delete a folder");
4069 g_object_unref (G_OBJECT (info->folder));
4074 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4075 folder_view = modest_main_window_get_child_widget (
4076 MODEST_MAIN_WINDOW (parent_window),
4077 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4078 #ifdef MODEST_TOOLKIT_HILDON2
4079 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4080 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4083 g_object_unref (G_OBJECT (info->folder));
4088 /* Unselect the folder before deleting it to free the headers */
4089 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4090 gtk_tree_selection_unselect_all (sel);
4092 /* Create the mail operation */
4094 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4095 modest_ui_actions_delete_folder_error_handler,
4098 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4100 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4102 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4104 g_object_unref (mail_op);
4105 g_object_unref (info->folder);
4110 delete_folder (ModestWindow *window, gboolean move_to_trash)
4112 TnyFolderStore *folder;
4113 GtkWidget *folder_view;
4117 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4119 if (MODEST_IS_MAIN_WINDOW (window)) {
4121 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4122 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4123 #ifdef MODEST_TOOLKIT_HILDON2
4124 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4125 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4133 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4138 /* Show an error if it's an account */
4139 if (!TNY_IS_FOLDER (folder)) {
4140 modest_platform_run_information_dialog (GTK_WINDOW (window),
4141 _("mail_in_ui_folder_delete_error"),
4143 g_object_unref (G_OBJECT (folder));
4148 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4149 tny_folder_get_name (TNY_FOLDER (folder)));
4150 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4151 (const gchar *) message);
4154 if (response == GTK_RESPONSE_OK) {
4155 TnyAccount *account = NULL;
4156 DeleteFolderInfo *info = NULL;
4157 info = g_new0(DeleteFolderInfo, 1);
4158 info->folder = g_object_ref (folder);
4159 info->move_to_trash = move_to_trash;
4161 account = tny_folder_get_account (TNY_FOLDER (folder));
4162 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4164 TNY_FOLDER_STORE (account),
4165 on_delete_folder_cb, info);
4166 g_object_unref (account);
4167 g_object_unref (folder);
4175 modest_ui_actions_on_delete_folder (GtkAction *action,
4176 ModestWindow *window)
4178 modest_ui_actions_on_edit_mode_delete_folder (window);
4182 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4184 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4186 return delete_folder (window, FALSE);
4190 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4192 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4194 delete_folder (MODEST_WINDOW (main_window), TRUE);
4198 typedef struct _PasswordDialogFields {
4199 GtkWidget *username;
4200 GtkWidget *password;
4202 } PasswordDialogFields;
4205 password_dialog_check_field (GtkEditable *editable,
4206 PasswordDialogFields *fields)
4209 gboolean any_value_empty = FALSE;
4211 #ifdef MODEST_TOOLKIT_HILDON2
4212 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4214 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4216 if ((value == NULL) || value[0] == '\0') {
4217 any_value_empty = TRUE;
4219 #ifdef MODEST_TOOLKIT_HILDON2
4220 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4222 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4224 if ((value == NULL) || value[0] == '\0') {
4225 any_value_empty = TRUE;
4227 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4231 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4232 const gchar* server_account_name,
4237 ModestMainWindow *main_window)
4239 g_return_if_fail(server_account_name);
4240 gboolean completed = FALSE;
4241 PasswordDialogFields *fields = NULL;
4243 /* Initalize output parameters: */
4250 #ifndef MODEST_TOOLKIT_GTK
4251 /* Maemo uses a different (awkward) button order,
4252 * It should probably just use gtk_alternative_dialog_button_order ().
4254 #ifdef MODEST_TOOLKIT_HILDON2
4256 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4259 _HL("wdgt_bd_done"),
4260 GTK_RESPONSE_ACCEPT,
4262 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4263 HILDON_MARGIN_DOUBLE);
4266 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4269 _("mcen_bd_dialog_ok"),
4270 GTK_RESPONSE_ACCEPT,
4271 _("mcen_bd_dialog_cancel"),
4272 GTK_RESPONSE_REJECT,
4274 #endif /* MODEST_TOOLKIT_HILDON2 */
4277 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4281 GTK_RESPONSE_REJECT,
4283 GTK_RESPONSE_ACCEPT,
4285 #endif /* MODEST_TOOLKIT_GTK */
4287 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4289 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4290 modest_runtime_get_account_mgr(), server_account_name);
4291 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4292 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4295 gtk_widget_destroy (dialog);
4299 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4300 GtkWidget *label = gtk_label_new (txt);
4301 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4303 g_free (server_name);
4304 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4309 gchar *initial_username = modest_account_mgr_get_server_account_username (
4310 modest_runtime_get_account_mgr(), server_account_name);
4312 #ifdef MODEST_TOOLKIT_HILDON2
4313 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4314 if (initial_username)
4315 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4317 GtkWidget *entry_username = gtk_entry_new ();
4318 if (initial_username)
4319 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4321 /* Dim this if a connection has ever succeeded with this username,
4322 * as per the UI spec: */
4323 /* const gboolean username_known = */
4324 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4325 /* modest_runtime_get_account_mgr(), server_account_name); */
4326 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4328 /* We drop the username sensitive code and disallow changing it here
4329 * as tinymail does not support really changing the username in the callback
4331 gtk_widget_set_sensitive (entry_username, FALSE);
4333 #ifndef MODEST_TOOLKIT_GTK
4334 /* Auto-capitalization is the default, so let's turn it off: */
4335 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4337 /* Create a size group to be used by all captions.
4338 * Note that HildonCaption does not create a default size group if we do not specify one.
4339 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4340 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4342 #ifdef MODEST_TOOLKIT_HILDON2
4343 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4344 _("mail_fi_username"), FALSE,
4347 GtkWidget *caption = hildon_caption_new (sizegroup,
4348 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4350 gtk_widget_show (entry_username);
4351 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4352 FALSE, FALSE, MODEST_MARGIN_HALF);
4353 gtk_widget_show (caption);
4355 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4357 #endif /* !MODEST_TOOLKIT_GTK */
4360 #ifdef MODEST_TOOLKIT_HILDON2
4361 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4363 GtkWidget *entry_password = gtk_entry_new ();
4365 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4366 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4368 #ifndef MODEST_TOOLKIT_GTK
4369 /* Auto-capitalization is the default, so let's turn it off: */
4370 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4371 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4373 #ifdef MODEST_TOOLKIT_HILDON2
4374 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4375 _("mail_fi_password"), FALSE,
4378 caption = hildon_caption_new (sizegroup,
4379 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4381 gtk_widget_show (entry_password);
4382 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4383 FALSE, FALSE, MODEST_MARGIN_HALF);
4384 gtk_widget_show (caption);
4385 g_object_unref (sizegroup);
4387 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4389 #endif /* !MODEST_TOOLKIT_GTK */
4391 if (initial_username != NULL)
4392 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4394 /* This is not in the Maemo UI spec:
4395 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4396 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4400 fields = g_slice_new0 (PasswordDialogFields);
4401 fields->username = entry_username;
4402 fields->password = entry_password;
4403 fields->dialog = dialog;
4405 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4406 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4407 password_dialog_check_field (NULL, fields);
4409 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4411 while (!completed) {
4413 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4415 #ifdef MODEST_TOOLKIT_HILDON2
4416 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4418 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4421 /* Note that an empty field becomes the "" string */
4422 if (*username && strlen (*username) > 0) {
4423 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4424 server_account_name,
4428 const gboolean username_was_changed =
4429 (strcmp (*username, initial_username) != 0);
4430 if (username_was_changed) {
4431 g_warning ("%s: tinymail does not yet support changing the "
4432 "username in the get_password() callback.\n", __FUNCTION__);
4438 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4439 _("mcen_ib_username_pw_incorrect"));
4445 #ifdef MODEST_TOOLKIT_HILDON2
4446 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4448 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4451 /* We do not save the password in the configuration,
4452 * because this function is only called for passwords that should
4453 * not be remembered:
4454 modest_server_account_set_password (
4455 modest_runtime_get_account_mgr(), server_account_name,
4462 #ifndef MODEST_TOOLKIT_HILDON2
4463 /* Set parent to NULL or the banner will disappear with its parent dialog */
4464 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4476 /* This is not in the Maemo UI spec:
4477 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4483 g_free (initial_username);
4484 gtk_widget_destroy (dialog);
4485 g_slice_free (PasswordDialogFields, fields);
4487 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4491 modest_ui_actions_on_cut (GtkAction *action,
4492 ModestWindow *window)
4494 GtkWidget *focused_widget;
4495 GtkClipboard *clipboard;
4497 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4498 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4499 if (GTK_IS_EDITABLE (focused_widget)) {
4500 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4501 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4502 gtk_clipboard_store (clipboard);
4503 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4504 GtkTextBuffer *buffer;
4506 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4507 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4508 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4509 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4510 gtk_clipboard_store (clipboard);
4512 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4513 TnyList *header_list = modest_header_view_get_selected_headers (
4514 MODEST_HEADER_VIEW (focused_widget));
4515 gboolean continue_download = FALSE;
4516 gint num_of_unc_msgs;
4518 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4520 if (num_of_unc_msgs) {
4521 TnyAccount *account = get_account_from_header_list (header_list);
4523 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4524 g_object_unref (account);
4528 if (num_of_unc_msgs == 0 || continue_download) {
4529 /* modest_platform_information_banner (
4530 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4531 modest_header_view_cut_selection (
4532 MODEST_HEADER_VIEW (focused_widget));
4535 g_object_unref (header_list);
4536 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4537 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4542 modest_ui_actions_on_copy (GtkAction *action,
4543 ModestWindow *window)
4545 GtkClipboard *clipboard;
4546 GtkWidget *focused_widget;
4547 gboolean copied = TRUE;
4549 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4550 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4552 if (GTK_IS_LABEL (focused_widget)) {
4554 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4555 gtk_clipboard_set_text (clipboard, selection, -1);
4557 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4558 gtk_clipboard_store (clipboard);
4559 } else if (GTK_IS_EDITABLE (focused_widget)) {
4560 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4561 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4562 gtk_clipboard_store (clipboard);
4563 } else if (GTK_IS_HTML (focused_widget)) {
4566 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4567 if ((sel == NULL) || (sel[0] == '\0')) {
4570 gtk_html_copy (GTK_HTML (focused_widget));
4571 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4572 gtk_clipboard_store (clipboard);
4574 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4575 GtkTextBuffer *buffer;
4576 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4577 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4578 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4579 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4580 gtk_clipboard_store (clipboard);
4582 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4583 TnyList *header_list = modest_header_view_get_selected_headers (
4584 MODEST_HEADER_VIEW (focused_widget));
4585 gboolean continue_download = FALSE;
4586 gint num_of_unc_msgs;
4588 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4590 if (num_of_unc_msgs) {
4591 TnyAccount *account = get_account_from_header_list (header_list);
4593 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4594 g_object_unref (account);
4598 if (num_of_unc_msgs == 0 || continue_download) {
4599 modest_platform_information_banner (
4600 NULL, NULL, _CS("mcen_ib_getting_items"));
4601 modest_header_view_copy_selection (
4602 MODEST_HEADER_VIEW (focused_widget));
4606 g_object_unref (header_list);
4608 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4609 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4612 /* Show information banner if there was a copy to clipboard */
4614 modest_platform_information_banner (
4615 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4619 modest_ui_actions_on_undo (GtkAction *action,
4620 ModestWindow *window)
4622 ModestEmailClipboard *clipboard = NULL;
4624 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4625 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4626 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4627 /* Clear clipboard source */
4628 clipboard = modest_runtime_get_email_clipboard ();
4629 modest_email_clipboard_clear (clipboard);
4632 g_return_if_reached ();
4637 modest_ui_actions_on_redo (GtkAction *action,
4638 ModestWindow *window)
4640 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4641 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4644 g_return_if_reached ();
4650 destroy_information_note (ModestMailOperation *mail_op,
4653 /* destroy information note */
4654 gtk_widget_destroy (GTK_WIDGET(user_data));
4658 destroy_folder_information_note (ModestMailOperation *mail_op,
4659 TnyFolder *new_folder,
4662 /* destroy information note */
4663 gtk_widget_destroy (GTK_WIDGET(user_data));
4668 paste_as_attachment_free (gpointer data)
4670 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4672 if (helper->banner) {
4673 gtk_widget_destroy (helper->banner);
4674 g_object_unref (helper->banner);
4680 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4685 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4686 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4691 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4696 modest_ui_actions_on_paste (GtkAction *action,
4697 ModestWindow *window)
4699 GtkWidget *focused_widget = NULL;
4700 GtkWidget *inf_note = NULL;
4701 ModestMailOperation *mail_op = NULL;
4703 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4704 if (GTK_IS_EDITABLE (focused_widget)) {
4705 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4706 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4707 ModestEmailClipboard *e_clipboard = NULL;
4708 e_clipboard = modest_runtime_get_email_clipboard ();
4709 if (modest_email_clipboard_cleared (e_clipboard)) {
4710 GtkTextBuffer *buffer;
4711 GtkClipboard *clipboard;
4713 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4714 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4715 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4716 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4717 ModestMailOperation *mail_op;
4718 TnyFolder *src_folder = NULL;
4719 TnyList *data = NULL;
4721 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4722 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4723 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4724 _CS("ckct_nw_pasting"));
4725 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4726 mail_op = modest_mail_operation_new (G_OBJECT (window));
4727 if (helper->banner != NULL) {
4728 g_object_ref (G_OBJECT (helper->banner));
4729 gtk_widget_show (GTK_WIDGET (helper->banner));
4733 modest_mail_operation_get_msgs_full (mail_op,
4735 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4737 paste_as_attachment_free);
4741 g_object_unref (data);
4743 g_object_unref (src_folder);
4746 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4747 ModestEmailClipboard *clipboard = NULL;
4748 TnyFolder *src_folder = NULL;
4749 TnyFolderStore *folder_store = NULL;
4750 TnyList *data = NULL;
4751 gboolean delete = FALSE;
4753 /* Check clipboard source */
4754 clipboard = modest_runtime_get_email_clipboard ();
4755 if (modest_email_clipboard_cleared (clipboard))
4758 /* Get elements to paste */
4759 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4761 /* Create a new mail operation */
4762 mail_op = modest_mail_operation_new (G_OBJECT(window));
4764 /* Get destination folder */
4765 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4767 /* transfer messages */
4771 /* Ask for user confirmation */
4773 modest_ui_actions_msgs_move_to_confirmation (window,
4774 TNY_FOLDER (folder_store),
4778 if (response == GTK_RESPONSE_OK) {
4779 /* Launch notification */
4780 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4781 _CS("ckct_nw_pasting"));
4782 if (inf_note != NULL) {
4783 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4784 gtk_widget_show (GTK_WIDGET(inf_note));
4787 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4788 modest_mail_operation_xfer_msgs (mail_op,
4790 TNY_FOLDER (folder_store),
4792 destroy_information_note,
4795 g_object_unref (mail_op);
4798 } else if (src_folder != NULL) {
4799 /* Launch notification */
4800 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4801 _CS("ckct_nw_pasting"));
4802 if (inf_note != NULL) {
4803 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4804 gtk_widget_show (GTK_WIDGET(inf_note));
4807 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4808 modest_mail_operation_xfer_folder (mail_op,
4812 destroy_folder_information_note,
4818 g_object_unref (data);
4819 if (src_folder != NULL)
4820 g_object_unref (src_folder);
4821 if (folder_store != NULL)
4822 g_object_unref (folder_store);
4828 modest_ui_actions_on_select_all (GtkAction *action,
4829 ModestWindow *window)
4831 GtkWidget *focused_widget;
4833 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4834 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4835 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4836 } else if (GTK_IS_LABEL (focused_widget)) {
4837 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4838 } else if (GTK_IS_EDITABLE (focused_widget)) {
4839 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4840 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4841 GtkTextBuffer *buffer;
4842 GtkTextIter start, end;
4844 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4845 gtk_text_buffer_get_start_iter (buffer, &start);
4846 gtk_text_buffer_get_end_iter (buffer, &end);
4847 gtk_text_buffer_select_range (buffer, &start, &end);
4848 } else if (GTK_IS_HTML (focused_widget)) {
4849 gtk_html_select_all (GTK_HTML (focused_widget));
4850 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4851 GtkWidget *header_view = focused_widget;
4852 GtkTreeSelection *selection = NULL;
4854 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4855 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4856 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4859 /* Disable window dimming management */
4860 modest_window_disable_dimming (MODEST_WINDOW(window));
4862 /* Select all messages */
4863 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4864 gtk_tree_selection_select_all (selection);
4866 /* Set focuse on header view */
4867 gtk_widget_grab_focus (header_view);
4869 /* Enable window dimming management */
4870 modest_window_enable_dimming (MODEST_WINDOW(window));
4871 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4872 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4878 modest_ui_actions_on_mark_as_read (GtkAction *action,
4879 ModestWindow *window)
4881 g_return_if_fail (MODEST_IS_WINDOW(window));
4883 /* Mark each header as read */
4884 do_headers_action (window, headers_action_mark_as_read, NULL);
4888 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4889 ModestWindow *window)
4891 g_return_if_fail (MODEST_IS_WINDOW(window));
4893 /* Mark each header as read */
4894 do_headers_action (window, headers_action_mark_as_unread, NULL);
4898 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4899 GtkRadioAction *selected,
4900 ModestWindow *window)
4904 value = gtk_radio_action_get_current_value (selected);
4905 if (MODEST_IS_WINDOW (window)) {
4906 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4911 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4912 GtkRadioAction *selected,
4913 ModestWindow *window)
4915 TnyHeaderFlags flags;
4916 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4918 flags = gtk_radio_action_get_current_value (selected);
4919 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4923 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4924 GtkRadioAction *selected,
4925 ModestWindow *window)
4929 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4931 file_format = gtk_radio_action_get_current_value (selected);
4932 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4937 modest_ui_actions_on_zoom_plus (GtkAction *action,
4938 ModestWindow *window)
4940 g_return_if_fail (MODEST_IS_WINDOW (window));
4942 modest_window_zoom_plus (MODEST_WINDOW (window));
4946 modest_ui_actions_on_zoom_minus (GtkAction *action,
4947 ModestWindow *window)
4949 g_return_if_fail (MODEST_IS_WINDOW (window));
4951 modest_window_zoom_minus (MODEST_WINDOW (window));
4955 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4956 ModestWindow *window)
4958 ModestWindowMgr *mgr;
4959 gboolean fullscreen, active;
4960 g_return_if_fail (MODEST_IS_WINDOW (window));
4962 mgr = modest_runtime_get_window_mgr ();
4964 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4965 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4967 if (active != fullscreen) {
4968 modest_window_mgr_set_fullscreen_mode (mgr, active);
4969 #ifndef MODEST_TOOLKIT_HILDON2
4970 gtk_window_present (GTK_WINDOW (window));
4976 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4977 ModestWindow *window)
4979 ModestWindowMgr *mgr;
4980 gboolean fullscreen;
4982 g_return_if_fail (MODEST_IS_WINDOW (window));
4984 mgr = modest_runtime_get_window_mgr ();
4985 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4986 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4988 #ifndef MODEST_TOOLKIT_HILDON2
4989 gtk_window_present (GTK_WINDOW (window));
4994 * Used by modest_ui_actions_on_details to call do_headers_action
4997 headers_action_show_details (TnyHeader *header,
4998 ModestWindow *window,
5002 gboolean async_retrieval;
5005 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5006 async_retrieval = TRUE;
5007 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
5008 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
5010 async_retrieval = FALSE;
5012 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
5014 g_object_unref (msg);
5018 * Show the header details in a ModestDetailsDialog widget
5021 modest_ui_actions_on_details (GtkAction *action,
5024 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5028 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
5032 header = tny_msg_get_header (msg);
5034 headers_action_show_details (header, win, NULL);
5035 g_object_unref (header);
5037 g_object_unref (msg);
5039 } else if (MODEST_IS_MAIN_WINDOW (win)) {
5040 GtkWidget *folder_view, *header_view;
5042 /* Check which widget has the focus */
5043 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5044 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5045 if (gtk_widget_is_focus (folder_view)) {
5046 TnyFolderStore *folder_store
5047 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5048 if (!folder_store) {
5049 g_warning ("%s: No item was selected.\n", __FUNCTION__);
5052 /* Show only when it's a folder */
5053 /* This function should not be called for account items,
5054 * because we dim the menu item for them. */
5055 if (TNY_IS_FOLDER (folder_store)) {
5056 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5057 TNY_FOLDER (folder_store));
5060 g_object_unref (folder_store);
5063 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5064 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5065 /* Show details of each header */
5066 do_headers_action (win, headers_action_show_details, header_view);
5068 #ifdef MODEST_TOOLKIT_HILDON2
5069 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5071 GtkWidget *header_view;
5073 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5074 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5076 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5078 g_object_unref (folder);
5085 modest_ui_actions_on_limit_error (GtkAction *action,
5088 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5090 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5095 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5096 ModestMsgEditWindow *window)
5098 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5100 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5104 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5105 ModestMsgEditWindow *window)
5107 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5109 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5113 modest_ui_actions_toggle_folders_view (GtkAction *action,
5114 ModestMainWindow *main_window)
5116 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5118 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5119 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5121 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5125 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5126 ModestWindow *window)
5128 gboolean active, fullscreen = FALSE;
5129 ModestWindowMgr *mgr;
5131 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5133 /* Check if we want to toggle the toolbar view in fullscreen
5135 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5136 "ViewShowToolbarFullScreen")) {
5140 /* Toggle toolbar */
5141 mgr = modest_runtime_get_window_mgr ();
5142 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5146 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5147 ModestMsgEditWindow *window)
5149 modest_msg_edit_window_select_font (window);
5154 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5155 const gchar *display_name,
5158 /* don't update the display name if it was already set;
5159 * updating the display name apparently is expensive */
5160 const gchar* old_name = gtk_window_get_title (window);
5162 if (display_name == NULL)
5165 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5166 return; /* don't do anything */
5168 /* This is usually used to change the title of the main window, which
5169 * is the one that holds the folder view. Note that this change can
5170 * happen even when the widget doesn't have the focus. */
5171 gtk_window_set_title (window, display_name);
5176 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5178 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5179 modest_msg_edit_window_select_contacts (window);
5183 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5185 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5186 modest_msg_edit_window_check_names (window, FALSE);
5189 #ifndef MODEST_TOOLKIT_HILDON2
5191 * This function is used to track changes in the selection of the
5192 * folder view that is inside the "move to" dialog to enable/disable
5193 * the OK button because we do not want the user to select a disallowed
5194 * destination for a folder.
5195 * The user also not desired to be able to use NEW button on items where
5196 * folder creation is not possibel.
5199 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5200 TnyFolderStore *folder_store,
5204 GtkWidget *dialog = NULL;
5205 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5206 gboolean moving_folder = FALSE;
5207 gboolean is_local_account = TRUE;
5208 GtkWidget *folder_view = NULL;
5209 ModestTnyFolderRules rules;
5211 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5216 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5220 /* check if folder_store is an remote account */
5221 if (TNY_IS_ACCOUNT (folder_store)) {
5222 TnyAccount *local_account = NULL;
5223 TnyAccount *mmc_account = NULL;
5224 ModestTnyAccountStore *account_store = NULL;
5226 account_store = modest_runtime_get_account_store ();
5227 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5228 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5230 if ((gpointer) local_account != (gpointer) folder_store &&
5231 (gpointer) mmc_account != (gpointer) folder_store) {
5232 ModestProtocolType proto;
5233 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5234 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5235 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5237 is_local_account = FALSE;
5238 /* New button should be dimmed on remote
5240 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5242 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5244 g_object_unref (local_account);
5246 /* It could not exist */
5248 g_object_unref (mmc_account);
5251 /* Check the target folder rules */
5252 if (TNY_IS_FOLDER (folder_store)) {
5253 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5254 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5255 ok_sensitive = FALSE;
5256 new_sensitive = FALSE;
5261 /* Check if we're moving a folder */
5262 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5263 /* Get the widgets */
5264 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5265 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5266 if (gtk_widget_is_focus (folder_view))
5267 moving_folder = TRUE;
5270 if (moving_folder) {
5271 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5273 /* Get the folder to move */
5274 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5276 /* Check that we're not moving to the same folder */
5277 if (TNY_IS_FOLDER (moved_folder)) {
5278 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5279 if (parent == folder_store)
5280 ok_sensitive = FALSE;
5281 g_object_unref (parent);
5284 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5285 /* Do not allow to move to an account unless it's the
5286 local folders account */
5287 if (!is_local_account)
5288 ok_sensitive = FALSE;
5291 if (ok_sensitive && (moved_folder == folder_store)) {
5292 /* Do not allow to move to itself */
5293 ok_sensitive = FALSE;
5295 g_object_unref (moved_folder);
5297 TnyFolder *src_folder = NULL;
5299 /* Moving a message */
5300 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5302 TnyHeader *header = NULL;
5303 header = modest_msg_view_window_get_header
5304 (MODEST_MSG_VIEW_WINDOW (user_data));
5305 if (!TNY_IS_HEADER(header))
5306 g_warning ("%s: could not get source header", __FUNCTION__);
5308 src_folder = tny_header_get_folder (header);
5311 g_object_unref (header);
5314 TNY_FOLDER (modest_folder_view_get_selected
5315 (MODEST_FOLDER_VIEW (folder_view)));
5318 if (TNY_IS_FOLDER(src_folder)) {
5319 /* Do not allow to move the msg to the same folder */
5320 /* Do not allow to move the msg to an account */
5321 if ((gpointer) src_folder == (gpointer) folder_store ||
5322 TNY_IS_ACCOUNT (folder_store))
5323 ok_sensitive = FALSE;
5324 g_object_unref (src_folder);
5326 g_warning ("%s: could not get source folder", __FUNCTION__);
5330 /* Set sensitivity of the OK and NEW button */
5331 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5332 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5337 on_move_to_dialog_response (GtkDialog *dialog,
5341 GtkWidget *parent_win;
5342 MoveToInfo *helper = NULL;
5343 ModestFolderView *folder_view;
5344 gboolean unset_edit_mode = FALSE;
5346 helper = (MoveToInfo *) user_data;
5348 parent_win = (GtkWidget *) helper->win;
5349 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5350 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5352 TnyFolderStore *dst_folder;
5353 TnyFolderStore *selected;
5355 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5356 selected = modest_folder_view_get_selected (folder_view);
5357 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5358 g_object_unref (selected);
5360 case GTK_RESPONSE_NONE:
5361 case GTK_RESPONSE_CANCEL:
5362 case GTK_RESPONSE_DELETE_EVENT:
5364 case GTK_RESPONSE_OK:
5365 dst_folder = modest_folder_view_get_selected (folder_view);
5367 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5368 /* Clean list to move used for filtering */
5369 modest_folder_view_set_list_to_move (folder_view, NULL);
5371 modest_ui_actions_on_main_window_move_to (NULL,
5372 GTK_WIDGET (folder_view),
5374 MODEST_MAIN_WINDOW (parent_win));
5375 #ifdef MODEST_TOOLKIT_HILDON2
5376 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5377 /* Clean list to move used for filtering */
5378 modest_folder_view_set_list_to_move (folder_view, NULL);
5380 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5383 GTK_WINDOW (parent_win));
5386 /* if the user selected a root folder
5387 (account) then do not perform any action */
5388 if (TNY_IS_ACCOUNT (dst_folder)) {
5389 g_signal_stop_emission_by_name (dialog, "response");
5393 /* Clean list to move used for filtering */
5394 modest_folder_view_set_list_to_move (folder_view, NULL);
5396 /* Moving from headers window in edit mode */
5397 modest_ui_actions_on_window_move_to (NULL, helper->list,
5399 MODEST_WINDOW (parent_win));
5403 g_object_unref (dst_folder);
5405 unset_edit_mode = TRUE;
5408 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5411 /* Free the helper and exit */
5413 g_object_unref (helper->list);
5414 if (unset_edit_mode) {
5415 #ifdef MODEST_TOOLKIT_HILDON2
5416 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5419 g_slice_free (MoveToInfo, helper);
5420 gtk_widget_destroy (GTK_WIDGET (dialog));
5424 create_move_to_dialog (GtkWindow *win,
5425 GtkWidget *folder_view,
5426 TnyList *list_to_move)
5428 GtkWidget *dialog, *tree_view = NULL;
5430 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5432 #ifndef MODEST_TOOLKIT_HILDON2
5433 /* Track changes in the selection to
5434 * disable the OK button whenever "Move to" is not possible
5435 * disbale NEW button whenever New is not possible */
5436 g_signal_connect (tree_view,
5437 "folder_selection_changed",
5438 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5442 /* It could happen that we're trying to move a message from a
5443 window (msg window for example) after the main window was
5444 closed, so we can not just get the model of the folder
5446 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5447 const gchar *visible_id = NULL;
5449 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5450 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5451 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5452 MODEST_FOLDER_VIEW(tree_view));
5455 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5457 /* Show the same account than the one that is shown in the main window */
5458 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5461 const gchar *active_account_name = NULL;
5462 ModestAccountMgr *mgr = NULL;
5463 ModestAccountSettings *settings = NULL;
5464 ModestServerAccountSettings *store_settings = NULL;
5466 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5467 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5469 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5470 mgr = modest_runtime_get_account_mgr ();
5471 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5474 const gchar *store_account_name;
5475 store_settings = modest_account_settings_get_store_settings (settings);
5476 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5478 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5479 store_account_name);
5480 g_object_unref (store_settings);
5481 g_object_unref (settings);
5485 /* we keep a pointer to the embedded folder view, so we can
5486 * retrieve it with get_folder_view_from_move_to_dialog (see
5487 * above) later (needed for focus handling)
5489 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5491 /* Hide special folders */
5492 #ifndef MODEST_TOOLKIT_HILDON2
5493 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5496 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5497 #ifndef MODEST_TOOLKIT_HILDON2
5498 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5501 gtk_widget_show (GTK_WIDGET (tree_view));
5507 * Shows a confirmation dialog to the user when we're moving messages
5508 * from a remote server to the local storage. Returns the dialog
5509 * response. If it's other kind of movement then it always returns
5512 * This one is used by the next functions:
5513 * modest_ui_actions_on_paste - commented out
5514 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5517 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5518 TnyFolder *dest_folder,
5522 gint response = GTK_RESPONSE_OK;
5523 TnyAccount *account = NULL;
5524 TnyFolder *src_folder = NULL;
5525 TnyIterator *iter = NULL;
5526 TnyHeader *header = NULL;
5528 /* return with OK if the destination is a remote folder */
5529 if (modest_tny_folder_is_remote_folder (dest_folder))
5530 return GTK_RESPONSE_OK;
5532 /* Get source folder */
5533 iter = tny_list_create_iterator (headers);
5534 header = TNY_HEADER (tny_iterator_get_current (iter));
5536 src_folder = tny_header_get_folder (header);
5537 g_object_unref (header);
5539 g_object_unref (iter);
5541 /* if no src_folder, message may be an attahcment */
5542 if (src_folder == NULL)
5543 return GTK_RESPONSE_CANCEL;
5545 /* If the source is a local or MMC folder */
5546 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5547 g_object_unref (src_folder);
5548 return GTK_RESPONSE_OK;
5551 /* Get the account */
5552 account = tny_folder_get_account (src_folder);
5554 /* now if offline we ask the user */
5555 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5556 response = GTK_RESPONSE_OK;
5558 response = GTK_RESPONSE_CANCEL;
5561 g_object_unref (src_folder);
5562 g_object_unref (account);
5568 move_to_helper_destroyer (gpointer user_data)
5570 MoveToHelper *helper = (MoveToHelper *) user_data;
5572 /* Close the "Pasting" information banner */
5573 if (helper->banner) {
5574 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5575 g_object_unref (helper->banner);
5577 if (gtk_tree_row_reference_valid (helper->reference)) {
5578 gtk_tree_row_reference_free (helper->reference);
5579 helper->reference = NULL;
5585 move_to_cb (ModestMailOperation *mail_op,
5588 MoveToHelper *helper = (MoveToHelper *) user_data;
5589 GObject *object = modest_mail_operation_get_source (mail_op);
5591 /* Note that the operation could have failed, in that case do
5593 if (modest_mail_operation_get_status (mail_op) !=
5594 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5597 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5598 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5600 if (!modest_msg_view_window_select_next_message (self) &&
5601 !modest_msg_view_window_select_previous_message (self)) {
5602 /* No more messages to view, so close this window */
5603 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5605 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5606 gtk_tree_row_reference_valid (helper->reference)) {
5607 GtkWidget *header_view;
5609 GtkTreeSelection *sel;
5611 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5612 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5613 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5614 path = gtk_tree_row_reference_get_path (helper->reference);
5615 /* We need to unselect the previous one
5616 because we could be copying instead of
5618 gtk_tree_selection_unselect_all (sel);
5619 gtk_tree_selection_select_path (sel, path);
5620 gtk_tree_path_free (path);
5622 g_object_unref (object);
5625 /* Destroy the helper */
5626 move_to_helper_destroyer (helper);
5630 folder_move_to_cb (ModestMailOperation *mail_op,
5631 TnyFolder *new_folder,
5634 GtkWidget *folder_view;
5637 object = modest_mail_operation_get_source (mail_op);
5638 if (MODEST_IS_MAIN_WINDOW (object)) {
5639 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5640 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5641 g_object_ref (folder_view);
5642 g_object_unref (object);
5643 move_to_cb (mail_op, user_data);
5644 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5645 g_object_unref (folder_view);
5647 move_to_cb (mail_op, user_data);
5652 msgs_move_to_cb (ModestMailOperation *mail_op,
5655 move_to_cb (mail_op, user_data);
5659 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5662 GObject *win = NULL;
5663 const GError *error;
5664 TnyAccount *account = NULL;
5666 #ifndef MODEST_TOOLKIT_HILDON2
5667 ModestWindow *main_window = NULL;
5669 /* Disable next automatic folder selection */
5670 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5671 FALSE); /* don't create */
5673 /* Show notification dialog only if the main window exists */
5675 GtkWidget *folder_view = NULL;
5677 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5678 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5679 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5681 if (user_data && TNY_IS_FOLDER (user_data)) {
5682 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5683 TNY_FOLDER (user_data), FALSE);
5687 win = modest_mail_operation_get_source (mail_op);
5688 error = modest_mail_operation_get_error (mail_op);
5690 if (TNY_IS_FOLDER (user_data))
5691 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5692 else if (TNY_IS_ACCOUNT (user_data))
5693 account = g_object_ref (user_data);
5695 /* If it's not a disk full error then show a generic error */
5696 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5697 (GtkWidget *) win, (GError *) error,
5699 modest_platform_run_information_dialog ((GtkWindow *) win,
5700 _("mail_in_ui_folder_move_target_error"),
5703 g_object_unref (account);
5705 g_object_unref (win);
5709 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5718 gint pending_purges = 0;
5719 gboolean some_purged = FALSE;
5720 ModestWindow *win = MODEST_WINDOW (user_data);
5721 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5723 /* If there was any error */
5724 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5725 modest_window_mgr_unregister_header (mgr, header);
5729 /* Once the message has been retrieved for purging, we check if
5730 * it's all ok for purging */
5732 parts = tny_simple_list_new ();
5733 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5734 iter = tny_list_create_iterator (parts);
5736 while (!tny_iterator_is_done (iter)) {
5738 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5739 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5740 if (tny_mime_part_is_purged (part))
5747 g_object_unref (part);
5749 tny_iterator_next (iter);
5751 g_object_unref (iter);
5754 if (pending_purges>0) {
5756 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5758 if (response == GTK_RESPONSE_OK) {
5761 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5762 iter = tny_list_create_iterator (parts);
5763 while (!tny_iterator_is_done (iter)) {
5766 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5767 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5768 tny_mime_part_set_purged (part);
5771 g_object_unref (part);
5773 tny_iterator_next (iter);
5775 g_object_unref (iter);
5777 tny_msg_rewrite_cache (msg);
5779 gtk_widget_destroy (info);
5783 modest_window_mgr_unregister_header (mgr, header);
5785 g_object_unref (parts);
5789 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5790 ModestMainWindow *win)
5792 GtkWidget *header_view;
5793 TnyList *header_list;
5795 TnyHeaderFlags flags;
5796 ModestWindow *msg_view_window = NULL;
5799 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5801 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5802 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5804 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5806 g_warning ("%s: no header selected", __FUNCTION__);
5810 if (tny_list_get_length (header_list) == 1) {
5811 TnyIterator *iter = tny_list_create_iterator (header_list);
5812 header = TNY_HEADER (tny_iterator_get_current (iter));
5813 g_object_unref (iter);
5817 if (!header || !TNY_IS_HEADER(header)) {
5818 g_warning ("%s: header is not valid", __FUNCTION__);
5822 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5823 header, &msg_view_window);
5824 flags = tny_header_get_flags (header);
5825 if (!(flags & TNY_HEADER_FLAG_CACHED))
5828 if (msg_view_window != NULL)
5829 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5831 /* do nothing; uid was registered before, so window is probably on it's way */
5832 g_debug ("header %p has already been registered", header);
5835 ModestMailOperation *mail_op = NULL;
5836 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5837 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5838 modest_ui_actions_disk_operations_error_handler,
5840 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5841 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5843 g_object_unref (mail_op);
5846 g_object_unref (header);
5848 g_object_unref (header_list);
5852 * Checks if we need a connection to do the transfer and if the user
5853 * wants to connect to complete it
5856 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5857 TnyFolderStore *src_folder,
5859 TnyFolder *dst_folder,
5860 gboolean delete_originals,
5861 gboolean *need_connection,
5864 TnyAccount *src_account;
5865 gint uncached_msgs = 0;
5867 /* We don't need any further check if
5869 * 1- the source folder is local OR
5870 * 2- the device is already online
5872 if (!modest_tny_folder_store_is_remote (src_folder) ||
5873 tny_device_is_online (modest_runtime_get_device())) {
5874 *need_connection = FALSE;
5879 /* We must ask for a connection when
5881 * - the message(s) is not already cached OR
5882 * - the message(s) is cached but the leave_on_server setting
5883 * is FALSE (because we need to sync the source folder to
5884 * delete the message from the server (for IMAP we could do it
5885 * offline, it'll take place the next time we get a
5888 uncached_msgs = header_list_count_uncached_msgs (headers);
5889 src_account = get_account_from_folder_store (src_folder);
5890 if (uncached_msgs > 0) {
5894 *need_connection = TRUE;
5895 num_headers = tny_list_get_length (headers);
5896 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5898 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5899 GTK_RESPONSE_CANCEL) {
5905 /* The transfer is possible and the user wants to */
5908 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5909 const gchar *account_name;
5910 gboolean leave_on_server;
5912 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5913 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5916 if (leave_on_server == TRUE) {
5917 *need_connection = FALSE;
5919 *need_connection = TRUE;
5922 *need_connection = FALSE;
5927 g_object_unref (src_account);
5931 xfer_messages_error_handler (ModestMailOperation *mail_op,
5935 const GError *error;
5936 TnyAccount *account;
5938 win = modest_mail_operation_get_source (mail_op);
5939 error = modest_mail_operation_get_error (mail_op);
5941 /* We cannot get the account from the mail op as that is the
5942 source account and for checking memory full conditions we
5943 need the destination one */
5944 account = TNY_ACCOUNT (user_data);
5947 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5948 (GtkWidget *) win, (GError*) error,
5949 account, _KR("cerm_memory_card_full"))) {
5950 modest_platform_run_information_dialog ((GtkWindow *) win,
5951 _("mail_in_ui_folder_move_target_error"),
5955 g_object_unref (win);
5959 TnyFolderStore *dst_folder;
5964 * Utility function that transfer messages from both the main window
5965 * and the msg view window when using the "Move to" dialog
5968 xfer_messages_performer (gboolean canceled,
5970 GtkWindow *parent_window,
5971 TnyAccount *account,
5974 ModestWindow *win = MODEST_WINDOW (parent_window);
5975 TnyAccount *dst_account = NULL;
5976 gboolean dst_forbids_message_add = FALSE;
5977 XferMsgsHelper *helper;
5978 MoveToHelper *movehelper;
5979 ModestMailOperation *mail_op;
5981 helper = (XferMsgsHelper *) user_data;
5983 if (canceled || err) {
5984 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5985 (GtkWidget *) parent_window, err,
5987 /* Show the proper error message */
5988 modest_ui_actions_on_account_connection_error (parent_window, account);
5993 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5995 /* tinymail will return NULL for local folders it seems */
5996 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5997 modest_tny_account_get_protocol_type (dst_account),
5998 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
6000 if (dst_forbids_message_add) {
6001 modest_platform_information_banner (GTK_WIDGET (win),
6003 ngettext("mail_in_ui_folder_move_target_error",
6004 "mail_in_ui_folder_move_targets_error",
6005 tny_list_get_length (helper->headers)));
6009 movehelper = g_new0 (MoveToHelper, 1);
6011 #ifndef MODEST_TOOLKIT_HILDON2
6012 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
6013 _CS("ckct_nw_pasting"));
6014 if (movehelper->banner != NULL) {
6015 g_object_ref (movehelper->banner);
6016 gtk_widget_show (GTK_WIDGET (movehelper->banner));
6020 if (MODEST_IS_MAIN_WINDOW (win)) {
6021 GtkWidget *header_view =
6022 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6023 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6024 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
6027 /* Perform the mail operation */
6028 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
6029 xfer_messages_error_handler,
6030 g_object_ref (dst_account),
6032 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6035 modest_mail_operation_xfer_msgs (mail_op,
6037 TNY_FOLDER (helper->dst_folder),
6042 g_object_unref (G_OBJECT (mail_op));
6045 g_object_unref (dst_account);
6046 g_object_unref (helper->dst_folder);
6047 g_object_unref (helper->headers);
6048 g_slice_free (XferMsgsHelper, helper);
6052 TnyFolder *src_folder;
6053 TnyFolderStore *dst_folder;
6054 gboolean delete_original;
6055 GtkWidget *folder_view;
6059 on_move_folder_cb (gboolean canceled,
6061 GtkWindow *parent_window,
6062 TnyAccount *account,
6065 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
6066 GtkTreeSelection *sel;
6067 ModestMailOperation *mail_op = NULL;
6069 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6070 /* Note that the connection process can fail due to
6071 memory low conditions as it can not successfully
6072 store the summary */
6073 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6074 (GtkWidget*) parent_window, err,
6076 g_debug ("Error connecting when trying to move a folder");
6078 g_object_unref (G_OBJECT (info->src_folder));
6079 g_object_unref (G_OBJECT (info->dst_folder));
6084 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6085 #ifndef MODEST_TOOLKIT_HILDON2
6086 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6087 _CS("ckct_nw_pasting"));
6088 if (helper->banner != NULL) {
6089 g_object_ref (helper->banner);
6090 gtk_widget_show (GTK_WIDGET(helper->banner));
6093 /* Clean folder on header view before moving it */
6094 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6095 gtk_tree_selection_unselect_all (sel);
6097 /* Let gtk events run. We need that the folder
6098 view frees its reference to the source
6099 folder *before* issuing the mail operation
6100 so we need the signal handler of selection
6101 changed to happen before the mail
6103 while (gtk_events_pending ())
6104 gtk_main_iteration (); */
6107 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6108 modest_ui_actions_move_folder_error_handler,
6109 g_object_ref (info->dst_folder), g_object_unref);
6110 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6113 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6114 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6115 TNY_FOLDER (info->dst_folder), TRUE);
6117 modest_mail_operation_xfer_folder (mail_op,
6118 TNY_FOLDER (info->src_folder),
6120 info->delete_original,
6123 g_object_unref (G_OBJECT (info->src_folder));
6125 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6128 /* Unref mail operation */
6129 g_object_unref (G_OBJECT (mail_op));
6130 g_object_unref (G_OBJECT (info->dst_folder));
6135 get_account_from_folder_store (TnyFolderStore *folder_store)
6137 if (TNY_IS_ACCOUNT (folder_store))
6138 return g_object_ref (folder_store);
6140 return tny_folder_get_account (TNY_FOLDER (folder_store));
6144 * UI handler for the "Move to" action when invoked from the
6148 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6149 GtkWidget *folder_view,
6150 TnyFolderStore *dst_folder,
6151 ModestMainWindow *win)
6153 ModestHeaderView *header_view = NULL;
6154 TnyFolderStore *src_folder = NULL;
6156 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6158 /* Get the source folder */
6159 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6161 /* Get header view */
6162 header_view = (ModestHeaderView *)
6163 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6165 /* Get folder or messages to transfer */
6166 if (gtk_widget_is_focus (folder_view)) {
6167 gboolean do_xfer = TRUE;
6169 /* Allow only to transfer folders to the local root folder */
6170 if (TNY_IS_ACCOUNT (dst_folder) &&
6171 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6172 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6174 } else if (!TNY_IS_FOLDER (src_folder)) {
6175 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6180 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6181 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6183 info->src_folder = g_object_ref (src_folder);
6184 info->dst_folder = g_object_ref (dst_folder);
6185 info->delete_original = TRUE;
6186 info->folder_view = folder_view;
6188 connect_info->callback = on_move_folder_cb;
6189 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6190 connect_info->data = info;
6192 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6193 TNY_FOLDER_STORE (src_folder),
6196 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6199 headers = modest_header_view_get_selected_headers(header_view);
6201 /* Transfer the messages */
6202 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6203 headers, TNY_FOLDER (dst_folder));
6205 g_object_unref (headers);
6209 g_object_unref (src_folder);
6212 #ifdef MODEST_TOOLKIT_HILDON2
6214 * UI handler for the "Move to" action when invoked from the
6215 * ModestFolderWindow
6218 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6219 TnyFolderStore *dst_folder,
6223 TnyFolderStore *src_folder = NULL;
6224 TnyIterator *iterator;
6226 if (tny_list_get_length (selection) != 1)
6229 iterator = tny_list_create_iterator (selection);
6230 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6231 g_object_unref (iterator);
6234 gboolean do_xfer = TRUE;
6236 /* Allow only to transfer folders to the local root folder */
6237 if (TNY_IS_ACCOUNT (dst_folder) &&
6238 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6239 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6242 modest_platform_run_information_dialog (win,
6243 _("mail_in_ui_folder_move_target_error"),
6245 } else if (!TNY_IS_FOLDER (src_folder)) {
6246 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6251 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6252 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6254 info->src_folder = g_object_ref (src_folder);
6255 info->dst_folder = g_object_ref (dst_folder);
6256 info->delete_original = TRUE;
6257 info->folder_view = folder_view;
6259 connect_info->callback = on_move_folder_cb;
6260 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6261 connect_info->data = info;
6263 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6264 TNY_FOLDER_STORE (src_folder),
6269 g_object_unref (src_folder);
6275 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6276 TnyFolder *src_folder,
6278 TnyFolder *dst_folder)
6280 gboolean need_connection = TRUE;
6281 gboolean do_xfer = TRUE;
6282 XferMsgsHelper *helper;
6284 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6285 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6286 g_return_if_fail (TNY_IS_LIST (headers));
6288 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6289 headers, TNY_FOLDER (dst_folder),
6290 TRUE, &need_connection,
6293 /* If we don't want to transfer just return */
6297 /* Create the helper */
6298 helper = g_slice_new (XferMsgsHelper);
6299 helper->dst_folder = g_object_ref (dst_folder);
6300 helper->headers = g_object_ref (headers);
6302 if (need_connection) {
6303 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6304 connect_info->callback = xfer_messages_performer;
6305 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6306 connect_info->data = helper;
6308 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6309 TNY_FOLDER_STORE (src_folder),
6312 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6313 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6314 src_account, helper);
6315 g_object_unref (src_account);
6320 * UI handler for the "Move to" action when invoked from the
6321 * ModestMsgViewWindow
6324 modest_ui_actions_on_window_move_to (GtkAction *action,
6326 TnyFolderStore *dst_folder,
6329 TnyFolder *src_folder = NULL;
6331 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6334 TnyHeader *header = NULL;
6337 iter = tny_list_create_iterator (headers);
6338 header = (TnyHeader *) tny_iterator_get_current (iter);
6339 src_folder = tny_header_get_folder (header);
6341 /* Transfer the messages */
6342 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6344 TNY_FOLDER (dst_folder));
6347 g_object_unref (header);
6348 g_object_unref (iter);
6349 g_object_unref (src_folder);
6354 modest_ui_actions_on_move_to (GtkAction *action,
6357 modest_ui_actions_on_edit_mode_move_to (win);
6361 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6363 GtkWidget *dialog = NULL;
6364 MoveToInfo *helper = NULL;
6365 TnyList *list_to_move;
6367 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6369 #ifndef MODEST_TOOLKIT_HILDON2
6370 /* Get the main window if exists */
6371 ModestMainWindow *main_window;
6372 if (MODEST_IS_MAIN_WINDOW (win))
6373 main_window = MODEST_MAIN_WINDOW (win);
6376 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6377 FALSE)); /* don't create */
6380 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6385 if (tny_list_get_length (list_to_move) < 1) {
6386 g_object_unref (list_to_move);
6390 /* Create and run the dialog */
6391 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6392 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6393 GTK_WINDOW (dialog),
6397 helper = g_slice_new0 (MoveToInfo);
6398 helper->list = list_to_move;
6401 /* Listen to response signal */
6402 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6404 /* Show the dialog */
6405 gtk_widget_show (dialog);
6411 * Calls #HeadersFunc for each header already selected in the main
6412 * window or the message currently being shown in the msg view window
6415 do_headers_action (ModestWindow *win,
6419 TnyList *headers_list = NULL;
6420 TnyIterator *iter = NULL;
6421 TnyHeader *header = NULL;
6422 TnyFolder *folder = NULL;
6425 headers_list = get_selected_headers (win);
6429 /* Get the folder */
6430 iter = tny_list_create_iterator (headers_list);
6431 header = TNY_HEADER (tny_iterator_get_current (iter));
6433 folder = tny_header_get_folder (header);
6434 g_object_unref (header);
6437 /* Call the function for each header */
6438 while (!tny_iterator_is_done (iter)) {
6439 header = TNY_HEADER (tny_iterator_get_current (iter));
6440 func (header, win, user_data);
6441 g_object_unref (header);
6442 tny_iterator_next (iter);
6445 /* Trick: do a poke status in order to speed up the signaling
6448 tny_folder_poke_status (folder);
6449 g_object_unref (folder);
6453 g_object_unref (iter);
6454 g_object_unref (headers_list);
6458 modest_ui_actions_view_attachment (GtkAction *action,
6459 ModestWindow *window)
6461 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6462 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6464 /* not supported window for this action */
6465 g_return_if_reached ();
6470 modest_ui_actions_save_attachments (GtkAction *action,
6471 ModestWindow *window)
6473 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6475 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6478 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6480 /* not supported window for this action */
6481 g_return_if_reached ();
6486 modest_ui_actions_remove_attachments (GtkAction *action,
6487 ModestWindow *window)
6489 if (MODEST_IS_MAIN_WINDOW (window)) {
6490 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6491 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6492 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6494 /* not supported window for this action */
6495 g_return_if_reached ();
6500 modest_ui_actions_on_settings (GtkAction *action,
6505 dialog = modest_platform_get_global_settings_dialog ();
6506 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6507 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6508 gtk_widget_show_all (dialog);
6510 gtk_dialog_run (GTK_DIALOG (dialog));
6512 gtk_widget_destroy (dialog);
6516 modest_ui_actions_on_help (GtkAction *action,
6519 /* Help app is not available at all in fremantle */
6520 #ifndef MODEST_TOOLKIT_HILDON2
6521 const gchar *help_id;
6523 g_return_if_fail (win && GTK_IS_WINDOW(win));
6525 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6528 modest_platform_show_help (GTK_WINDOW (win), help_id);
6533 modest_ui_actions_on_csm_help (GtkAction *action,
6536 /* Help app is not available at all in fremantle */
6537 #ifndef MODEST_TOOLKIT_HILDON2
6539 const gchar* help_id = NULL;
6540 GtkWidget *folder_view;
6541 TnyFolderStore *folder_store;
6543 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6545 /* Get selected folder */
6546 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6547 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6548 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6550 /* Switch help_id */
6551 if (folder_store && TNY_IS_FOLDER (folder_store))
6552 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6555 g_object_unref (folder_store);
6558 modest_platform_show_help (GTK_WINDOW (win), help_id);
6560 modest_ui_actions_on_help (action, win);
6565 retrieve_contents_cb (ModestMailOperation *mail_op,
6572 /* We only need this callback to show an error in case of
6573 memory low condition */
6574 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6575 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6580 retrieve_msg_contents_performer (gboolean canceled,
6582 GtkWindow *parent_window,
6583 TnyAccount *account,
6586 ModestMailOperation *mail_op;
6587 TnyList *headers = TNY_LIST (user_data);
6589 if (err || canceled) {
6590 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6591 (GtkWidget *) parent_window, err,
6596 /* Create mail operation */
6597 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6598 modest_ui_actions_disk_operations_error_handler,
6600 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6601 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6604 g_object_unref (mail_op);
6606 g_object_unref (headers);
6607 g_object_unref (account);
6611 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6612 ModestWindow *window)
6614 TnyList *headers = NULL;
6615 TnyAccount *account = NULL;
6616 TnyIterator *iter = NULL;
6617 TnyHeader *header = NULL;
6618 TnyFolder *folder = NULL;
6621 headers = get_selected_headers (window);
6625 /* Pick the account */
6626 iter = tny_list_create_iterator (headers);
6627 header = TNY_HEADER (tny_iterator_get_current (iter));
6628 folder = tny_header_get_folder (header);
6629 account = tny_folder_get_account (folder);
6630 g_object_unref (folder);
6631 g_object_unref (header);
6632 g_object_unref (iter);
6634 /* Connect and perform the message retrieval */
6635 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6636 g_object_ref (account),
6637 retrieve_msg_contents_performer,
6638 g_object_ref (headers));
6641 g_object_unref (account);
6642 g_object_unref (headers);
6646 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6648 g_return_if_fail (MODEST_IS_WINDOW (window));
6651 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6655 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6657 g_return_if_fail (MODEST_IS_WINDOW (window));
6660 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6664 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6665 ModestWindow *window)
6667 g_return_if_fail (MODEST_IS_WINDOW (window));
6670 modest_ui_actions_check_menu_dimming_rules (window);
6674 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6675 ModestWindow *window)
6677 g_return_if_fail (MODEST_IS_WINDOW (window));
6680 modest_ui_actions_check_menu_dimming_rules (window);
6684 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6685 ModestWindow *window)
6687 g_return_if_fail (MODEST_IS_WINDOW (window));
6690 modest_ui_actions_check_menu_dimming_rules (window);
6694 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6695 ModestWindow *window)
6697 g_return_if_fail (MODEST_IS_WINDOW (window));
6700 modest_ui_actions_check_menu_dimming_rules (window);
6704 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6705 ModestWindow *window)
6707 g_return_if_fail (MODEST_IS_WINDOW (window));
6710 modest_ui_actions_check_menu_dimming_rules (window);
6714 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6715 ModestWindow *window)
6717 g_return_if_fail (MODEST_IS_WINDOW (window));
6720 modest_ui_actions_check_menu_dimming_rules (window);
6724 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6725 ModestWindow *window)
6727 g_return_if_fail (MODEST_IS_WINDOW (window));
6730 modest_ui_actions_check_menu_dimming_rules (window);
6734 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6735 ModestWindow *window)
6737 g_return_if_fail (MODEST_IS_WINDOW (window));
6740 modest_ui_actions_check_menu_dimming_rules (window);
6744 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6745 ModestWindow *window)
6747 g_return_if_fail (MODEST_IS_WINDOW (window));
6750 modest_ui_actions_check_menu_dimming_rules (window);
6754 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6756 g_return_if_fail (MODEST_IS_WINDOW (window));
6758 /* we check for low-mem; in that case, show a warning, and don't allow
6761 if (modest_platform_check_memory_low (window, TRUE))
6764 modest_platform_show_search_messages (GTK_WINDOW (window));
6768 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6770 g_return_if_fail (MODEST_IS_WINDOW (win));
6773 /* we check for low-mem; in that case, show a warning, and don't allow
6774 * for the addressbook
6776 if (modest_platform_check_memory_low (win, TRUE))
6780 modest_platform_show_addressbook (GTK_WINDOW (win));
6785 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6786 ModestWindow *window)
6789 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6791 if (GTK_IS_TOGGLE_ACTION (action))
6792 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6796 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6801 on_send_receive_finished (ModestMailOperation *mail_op,
6804 GtkWidget *header_view, *folder_view;
6805 TnyFolderStore *folder_store;
6806 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6808 /* Set send/receive operation finished */
6809 modest_main_window_notify_send_receive_completed (main_win);
6811 /* Don't refresh the current folder if there were any errors */
6812 if (modest_mail_operation_get_status (mail_op) !=
6813 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6816 /* Refresh the current folder if we're viewing a window. We do
6817 this because the user won't be able to see the new mails in
6818 the selected folder after a Send&Receive because it only
6819 performs a poke_status, i.e, only the number of read/unread
6820 messages is updated, but the new headers are not
6822 folder_view = modest_main_window_get_child_widget (main_win,
6823 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6827 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6829 /* Do not need to refresh INBOX again because the
6830 update_account does it always automatically */
6831 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6832 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6833 ModestMailOperation *refresh_op;
6835 header_view = modest_main_window_get_child_widget (main_win,
6836 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6838 /* We do not need to set the contents style
6839 because it hasn't changed. We also do not
6840 need to save the widget status. Just force
6842 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6843 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6844 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6845 folder_refreshed_cb, main_win);
6846 g_object_unref (refresh_op);
6850 g_object_unref (folder_store);
6855 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6861 const gchar* server_name = NULL;
6862 TnyTransportAccount *transport;
6863 gchar *message = NULL;
6864 ModestProtocol *protocol;
6866 /* Don't show anything if the user cancelled something or the
6867 * send receive request is not interactive. Authentication
6868 * errors are managed by the account store so no need to show
6869 * a dialog here again */
6870 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6871 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6872 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6876 /* Get the server name. Note that we could be using a
6877 connection specific transport account */
6878 transport = (TnyTransportAccount *)
6879 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6881 ModestTnyAccountStore *acc_store;
6882 const gchar *acc_name;
6883 TnyTransportAccount *conn_specific;
6885 acc_store = modest_runtime_get_account_store();
6886 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6887 conn_specific = (TnyTransportAccount *)
6888 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6889 if (conn_specific) {
6890 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6891 g_object_unref (conn_specific);
6893 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6895 g_object_unref (transport);
6899 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6900 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6901 tny_account_get_proto (TNY_ACCOUNT (transport)));
6903 g_warning ("%s: Account with no proto", __FUNCTION__);
6907 /* Show the appropriate message text for the GError: */
6908 switch (err->code) {
6909 case TNY_SERVICE_ERROR_CONNECT:
6910 message = modest_protocol_get_translation (protocol,
6911 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6914 case TNY_SERVICE_ERROR_SEND:
6915 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6917 case TNY_SERVICE_ERROR_UNAVAILABLE:
6918 message = modest_protocol_get_translation (protocol,
6919 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6923 g_warning ("%s: unexpected ERROR %d",
6924 __FUNCTION__, err->code);
6925 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6929 modest_platform_run_information_dialog (NULL, message, FALSE);
6934 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6939 ModestWindow *top_window = NULL;
6940 ModestWindowMgr *mgr = NULL;
6941 GtkWidget *header_view = NULL;
6942 TnyFolder *selected_folder = NULL;
6943 TnyFolderType folder_type;
6945 mgr = modest_runtime_get_window_mgr ();
6946 top_window = modest_window_mgr_get_current_top (mgr);
6951 #ifndef MODEST_TOOLKIT_HILDON2
6952 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6953 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6954 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6957 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6958 header_view = (GtkWidget *)
6959 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6963 /* Get selected folder */
6965 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6966 if (!selected_folder)
6969 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6970 #if GTK_CHECK_VERSION(2, 8, 0)
6971 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6972 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6973 GtkTreeViewColumn *tree_column;
6975 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6976 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6978 gtk_tree_view_column_queue_resize (tree_column);
6980 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6981 gtk_widget_queue_draw (header_view);
6984 #ifndef MODEST_TOOLKIT_HILDON2
6985 /* Rerun dimming rules, because the message could become deletable for example */
6986 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6987 MODEST_DIMMING_RULES_TOOLBAR);
6988 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6989 MODEST_DIMMING_RULES_MENU);
6993 g_object_unref (selected_folder);
6997 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6998 TnyAccount *account)
7000 ModestProtocolType protocol_type;
7001 ModestProtocol *protocol;
7002 gchar *error_note = NULL;
7004 protocol_type = modest_tny_account_get_protocol_type (account);
7005 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7008 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
7009 if (error_note == NULL) {
7010 g_warning ("%s: This should not be reached", __FUNCTION__);
7012 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
7013 g_free (error_note);
7018 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
7022 TnyFolderStore *folder = NULL;
7023 TnyAccount *account = NULL;
7024 ModestProtocolType proto;
7025 ModestProtocol *protocol;
7026 TnyHeader *header = NULL;
7028 if (MODEST_IS_MAIN_WINDOW (win)) {
7029 GtkWidget *header_view;
7030 TnyList* headers = NULL;
7032 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
7033 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7034 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7035 if (!headers || tny_list_get_length (headers) == 0) {
7037 g_object_unref (headers);
7040 iter = tny_list_create_iterator (headers);
7041 header = TNY_HEADER (tny_iterator_get_current (iter));
7042 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7043 g_object_unref (iter);
7044 g_object_unref (headers);
7045 #ifdef MODEST_TOOLKIT_HILDON2
7046 } else if (MODEST_IS_HEADER_WINDOW (win)) {
7047 GtkWidget *header_view;
7048 TnyList* headers = NULL;
7050 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
7051 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7052 if (!headers || tny_list_get_length (headers) == 0) {
7054 g_object_unref (headers);
7057 iter = tny_list_create_iterator (headers);
7058 header = TNY_HEADER (tny_iterator_get_current (iter));
7060 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7062 g_warning ("List should contain headers");
7064 g_object_unref (iter);
7065 g_object_unref (headers);
7067 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7068 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7070 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7073 if (!header || !folder)
7076 /* Get the account type */
7077 account = tny_folder_get_account (TNY_FOLDER (folder));
7078 proto = modest_tny_account_get_protocol_type (account);
7079 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7082 subject = tny_header_dup_subject (header);
7083 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7087 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7093 g_object_unref (account);
7095 g_object_unref (folder);
7097 g_object_unref (header);
7103 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7104 const gchar *account_name,
7105 const gchar *account_title)
7107 ModestAccountMgr *account_mgr;
7110 ModestProtocol *protocol;
7111 gboolean removed = FALSE;
7113 g_return_val_if_fail (account_name, FALSE);
7114 g_return_val_if_fail (account_title, FALSE);
7116 account_mgr = modest_runtime_get_account_mgr();
7118 /* The warning text depends on the account type: */
7119 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7120 modest_account_mgr_get_store_protocol (account_mgr,
7122 txt = modest_protocol_get_translation (protocol,
7123 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7126 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7128 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7132 if (response == GTK_RESPONSE_OK) {
7133 /* Remove account. If it succeeds then it also removes
7134 the account from the ModestAccountView: */
7135 gboolean is_default = FALSE;
7136 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7137 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7139 g_free (default_account_name);
7141 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7143 #ifdef MODEST_TOOLKIT_HILDON2
7144 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7146 /* Close all email notifications, we cannot
7147 distinguish if the notification belongs to
7148 this account or not, so for safety reasons
7149 we remove them all */
7150 modest_platform_remove_new_mail_notifications (FALSE, account_name);
7152 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7159 on_fetch_images_performer (gboolean canceled,
7161 GtkWindow *parent_window,
7162 TnyAccount *account,
7165 if (err || canceled) {
7166 /* Show an unable to retrieve images ??? */
7170 /* Note that the user could have closed the window while connecting */
7171 if (GTK_WIDGET_VISIBLE (parent_window))
7172 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7173 g_object_unref ((GObject *) user_data);
7177 modest_ui_actions_on_fetch_images (GtkAction *action,
7178 ModestWindow *window)
7180 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7182 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7184 on_fetch_images_performer,
7185 g_object_ref (window));
7189 modest_ui_actions_on_reload_message (const gchar *msg_id)
7191 ModestWindow *window = NULL;
7193 g_return_if_fail (msg_id && msg_id[0] != '\0');
7194 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7200 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7203 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7206 /** Check whether any connections are active, and cancel them if
7208 * Returns TRUE is there was no problem,
7209 * or if an operation was cancelled so we can continue.
7210 * Returns FALSE if the user chose to cancel his request instead.
7214 modest_ui_actions_check_for_active_account (ModestWindow *self,
7215 const gchar* account_name)
7217 ModestTnySendQueue *send_queue;
7218 ModestTnyAccountStore *acc_store;
7219 ModestMailOperationQueue* queue;
7220 TnyConnectionStatus store_conn_status;
7221 TnyAccount *store_account = NULL, *transport_account = NULL;
7222 gboolean retval = TRUE, sending = FALSE;
7224 acc_store = modest_runtime_get_account_store ();
7225 queue = modest_runtime_get_mail_operation_queue ();
7228 modest_tny_account_store_get_server_account (acc_store,
7230 TNY_ACCOUNT_TYPE_STORE);
7232 /* This could happen if the account was deleted before the
7233 call to this function */
7238 modest_tny_account_store_get_server_account (acc_store,
7240 TNY_ACCOUNT_TYPE_TRANSPORT);
7242 /* This could happen if the account was deleted before the
7243 call to this function */
7244 if (!transport_account) {
7245 g_object_unref (store_account);
7249 /* If the transport account was not used yet, then the send
7250 queue could not exist (it's created on demand) */
7251 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7252 if (TNY_IS_SEND_QUEUE (send_queue))
7253 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7255 store_conn_status = tny_account_get_connection_status (store_account);
7256 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7259 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7260 _("emev_nc_disconnect_account"));
7261 if (response == GTK_RESPONSE_OK) {
7270 /* FIXME: We should only cancel those of this account */
7271 modest_mail_operation_queue_cancel_all (queue);
7273 /* Also disconnect the account */
7274 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7275 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7276 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7280 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7286 g_object_unref (store_account);
7287 g_object_unref (transport_account);