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-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46 #include "modest-debug.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
51 #ifdef MODEST_TOOLKIT_HILDON2
52 #include <hildon/hildon-pannable-area.h>
53 #include <modest-header-window.h>
56 #ifdef MODEST_PLATFORM_MAEMO
57 #include "maemo/modest-osso-state-saving.h"
58 #endif /* MODEST_PLATFORM_MAEMO */
59 #ifndef MODEST_TOOLKIT_GTK
60 #include "maemo/modest-hildon-includes.h"
61 #include "maemo/modest-connection-specific-smtp-window.h"
62 #endif /* !MODEST_TOOLKIT_GTK */
63 #include <modest-utils.h>
65 #include "widgets/modest-ui-constants.h"
66 #include <widgets/modest-main-window.h>
67 #include <widgets/modest-msg-view-window.h>
68 #include <widgets/modest-account-view-window.h>
69 #include <widgets/modest-details-dialog.h>
70 #include <widgets/modest-attachments-view.h>
71 #include "widgets/modest-folder-view.h"
72 #include "widgets/modest-global-settings-dialog.h"
73 #include "modest-account-mgr-helpers.h"
74 #include "modest-mail-operation.h"
75 #include "modest-text-utils.h"
76 #include <modest-widget-memory.h>
77 #include <tny-error.h>
78 #include <tny-simple-list.h>
79 #include <tny-msg-view.h>
80 #include <tny-device.h>
81 #include <tny-merge-folder.h>
83 #include <gtkhtml/gtkhtml.h>
85 #define MIN_FREE_SPACE 5 * 1024 * 1024
86 #define MOVE_FOLDER_OK_BUTTON "ok-button"
87 #define MOVE_FOLDER_NEW_BUTTON "new-button"
89 typedef struct _GetMsgAsyncHelper {
91 ModestMailOperation *mail_op;
98 typedef enum _ReplyForwardAction {
102 } ReplyForwardAction;
104 typedef struct _ReplyForwardHelper {
105 guint reply_forward_type;
106 ReplyForwardAction action;
108 GtkWidget *parent_window;
110 } ReplyForwardHelper;
112 typedef struct _MoveToHelper {
113 GtkTreeRowReference *reference;
117 typedef struct _PasteAsAttachmentHelper {
118 ModestMsgEditWindow *window;
120 } PasteAsAttachmentHelper;
124 * The do_headers_action uses this kind of functions to perform some
125 * action to each member of a list of headers
127 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
129 static void do_headers_action (ModestWindow *win,
133 static void open_msg_cb (ModestMailOperation *mail_op,
140 static void reply_forward_cb (ModestMailOperation *mail_op,
147 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
149 static void folder_refreshed_cb (ModestMailOperation *mail_op,
153 static void on_send_receive_finished (ModestMailOperation *mail_op,
156 static gint header_list_count_uncached_msgs (TnyList *header_list);
158 static gboolean connect_to_get_msg (ModestWindow *win,
159 gint num_of_uncached_msgs,
160 TnyAccount *account);
162 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
164 static void do_create_folder (GtkWindow *window,
165 TnyFolderStore *parent_folder,
166 const gchar *suggested_name);
168 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
170 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
173 * This function checks whether a TnyFolderStore is a pop account
176 remote_folder_has_leave_on_server (TnyFolderStore *folder)
181 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
183 account = get_account_from_folder_store (folder);
184 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
185 modest_tny_account_get_protocol_type (account)));
186 g_object_unref (account);
191 /* FIXME: this should be merged with the similar code in modest-account-view-window */
192 /* Show the account creation wizard dialog.
193 * returns: TRUE if an account was created. FALSE if the user cancelled.
196 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
198 gboolean result = FALSE;
200 gint dialog_response;
202 /* there is no such wizard yet */
203 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
204 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
206 /* always present a main window in the background
207 * we do it here, so we cannot end up with two wizards (as this
208 * function might be called in modest_window_mgr_get_main_window as well */
210 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
211 TRUE); /* create if not existent */
213 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
215 /* make sure the mainwindow is visible. We need to present the
216 wizard again to give it the focus back. show_all are needed
217 in order to get the widgets properly drawn (MainWindow main
218 paned won't be in its right position and the dialog will be
220 #ifndef MODEST_TOOLKIT_HILDON2
221 gtk_widget_show_all (GTK_WIDGET (win));
222 gtk_widget_show_all (GTK_WIDGET (wizard));
223 gtk_window_present (GTK_WINDOW (win));
224 gtk_window_present (GTK_WINDOW (wizard));
227 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
228 gtk_widget_destroy (GTK_WIDGET (wizard));
229 if (gtk_events_pending ())
230 gtk_main_iteration ();
232 if (dialog_response == GTK_RESPONSE_CANCEL) {
235 /* Check whether an account was created: */
236 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
243 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
246 const gchar *authors[] = {
247 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
250 about = gtk_about_dialog_new ();
251 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
252 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
253 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
254 _("Copyright (c) 2006, Nokia Corporation\n"
255 "All rights reserved."));
256 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
257 _("a modest e-mail client\n\n"
258 "design and implementation: Dirk-Jan C. Binnema\n"
259 "contributions from the fine people at KC and Ig\n"
260 "uses the tinymail email framework written by Philip van Hoof"));
261 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
262 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
263 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
264 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
266 gtk_dialog_run (GTK_DIALOG (about));
267 gtk_widget_destroy(about);
271 * Gets the list of currently selected messages. If the win is the
272 * main window, then it returns a newly allocated list of the headers
273 * selected in the header view. If win is the msg view window, then
274 * the value returned is a list with just a single header.
276 * The caller of this funcion must free the list.
279 get_selected_headers (ModestWindow *win)
281 if (MODEST_IS_MAIN_WINDOW(win)) {
282 GtkWidget *header_view;
284 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
285 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
286 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
288 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
289 /* for MsgViewWindows, we simply return a list with one element */
291 TnyList *list = NULL;
293 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
294 if (header != NULL) {
295 list = tny_simple_list_new ();
296 tny_list_prepend (list, G_OBJECT(header));
297 g_object_unref (G_OBJECT(header));
302 } else if (MODEST_IS_HEADER_WINDOW (win)) {
303 GtkWidget *header_view;
305 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
306 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
311 static GtkTreeRowReference *
312 get_next_after_selected_headers (ModestHeaderView *header_view)
314 GtkTreeSelection *sel;
315 GList *selected_rows, *node;
317 GtkTreeRowReference *result;
320 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
321 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
322 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
324 if (selected_rows == NULL)
327 node = g_list_last (selected_rows);
328 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
329 gtk_tree_path_next (path);
331 result = gtk_tree_row_reference_new (model, path);
333 gtk_tree_path_free (path);
334 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
335 g_list_free (selected_rows);
341 headers_action_mark_as_read (TnyHeader *header,
345 TnyHeaderFlags flags;
347 g_return_if_fail (TNY_IS_HEADER(header));
349 flags = tny_header_get_flags (header);
350 if (flags & TNY_HEADER_FLAG_SEEN) return;
351 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
355 headers_action_mark_as_unread (TnyHeader *header,
359 TnyHeaderFlags flags;
361 g_return_if_fail (TNY_IS_HEADER(header));
363 flags = tny_header_get_flags (header);
364 if (flags & TNY_HEADER_FLAG_SEEN) {
365 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
369 /** After deleing a message that is currently visible in a window,
370 * show the next message from the list, or close the window if there are no more messages.
373 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
375 /* Close msg view window or select next */
376 if (!modest_msg_view_window_select_next_message (win) &&
377 !modest_msg_view_window_select_previous_message (win)) {
379 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
385 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
387 modest_ui_actions_on_edit_mode_delete_message (win);
391 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
393 TnyList *header_list = NULL;
394 TnyIterator *iter = NULL;
395 TnyHeader *header = NULL;
396 gchar *message = NULL;
399 ModestWindowMgr *mgr;
400 GtkWidget *header_view = NULL;
401 gboolean retval = TRUE;
403 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
405 /* Check first if the header view has the focus */
406 if (MODEST_IS_MAIN_WINDOW (win)) {
408 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
409 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
410 if (!gtk_widget_is_focus (header_view))
414 /* Get the headers, either from the header view (if win is the main window),
415 * or from the message view window: */
416 header_list = get_selected_headers (win);
417 if (!header_list) return FALSE;
419 /* Check if any of the headers are already opened, or in the process of being opened */
420 if (MODEST_IS_MAIN_WINDOW (win)) {
421 gint opened_headers = 0;
423 iter = tny_list_create_iterator (header_list);
424 mgr = modest_runtime_get_window_mgr ();
425 while (!tny_iterator_is_done (iter)) {
426 header = TNY_HEADER (tny_iterator_get_current (iter));
428 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
430 g_object_unref (header);
432 tny_iterator_next (iter);
434 g_object_unref (iter);
436 if (opened_headers > 0) {
439 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
442 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
445 g_object_unref (header_list);
451 if (tny_list_get_length(header_list) == 1) {
452 iter = tny_list_create_iterator (header_list);
453 header = TNY_HEADER (tny_iterator_get_current (iter));
456 subject = tny_header_dup_subject (header);
458 subject = g_strdup (_("mail_va_no_subject"));
459 desc = g_strdup_printf ("%s", subject);
461 g_object_unref (header);
464 g_object_unref (iter);
466 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
467 tny_list_get_length(header_list)), desc);
469 /* Confirmation dialog */
470 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
474 if (response == GTK_RESPONSE_OK) {
475 ModestWindow *main_window = NULL;
476 ModestWindowMgr *mgr = NULL;
477 GtkTreeModel *model = NULL;
478 GtkTreeSelection *sel = NULL;
479 GList *sel_list = NULL, *tmp = NULL;
480 GtkTreeRowReference *next_row_reference = NULL;
481 GtkTreeRowReference *prev_row_reference = NULL;
482 GtkTreePath *next_path = NULL;
483 GtkTreePath *prev_path = NULL;
484 ModestMailOperation *mail_op = NULL;
486 /* Find last selected row */
487 if (MODEST_IS_MAIN_WINDOW (win)) {
488 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
489 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
490 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
491 for (tmp=sel_list; tmp; tmp=tmp->next) {
492 if (tmp->next == NULL) {
493 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
494 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
496 gtk_tree_path_prev (prev_path);
497 gtk_tree_path_next (next_path);
499 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
500 next_row_reference = gtk_tree_row_reference_new (model, next_path);
505 /* Disable window dimming management */
506 modest_window_disable_dimming (MODEST_WINDOW(win));
508 /* Remove each header. If it's a view window header_view == NULL */
509 mail_op = modest_mail_operation_new ((GObject *) win);
510 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
512 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
513 g_object_unref (mail_op);
515 /* Enable window dimming management */
517 gtk_tree_selection_unselect_all (sel);
519 modest_window_enable_dimming (MODEST_WINDOW(win));
521 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
522 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
524 /* Get main window */
525 mgr = modest_runtime_get_window_mgr ();
526 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
527 } else if (MODEST_IS_MAIN_WINDOW (win)) {
528 /* Move cursor to next row */
531 /* Select next or previous row */
532 if (gtk_tree_row_reference_valid (next_row_reference)) {
533 gtk_tree_selection_select_path (sel, next_path);
535 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
536 gtk_tree_selection_select_path (sel, prev_path);
540 if (gtk_tree_row_reference_valid (next_row_reference))
541 gtk_tree_row_reference_free (next_row_reference);
542 if (next_path != NULL)
543 gtk_tree_path_free (next_path);
544 if (gtk_tree_row_reference_valid (prev_row_reference))
545 gtk_tree_row_reference_free (prev_row_reference);
546 if (prev_path != NULL)
547 gtk_tree_path_free (prev_path);
550 /* Update toolbar dimming state */
552 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
553 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
557 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
558 g_list_free (sel_list);
567 g_object_unref (header_list);
575 /* delete either message or folder, based on where we are */
577 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
579 g_return_if_fail (MODEST_IS_WINDOW(win));
581 /* Check first if the header view has the focus */
582 if (MODEST_IS_MAIN_WINDOW (win)) {
584 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
585 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
586 if (gtk_widget_is_focus (w)) {
587 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
591 modest_ui_actions_on_delete_message (action, win);
595 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
597 ModestWindowMgr *mgr = NULL;
599 #ifdef MODEST_PLATFORM_MAEMO
600 modest_osso_save_state();
601 #endif /* MODEST_PLATFORM_MAEMO */
603 g_debug ("closing down, clearing %d item(s) from operation queue",
604 modest_mail_operation_queue_num_elements
605 (modest_runtime_get_mail_operation_queue()));
607 /* cancel all outstanding operations */
608 modest_mail_operation_queue_cancel_all
609 (modest_runtime_get_mail_operation_queue());
611 g_debug ("queue has been cleared");
614 /* Check if there are opened editing windows */
615 mgr = modest_runtime_get_window_mgr ();
616 modest_window_mgr_close_all_windows (mgr);
618 /* note: when modest-tny-account-store is finalized,
619 it will automatically set all network connections
622 /* gtk_main_quit (); */
626 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
630 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
632 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
633 /* gtk_widget_destroy (GTK_WIDGET (win)); */
634 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
635 /* gboolean ret_value; */
636 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
637 /* } else if (MODEST_IS_WINDOW (win)) { */
638 /* gtk_widget_destroy (GTK_WIDGET (win)); */
640 /* g_return_if_reached (); */
645 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
647 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
649 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
653 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
655 GtkClipboard *clipboard = NULL;
656 gchar *selection = NULL;
658 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
659 selection = gtk_clipboard_wait_for_text (clipboard);
661 /* Question: why is the clipboard being used here?
662 * It doesn't really make a lot of sense. */
666 modest_address_book_add_address (selection);
672 modest_ui_actions_on_accounts (GtkAction *action,
675 /* This is currently only implemented for Maemo */
676 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
677 if (!modest_ui_actions_run_account_setup_wizard (win))
678 g_debug ("%s: wizard was already running", __FUNCTION__);
682 /* Show the list of accounts */
683 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
685 /* The accounts dialog must be modal */
686 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
687 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
692 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
694 /* This is currently only implemented for Maemo,
695 * because it requires an API (libconic) to detect different connection
698 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
700 /* Create the window if necessary: */
701 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
702 modest_connection_specific_smtp_window_fill_with_connections (
703 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
704 modest_runtime_get_account_mgr());
706 /* Show the window: */
707 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
708 GTK_WINDOW (specific_window), (GtkWindow *) win);
709 gtk_widget_show (specific_window);
710 #endif /* !MODEST_TOOLKIT_GTK */
714 modest_ui_actions_compose_msg(ModestWindow *win,
717 const gchar *bcc_str,
718 const gchar *subject_str,
719 const gchar *body_str,
721 gboolean set_as_modified)
723 gchar *account_name = NULL;
725 TnyAccount *account = NULL;
726 TnyFolder *folder = NULL;
727 gchar *from_str = NULL, *signature = NULL, *body = NULL;
728 gboolean use_signature = FALSE;
729 ModestWindow *msg_win = NULL;
730 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
731 ModestTnyAccountStore *store = modest_runtime_get_account_store();
732 GnomeVFSFileSize total_size, allowed_size;
734 /* we check for low-mem */
735 if (modest_platform_check_memory_low (win, TRUE))
738 #ifdef MODEST_TOOLKIT_HILDON2
739 account_name = g_strdup (modest_window_get_active_account(win));
742 account_name = modest_account_mgr_get_default_account(mgr);
745 g_printerr ("modest: no account found\n");
748 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
750 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
753 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
755 g_printerr ("modest: failed to find Drafts folder\n");
758 from_str = modest_account_mgr_get_from_string (mgr, account_name);
760 g_printerr ("modest: failed get from string for '%s'\n", account_name);
764 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
765 if (body_str != NULL) {
766 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
768 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
771 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
773 g_printerr ("modest: failed to create new msg\n");
777 /* Create and register edit window */
778 /* This is destroyed by TODO. */
780 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
781 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
783 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL)) {
784 gtk_widget_destroy (GTK_WIDGET (msg_win));
787 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
788 gtk_widget_show_all (GTK_WIDGET (msg_win));
790 while (attachments) {
792 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
793 attachments->data, allowed_size);
795 if (total_size > allowed_size) {
796 g_warning ("%s: total size: %u",
797 __FUNCTION__, (unsigned int)total_size);
800 allowed_size -= total_size;
802 attachments = g_slist_next(attachments);
809 g_free (account_name);
811 g_object_unref (G_OBJECT(account));
813 g_object_unref (G_OBJECT(folder));
815 g_object_unref (G_OBJECT(msg));
819 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
821 /* if there are no accounts yet, just show the wizard */
822 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
823 if (!modest_ui_actions_run_account_setup_wizard (win))
826 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
831 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
835 ModestMailOperationStatus status;
837 /* If there is no message or the operation was not successful */
838 status = modest_mail_operation_get_status (mail_op);
839 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
842 /* If it's a memory low issue, then show a banner */
843 error = modest_mail_operation_get_error (mail_op);
844 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
845 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
846 GObject *source = modest_mail_operation_get_source (mail_op);
847 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
848 dgettext("ke-recv","memr_ib_operation_disabled"),
850 g_object_unref (source);
853 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
854 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
855 gchar *subject, *msg;
856 subject = tny_header_dup_subject (header);
858 subject = g_strdup (_("mail_va_no_subject"));;
859 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
861 modest_platform_run_information_dialog (NULL, msg, FALSE);
866 /* Remove the header from the preregistered uids */
867 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
885 OpenMsgBannerInfo *banner_info;
886 GtkTreeRowReference *rowref;
890 open_msg_banner_idle (gpointer userdata)
892 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
894 gdk_threads_enter ();
895 banner_info->idle_handler = 0;
896 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
898 g_object_ref (banner_info->banner);
900 gdk_threads_leave ();
907 get_header_view_from_window (ModestWindow *window)
909 GtkWidget *header_view;
911 if (MODEST_IS_MAIN_WINDOW (window)) {
912 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
913 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
914 #ifdef MODEST_TOOLKIT_HILDON2
915 } else if (MODEST_IS_HEADER_WINDOW (window)){
916 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
926 get_info_from_header (TnyHeader *header, gboolean *is_draft)
929 gchar *account = NULL;
930 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
934 folder = tny_header_get_folder (header);
935 /* Gets folder type (OUTBOX headers will be opened in edit window */
936 if (modest_tny_folder_is_local_folder (folder)) {
937 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
938 if (folder_type == TNY_FOLDER_TYPE_INVALID)
939 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
942 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
943 TnyTransportAccount *traccount = NULL;
944 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
945 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
947 ModestTnySendQueue *send_queue = NULL;
948 ModestTnySendQueueStatus status;
950 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
951 TNY_ACCOUNT(traccount)));
952 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
953 if (TNY_IS_SEND_QUEUE (send_queue)) {
954 msg_id = modest_tny_send_queue_get_msg_id (header);
955 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
957 /* Only open messages in outbox with the editor if they are in Failed state */
958 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
961 #ifdef MODEST_TOOLKIT_HILDON2
963 /* In Fremantle we can not
964 open any message from
965 outbox which is not in
967 g_object_unref(traccount);
971 g_object_unref(traccount);
973 g_warning("Cannot get transport account for message in outbox!!");
975 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
976 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
979 g_object_unref (folder);
985 open_msg_cb (ModestMailOperation *mail_op,
992 ModestWindowMgr *mgr = NULL;
993 ModestWindow *parent_win = NULL;
994 ModestWindow *win = NULL;
995 gchar *account = NULL;
996 gboolean open_in_editor = FALSE;
997 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
999 /* Do nothing if there was any problem with the mail
1000 operation. The error will be shown by the error_handler of
1001 the mail operation */
1002 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1005 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1007 /* Mark header as read */
1008 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1010 account = get_info_from_header (header, &open_in_editor);
1014 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1016 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1018 if (open_in_editor) {
1019 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1020 gchar *from_header = NULL, *acc_name;
1022 from_header = tny_header_dup_from (header);
1024 /* we cannot edit without a valid account... */
1025 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1026 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1027 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1029 g_free (from_header);
1034 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1035 g_free (from_header);
1041 win = modest_msg_edit_window_new (msg, account, TRUE);
1043 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1045 if (helper->rowref && helper->model) {
1046 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1047 helper->model, helper->rowref);
1049 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1054 /* Register and show new window */
1056 mgr = modest_runtime_get_window_mgr ();
1057 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1058 gtk_widget_destroy (GTK_WIDGET (win));
1061 gtk_widget_show_all (GTK_WIDGET(win));
1064 /* Update toolbar dimming state */
1065 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1066 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1072 g_object_unref (parent_win);
1076 is_memory_full_error (GError *error)
1078 gboolean enough_free_space = TRUE;
1079 GnomeVFSURI *cache_dir_uri;
1080 const gchar *cache_dir;
1081 GnomeVFSFileSize free_space;
1083 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1084 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1085 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1086 if (free_space < MIN_FREE_SPACE)
1087 enough_free_space = FALSE;
1089 gnome_vfs_uri_unref (cache_dir_uri);
1091 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1092 /* When asking for a mail and no space left on device
1093 tinymail returns this error */
1094 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1095 /* When the folder summary could not be read or
1097 error->code == TNY_IO_ERROR_WRITE ||
1098 error->code == TNY_IO_ERROR_READ) &&
1099 !enough_free_space) {
1107 check_memory_full_error (GtkWidget *parent_window, GError *err)
1112 if (is_memory_full_error (err))
1113 modest_platform_information_banner (parent_window,
1114 NULL, dgettext("ke-recv",
1115 "cerm_device_memory_full"));
1116 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1117 /* If the account was created in memory full
1118 conditions then tinymail won't be able to
1119 connect so it'll return this error code */
1120 modest_platform_information_banner (parent_window,
1121 NULL, _("emev_ui_imap_inbox_select_error"));
1129 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1132 const GError *error;
1133 GObject *win = NULL;
1134 ModestMailOperationStatus status;
1136 win = modest_mail_operation_get_source (mail_op);
1137 error = modest_mail_operation_get_error (mail_op);
1138 status = modest_mail_operation_get_status (mail_op);
1140 /* If the mail op has been cancelled then it's not an error:
1141 don't show any message */
1142 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1143 if (is_memory_full_error ((GError *) error)) {
1144 modest_platform_information_banner ((GtkWidget *) win,
1145 NULL, dgettext("ke-recv",
1146 "cerm_device_memory_full"));
1147 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1148 modest_platform_information_banner ((GtkWidget *) win,
1149 NULL, _("emev_ui_imap_inbox_select_error"));
1150 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1151 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1152 modest_platform_information_banner ((GtkWidget *) win,
1153 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1154 } else if (user_data) {
1155 modest_platform_information_banner ((GtkWidget *) win,
1161 g_object_unref (win);
1165 * Returns the account a list of headers belongs to. It returns a
1166 * *new* reference so don't forget to unref it
1169 get_account_from_header_list (TnyList *headers)
1171 TnyAccount *account = NULL;
1173 if (tny_list_get_length (headers) > 0) {
1174 TnyIterator *iter = tny_list_create_iterator (headers);
1175 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1176 TnyFolder *folder = tny_header_get_folder (header);
1179 g_object_unref (header);
1181 while (!tny_iterator_is_done (iter)) {
1182 header = TNY_HEADER (tny_iterator_get_current (iter));
1183 folder = tny_header_get_folder (header);
1186 g_object_unref (header);
1188 tny_iterator_next (iter);
1193 account = tny_folder_get_account (folder);
1194 g_object_unref (folder);
1198 g_object_unref (header);
1200 g_object_unref (iter);
1206 get_account_from_header (TnyHeader *header)
1208 TnyAccount *account = NULL;
1211 folder = tny_header_get_folder (header);
1214 account = tny_folder_get_account (folder);
1215 g_object_unref (folder);
1222 open_msg_helper_destroyer (gpointer user_data)
1224 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1226 if (helper->banner_info) {
1227 g_free (helper->banner_info->message);
1228 if (helper->banner_info->idle_handler > 0) {
1229 g_source_remove (helper->banner_info->idle_handler);
1230 helper->banner_info->idle_handler = 0;
1232 if (helper->banner_info->banner != NULL) {
1233 gtk_widget_destroy (helper->banner_info->banner);
1234 g_object_unref (helper->banner_info->banner);
1235 helper->banner_info->banner = NULL;
1237 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1238 helper->banner_info = NULL;
1240 g_object_unref (helper->model);
1241 g_object_unref (helper->header);
1242 gtk_tree_row_reference_free (helper->rowref);
1243 g_slice_free (OpenMsgHelper, helper);
1247 open_msg_performer(gboolean canceled,
1249 GtkWindow *parent_window,
1250 TnyAccount *account,
1253 ModestMailOperation *mail_op = NULL;
1255 ModestProtocolType proto;
1256 TnyConnectionStatus status;
1257 gboolean show_open_draft = FALSE;
1258 OpenMsgHelper *helper = NULL;
1260 helper = (OpenMsgHelper *) user_data;
1262 status = tny_account_get_connection_status (account);
1263 if (err || canceled) {
1264 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1265 /* Free the helper */
1266 open_msg_helper_destroyer (helper);
1268 /* In memory full conditions we could get this error here */
1269 check_memory_full_error ((GtkWidget *) parent_window, err);
1274 /* Get the error message depending on the protocol */
1275 proto = modest_tny_account_get_protocol_type (account);
1276 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1277 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1280 ModestProtocol *protocol;
1281 ModestProtocolRegistry *protocol_registry;
1284 protocol_registry = modest_runtime_get_protocol_registry ();
1285 subject = tny_header_dup_subject (helper->header);
1287 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1288 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1292 if (error_msg == NULL) {
1293 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1296 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1298 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1300 TnyFolderType folder_type;
1302 folder = tny_header_get_folder (helper->header);
1303 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1304 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1305 g_object_unref (folder);
1308 #ifdef MODEST_TOOLKIT_HILDON2
1310 gchar *account_name = get_info_from_header (helper->header, &is_draft);
1313 ModestWindow *window;
1314 GtkWidget *header_view;
1317 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1318 uid = modest_tny_folder_get_header_unique_id (helper->header);
1320 window = modest_msg_view_window_new_from_header_view
1321 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1322 if (window != NULL) {
1323 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1325 gtk_widget_destroy (GTK_WIDGET (window));
1327 gtk_widget_show_all (GTK_WIDGET(window));
1331 g_free (account_name);
1333 open_msg_helper_destroyer (helper);
1336 g_free (account_name);
1338 /* Create the mail operation */
1340 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1341 modest_ui_actions_disk_operations_error_handler,
1343 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1346 if (show_open_draft) {
1347 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1348 #ifdef MODEST_TOOLKIT_HILDON2
1349 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1351 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1353 helper->banner_info->banner = NULL;
1354 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1355 helper->banner_info);
1359 headers = TNY_LIST (tny_simple_list_new ());
1360 tny_list_prepend (headers, G_OBJECT (helper->header));
1361 modest_mail_operation_get_msgs_full (mail_op,
1365 open_msg_helper_destroyer);
1366 g_object_unref (headers);
1371 g_object_unref (mail_op);
1372 g_object_unref (account);
1376 * This function is used by both modest_ui_actions_on_open and
1377 * modest_ui_actions_on_header_activated. This way we always do the
1378 * same when trying to open messages.
1381 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1383 ModestWindowMgr *mgr = NULL;
1384 TnyAccount *account;
1385 gboolean cached = FALSE;
1387 GtkWidget *header_view = NULL;
1388 OpenMsgHelper *helper;
1389 ModestWindow *window;
1391 g_return_if_fail (header != NULL && rowref != NULL);
1393 mgr = modest_runtime_get_window_mgr ();
1396 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1397 if (header_view == NULL)
1400 /* Get the account */
1401 account = get_account_from_header (header);
1406 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1408 /* Do not open again the message and present the
1409 window to the user */
1412 #ifndef MODEST_TOOLKIT_HILDON2
1413 gtk_window_present (GTK_WINDOW (window));
1416 /* the header has been registered already, we don't do
1417 * anything but wait for the window to come up*/
1418 g_debug ("header %p already registered, waiting for window", header);
1423 /* Open each message */
1424 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1426 /* Allways download if we are online. */
1427 if (!tny_device_is_online (modest_runtime_get_device ())) {
1430 /* If ask for user permission to download the messages */
1431 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1432 _("mcen_nc_get_msg"));
1434 /* End if the user does not want to continue */
1435 if (response == GTK_RESPONSE_CANCEL) {
1441 /* We register the window for opening */
1442 modest_window_mgr_register_header (mgr, header, NULL);
1444 /* Create the helper. We need to get a reference to the model
1445 here because it could change while the message is readed
1446 (the user could switch between folders) */
1447 helper = g_slice_new (OpenMsgHelper);
1448 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1449 helper->header = g_object_ref (header);
1450 helper->rowref = gtk_tree_row_reference_copy (rowref);
1451 helper->banner_info = NULL;
1453 /* Connect to the account and perform */
1455 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1456 open_msg_performer, helper);
1458 /* Call directly the performer, do not need to connect */
1459 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1460 g_object_ref (account), helper);
1465 g_object_unref (account);
1469 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1476 /* we check for low-mem; in that case, show a warning, and don't allow
1479 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1483 headers = get_selected_headers (win);
1487 headers_count = tny_list_get_length (headers);
1488 if (headers_count != 1) {
1489 if (headers_count > 1) {
1490 /* Don't allow activation if there are more than one message selected */
1491 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1494 g_object_unref (headers);
1498 iter = tny_list_create_iterator (headers);
1499 header = TNY_HEADER (tny_iterator_get_current (iter));
1500 g_object_unref (iter);
1504 open_msg_from_header (header, NULL, win);
1505 g_object_unref (header);
1508 g_object_unref(headers);
1511 static ReplyForwardHelper*
1512 create_reply_forward_helper (ReplyForwardAction action,
1514 guint reply_forward_type,
1517 ReplyForwardHelper *rf_helper = NULL;
1518 const gchar *active_acc = modest_window_get_active_account (win);
1520 rf_helper = g_slice_new0 (ReplyForwardHelper);
1521 rf_helper->reply_forward_type = reply_forward_type;
1522 rf_helper->action = action;
1523 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1524 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1525 rf_helper->account_name = (active_acc) ?
1526 g_strdup (active_acc) :
1527 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1533 free_reply_forward_helper (gpointer data)
1535 ReplyForwardHelper *helper;
1537 helper = (ReplyForwardHelper *) data;
1538 g_free (helper->account_name);
1540 g_object_unref (helper->header);
1541 g_slice_free (ReplyForwardHelper, helper);
1545 reply_forward_cb (ModestMailOperation *mail_op,
1552 TnyMsg *new_msg = NULL;
1553 ReplyForwardHelper *rf_helper;
1554 ModestWindow *msg_win = NULL;
1555 ModestEditType edit_type;
1557 TnyAccount *account = NULL;
1558 ModestWindowMgr *mgr = NULL;
1559 gchar *signature = NULL;
1560 gboolean use_signature;
1562 /* If there was any error. The mail operation could be NULL,
1563 this means that we already have the message downloaded and
1564 that we didn't do a mail operation to retrieve it */
1565 rf_helper = (ReplyForwardHelper *) user_data;
1566 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1569 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1570 rf_helper->account_name);
1571 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1572 rf_helper->account_name,
1575 /* Create reply mail */
1576 switch (rf_helper->action) {
1579 modest_tny_msg_create_reply_msg (msg, header, from,
1580 (use_signature) ? signature : NULL,
1581 rf_helper->reply_forward_type,
1582 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1584 case ACTION_REPLY_TO_ALL:
1586 modest_tny_msg_create_reply_msg (msg, header, from,
1587 (use_signature) ? signature : NULL,
1588 rf_helper->reply_forward_type,
1589 MODEST_TNY_MSG_REPLY_MODE_ALL);
1590 edit_type = MODEST_EDIT_TYPE_REPLY;
1592 case ACTION_FORWARD:
1594 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1595 rf_helper->reply_forward_type);
1596 edit_type = MODEST_EDIT_TYPE_FORWARD;
1599 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1601 g_return_if_reached ();
1609 g_warning ("%s: failed to create message\n", __FUNCTION__);
1613 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1614 rf_helper->account_name,
1615 TNY_ACCOUNT_TYPE_STORE);
1617 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1621 /* Create and register the windows */
1622 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1623 mgr = modest_runtime_get_window_mgr ();
1624 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1626 if (rf_helper->parent_window != NULL) {
1627 gdouble parent_zoom;
1629 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1630 modest_window_set_zoom (msg_win, parent_zoom);
1633 /* Show edit window */
1634 gtk_widget_show_all (GTK_WIDGET (msg_win));
1637 /* We always unregister the header because the message is
1638 forwarded or replied so the original one is no longer
1640 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1643 g_object_unref (G_OBJECT (new_msg));
1645 g_object_unref (G_OBJECT (account));
1646 free_reply_forward_helper (rf_helper);
1649 /* Checks a list of headers. If any of them are not currently
1650 * downloaded (CACHED) then returns TRUE else returns FALSE.
1653 header_list_count_uncached_msgs (TnyList *header_list)
1656 gint uncached_messages = 0;
1658 iter = tny_list_create_iterator (header_list);
1659 while (!tny_iterator_is_done (iter)) {
1662 header = TNY_HEADER (tny_iterator_get_current (iter));
1664 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1665 uncached_messages ++;
1666 g_object_unref (header);
1669 tny_iterator_next (iter);
1671 g_object_unref (iter);
1673 return uncached_messages;
1676 /* Returns FALSE if the user does not want to download the
1677 * messages. Returns TRUE if the user allowed the download.
1680 connect_to_get_msg (ModestWindow *win,
1681 gint num_of_uncached_msgs,
1682 TnyAccount *account)
1684 GtkResponseType response;
1686 /* Allways download if we are online. */
1687 if (tny_device_is_online (modest_runtime_get_device ()))
1690 /* If offline, then ask for user permission to download the messages */
1691 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1692 ngettext("mcen_nc_get_msg",
1694 num_of_uncached_msgs));
1696 if (response == GTK_RESPONSE_CANCEL)
1699 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1703 reply_forward_performer (gboolean canceled,
1705 GtkWindow *parent_window,
1706 TnyAccount *account,
1709 ReplyForwardHelper *rf_helper = NULL;
1710 ModestMailOperation *mail_op;
1712 rf_helper = (ReplyForwardHelper *) user_data;
1714 if (canceled || err) {
1715 free_reply_forward_helper (rf_helper);
1719 /* Retrieve the message */
1720 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1721 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1722 modest_ui_actions_disk_operations_error_handler,
1724 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1725 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1728 g_object_unref(mail_op);
1732 * Common code for the reply and forward actions
1735 reply_forward (ReplyForwardAction action, ModestWindow *win)
1737 ReplyForwardHelper *rf_helper = NULL;
1738 guint reply_forward_type;
1740 g_return_if_fail (MODEST_IS_WINDOW(win));
1742 /* we check for low-mem; in that case, show a warning, and don't allow
1743 * reply/forward (because it could potentially require a lot of memory */
1744 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1748 /* we need an account when editing */
1749 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1750 if (!modest_ui_actions_run_account_setup_wizard (win))
1754 reply_forward_type =
1755 modest_conf_get_int (modest_runtime_get_conf (),
1756 (action == ACTION_FORWARD) ?
1757 MODEST_CONF_FORWARD_TYPE :
1758 MODEST_CONF_REPLY_TYPE,
1761 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1763 TnyHeader *header = NULL;
1764 /* Get header and message. Do not free them here, the
1765 reply_forward_cb must do it */
1766 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1767 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1769 if (msg && header) {
1771 rf_helper = create_reply_forward_helper (action, win,
1772 reply_forward_type, header);
1773 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1775 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1779 g_object_unref (msg);
1781 g_object_unref (header);
1783 TnyHeader *header = NULL;
1785 gboolean do_retrieve = TRUE;
1786 TnyList *header_list = NULL;
1788 header_list = get_selected_headers (win);
1791 /* Check that only one message is selected for replying */
1792 if (tny_list_get_length (header_list) != 1) {
1793 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1794 NULL, _("mcen_ib_select_one_message"));
1795 g_object_unref (header_list);
1799 /* Only reply/forward to one message */
1800 iter = tny_list_create_iterator (header_list);
1801 header = TNY_HEADER (tny_iterator_get_current (iter));
1802 g_object_unref (iter);
1804 /* Retrieve messages */
1805 do_retrieve = (action == ACTION_FORWARD) ||
1806 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1809 TnyAccount *account = NULL;
1810 TnyFolder *folder = NULL;
1811 gdouble download = TRUE;
1812 guint uncached_msgs = 0;
1814 folder = tny_header_get_folder (header);
1816 goto do_retrieve_frees;
1817 account = tny_folder_get_account (folder);
1819 goto do_retrieve_frees;
1821 uncached_msgs = header_list_count_uncached_msgs (header_list);
1823 if (uncached_msgs > 0) {
1824 /* Allways download if we are online. */
1825 if (!tny_device_is_online (modest_runtime_get_device ())) {
1828 /* If ask for user permission to download the messages */
1829 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1830 ngettext("mcen_nc_get_msg",
1834 /* End if the user does not want to continue */
1835 if (response == GTK_RESPONSE_CANCEL)
1842 rf_helper = create_reply_forward_helper (action, win,
1843 reply_forward_type, header);
1844 if (uncached_msgs > 0) {
1845 modest_platform_connect_and_perform (GTK_WINDOW (win),
1847 reply_forward_performer,
1850 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1851 account, rf_helper);
1856 g_object_unref (account);
1858 g_object_unref (folder);
1860 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1863 g_object_unref (header_list);
1864 g_object_unref (header);
1869 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1871 g_return_if_fail (MODEST_IS_WINDOW(win));
1873 reply_forward (ACTION_REPLY, win);
1877 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1879 g_return_if_fail (MODEST_IS_WINDOW(win));
1881 reply_forward (ACTION_FORWARD, win);
1885 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1887 g_return_if_fail (MODEST_IS_WINDOW(win));
1889 reply_forward (ACTION_REPLY_TO_ALL, win);
1893 modest_ui_actions_on_next (GtkAction *action,
1894 ModestWindow *window)
1896 if (MODEST_IS_MAIN_WINDOW (window)) {
1897 GtkWidget *header_view;
1899 header_view = modest_main_window_get_child_widget (
1900 MODEST_MAIN_WINDOW(window),
1901 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1905 modest_header_view_select_next (
1906 MODEST_HEADER_VIEW(header_view));
1907 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1908 modest_msg_view_window_select_next_message (
1909 MODEST_MSG_VIEW_WINDOW (window));
1911 g_return_if_reached ();
1916 modest_ui_actions_on_prev (GtkAction *action,
1917 ModestWindow *window)
1919 g_return_if_fail (MODEST_IS_WINDOW(window));
1921 if (MODEST_IS_MAIN_WINDOW (window)) {
1922 GtkWidget *header_view;
1923 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1924 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1928 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1929 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1930 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1932 g_return_if_reached ();
1937 modest_ui_actions_on_sort (GtkAction *action,
1938 ModestWindow *window)
1940 GtkWidget *header_view = NULL;
1942 g_return_if_fail (MODEST_IS_WINDOW(window));
1944 if (MODEST_IS_MAIN_WINDOW (window)) {
1945 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1946 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1947 #ifdef MODEST_TOOLKIT_HILDON2
1948 } else if (MODEST_IS_HEADER_WINDOW (window)) {
1949 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1954 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1959 /* Show sorting dialog */
1960 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1964 new_messages_arrived (ModestMailOperation *self,
1965 TnyList *new_headers,
1969 gboolean show_visual_notifications;
1971 source = modest_mail_operation_get_source (self);
1972 show_visual_notifications = (source) ? FALSE : TRUE;
1974 g_object_unref (source);
1976 /* Notify new messages have been downloaded. If the
1977 send&receive was invoked by the user then do not show any
1978 visual notification, only play a sound and activate the LED
1979 (for the Maemo version) */
1980 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1981 modest_platform_on_new_headers_received (new_headers,
1982 show_visual_notifications);
1987 retrieve_all_messages_cb (GObject *source,
1989 guint retrieve_limit)
1995 window = GTK_WINDOW (source);
1996 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1997 num_msgs, retrieve_limit);
1999 /* Ask the user if they want to retrieve all the messages */
2001 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2002 _("mcen_bd_get_all"),
2003 _("mcen_bd_newest_only"));
2004 /* Free and return */
2006 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2010 TnyAccount *account;
2012 gchar *account_name;
2013 gboolean poke_status;
2014 gboolean interactive;
2015 ModestMailOperation *mail_op;
2019 do_send_receive_performer (gboolean canceled,
2021 GtkWindow *parent_window,
2022 TnyAccount *account,
2025 SendReceiveInfo *info;
2027 info = (SendReceiveInfo *) user_data;
2029 if (err || canceled) {
2030 /* In memory full conditions we could get this error here */
2031 check_memory_full_error ((GtkWidget *) parent_window, err);
2033 if (info->mail_op) {
2034 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2040 /* Set send/receive operation in progress */
2041 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2042 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2045 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2046 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2047 G_CALLBACK (on_send_receive_finished),
2050 /* Send & receive. */
2051 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2052 (info->win) ? retrieve_all_messages_cb : NULL,
2053 new_messages_arrived, info->win);
2058 g_object_unref (G_OBJECT (info->mail_op));
2059 if (info->account_name)
2060 g_free (info->account_name);
2062 g_object_unref (info->win);
2064 g_object_unref (info->account);
2065 g_slice_free (SendReceiveInfo, info);
2069 * This function performs the send & receive required actions. The
2070 * window is used to create the mail operation. Typically it should
2071 * always be the main window, but we pass it as argument in order to
2075 modest_ui_actions_do_send_receive (const gchar *account_name,
2076 gboolean force_connection,
2077 gboolean poke_status,
2078 gboolean interactive,
2081 gchar *acc_name = NULL;
2082 SendReceiveInfo *info;
2083 ModestTnyAccountStore *acc_store;
2085 /* If no account name was provided then get the current account, and if
2086 there is no current account then pick the default one: */
2087 if (!account_name) {
2089 acc_name = g_strdup (modest_window_get_active_account (win));
2091 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2093 g_printerr ("modest: cannot get default account\n");
2097 acc_name = g_strdup (account_name);
2100 acc_store = modest_runtime_get_account_store ();
2102 /* Create the info for the connect and perform */
2103 info = g_slice_new (SendReceiveInfo);
2104 info->account_name = acc_name;
2105 info->win = (win) ? g_object_ref (win) : NULL;
2106 info->poke_status = poke_status;
2107 info->interactive = interactive;
2108 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2109 TNY_ACCOUNT_TYPE_STORE);
2110 /* We need to create the operation here, because otherwise it
2111 could happen that the queue emits the queue-empty signal
2112 while we're trying to connect the account */
2113 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2114 modest_ui_actions_disk_operations_error_handler,
2116 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2118 /* Invoke the connect and perform */
2119 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2120 force_connection, info->account,
2121 do_send_receive_performer, info);
2126 modest_ui_actions_do_cancel_send (const gchar *account_name,
2129 TnyTransportAccount *transport_account;
2130 TnySendQueue *send_queue = NULL;
2131 GError *error = NULL;
2133 /* Get transport account */
2135 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2136 (modest_runtime_get_account_store(),
2138 TNY_ACCOUNT_TYPE_TRANSPORT));
2139 if (!transport_account) {
2140 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2145 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2146 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2147 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2148 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2149 "modest: could not find send queue for account\n");
2151 /* Cancel the current send */
2152 tny_account_cancel (TNY_ACCOUNT (transport_account));
2154 /* Suspend all pending messages */
2155 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2159 if (transport_account != NULL)
2160 g_object_unref (G_OBJECT (transport_account));
2164 modest_ui_actions_cancel_send_all (ModestWindow *win)
2166 GSList *account_names, *iter;
2168 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2171 iter = account_names;
2173 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2174 iter = g_slist_next (iter);
2177 modest_account_mgr_free_account_names (account_names);
2178 account_names = NULL;
2182 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2185 /* Check if accounts exist */
2186 gboolean accounts_exist =
2187 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2189 /* If not, allow the user to create an account before trying to send/receive. */
2190 if (!accounts_exist)
2191 modest_ui_actions_on_accounts (NULL, win);
2193 /* Cancel all sending operaitons */
2194 modest_ui_actions_cancel_send_all (win);
2198 * Refreshes all accounts. This function will be used by automatic
2202 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2203 gboolean force_connection,
2204 gboolean poke_status,
2205 gboolean interactive)
2207 GSList *account_names, *iter;
2209 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2212 iter = account_names;
2214 modest_ui_actions_do_send_receive ((const char*) iter->data,
2216 poke_status, interactive, win);
2217 iter = g_slist_next (iter);
2220 modest_account_mgr_free_account_names (account_names);
2221 account_names = NULL;
2225 * Handler of the click on Send&Receive button in the main toolbar
2228 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2230 /* Check if accounts exist */
2231 gboolean accounts_exist;
2234 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2236 /* If not, allow the user to create an account before trying to send/receive. */
2237 if (!accounts_exist)
2238 modest_ui_actions_on_accounts (NULL, win);
2240 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2241 if (MODEST_IS_MAIN_WINDOW (win)) {
2242 GtkWidget *folder_view;
2243 TnyFolderStore *folder_store;
2246 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2247 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2251 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2254 g_object_unref (folder_store);
2255 /* Refresh the active account. Force the connection if needed
2256 and poke the status of all folders */
2257 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2259 const gchar *active_account;
2260 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2262 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2269 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2272 GtkWidget *header_view;
2274 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2276 header_view = modest_main_window_get_child_widget (main_window,
2277 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2281 conf = modest_runtime_get_conf ();
2283 /* what is saved/restored is depending on the style; thus; we save with
2284 * old style, then update the style, and restore for this new style
2286 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2288 if (modest_header_view_get_style
2289 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2290 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2291 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2293 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2294 MODEST_HEADER_VIEW_STYLE_DETAILS);
2296 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2297 MODEST_CONF_HEADER_VIEW_KEY);
2302 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2304 ModestMainWindow *main_window)
2306 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2307 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2309 /* in the case the folder is empty, show the empty folder message and focus
2311 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2312 if (modest_header_view_is_empty (header_view)) {
2313 TnyFolder *folder = modest_header_view_get_folder (header_view);
2314 GtkWidget *folder_view =
2315 modest_main_window_get_child_widget (main_window,
2316 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2317 if (folder != NULL) {
2318 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2319 g_object_unref (folder);
2321 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2325 /* If no header has been selected then exit */
2330 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2331 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2333 /* Update toolbar dimming state */
2334 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2335 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2339 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2342 ModestWindow *window)
2344 GtkWidget *open_widget;
2345 GtkTreeRowReference *rowref;
2347 g_return_if_fail (MODEST_IS_WINDOW(window));
2348 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2349 g_return_if_fail (TNY_IS_HEADER (header));
2351 if (modest_header_view_count_selected_headers (header_view) > 1) {
2352 /* Don't allow activation if there are more than one message selected */
2353 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2357 /* we check for low-mem; in that case, show a warning, and don't allow
2358 * activating headers
2360 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2363 if (MODEST_IS_MAIN_WINDOW (window)) {
2364 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2365 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2366 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2370 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2371 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2372 gtk_tree_row_reference_free (rowref);
2376 set_active_account_from_tny_account (TnyAccount *account,
2377 ModestWindow *window)
2379 const gchar *server_acc_name = tny_account_get_id (account);
2381 /* We need the TnyAccount provided by the
2382 account store because that is the one that
2383 knows the name of the Modest account */
2384 TnyAccount *modest_server_account = modest_server_account =
2385 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2386 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2388 if (!modest_server_account) {
2389 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2393 /* Update active account, but only if it's not a pseudo-account */
2394 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2395 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2396 const gchar *modest_acc_name =
2397 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2398 if (modest_acc_name)
2399 modest_window_set_active_account (window, modest_acc_name);
2402 g_object_unref (modest_server_account);
2407 folder_refreshed_cb (ModestMailOperation *mail_op,
2411 ModestMainWindow *win = NULL;
2412 GtkWidget *folder_view;
2413 const GError *error;
2415 g_return_if_fail (TNY_IS_FOLDER (folder));
2417 win = MODEST_MAIN_WINDOW (user_data);
2419 /* Check if the operation failed due to memory low conditions */
2420 error = modest_mail_operation_get_error (mail_op);
2421 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2422 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2423 modest_platform_run_information_dialog (GTK_WINDOW (win),
2424 dgettext("ke-recv","memr_ib_operation_disabled"),
2430 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2433 TnyFolderStore *current_folder;
2435 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2436 if (current_folder) {
2437 gboolean different = ((TnyFolderStore *) folder != current_folder);
2438 g_object_unref (current_folder);
2444 /* Check if folder is empty and set headers view contents style */
2445 if (tny_folder_get_all_count (folder) == 0)
2446 modest_main_window_set_contents_style (win,
2447 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2452 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2453 TnyFolderStore *folder_store,
2455 ModestMainWindow *main_window)
2458 GtkWidget *header_view;
2460 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2462 header_view = modest_main_window_get_child_widget(main_window,
2463 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2467 conf = modest_runtime_get_conf ();
2469 if (TNY_IS_ACCOUNT (folder_store)) {
2471 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2473 /* Show account details */
2474 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2477 if (TNY_IS_FOLDER (folder_store) && selected) {
2478 TnyAccount *account;
2479 const gchar *account_name = NULL;
2481 /* Update the active account */
2482 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2484 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2486 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2487 g_object_unref (account);
2491 /* Set the header style by default, it could
2492 be changed later by the refresh callback to
2494 modest_main_window_set_contents_style (main_window,
2495 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2497 /* Set folder on header view. This function
2498 will call tny_folder_refresh_async so we
2499 pass a callback that will be called when
2500 finished. We use that callback to set the
2501 empty view if there are no messages */
2502 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2503 TNY_FOLDER (folder_store),
2505 MODEST_WINDOW (main_window),
2506 folder_refreshed_cb,
2509 /* Restore configuration. We need to do this
2510 *after* the set_folder because the widget
2511 memory asks the header view about its
2513 modest_widget_memory_restore (modest_runtime_get_conf (),
2514 G_OBJECT(header_view),
2515 MODEST_CONF_HEADER_VIEW_KEY);
2517 /* No need to save the header view
2518 configuration for Maemo because it only
2519 saves the sorting stuff and that it's
2520 already being done by the sort
2521 dialog. Remove it when the GNOME version
2522 has the same behaviour */
2523 #ifdef MODEST_TOOLKIT_GTK
2524 if (modest_main_window_get_contents_style (main_window) ==
2525 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2526 modest_widget_memory_save (conf, G_OBJECT (header_view),
2527 MODEST_CONF_HEADER_VIEW_KEY);
2529 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2533 /* Update dimming state */
2534 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2535 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2539 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2546 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2548 online = tny_device_is_online (modest_runtime_get_device());
2551 /* already online -- the item is simply not there... */
2552 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2554 GTK_MESSAGE_WARNING,
2556 _("The %s you selected cannot be found"),
2558 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2559 gtk_dialog_run (GTK_DIALOG(dialog));
2561 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2564 _("mcen_bd_dialog_cancel"),
2565 GTK_RESPONSE_REJECT,
2566 _("mcen_bd_dialog_ok"),
2567 GTK_RESPONSE_ACCEPT,
2569 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2570 "Do you want to get online?"), item);
2571 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2572 gtk_label_new (txt), FALSE, FALSE, 0);
2573 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2576 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2577 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2578 /* TODO: Comment about why is this commented out: */
2579 /* modest_platform_connect_and_wait (); */
2582 gtk_widget_destroy (dialog);
2586 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2589 /* g_message ("%s %s", __FUNCTION__, link); */
2594 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2597 modest_platform_activate_uri (link);
2601 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2604 modest_platform_show_uri_popup (link);
2608 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2611 /* we check for low-mem; in that case, show a warning, and don't allow
2612 * viewing attachments
2614 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2617 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2621 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2622 const gchar *address,
2625 /* g_message ("%s %s", __FUNCTION__, address); */
2629 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2630 TnyMsg *saved_draft,
2633 ModestMsgEditWindow *edit_window;
2635 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2636 #ifndef MODEST_TOOLKIT_HILDON2
2637 ModestMainWindow *win;
2639 /* FIXME. Make the header view sensitive again. This is a
2640 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2642 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2643 modest_runtime_get_window_mgr(), FALSE));
2645 GtkWidget *hdrview = modest_main_window_get_child_widget(
2646 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2647 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2651 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2653 /* Set draft is there was no error */
2654 if (!modest_mail_operation_get_error (mail_op))
2655 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2657 g_object_unref(edit_window);
2661 enough_space_for_message (ModestMsgEditWindow *edit_window,
2664 TnyAccountStore *acc_store;
2665 guint64 available_disk, expected_size;
2670 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2671 available_disk = modest_utils_get_available_space (NULL);
2672 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2673 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2678 /* Double check: memory full condition or message too big */
2679 if (available_disk < MIN_FREE_SPACE ||
2680 expected_size > available_disk) {
2682 modest_platform_information_banner (NULL, NULL,
2684 "cerm_device_memory_full"));
2689 * djcb: if we're in low-memory state, we only allow for
2690 * saving messages smaller than
2691 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2692 * should still allow for sending anything critical...
2694 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2695 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2699 * djcb: we also make sure that the attachments are smaller than the max size
2700 * this is for the case where we'd try to forward a message with attachments
2701 * bigger than our max allowed size, or sending an message from drafts which
2702 * somehow got past our checks when attaching.
2704 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2705 modest_platform_run_information_dialog (
2706 GTK_WINDOW(edit_window),
2707 dgettext("ke-recv","memr_ib_operation_disabled"),
2716 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2718 TnyTransportAccount *transport_account;
2719 ModestMailOperation *mail_operation;
2721 gchar *account_name, *from;
2722 ModestAccountMgr *account_mgr;
2723 gboolean had_error = FALSE;
2724 ModestMainWindow *win = NULL;
2726 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2728 data = modest_msg_edit_window_get_msg_data (edit_window);
2731 if (!enough_space_for_message (edit_window, data)) {
2732 modest_msg_edit_window_free_msg_data (edit_window, data);
2736 account_name = g_strdup (data->account_name);
2737 account_mgr = modest_runtime_get_account_mgr();
2739 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2741 account_name = modest_account_mgr_get_default_account (account_mgr);
2742 if (!account_name) {
2743 g_printerr ("modest: no account found\n");
2744 modest_msg_edit_window_free_msg_data (edit_window, data);
2748 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2749 account_name = g_strdup (data->account_name);
2753 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2754 (modest_runtime_get_account_store (),
2756 TNY_ACCOUNT_TYPE_TRANSPORT));
2757 if (!transport_account) {
2758 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2759 g_free (account_name);
2760 modest_msg_edit_window_free_msg_data (edit_window, data);
2763 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2765 /* Create the mail operation */
2766 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2768 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2770 modest_mail_operation_save_to_drafts (mail_operation,
2782 data->priority_flags,
2783 on_save_to_drafts_cb,
2784 g_object_ref(edit_window));
2786 #ifdef MODEST_TOOLKIT_HILDON2
2787 /* In hildon2 we always show the information banner on saving to drafts.
2788 * It will be a system information banner in this case.
2790 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2791 modest_platform_information_banner (NULL, NULL, text);
2794 /* Use the main window as the parent of the banner, if the
2795 main window does not exist it won't be shown, if the parent
2796 window exists then it's properly shown. We don't use the
2797 editor window because it could be closed (save to drafts
2798 could happen after closing the window */
2799 win = (ModestMainWindow *)
2800 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2802 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2803 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2807 modest_msg_edit_window_set_modified (edit_window, FALSE);
2811 g_free (account_name);
2812 g_object_unref (G_OBJECT (transport_account));
2813 g_object_unref (G_OBJECT (mail_operation));
2815 modest_msg_edit_window_free_msg_data (edit_window, data);
2818 * If the drafts folder is selected then make the header view
2819 * insensitive while the message is being saved to drafts
2820 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2821 * is not very clean but it avoids letting the drafts folder
2822 * in an inconsistent state: the user could edit the message
2823 * being saved and undesirable things would happen.
2824 * In the average case the user won't notice anything at
2825 * all. In the worst case (the user is editing a really big
2826 * file from Drafts) the header view will be insensitive
2827 * during the saving process (10 or 20 seconds, depending on
2828 * the message). Anyway this is just a quick workaround: once
2829 * we find a better solution it should be removed
2830 * See NB#65125 (commend #18) for details.
2832 if (!had_error && win != NULL) {
2833 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2834 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2836 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2838 if (modest_tny_folder_is_local_folder(folder)) {
2839 TnyFolderType folder_type;
2840 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2841 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2842 GtkWidget *hdrview = modest_main_window_get_child_widget(
2843 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2844 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2848 if (folder != NULL) g_object_unref(folder);
2855 /* For instance, when clicking the Send toolbar button when editing a message: */
2857 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2859 TnyTransportAccount *transport_account = NULL;
2860 gboolean had_error = FALSE;
2862 ModestAccountMgr *account_mgr;
2863 gchar *account_name;
2865 ModestMailOperation *mail_operation;
2867 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2869 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2872 data = modest_msg_edit_window_get_msg_data (edit_window);
2875 if (!enough_space_for_message (edit_window, data)) {
2876 modest_msg_edit_window_free_msg_data (edit_window, data);
2880 account_mgr = modest_runtime_get_account_mgr();
2881 account_name = g_strdup (data->account_name);
2883 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2886 account_name = modest_account_mgr_get_default_account (account_mgr);
2888 if (!account_name) {
2889 modest_msg_edit_window_free_msg_data (edit_window, data);
2890 /* Run account setup wizard */
2891 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2896 /* Get the currently-active transport account for this modest account: */
2897 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2899 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2900 (modest_runtime_get_account_store (),
2901 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2904 if (!transport_account) {
2905 modest_msg_edit_window_free_msg_data (edit_window, data);
2906 /* Run account setup wizard */
2907 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2912 /* Create the mail operation */
2913 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2914 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2915 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2917 modest_mail_operation_send_new_mail (mail_operation,
2929 data->priority_flags);
2931 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2932 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2935 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2936 const GError *error = modest_mail_operation_get_error (mail_operation);
2937 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2938 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2939 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2940 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2947 g_free (account_name);
2948 g_object_unref (G_OBJECT (transport_account));
2949 g_object_unref (G_OBJECT (mail_operation));
2951 modest_msg_edit_window_free_msg_data (edit_window, data);
2954 modest_msg_edit_window_set_sent (edit_window, TRUE);
2956 /* Save settings and close the window: */
2957 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2964 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2965 ModestMsgEditWindow *window)
2967 ModestMsgEditFormatState *format_state = NULL;
2969 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2970 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2972 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2975 format_state = modest_msg_edit_window_get_format_state (window);
2976 g_return_if_fail (format_state != NULL);
2978 format_state->bold = gtk_toggle_action_get_active (action);
2979 modest_msg_edit_window_set_format_state (window, format_state);
2980 g_free (format_state);
2985 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2986 ModestMsgEditWindow *window)
2988 ModestMsgEditFormatState *format_state = NULL;
2990 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2991 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2993 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2996 format_state = modest_msg_edit_window_get_format_state (window);
2997 g_return_if_fail (format_state != NULL);
2999 format_state->italics = gtk_toggle_action_get_active (action);
3000 modest_msg_edit_window_set_format_state (window, format_state);
3001 g_free (format_state);
3006 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3007 ModestMsgEditWindow *window)
3009 ModestMsgEditFormatState *format_state = NULL;
3011 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3012 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3014 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3017 format_state = modest_msg_edit_window_get_format_state (window);
3018 g_return_if_fail (format_state != NULL);
3020 format_state->bullet = gtk_toggle_action_get_active (action);
3021 modest_msg_edit_window_set_format_state (window, format_state);
3022 g_free (format_state);
3027 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3028 GtkRadioAction *selected,
3029 ModestMsgEditWindow *window)
3031 ModestMsgEditFormatState *format_state = NULL;
3032 GtkJustification value;
3034 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3036 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3039 value = gtk_radio_action_get_current_value (selected);
3041 format_state = modest_msg_edit_window_get_format_state (window);
3042 g_return_if_fail (format_state != NULL);
3044 format_state->justification = value;
3045 modest_msg_edit_window_set_format_state (window, format_state);
3046 g_free (format_state);
3050 modest_ui_actions_on_select_editor_color (GtkAction *action,
3051 ModestMsgEditWindow *window)
3053 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3054 g_return_if_fail (GTK_IS_ACTION (action));
3056 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3059 modest_msg_edit_window_select_color (window);
3063 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3064 ModestMsgEditWindow *window)
3066 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3067 g_return_if_fail (GTK_IS_ACTION (action));
3069 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3072 modest_msg_edit_window_select_background_color (window);
3076 modest_ui_actions_on_insert_image (GtkAction *action,
3077 ModestMsgEditWindow *window)
3079 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3080 g_return_if_fail (GTK_IS_ACTION (action));
3083 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3086 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3089 modest_msg_edit_window_insert_image (window);
3093 modest_ui_actions_on_attach_file (GtkAction *action,
3094 ModestMsgEditWindow *window)
3096 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3097 g_return_if_fail (GTK_IS_ACTION (action));
3099 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3102 modest_msg_edit_window_offer_attach_file (window);
3106 modest_ui_actions_on_remove_attachments (GtkAction *action,
3107 ModestMsgEditWindow *window)
3109 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3110 g_return_if_fail (GTK_IS_ACTION (action));
3112 modest_msg_edit_window_remove_attachments (window, NULL);
3116 #ifndef MODEST_TOOLKIT_GTK
3121 TnyFolderStore *folder;
3122 } CreateFolderHelper;
3125 show_create_folder_in_timeout (gpointer data)
3127 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3129 /* Remove the timeout ASAP, we can not wait until the dialog
3130 is shown because it could take a lot of time and so the
3131 timeout could be called twice or more times */
3132 g_source_remove (helper->handler);
3134 gdk_threads_enter ();
3135 do_create_folder (helper->win, helper->folder, helper->name);
3136 gdk_threads_leave ();
3138 g_object_unref (helper->win);
3139 g_object_unref (helper->folder);
3140 g_free (helper->name);
3141 g_slice_free (CreateFolderHelper, helper);
3148 do_create_folder_cb (ModestMailOperation *mail_op,
3149 TnyFolderStore *parent_folder,
3150 TnyFolder *new_folder,
3153 gchar *suggested_name = (gchar *) user_data;
3154 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3156 if (modest_mail_operation_get_error (mail_op)) {
3158 /* Show an error. If there was some problem writing to
3159 disk, show it, otherwise show the generic folder
3160 create error. We do it here and not in an error
3161 handler because the call to do_create_folder will
3162 stop the main loop in a gtk_dialog_run and then,
3163 the message won't be shown until that dialog is
3165 modest_ui_actions_disk_operations_error_handler (mail_op,
3166 _("mail_in_ui_folder_create_error"));
3168 /* Try again. Do *NOT* show any error because the mail
3169 operations system will do it for us because we
3170 created the mail_op with new_with_error_handler */
3171 #ifndef MODEST_TOOLKIT_GTK
3172 CreateFolderHelper *helper;
3173 helper = g_slice_new0 (CreateFolderHelper);
3174 helper->name = g_strdup (suggested_name);
3175 helper->folder = g_object_ref (parent_folder);
3176 helper->win = g_object_ref (source_win);
3178 /* Ugly but neccesary stuff. The problem is that the
3179 dialog when is shown calls a function that destroys
3180 all the temporary windows, so the banner is
3182 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3184 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3187 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3188 * FIXME: any other? */
3189 GtkWidget *folder_view;
3191 if (MODEST_IS_MAIN_WINDOW(source_win))
3193 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3194 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3197 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3199 /* Select the newly created folder. It could happen
3200 that the widget is no longer there (i.e. the window
3201 has been destroyed, so we need to check this */
3203 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3205 g_object_unref (new_folder);
3207 /* Free. Note that the first time it'll be NULL so noop */
3208 g_free (suggested_name);
3209 g_object_unref (source_win);
3213 do_create_folder (GtkWindow *parent_window,
3214 TnyFolderStore *parent_folder,
3215 const gchar *suggested_name)
3218 gchar *folder_name = NULL;
3220 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3222 (gchar *) suggested_name,
3225 if (result == GTK_RESPONSE_ACCEPT) {
3226 ModestMailOperation *mail_op;
3228 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3229 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3231 modest_mail_operation_create_folder (mail_op,
3233 (const gchar *) folder_name,
3234 do_create_folder_cb,
3236 g_object_unref (mail_op);
3241 create_folder_performer (gboolean canceled,
3243 GtkWindow *parent_window,
3244 TnyAccount *account,
3247 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3249 if (canceled || err) {
3250 /* In memory full conditions we could get this error here */
3251 check_memory_full_error ((GtkWidget *) parent_window, err);
3255 /* Run the new folder dialog */
3256 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3259 g_object_unref (parent_folder);
3263 modest_ui_actions_create_folder(GtkWidget *parent_window,
3264 GtkWidget *folder_view)
3266 TnyFolderStore *parent_folder;
3268 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3270 if (parent_folder) {
3271 /* The parent folder will be freed in the callback */
3272 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3275 create_folder_performer,
3281 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3283 GtkWidget *folder_view;
3285 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3287 folder_view = modest_main_window_get_child_widget (main_window,
3288 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3292 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3296 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3299 const GError *error = NULL;
3300 const gchar *message = NULL;
3302 /* Get error message */
3303 error = modest_mail_operation_get_error (mail_op);
3305 g_return_if_reached ();
3307 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3308 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3309 message = _CS("ckdg_ib_folder_already_exists");
3310 } else if (error->domain == TNY_ERROR_DOMAIN &&
3311 error->code == TNY_SERVICE_ERROR_STATE) {
3312 /* This means that the folder is already in use (a
3313 message is opened for example */
3314 message = _("emev_ni_internal_error");
3316 message = _("emev_ib_ui_imap_unable_to_rename");
3319 /* We don't set a parent for the dialog because the dialog
3320 will be destroyed so the banner won't appear */
3321 modest_platform_information_banner (NULL, NULL, message);
3325 TnyFolderStore *folder;
3330 on_rename_folder_cb (ModestMailOperation *mail_op,
3331 TnyFolder *new_folder,
3334 ModestFolderView *folder_view;
3336 /* If the window was closed when renaming a folder this could
3338 if (!MODEST_IS_FOLDER_VIEW (user_data))
3341 folder_view = MODEST_FOLDER_VIEW (user_data);
3342 /* Note that if the rename fails new_folder will be NULL */
3344 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3346 modest_folder_view_select_first_inbox_or_local (folder_view);
3348 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3352 on_rename_folder_performer (gboolean canceled,
3354 GtkWindow *parent_window,
3355 TnyAccount *account,
3358 ModestMailOperation *mail_op = NULL;
3359 GtkTreeSelection *sel = NULL;
3360 GtkWidget *folder_view = NULL;
3361 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3363 if (canceled || err) {
3364 /* In memory full conditions we could get this error here */
3365 check_memory_full_error ((GtkWidget *) parent_window, err);
3366 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3368 folder_view = modest_main_window_get_child_widget (
3369 MODEST_MAIN_WINDOW (parent_window),
3370 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3373 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3374 modest_ui_actions_rename_folder_error_handler,
3375 parent_window, NULL);
3377 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3380 /* Clear the headers view */
3381 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3382 gtk_tree_selection_unselect_all (sel);
3384 /* Actually rename the folder */
3385 modest_mail_operation_rename_folder (mail_op,
3386 TNY_FOLDER (data->folder),
3387 (const gchar *) (data->new_name),
3388 on_rename_folder_cb,
3390 g_object_unref (data->folder);
3391 g_object_unref (mail_op);
3394 g_free (data->new_name);
3399 modest_ui_actions_on_rename_folder (GtkAction *action,
3400 ModestMainWindow *main_window)
3402 TnyFolderStore *folder;
3403 GtkWidget *folder_view;
3404 GtkWidget *header_view;
3406 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3408 folder_view = modest_main_window_get_child_widget (main_window,
3409 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3413 header_view = modest_main_window_get_child_widget (main_window,
3414 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3419 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3424 if (TNY_IS_FOLDER (folder)) {
3425 gchar *folder_name = NULL;
3427 const gchar *current_name;
3428 TnyFolderStore *parent;
3429 gboolean do_rename = TRUE;
3431 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3432 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3433 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3434 parent, current_name,
3436 g_object_unref (parent);
3438 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3441 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3442 rename_folder_data->folder = g_object_ref (folder);
3443 rename_folder_data->new_name = folder_name;
3444 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3445 folder, on_rename_folder_performer, rename_folder_data);
3448 g_object_unref (folder);
3452 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3455 GObject *win = modest_mail_operation_get_source (mail_op);
3457 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3458 _("mail_in_ui_folder_delete_error"),
3460 g_object_unref (win);
3464 TnyFolderStore *folder;
3465 gboolean move_to_trash;
3469 on_delete_folder_cb (gboolean canceled,
3471 GtkWindow *parent_window,
3472 TnyAccount *account,
3475 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3476 GtkWidget *folder_view;
3477 ModestMailOperation *mail_op;
3478 GtkTreeSelection *sel;
3480 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3481 g_object_unref (G_OBJECT (info->folder));
3486 folder_view = modest_main_window_get_child_widget (
3487 MODEST_MAIN_WINDOW (parent_window),
3488 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3490 /* Unselect the folder before deleting it to free the headers */
3491 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3492 gtk_tree_selection_unselect_all (sel);
3494 /* Create the mail operation */
3496 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3497 modest_ui_actions_delete_folder_error_handler,
3500 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3502 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3504 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3506 g_object_unref (G_OBJECT (mail_op));
3507 g_object_unref (G_OBJECT (info->folder));
3512 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3514 TnyFolderStore *folder;
3515 GtkWidget *folder_view;
3519 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3521 folder_view = modest_main_window_get_child_widget (main_window,
3522 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3526 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3528 /* Show an error if it's an account */
3529 if (!TNY_IS_FOLDER (folder)) {
3530 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3531 _("mail_in_ui_folder_delete_error"),
3533 g_object_unref (G_OBJECT (folder));
3538 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3539 tny_folder_get_name (TNY_FOLDER (folder)));
3540 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3541 (const gchar *) message);
3544 if (response == GTK_RESPONSE_OK) {
3545 DeleteFolderInfo *info;
3546 info = g_new0(DeleteFolderInfo, 1);
3547 info->folder = folder;
3548 info->move_to_trash = move_to_trash;
3549 g_object_ref (G_OBJECT (info->folder));
3550 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3551 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3553 TNY_FOLDER_STORE (account),
3554 on_delete_folder_cb, info);
3555 g_object_unref (account);
3557 g_object_unref (G_OBJECT (folder));
3561 modest_ui_actions_on_delete_folder (GtkAction *action,
3562 ModestMainWindow *main_window)
3564 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3566 delete_folder (main_window, FALSE);
3570 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3572 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3574 delete_folder (main_window, TRUE);
3578 typedef struct _PasswordDialogFields {
3579 GtkWidget *username;
3580 GtkWidget *password;
3582 } PasswordDialogFields;
3585 password_dialog_check_field (GtkEditable *editable,
3586 PasswordDialogFields *fields)
3589 gboolean any_value_empty = FALSE;
3591 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3592 if ((value == NULL) || value[0] == '\0') {
3593 any_value_empty = TRUE;
3595 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3596 if ((value == NULL) || value[0] == '\0') {
3597 any_value_empty = TRUE;
3599 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3603 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3604 const gchar* server_account_name,
3609 ModestMainWindow *main_window)
3611 g_return_if_fail(server_account_name);
3612 gboolean completed = FALSE;
3613 PasswordDialogFields *fields = NULL;
3615 /* Initalize output parameters: */
3622 #ifndef MODEST_TOOLKIT_GTK
3623 /* Maemo uses a different (awkward) button order,
3624 * It should probably just use gtk_alternative_dialog_button_order ().
3626 #ifdef MODEST_TOOLKIT_HILDON2
3628 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3631 _HL("wdgt_bd_done"),
3632 GTK_RESPONSE_ACCEPT,
3636 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3639 _("mcen_bd_dialog_ok"),
3640 GTK_RESPONSE_ACCEPT,
3641 _("mcen_bd_dialog_cancel"),
3642 GTK_RESPONSE_REJECT,
3644 #endif /* MODEST_TOOLKIT_HILDON2 */
3647 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3651 GTK_RESPONSE_REJECT,
3653 GTK_RESPONSE_ACCEPT,
3655 #endif /* MODEST_TOOLKIT_GTK */
3657 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3659 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3660 modest_runtime_get_account_mgr(), server_account_name);
3661 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3662 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3665 gtk_widget_destroy (dialog);
3669 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3670 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3673 g_free (server_name);
3677 gchar *initial_username = modest_account_mgr_get_server_account_username (
3678 modest_runtime_get_account_mgr(), server_account_name);
3680 GtkWidget *entry_username = gtk_entry_new ();
3681 if (initial_username)
3682 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3683 /* Dim this if a connection has ever succeeded with this username,
3684 * as per the UI spec: */
3685 /* const gboolean username_known = */
3686 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3687 /* modest_runtime_get_account_mgr(), server_account_name); */
3688 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3690 /* We drop the username sensitive code and disallow changing it here
3691 * as tinymail does not support really changing the username in the callback
3693 gtk_widget_set_sensitive (entry_username, FALSE);
3695 #ifndef MODEST_TOOLKIT_GTK
3696 /* Auto-capitalization is the default, so let's turn it off: */
3697 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3699 /* Create a size group to be used by all captions.
3700 * Note that HildonCaption does not create a default size group if we do not specify one.
3701 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3702 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3704 GtkWidget *caption = hildon_caption_new (sizegroup,
3705 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3706 gtk_widget_show (entry_username);
3707 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3708 FALSE, FALSE, MODEST_MARGIN_HALF);
3709 gtk_widget_show (caption);
3711 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3713 #endif /* !MODEST_TOOLKIT_GTK */
3716 GtkWidget *entry_password = gtk_entry_new ();
3717 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3718 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3720 #ifndef MODEST_TOOLKIT_GTK
3721 /* Auto-capitalization is the default, so let's turn it off: */
3722 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3723 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3725 caption = hildon_caption_new (sizegroup,
3726 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3727 gtk_widget_show (entry_password);
3728 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3729 FALSE, FALSE, MODEST_MARGIN_HALF);
3730 gtk_widget_show (caption);
3731 g_object_unref (sizegroup);
3733 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3735 #endif /* !MODEST_TOOLKIT_GTK */
3737 if (initial_username != NULL)
3738 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3740 /* This is not in the Maemo UI spec:
3741 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3742 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3746 fields = g_slice_new0 (PasswordDialogFields);
3747 fields->username = entry_username;
3748 fields->password = entry_password;
3749 fields->dialog = dialog;
3751 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3752 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3753 password_dialog_check_field (NULL, fields);
3755 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3757 while (!completed) {
3759 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3761 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3763 /* Note that an empty field becomes the "" string */
3764 if (*username && strlen (*username) > 0) {
3765 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3766 server_account_name,
3770 const gboolean username_was_changed =
3771 (strcmp (*username, initial_username) != 0);
3772 if (username_was_changed) {
3773 g_warning ("%s: tinymail does not yet support changing the "
3774 "username in the get_password() callback.\n", __FUNCTION__);
3780 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3781 _("mcen_ib_username_pw_incorrect"));
3787 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3789 /* We do not save the password in the configuration,
3790 * because this function is only called for passwords that should
3791 * not be remembered:
3792 modest_server_account_set_password (
3793 modest_runtime_get_account_mgr(), server_account_name,
3800 #ifndef MODEST_TOOLKIT_HILDON2
3801 /* Set parent to NULL or the banner will disappear with its parent dialog */
3802 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3814 /* This is not in the Maemo UI spec:
3815 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3821 g_free (initial_username);
3822 gtk_widget_destroy (dialog);
3823 g_slice_free (PasswordDialogFields, fields);
3825 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3829 modest_ui_actions_on_cut (GtkAction *action,
3830 ModestWindow *window)
3832 GtkWidget *focused_widget;
3833 GtkClipboard *clipboard;
3835 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3836 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3837 if (GTK_IS_EDITABLE (focused_widget)) {
3838 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3839 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3840 gtk_clipboard_store (clipboard);
3841 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3842 GtkTextBuffer *buffer;
3844 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3845 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3846 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3847 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3848 gtk_clipboard_store (clipboard);
3850 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3851 TnyList *header_list = modest_header_view_get_selected_headers (
3852 MODEST_HEADER_VIEW (focused_widget));
3853 gboolean continue_download = FALSE;
3854 gint num_of_unc_msgs;
3856 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3858 if (num_of_unc_msgs) {
3859 TnyAccount *account = get_account_from_header_list (header_list);
3861 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3862 g_object_unref (account);
3866 if (num_of_unc_msgs == 0 || continue_download) {
3867 /* modest_platform_information_banner (
3868 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3869 modest_header_view_cut_selection (
3870 MODEST_HEADER_VIEW (focused_widget));
3873 g_object_unref (header_list);
3874 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3875 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3880 modest_ui_actions_on_copy (GtkAction *action,
3881 ModestWindow *window)
3883 GtkClipboard *clipboard;
3884 GtkWidget *focused_widget;
3885 gboolean copied = TRUE;
3887 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3888 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3890 if (GTK_IS_LABEL (focused_widget)) {
3892 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3893 gtk_clipboard_set_text (clipboard, selection, -1);
3895 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3896 gtk_clipboard_store (clipboard);
3897 } else if (GTK_IS_EDITABLE (focused_widget)) {
3898 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3899 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3900 gtk_clipboard_store (clipboard);
3901 } else if (GTK_IS_HTML (focused_widget)) {
3904 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3905 if ((sel == NULL) || (sel[0] == '\0')) {
3908 gtk_html_copy (GTK_HTML (focused_widget));
3909 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3910 gtk_clipboard_store (clipboard);
3912 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3913 GtkTextBuffer *buffer;
3914 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3915 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3916 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3917 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3918 gtk_clipboard_store (clipboard);
3920 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3921 TnyList *header_list = modest_header_view_get_selected_headers (
3922 MODEST_HEADER_VIEW (focused_widget));
3923 gboolean continue_download = FALSE;
3924 gint num_of_unc_msgs;
3926 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3928 if (num_of_unc_msgs) {
3929 TnyAccount *account = get_account_from_header_list (header_list);
3931 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3932 g_object_unref (account);
3936 if (num_of_unc_msgs == 0 || continue_download) {
3937 modest_platform_information_banner (
3938 NULL, NULL, _CS("mcen_ib_getting_items"));
3939 modest_header_view_copy_selection (
3940 MODEST_HEADER_VIEW (focused_widget));
3944 g_object_unref (header_list);
3946 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3947 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3950 /* Show information banner if there was a copy to clipboard */
3952 modest_platform_information_banner (
3953 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3957 modest_ui_actions_on_undo (GtkAction *action,
3958 ModestWindow *window)
3960 ModestEmailClipboard *clipboard = NULL;
3962 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3963 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3964 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3965 /* Clear clipboard source */
3966 clipboard = modest_runtime_get_email_clipboard ();
3967 modest_email_clipboard_clear (clipboard);
3970 g_return_if_reached ();
3975 modest_ui_actions_on_redo (GtkAction *action,
3976 ModestWindow *window)
3978 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3979 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3982 g_return_if_reached ();
3988 destroy_information_note (ModestMailOperation *mail_op,
3991 /* destroy information note */
3992 gtk_widget_destroy (GTK_WIDGET(user_data));
3996 destroy_folder_information_note (ModestMailOperation *mail_op,
3997 TnyFolder *new_folder,
4000 /* destroy information note */
4001 gtk_widget_destroy (GTK_WIDGET(user_data));
4006 paste_as_attachment_free (gpointer data)
4008 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4010 if (helper->banner) {
4011 gtk_widget_destroy (helper->banner);
4012 g_object_unref (helper->banner);
4018 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4023 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4024 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4029 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4034 modest_ui_actions_on_paste (GtkAction *action,
4035 ModestWindow *window)
4037 GtkWidget *focused_widget = NULL;
4038 GtkWidget *inf_note = NULL;
4039 ModestMailOperation *mail_op = NULL;
4041 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4042 if (GTK_IS_EDITABLE (focused_widget)) {
4043 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4044 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4045 ModestEmailClipboard *e_clipboard = NULL;
4046 e_clipboard = modest_runtime_get_email_clipboard ();
4047 if (modest_email_clipboard_cleared (e_clipboard)) {
4048 GtkTextBuffer *buffer;
4049 GtkClipboard *clipboard;
4051 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4052 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4053 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4054 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4055 ModestMailOperation *mail_op;
4056 TnyFolder *src_folder = NULL;
4057 TnyList *data = NULL;
4059 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4060 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4061 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4062 _CS("ckct_nw_pasting"));
4063 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4064 mail_op = modest_mail_operation_new (G_OBJECT (window));
4065 if (helper->banner != NULL) {
4066 g_object_ref (G_OBJECT (helper->banner));
4067 gtk_widget_show (GTK_WIDGET (helper->banner));
4071 modest_mail_operation_get_msgs_full (mail_op,
4073 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4075 paste_as_attachment_free);
4079 g_object_unref (data);
4081 g_object_unref (src_folder);
4084 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4085 ModestEmailClipboard *clipboard = NULL;
4086 TnyFolder *src_folder = NULL;
4087 TnyFolderStore *folder_store = NULL;
4088 TnyList *data = NULL;
4089 gboolean delete = FALSE;
4091 /* Check clipboard source */
4092 clipboard = modest_runtime_get_email_clipboard ();
4093 if (modest_email_clipboard_cleared (clipboard))
4096 /* Get elements to paste */
4097 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4099 /* Create a new mail operation */
4100 mail_op = modest_mail_operation_new (G_OBJECT(window));
4102 /* Get destination folder */
4103 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4105 /* transfer messages */
4109 /* Ask for user confirmation */
4111 modest_ui_actions_msgs_move_to_confirmation (window,
4112 TNY_FOLDER (folder_store),
4116 if (response == GTK_RESPONSE_OK) {
4117 /* Launch notification */
4118 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4119 _CS("ckct_nw_pasting"));
4120 if (inf_note != NULL) {
4121 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4122 gtk_widget_show (GTK_WIDGET(inf_note));
4125 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4126 modest_mail_operation_xfer_msgs (mail_op,
4128 TNY_FOLDER (folder_store),
4130 destroy_information_note,
4133 g_object_unref (mail_op);
4136 } else if (src_folder != NULL) {
4137 /* Launch notification */
4138 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4139 _CS("ckct_nw_pasting"));
4140 if (inf_note != NULL) {
4141 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4142 gtk_widget_show (GTK_WIDGET(inf_note));
4145 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4146 modest_mail_operation_xfer_folder (mail_op,
4150 destroy_folder_information_note,
4156 g_object_unref (data);
4157 if (src_folder != NULL)
4158 g_object_unref (src_folder);
4159 if (folder_store != NULL)
4160 g_object_unref (folder_store);
4166 modest_ui_actions_on_select_all (GtkAction *action,
4167 ModestWindow *window)
4169 GtkWidget *focused_widget;
4171 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4172 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4173 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4174 } else if (GTK_IS_LABEL (focused_widget)) {
4175 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4176 } else if (GTK_IS_EDITABLE (focused_widget)) {
4177 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4178 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4179 GtkTextBuffer *buffer;
4180 GtkTextIter start, end;
4182 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4183 gtk_text_buffer_get_start_iter (buffer, &start);
4184 gtk_text_buffer_get_end_iter (buffer, &end);
4185 gtk_text_buffer_select_range (buffer, &start, &end);
4186 } else if (GTK_IS_HTML (focused_widget)) {
4187 gtk_html_select_all (GTK_HTML (focused_widget));
4188 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4189 GtkWidget *header_view = focused_widget;
4190 GtkTreeSelection *selection = NULL;
4192 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4193 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4194 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4197 /* Disable window dimming management */
4198 modest_window_disable_dimming (MODEST_WINDOW(window));
4200 /* Select all messages */
4201 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4202 gtk_tree_selection_select_all (selection);
4204 /* Set focuse on header view */
4205 gtk_widget_grab_focus (header_view);
4207 /* Enable window dimming management */
4208 modest_window_enable_dimming (MODEST_WINDOW(window));
4209 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4210 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4216 modest_ui_actions_on_mark_as_read (GtkAction *action,
4217 ModestWindow *window)
4219 g_return_if_fail (MODEST_IS_WINDOW(window));
4221 /* Mark each header as read */
4222 do_headers_action (window, headers_action_mark_as_read, NULL);
4226 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4227 ModestWindow *window)
4229 g_return_if_fail (MODEST_IS_WINDOW(window));
4231 /* Mark each header as read */
4232 do_headers_action (window, headers_action_mark_as_unread, NULL);
4236 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4237 GtkRadioAction *selected,
4238 ModestWindow *window)
4242 value = gtk_radio_action_get_current_value (selected);
4243 if (MODEST_IS_WINDOW (window)) {
4244 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4249 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4250 GtkRadioAction *selected,
4251 ModestWindow *window)
4253 TnyHeaderFlags flags;
4254 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4256 flags = gtk_radio_action_get_current_value (selected);
4257 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4261 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4262 GtkRadioAction *selected,
4263 ModestWindow *window)
4267 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4269 file_format = gtk_radio_action_get_current_value (selected);
4270 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4275 modest_ui_actions_on_zoom_plus (GtkAction *action,
4276 ModestWindow *window)
4278 g_return_if_fail (MODEST_IS_WINDOW (window));
4280 modest_window_zoom_plus (MODEST_WINDOW (window));
4284 modest_ui_actions_on_zoom_minus (GtkAction *action,
4285 ModestWindow *window)
4287 g_return_if_fail (MODEST_IS_WINDOW (window));
4289 modest_window_zoom_minus (MODEST_WINDOW (window));
4293 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4294 ModestWindow *window)
4296 ModestWindowMgr *mgr;
4297 gboolean fullscreen, active;
4298 g_return_if_fail (MODEST_IS_WINDOW (window));
4300 mgr = modest_runtime_get_window_mgr ();
4302 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4303 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4305 if (active != fullscreen) {
4306 modest_window_mgr_set_fullscreen_mode (mgr, active);
4307 #ifndef MODEST_TOOLKIT_HILDON2
4308 gtk_window_present (GTK_WINDOW (window));
4314 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4315 ModestWindow *window)
4317 ModestWindowMgr *mgr;
4318 gboolean fullscreen;
4320 g_return_if_fail (MODEST_IS_WINDOW (window));
4322 mgr = modest_runtime_get_window_mgr ();
4323 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4324 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4326 #ifndef MODEST_TOOLKIT_HILDON2
4327 gtk_window_present (GTK_WINDOW (window));
4332 * Used by modest_ui_actions_on_details to call do_headers_action
4335 headers_action_show_details (TnyHeader *header,
4336 ModestWindow *window,
4340 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4344 * Show the header details in a ModestDetailsDialog widget
4347 modest_ui_actions_on_details (GtkAction *action,
4350 TnyList * headers_list;
4354 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4357 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4360 g_object_unref (msg);
4362 headers_list = get_selected_headers (win);
4366 iter = tny_list_create_iterator (headers_list);
4368 header = TNY_HEADER (tny_iterator_get_current (iter));
4370 headers_action_show_details (header, win, NULL);
4371 g_object_unref (header);
4374 g_object_unref (iter);
4375 g_object_unref (headers_list);
4377 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4378 GtkWidget *folder_view, *header_view;
4380 /* Check which widget has the focus */
4381 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4382 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4383 if (gtk_widget_is_focus (folder_view)) {
4384 TnyFolderStore *folder_store
4385 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4386 if (!folder_store) {
4387 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4390 /* Show only when it's a folder */
4391 /* This function should not be called for account items,
4392 * because we dim the menu item for them. */
4393 if (TNY_IS_FOLDER (folder_store)) {
4394 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4395 TNY_FOLDER (folder_store));
4398 g_object_unref (folder_store);
4401 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4402 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4403 /* Show details of each header */
4404 do_headers_action (win, headers_action_show_details, header_view);
4406 #ifdef MODEST_TOOLKIT_HILDON2
4407 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4409 GtkWidget *header_view;
4411 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4412 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4414 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4416 g_object_unref (folder);
4423 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4424 ModestMsgEditWindow *window)
4426 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4428 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4432 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4433 ModestMsgEditWindow *window)
4435 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4437 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4441 modest_ui_actions_toggle_folders_view (GtkAction *action,
4442 ModestMainWindow *main_window)
4444 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4446 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4447 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4449 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4453 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4454 ModestWindow *window)
4456 gboolean active, fullscreen = FALSE;
4457 ModestWindowMgr *mgr;
4459 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4461 /* Check if we want to toggle the toolbar view in fullscreen
4463 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4464 "ViewShowToolbarFullScreen")) {
4468 /* Toggle toolbar */
4469 mgr = modest_runtime_get_window_mgr ();
4470 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4474 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4475 ModestMsgEditWindow *window)
4477 modest_msg_edit_window_select_font (window);
4482 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4483 const gchar *display_name,
4486 /* don't update the display name if it was already set;
4487 * updating the display name apparently is expensive */
4488 const gchar* old_name = gtk_window_get_title (window);
4490 if (display_name == NULL)
4493 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4494 return; /* don't do anything */
4496 /* This is usually used to change the title of the main window, which
4497 * is the one that holds the folder view. Note that this change can
4498 * happen even when the widget doesn't have the focus. */
4499 gtk_window_set_title (window, display_name);
4504 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4506 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4507 modest_msg_edit_window_select_contacts (window);
4511 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4513 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4514 modest_msg_edit_window_check_names (window, FALSE);
4518 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4520 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4521 GTK_WIDGET (user_data));
4524 #ifndef MODEST_TOOLKIT_HILDON2
4526 * This function is used to track changes in the selection of the
4527 * folder view that is inside the "move to" dialog to enable/disable
4528 * the OK button because we do not want the user to select a disallowed
4529 * destination for a folder.
4530 * The user also not desired to be able to use NEW button on items where
4531 * folder creation is not possibel.
4534 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4535 TnyFolderStore *folder_store,
4539 GtkWidget *dialog = NULL;
4540 GtkWidget *ok_button = NULL, *new_button = NULL;
4541 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4542 gboolean moving_folder = FALSE;
4543 gboolean is_local_account = TRUE;
4544 GtkWidget *folder_view = NULL;
4545 ModestTnyFolderRules rules;
4547 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4552 /* Get the OK button */
4553 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4557 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4558 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4560 /* check if folder_store is an remote account */
4561 if (TNY_IS_ACCOUNT (folder_store)) {
4562 TnyAccount *local_account = NULL;
4563 TnyAccount *mmc_account = NULL;
4564 ModestTnyAccountStore *account_store = NULL;
4566 account_store = modest_runtime_get_account_store ();
4567 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4568 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4570 if ((gpointer) local_account != (gpointer) folder_store &&
4571 (gpointer) mmc_account != (gpointer) folder_store) {
4572 ModestProtocolType proto;
4573 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4574 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4575 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4577 is_local_account = FALSE;
4578 /* New button should be dimmed on remote
4580 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4582 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4584 g_object_unref (local_account);
4586 /* It could not exist */
4588 g_object_unref (mmc_account);
4591 /* Check the target folder rules */
4592 if (TNY_IS_FOLDER (folder_store)) {
4593 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4594 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4595 ok_sensitive = FALSE;
4596 new_sensitive = FALSE;
4601 /* Check if we're moving a folder */
4602 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4603 /* Get the widgets */
4604 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4605 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4606 if (gtk_widget_is_focus (folder_view))
4607 moving_folder = TRUE;
4610 if (moving_folder) {
4611 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4613 /* Get the folder to move */
4614 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4616 /* Check that we're not moving to the same folder */
4617 if (TNY_IS_FOLDER (moved_folder)) {
4618 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4619 if (parent == folder_store)
4620 ok_sensitive = FALSE;
4621 g_object_unref (parent);
4624 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4625 /* Do not allow to move to an account unless it's the
4626 local folders account */
4627 if (!is_local_account)
4628 ok_sensitive = FALSE;
4631 if (ok_sensitive && (moved_folder == folder_store)) {
4632 /* Do not allow to move to itself */
4633 ok_sensitive = FALSE;
4635 g_object_unref (moved_folder);
4637 TnyFolder *src_folder = NULL;
4639 /* Moving a message */
4640 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4642 TnyHeader *header = NULL;
4643 header = modest_msg_view_window_get_header
4644 (MODEST_MSG_VIEW_WINDOW (user_data));
4645 if (!TNY_IS_HEADER(header))
4646 g_warning ("%s: could not get source header", __FUNCTION__);
4648 src_folder = tny_header_get_folder (header);
4651 g_object_unref (header);
4654 TNY_FOLDER (modest_folder_view_get_selected
4655 (MODEST_FOLDER_VIEW (folder_view)));
4658 if (TNY_IS_FOLDER(src_folder)) {
4659 /* Do not allow to move the msg to the same folder */
4660 /* Do not allow to move the msg to an account */
4661 if ((gpointer) src_folder == (gpointer) folder_store ||
4662 TNY_IS_ACCOUNT (folder_store))
4663 ok_sensitive = FALSE;
4664 g_object_unref (src_folder);
4666 g_warning ("%s: could not get source folder", __FUNCTION__);
4670 /* Set sensitivity of the OK button */
4671 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4672 /* Set sensitivity of the NEW button */
4673 gtk_widget_set_sensitive (new_button, new_sensitive);
4677 #ifdef MODEST_TOOLKIT_HILDON2
4679 on_move_to_dialog_folder_activated (GtkTreeView *tree_view,
4681 GtkTreeViewColumn *column,
4684 gtk_dialog_response (GTK_DIALOG (user_data), GTK_RESPONSE_ACCEPT);
4689 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4692 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4694 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4695 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4699 create_move_to_dialog (GtkWindow *win,
4700 GtkWidget *folder_view,
4701 GtkWidget **tree_view)
4704 #ifdef MODEST_TOOLKIT_HILDON2
4705 GtkWidget *pannable;
4708 GtkWidget *ok_button;
4710 GtkWidget *new_button;
4712 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4714 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4717 #ifndef MODEST_TOOLKIT_GTK
4718 #ifndef MODEST_TOOLKIT_HILDON2
4719 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4721 /* We do this manually so GTK+ does not associate a response ID for
4723 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4724 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4725 #ifndef MODEST_TOOLKIT_HILDON2
4726 hildon_gtk_widget_set_theme_size (new_button, HILDON_SIZE_FINGER_HEIGHT);
4727 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4729 gtk_widget_show (new_button);
4731 /* We do this manually so GTK+ does not associate a response ID for
4733 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4734 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4735 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4736 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4737 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4738 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4739 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4742 #ifndef MODEST_TOOLKIT_HILDON2
4743 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4745 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4747 /* Create scrolled window */
4748 #ifdef MODEST_TOOLKIT_HILDON2
4749 pannable = hildon_pannable_area_new ();
4751 scroll = gtk_scrolled_window_new (NULL, NULL);
4752 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4753 GTK_POLICY_AUTOMATIC,
4754 GTK_POLICY_AUTOMATIC);
4757 #ifdef MODEST_TOOLKIT_GTK
4758 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4761 /* Create folder view */
4762 *tree_view = modest_platform_create_folder_view (NULL);
4764 #ifdef MODEST_TOOLKIT_HILDON2
4765 /* We return OK on activation */
4766 g_signal_connect (*tree_view,
4768 G_CALLBACK (on_move_to_dialog_folder_activated),
4771 /* Track changes in the selection to
4772 * disable the OK button whenever "Move to" is not possible
4773 * disbale NEW button whenever New is not possible */
4774 g_signal_connect (*tree_view,
4775 "folder_selection_changed",
4776 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4780 /* Listen to clicks on New button */
4781 g_signal_connect (G_OBJECT (new_button),
4783 G_CALLBACK(create_move_to_dialog_on_new_folder),
4786 #ifdef MODEST_TOOLKIT_HILDON2
4787 modest_folder_view_set_cell_style (MODEST_FOLDER_VIEW (*tree_view),
4788 MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT);
4791 /* It could happen that we're trying to move a message from a
4792 window (msg window for example) after the main window was
4793 closed, so we can not just get the model of the folder
4795 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4796 const gchar *visible_id = NULL;
4798 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4799 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4800 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4801 MODEST_FOLDER_VIEW(*tree_view));
4804 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4806 /* Show the same account than the one that is shown in the main window */
4807 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4810 const gchar *active_account_name = NULL;
4811 ModestAccountMgr *mgr = NULL;
4812 ModestAccountSettings *settings = NULL;
4813 ModestServerAccountSettings *store_settings = NULL;
4815 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4816 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4817 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4818 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4820 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4821 mgr = modest_runtime_get_account_mgr ();
4822 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4825 const gchar *store_account_name;
4826 store_settings = modest_account_settings_get_store_settings (settings);
4827 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4829 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4830 store_account_name);
4831 g_object_unref (store_settings);
4832 g_object_unref (settings);
4836 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4837 * get_folder_view_from_move_to_dialog
4838 * (see above) later (needed for focus handling)
4840 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4843 /* Hide special folders */
4844 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4846 #ifdef MODEST_TOOLKIT_HILDON2
4847 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4848 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4849 pannable, TRUE, TRUE, 0);
4851 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4852 /* Add scroll to dialog */
4853 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4854 scroll, TRUE, TRUE, 0);
4858 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4859 #ifndef MODEST_TOOLKIT_GTK
4860 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4862 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4871 * Shows a confirmation dialog to the user when we're moving messages
4872 * from a remote server to the local storage. Returns the dialog
4873 * response. If it's other kind of movement then it always returns
4876 * This one is used by the next functions:
4877 * modest_ui_actions_on_paste - commented out
4878 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4881 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4882 TnyFolder *dest_folder,
4886 gint response = GTK_RESPONSE_OK;
4887 TnyAccount *account = NULL;
4888 TnyFolder *src_folder = NULL;
4889 TnyIterator *iter = NULL;
4890 TnyHeader *header = NULL;
4892 /* return with OK if the destination is a remote folder */
4893 if (modest_tny_folder_is_remote_folder (dest_folder))
4894 return GTK_RESPONSE_OK;
4896 /* Get source folder */
4897 iter = tny_list_create_iterator (headers);
4898 header = TNY_HEADER (tny_iterator_get_current (iter));
4900 src_folder = tny_header_get_folder (header);
4901 g_object_unref (header);
4903 g_object_unref (iter);
4905 /* if no src_folder, message may be an attahcment */
4906 if (src_folder == NULL)
4907 return GTK_RESPONSE_CANCEL;
4909 /* If the source is a local or MMC folder */
4910 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4911 g_object_unref (src_folder);
4912 return GTK_RESPONSE_OK;
4915 /* Get the account */
4916 account = tny_folder_get_account (src_folder);
4918 /* now if offline we ask the user */
4919 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4920 response = GTK_RESPONSE_OK;
4922 response = GTK_RESPONSE_CANCEL;
4925 g_object_unref (src_folder);
4926 g_object_unref (account);
4932 move_to_helper_destroyer (gpointer user_data)
4934 MoveToHelper *helper = (MoveToHelper *) user_data;
4936 /* Close the "Pasting" information banner */
4937 if (helper->banner) {
4938 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4939 g_object_unref (helper->banner);
4941 if (gtk_tree_row_reference_valid (helper->reference)) {
4942 gtk_tree_row_reference_free (helper->reference);
4943 helper->reference = NULL;
4949 move_to_cb (ModestMailOperation *mail_op,
4952 MoveToHelper *helper = (MoveToHelper *) user_data;
4954 /* Note that the operation could have failed, in that case do
4956 if (modest_mail_operation_get_status (mail_op) ==
4957 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4959 GObject *object = modest_mail_operation_get_source (mail_op);
4960 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4961 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4963 if (!modest_msg_view_window_select_next_message (self) &&
4964 !modest_msg_view_window_select_previous_message (self)) {
4965 /* No more messages to view, so close this window */
4966 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4968 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4969 gtk_tree_row_reference_valid (helper->reference)) {
4970 GtkWidget *header_view;
4972 GtkTreeSelection *sel;
4974 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4975 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4976 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4977 path = gtk_tree_row_reference_get_path (helper->reference);
4978 /* We need to unselect the previous one
4979 because we could be copying instead of
4981 gtk_tree_selection_unselect_all (sel);
4982 gtk_tree_selection_select_path (sel, path);
4983 gtk_tree_path_free (path);
4985 g_object_unref (object);
4987 /* Destroy the helper */
4988 move_to_helper_destroyer (helper);
4992 folder_move_to_cb (ModestMailOperation *mail_op,
4993 TnyFolder *new_folder,
4996 GtkWidget *folder_view;
4999 object = modest_mail_operation_get_source (mail_op);
5000 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5001 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5002 g_object_ref (folder_view);
5003 g_object_unref (object);
5004 move_to_cb (mail_op, user_data);
5005 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5006 g_object_unref (folder_view);
5010 msgs_move_to_cb (ModestMailOperation *mail_op,
5013 move_to_cb (mail_op, user_data);
5017 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5020 ModestWindow *main_window = NULL;
5022 /* Disable next automatic folder selection */
5023 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5024 FALSE); /* don't create */
5026 GObject *win = NULL;
5027 GtkWidget *folder_view = NULL;
5029 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5030 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5031 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5033 if (user_data && TNY_IS_FOLDER (user_data)) {
5034 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5035 TNY_FOLDER (user_data), FALSE);
5038 /* Show notification dialog only if the main window exists */
5039 win = modest_mail_operation_get_source (mail_op);
5040 modest_platform_run_information_dialog ((GtkWindow *) win,
5041 _("mail_in_ui_folder_move_target_error"),
5044 g_object_unref (win);
5049 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5058 gint pending_purges = 0;
5059 gboolean some_purged = FALSE;
5060 ModestWindow *win = MODEST_WINDOW (user_data);
5061 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5063 /* If there was any error */
5064 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5065 modest_window_mgr_unregister_header (mgr, header);
5069 /* Once the message has been retrieved for purging, we check if
5070 * it's all ok for purging */
5072 parts = tny_simple_list_new ();
5073 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5074 iter = tny_list_create_iterator (parts);
5076 while (!tny_iterator_is_done (iter)) {
5078 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5079 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5080 if (tny_mime_part_is_purged (part))
5087 g_object_unref (part);
5089 tny_iterator_next (iter);
5091 g_object_unref (iter);
5094 if (pending_purges>0) {
5096 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5098 if (response == GTK_RESPONSE_OK) {
5101 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5102 iter = tny_list_create_iterator (parts);
5103 while (!tny_iterator_is_done (iter)) {
5106 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5107 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5108 tny_mime_part_set_purged (part);
5111 g_object_unref (part);
5113 tny_iterator_next (iter);
5115 g_object_unref (iter);
5117 tny_msg_rewrite_cache (msg);
5119 gtk_widget_destroy (info);
5123 modest_window_mgr_unregister_header (mgr, header);
5125 g_object_unref (parts);
5129 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5130 ModestMainWindow *win)
5132 GtkWidget *header_view;
5133 TnyList *header_list;
5135 TnyHeaderFlags flags;
5136 ModestWindow *msg_view_window = NULL;
5139 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5141 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5142 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5144 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5146 g_warning ("%s: no header selected", __FUNCTION__);
5150 if (tny_list_get_length (header_list) == 1) {
5151 TnyIterator *iter = tny_list_create_iterator (header_list);
5152 header = TNY_HEADER (tny_iterator_get_current (iter));
5153 g_object_unref (iter);
5157 if (!header || !TNY_IS_HEADER(header)) {
5158 g_warning ("%s: header is not valid", __FUNCTION__);
5162 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5163 header, &msg_view_window);
5164 flags = tny_header_get_flags (header);
5165 if (!(flags & TNY_HEADER_FLAG_CACHED))
5168 if (msg_view_window != NULL)
5169 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5171 /* do nothing; uid was registered before, so window is probably on it's way */
5172 g_warning ("debug: header %p has already been registered", header);
5175 ModestMailOperation *mail_op = NULL;
5176 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5177 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5178 modest_ui_actions_disk_operations_error_handler,
5180 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5181 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5183 g_object_unref (mail_op);
5186 g_object_unref (header);
5188 g_object_unref (header_list);
5192 * Checks if we need a connection to do the transfer and if the user
5193 * wants to connect to complete it
5196 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5197 TnyFolderStore *src_folder,
5199 TnyFolder *dst_folder,
5200 gboolean delete_originals,
5201 gboolean *need_connection,
5204 TnyAccount *src_account;
5205 gint uncached_msgs = 0;
5207 uncached_msgs = header_list_count_uncached_msgs (headers);
5209 /* We don't need any further check if
5211 * 1- the source folder is local OR
5212 * 2- the device is already online
5214 if (!modest_tny_folder_store_is_remote (src_folder) ||
5215 tny_device_is_online (modest_runtime_get_device())) {
5216 *need_connection = FALSE;
5221 /* We must ask for a connection when
5223 * - the message(s) is not already cached OR
5224 * - the message(s) is cached but the leave_on_server setting
5225 * is FALSE (because we need to sync the source folder to
5226 * delete the message from the server (for IMAP we could do it
5227 * offline, it'll take place the next time we get a
5230 src_account = get_account_from_folder_store (src_folder);
5231 if (uncached_msgs > 0) {
5235 *need_connection = TRUE;
5236 num_headers = tny_list_get_length (headers);
5237 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5239 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5240 GTK_RESPONSE_CANCEL) {
5246 /* The transfer is possible and the user wants to */
5249 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5250 const gchar *account_name;
5251 gboolean leave_on_server;
5253 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5254 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5257 if (leave_on_server == TRUE) {
5258 *need_connection = FALSE;
5260 *need_connection = TRUE;
5263 *need_connection = FALSE;
5268 g_object_unref (src_account);
5272 xfer_messages_error_handler (ModestMailOperation *mail_op,
5275 ModestWindow *main_window = NULL;
5277 /* Disable next automatic folder selection */
5278 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5279 FALSE); /* don't create */
5281 GObject *win = modest_mail_operation_get_source (mail_op);
5282 modest_platform_run_information_dialog ((GtkWindow *) win,
5283 _("mail_in_ui_folder_move_target_error"),
5286 g_object_unref (win);
5288 move_to_helper_destroyer (user_data);
5292 TnyFolderStore *dst_folder;
5297 * Utility function that transfer messages from both the main window
5298 * and the msg view window when using the "Move to" dialog
5301 xfer_messages_performer (gboolean canceled,
5303 GtkWindow *parent_window,
5304 TnyAccount *account,
5307 ModestWindow *win = MODEST_WINDOW (parent_window);
5308 TnyAccount *dst_account = NULL;
5309 gboolean dst_forbids_message_add = FALSE;
5310 XferMsgsHelper *helper;
5311 MoveToHelper *movehelper;
5312 ModestMailOperation *mail_op;
5314 helper = (XferMsgsHelper *) user_data;
5316 if (canceled || err) {
5317 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5318 /* Show the proper error message */
5319 modest_ui_actions_on_account_connection_error (parent_window, account);
5324 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5326 /* tinymail will return NULL for local folders it seems */
5327 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5328 modest_tny_account_get_protocol_type (dst_account),
5329 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5330 g_object_unref (dst_account);
5332 if (dst_forbids_message_add) {
5333 modest_platform_information_banner (GTK_WIDGET (win),
5335 ngettext("mail_in_ui_folder_move_target_error",
5336 "mail_in_ui_folder_move_targets_error",
5337 tny_list_get_length (helper->headers)));
5341 movehelper = g_new0 (MoveToHelper, 1);
5342 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5343 _CS("ckct_nw_pasting"));
5344 if (movehelper->banner != NULL) {
5345 g_object_ref (movehelper->banner);
5346 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5349 if (MODEST_IS_MAIN_WINDOW (win)) {
5350 GtkWidget *header_view =
5351 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5352 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5353 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5356 /* Perform the mail operation */
5357 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5358 xfer_messages_error_handler,
5360 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5363 modest_mail_operation_xfer_msgs (mail_op,
5365 TNY_FOLDER (helper->dst_folder),
5370 g_object_unref (G_OBJECT (mail_op));
5372 g_object_unref (helper->dst_folder);
5373 g_object_unref (helper->headers);
5374 g_slice_free (XferMsgsHelper, helper);
5378 TnyFolder *src_folder;
5379 TnyFolderStore *dst_folder;
5380 gboolean delete_original;
5381 GtkWidget *folder_view;
5385 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5386 TnyAccount *account, gpointer user_data)
5388 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5389 GtkTreeSelection *sel;
5390 ModestMailOperation *mail_op = NULL;
5392 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5393 g_object_unref (G_OBJECT (info->src_folder));
5394 g_object_unref (G_OBJECT (info->dst_folder));
5399 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5400 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5401 _CS("ckct_nw_pasting"));
5402 if (helper->banner != NULL) {
5403 g_object_ref (helper->banner);
5404 gtk_widget_show (GTK_WIDGET(helper->banner));
5406 /* Clean folder on header view before moving it */
5407 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5408 gtk_tree_selection_unselect_all (sel);
5410 /* Let gtk events run. We need that the folder
5411 view frees its reference to the source
5412 folder *before* issuing the mail operation
5413 so we need the signal handler of selection
5414 changed to happen before the mail
5416 while (gtk_events_pending ())
5417 gtk_main_iteration (); */
5420 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5421 modest_ui_actions_move_folder_error_handler,
5422 info->src_folder, NULL);
5423 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5426 /* Select *after* the changes */
5427 /* TODO: this function hangs UI after transfer */
5428 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5429 /* TNY_FOLDER (src_folder), TRUE); */
5431 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5432 TNY_FOLDER (info->dst_folder), TRUE);
5433 modest_mail_operation_xfer_folder (mail_op,
5434 TNY_FOLDER (info->src_folder),
5436 info->delete_original,
5439 g_object_unref (G_OBJECT (info->src_folder));
5441 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5444 /* Unref mail operation */
5445 g_object_unref (G_OBJECT (mail_op));
5446 g_object_unref (G_OBJECT (info->dst_folder));
5451 get_account_from_folder_store (TnyFolderStore *folder_store)
5453 if (TNY_IS_ACCOUNT (folder_store))
5454 return g_object_ref (folder_store);
5456 return tny_folder_get_account (TNY_FOLDER (folder_store));
5460 * UI handler for the "Move to" action when invoked from the
5464 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5465 GtkWidget *folder_view,
5466 TnyFolderStore *dst_folder,
5467 ModestMainWindow *win)
5469 ModestHeaderView *header_view = NULL;
5470 TnyFolderStore *src_folder = NULL;
5472 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5474 /* Get the source folder */
5475 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5477 /* Get header view */
5478 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5480 /* Get folder or messages to transfer */
5481 if (gtk_widget_is_focus (folder_view)) {
5482 gboolean do_xfer = TRUE;
5484 /* Allow only to transfer folders to the local root folder */
5485 if (TNY_IS_ACCOUNT (dst_folder) &&
5486 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5487 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5489 } else if (!TNY_IS_FOLDER (src_folder)) {
5490 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5495 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5496 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5498 info->src_folder = g_object_ref (src_folder);
5499 info->dst_folder = g_object_ref (dst_folder);
5500 info->delete_original = TRUE;
5501 info->folder_view = folder_view;
5503 connect_info->callback = on_move_folder_cb;
5504 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5505 connect_info->data = info;
5507 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5508 TNY_FOLDER_STORE (src_folder),
5511 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5514 headers = modest_header_view_get_selected_headers(header_view);
5516 /* Transfer the messages */
5517 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5518 headers, TNY_FOLDER (dst_folder));
5520 g_object_unref (headers);
5524 g_object_unref (src_folder);
5529 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5530 TnyFolder *src_folder,
5532 TnyFolder *dst_folder)
5534 gboolean need_connection = TRUE;
5535 gboolean do_xfer = TRUE;
5536 XferMsgsHelper *helper;
5538 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5539 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5540 g_return_if_fail (TNY_IS_LIST (headers));
5542 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5543 headers, TNY_FOLDER (dst_folder),
5544 TRUE, &need_connection,
5547 /* If we don't want to transfer just return */
5551 /* Create the helper */
5552 helper = g_slice_new (XferMsgsHelper);
5553 helper->dst_folder = g_object_ref (dst_folder);
5554 helper->headers = g_object_ref (headers);
5556 if (need_connection) {
5557 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5558 connect_info->callback = xfer_messages_performer;
5559 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5560 connect_info->data = helper;
5562 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5563 TNY_FOLDER_STORE (src_folder),
5566 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5567 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5568 src_account, helper);
5569 g_object_unref (src_account);
5574 * UI handler for the "Move to" action when invoked from the
5575 * ModestMsgViewWindow
5578 modest_ui_actions_on_window_move_to (GtkAction *action,
5579 TnyFolderStore *dst_folder,
5582 TnyList *headers = NULL;
5583 TnyFolder *src_folder = NULL;
5585 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5587 /* Create header list */
5588 headers = get_selected_headers (MODEST_WINDOW (win));
5590 if (tny_list_get_length (headers) > 0) {
5591 TnyHeader *header = NULL;
5594 iter = tny_list_create_iterator (headers);
5595 header = (TnyHeader *) tny_iterator_get_current (iter);
5596 src_folder = tny_header_get_folder (header);
5598 g_object_unref (header);
5599 g_object_unref (iter);
5601 /* Transfer the messages */
5602 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5603 TNY_FOLDER (dst_folder));
5609 g_object_unref (src_folder);
5610 g_object_unref (headers);
5614 modest_ui_actions_on_move_to (GtkAction *action,
5617 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5619 TnyFolderStore *dst_folder = NULL;
5620 ModestMainWindow *main_window;
5622 g_return_if_fail (MODEST_IS_WINDOW (win));
5624 /* Get the main window if exists */
5625 if (MODEST_IS_MAIN_WINDOW (win))
5626 main_window = MODEST_MAIN_WINDOW (win);
5629 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5630 FALSE)); /* don't create */
5632 /* Get the folder view widget if exists */
5634 folder_view = modest_main_window_get_child_widget (main_window,
5635 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5639 /* Create and run the dialog */
5640 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5641 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5642 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5643 result = gtk_dialog_run (GTK_DIALOG(dialog));
5644 g_object_ref (tree_view);
5645 gtk_widget_destroy (dialog);
5647 if (result != GTK_RESPONSE_ACCEPT)
5650 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5651 /* Do window specific stuff */
5652 if (MODEST_IS_MAIN_WINDOW (win)) {
5653 modest_ui_actions_on_main_window_move_to (action,
5656 MODEST_MAIN_WINDOW (win));
5658 modest_ui_actions_on_window_move_to (action,
5660 MODEST_WINDOW (win));
5664 g_object_unref (dst_folder);
5668 * Calls #HeadersFunc for each header already selected in the main
5669 * window or the message currently being shown in the msg view window
5672 do_headers_action (ModestWindow *win,
5676 TnyList *headers_list = NULL;
5677 TnyIterator *iter = NULL;
5678 TnyHeader *header = NULL;
5679 TnyFolder *folder = NULL;
5682 headers_list = get_selected_headers (win);
5686 /* Get the folder */
5687 iter = tny_list_create_iterator (headers_list);
5688 header = TNY_HEADER (tny_iterator_get_current (iter));
5690 folder = tny_header_get_folder (header);
5691 g_object_unref (header);
5694 /* Call the function for each header */
5695 while (!tny_iterator_is_done (iter)) {
5696 header = TNY_HEADER (tny_iterator_get_current (iter));
5697 func (header, win, user_data);
5698 g_object_unref (header);
5699 tny_iterator_next (iter);
5702 /* Trick: do a poke status in order to speed up the signaling
5704 tny_folder_poke_status (folder);
5707 g_object_unref (folder);
5708 g_object_unref (iter);
5709 g_object_unref (headers_list);
5713 modest_ui_actions_view_attachment (GtkAction *action,
5714 ModestWindow *window)
5716 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5717 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5719 /* not supported window for this action */
5720 g_return_if_reached ();
5725 modest_ui_actions_save_attachments (GtkAction *action,
5726 ModestWindow *window)
5728 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5730 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5733 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5735 /* not supported window for this action */
5736 g_return_if_reached ();
5741 modest_ui_actions_remove_attachments (GtkAction *action,
5742 ModestWindow *window)
5744 if (MODEST_IS_MAIN_WINDOW (window)) {
5745 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5746 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5747 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5749 /* not supported window for this action */
5750 g_return_if_reached ();
5755 modest_ui_actions_on_settings (GtkAction *action,
5760 dialog = modest_platform_get_global_settings_dialog ();
5761 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5762 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5763 gtk_widget_show_all (dialog);
5765 gtk_dialog_run (GTK_DIALOG (dialog));
5767 gtk_widget_destroy (dialog);
5771 modest_ui_actions_on_help (GtkAction *action,
5774 /* Help app is not available at all in fremantle */
5775 #ifndef MODEST_TOOLKIT_HILDON2
5776 const gchar *help_id;
5778 g_return_if_fail (win && GTK_IS_WINDOW(win));
5780 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5783 modest_platform_show_help (GTK_WINDOW (win), help_id);
5788 modest_ui_actions_on_csm_help (GtkAction *action,
5791 /* Help app is not available at all in fremantle */
5792 #ifndef MODEST_TOOLKIT_HILDON2
5794 const gchar* help_id = NULL;
5795 GtkWidget *folder_view;
5796 TnyFolderStore *folder_store;
5798 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5800 /* Get selected folder */
5801 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5802 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5803 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5805 /* Switch help_id */
5806 if (folder_store && TNY_IS_FOLDER (folder_store))
5807 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5810 g_object_unref (folder_store);
5813 modest_platform_show_help (GTK_WINDOW (win), help_id);
5815 modest_ui_actions_on_help (action, win);
5820 retrieve_contents_cb (ModestMailOperation *mail_op,
5827 /* We only need this callback to show an error in case of
5828 memory low condition */
5829 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5833 retrieve_msg_contents_performer (gboolean canceled,
5835 GtkWindow *parent_window,
5836 TnyAccount *account,
5839 ModestMailOperation *mail_op;
5840 TnyList *headers = TNY_LIST (user_data);
5842 if (err || canceled) {
5843 check_memory_full_error ((GtkWidget *) parent_window, err);
5847 /* Create mail operation */
5848 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5849 modest_ui_actions_disk_operations_error_handler,
5851 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5852 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5855 g_object_unref (mail_op);
5857 g_object_unref (headers);
5858 g_object_unref (account);
5862 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5863 ModestWindow *window)
5865 TnyList *headers = NULL;
5866 TnyAccount *account = NULL;
5867 TnyIterator *iter = NULL;
5868 TnyHeader *header = NULL;
5869 TnyFolder *folder = NULL;
5872 headers = get_selected_headers (window);
5876 /* Pick the account */
5877 iter = tny_list_create_iterator (headers);
5878 header = TNY_HEADER (tny_iterator_get_current (iter));
5879 folder = tny_header_get_folder (header);
5880 account = tny_folder_get_account (folder);
5881 g_object_unref (folder);
5882 g_object_unref (header);
5883 g_object_unref (iter);
5885 /* Connect and perform the message retrieval */
5886 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5887 g_object_ref (account),
5888 retrieve_msg_contents_performer,
5889 g_object_ref (headers));
5892 g_object_unref (account);
5893 g_object_unref (headers);
5897 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5899 g_return_if_fail (MODEST_IS_WINDOW (window));
5902 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5906 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5908 g_return_if_fail (MODEST_IS_WINDOW (window));
5911 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5915 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5916 ModestWindow *window)
5918 g_return_if_fail (MODEST_IS_WINDOW (window));
5921 modest_ui_actions_check_menu_dimming_rules (window);
5925 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5926 ModestWindow *window)
5928 g_return_if_fail (MODEST_IS_WINDOW (window));
5931 modest_ui_actions_check_menu_dimming_rules (window);
5935 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5936 ModestWindow *window)
5938 g_return_if_fail (MODEST_IS_WINDOW (window));
5941 modest_ui_actions_check_menu_dimming_rules (window);
5945 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5946 ModestWindow *window)
5948 g_return_if_fail (MODEST_IS_WINDOW (window));
5951 modest_ui_actions_check_menu_dimming_rules (window);
5955 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5956 ModestWindow *window)
5958 g_return_if_fail (MODEST_IS_WINDOW (window));
5961 modest_ui_actions_check_menu_dimming_rules (window);
5965 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5966 ModestWindow *window)
5968 g_return_if_fail (MODEST_IS_WINDOW (window));
5971 modest_ui_actions_check_menu_dimming_rules (window);
5975 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5976 ModestWindow *window)
5978 g_return_if_fail (MODEST_IS_WINDOW (window));
5981 modest_ui_actions_check_menu_dimming_rules (window);
5985 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5986 ModestWindow *window)
5988 g_return_if_fail (MODEST_IS_WINDOW (window));
5991 modest_ui_actions_check_menu_dimming_rules (window);
5995 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5996 ModestWindow *window)
5998 g_return_if_fail (MODEST_IS_WINDOW (window));
6001 modest_ui_actions_check_menu_dimming_rules (window);
6005 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6007 g_return_if_fail (MODEST_IS_WINDOW (window));
6009 /* we check for low-mem; in that case, show a warning, and don't allow
6012 if (modest_platform_check_memory_low (window, TRUE))
6015 modest_platform_show_search_messages (GTK_WINDOW (window));
6019 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6021 g_return_if_fail (MODEST_IS_WINDOW (win));
6024 /* we check for low-mem; in that case, show a warning, and don't allow
6025 * for the addressbook
6027 if (modest_platform_check_memory_low (win, TRUE))
6031 modest_platform_show_addressbook (GTK_WINDOW (win));
6036 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
6037 ModestWindow *window)
6039 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6041 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
6045 on_send_receive_finished (ModestMailOperation *mail_op,
6048 GtkWidget *header_view, *folder_view;
6049 TnyFolderStore *folder_store;
6050 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6052 /* Set send/receive operation finished */
6053 modest_main_window_notify_send_receive_completed (main_win);
6055 /* Don't refresh the current folder if there were any errors */
6056 if (modest_mail_operation_get_status (mail_op) !=
6057 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6060 /* Refresh the current folder if we're viewing a window. We do
6061 this because the user won't be able to see the new mails in
6062 the selected folder after a Send&Receive because it only
6063 performs a poke_status, i.e, only the number of read/unread
6064 messages is updated, but the new headers are not
6066 folder_view = modest_main_window_get_child_widget (main_win,
6067 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6071 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6073 /* Do not need to refresh INBOX again because the
6074 update_account does it always automatically */
6075 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6076 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6077 ModestMailOperation *refresh_op;
6079 header_view = modest_main_window_get_child_widget (main_win,
6080 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6082 /* We do not need to set the contents style
6083 because it hasn't changed. We also do not
6084 need to save the widget status. Just force
6086 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6087 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6088 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6089 folder_refreshed_cb, main_win);
6090 g_object_unref (refresh_op);
6094 g_object_unref (folder_store);
6099 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6105 const gchar* server_name = NULL;
6106 TnyTransportAccount *server_account;
6107 gchar *message = NULL;
6109 /* Don't show anything if the user cancelled something or the
6110 * send receive request is not interactive. Authentication
6111 * errors are managed by the account store so no need to show
6112 * a dialog here again */
6113 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6114 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6115 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6119 /* Get the server name: */
6121 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6123 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6125 g_return_if_reached ();
6127 /* Show the appropriate message text for the GError: */
6128 switch (err->code) {
6129 case TNY_SERVICE_ERROR_CONNECT:
6130 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6132 case TNY_SERVICE_ERROR_SEND:
6133 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6135 case TNY_SERVICE_ERROR_UNAVAILABLE:
6136 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6139 g_warning ("%s: unexpected ERROR %d",
6140 __FUNCTION__, err->code);
6141 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6145 modest_platform_run_information_dialog (NULL, message, FALSE);
6147 g_object_unref (server_account);
6151 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6156 ModestMainWindow *main_window = NULL;
6157 ModestWindowMgr *mgr = NULL;
6158 GtkWidget *folder_view = NULL, *header_view = NULL;
6159 TnyFolderStore *selected_folder = NULL;
6160 TnyFolderType folder_type;
6162 mgr = modest_runtime_get_window_mgr ();
6163 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6164 FALSE));/* don't create */
6168 /* Check if selected folder is OUTBOX */
6169 folder_view = modest_main_window_get_child_widget (main_window,
6170 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6171 header_view = modest_main_window_get_child_widget (main_window,
6172 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6174 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6175 if (!TNY_IS_FOLDER (selected_folder))
6178 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6179 #if GTK_CHECK_VERSION(2, 8, 0)
6180 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6181 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6182 GtkTreeViewColumn *tree_column;
6184 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6185 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6187 gtk_tree_view_column_queue_resize (tree_column);
6190 gtk_widget_queue_draw (header_view);
6193 /* Rerun dimming rules, because the message could become deletable for example */
6194 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6195 MODEST_DIMMING_RULES_TOOLBAR);
6196 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6197 MODEST_DIMMING_RULES_MENU);
6201 if (selected_folder != NULL)
6202 g_object_unref (selected_folder);
6206 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6207 TnyAccount *account)
6209 ModestProtocolType protocol_type;
6210 ModestProtocol *protocol;
6211 gchar *error_note = NULL;
6213 protocol_type = modest_tny_account_get_protocol_type (account);
6214 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6217 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6218 if (error_note == NULL) {
6219 g_warning ("%s: This should not be reached", __FUNCTION__);
6221 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6222 g_free (error_note);
6227 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6231 TnyFolderStore *folder = NULL;
6232 TnyAccount *account = NULL;
6233 ModestProtocolType proto;
6234 ModestProtocol *protocol;
6235 TnyHeader *header = NULL;
6237 if (MODEST_IS_MAIN_WINDOW (win)) {
6238 GtkWidget *header_view;
6239 TnyList* headers = NULL;
6241 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6242 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6243 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6244 if (!headers || tny_list_get_length (headers) == 0) {
6246 g_object_unref (headers);
6249 iter = tny_list_create_iterator (headers);
6250 header = TNY_HEADER (tny_iterator_get_current (iter));
6251 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6252 g_object_unref (iter);
6253 g_object_unref (headers);
6254 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6255 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6256 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6259 /* Get the account type */
6260 account = tny_folder_get_account (TNY_FOLDER (folder));
6261 proto = modest_tny_account_get_protocol_type (account);
6262 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6265 subject = tny_header_dup_subject (header);
6266 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6270 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6274 g_object_unref (account);
6275 g_object_unref (folder);
6276 g_object_unref (header);
6282 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6283 const gchar *account_name,
6284 const gchar *account_title)
6286 ModestAccountMgr *account_mgr;
6289 ModestProtocol *protocol;
6290 gboolean removed = FALSE;
6292 g_return_val_if_fail (account_name, FALSE);
6293 g_return_val_if_fail (account_title, FALSE);
6295 account_mgr = modest_runtime_get_account_mgr();
6297 /* The warning text depends on the account type: */
6298 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6299 modest_account_mgr_get_store_protocol (account_mgr,
6301 txt = modest_protocol_get_translation (protocol,
6302 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6305 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6307 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6311 if (response == GTK_RESPONSE_OK) {
6312 /* Remove account. If it succeeds then it also removes
6313 the account from the ModestAccountView: */
6314 gboolean is_default = FALSE;
6315 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6316 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6318 g_free (default_account_name);
6320 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6322 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);