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 /* It could happen that we're trying to move a message from a
4787 window (msg window for example) after the main window was
4788 closed, so we can not just get the model of the folder
4790 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4791 const gchar *visible_id = NULL;
4793 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4794 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4795 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4796 MODEST_FOLDER_VIEW(*tree_view));
4799 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4801 /* Show the same account than the one that is shown in the main window */
4802 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4805 const gchar *active_account_name = NULL;
4806 ModestAccountMgr *mgr = NULL;
4807 ModestAccountSettings *settings = NULL;
4808 ModestServerAccountSettings *store_settings = NULL;
4810 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4811 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4812 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4813 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4815 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4816 mgr = modest_runtime_get_account_mgr ();
4817 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4820 const gchar *store_account_name;
4821 store_settings = modest_account_settings_get_store_settings (settings);
4822 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4824 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4825 store_account_name);
4826 g_object_unref (store_settings);
4827 g_object_unref (settings);
4831 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4832 * get_folder_view_from_move_to_dialog
4833 * (see above) later (needed for focus handling)
4835 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4838 /* Hide special folders */
4839 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4841 #ifdef MODEST_TOOLKIT_HILDON2
4842 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4843 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4844 pannable, TRUE, TRUE, 0);
4846 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4847 /* Add scroll to dialog */
4848 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4849 scroll, TRUE, TRUE, 0);
4853 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4854 #ifndef MODEST_TOOLKIT_GTK
4855 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4857 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4866 * Shows a confirmation dialog to the user when we're moving messages
4867 * from a remote server to the local storage. Returns the dialog
4868 * response. If it's other kind of movement then it always returns
4871 * This one is used by the next functions:
4872 * modest_ui_actions_on_paste - commented out
4873 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4876 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4877 TnyFolder *dest_folder,
4881 gint response = GTK_RESPONSE_OK;
4882 TnyAccount *account = NULL;
4883 TnyFolder *src_folder = NULL;
4884 TnyIterator *iter = NULL;
4885 TnyHeader *header = NULL;
4887 /* return with OK if the destination is a remote folder */
4888 if (modest_tny_folder_is_remote_folder (dest_folder))
4889 return GTK_RESPONSE_OK;
4891 /* Get source folder */
4892 iter = tny_list_create_iterator (headers);
4893 header = TNY_HEADER (tny_iterator_get_current (iter));
4895 src_folder = tny_header_get_folder (header);
4896 g_object_unref (header);
4898 g_object_unref (iter);
4900 /* if no src_folder, message may be an attahcment */
4901 if (src_folder == NULL)
4902 return GTK_RESPONSE_CANCEL;
4904 /* If the source is a local or MMC folder */
4905 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4906 g_object_unref (src_folder);
4907 return GTK_RESPONSE_OK;
4910 /* Get the account */
4911 account = tny_folder_get_account (src_folder);
4913 /* now if offline we ask the user */
4914 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4915 response = GTK_RESPONSE_OK;
4917 response = GTK_RESPONSE_CANCEL;
4920 g_object_unref (src_folder);
4921 g_object_unref (account);
4927 move_to_helper_destroyer (gpointer user_data)
4929 MoveToHelper *helper = (MoveToHelper *) user_data;
4931 /* Close the "Pasting" information banner */
4932 if (helper->banner) {
4933 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4934 g_object_unref (helper->banner);
4936 if (gtk_tree_row_reference_valid (helper->reference)) {
4937 gtk_tree_row_reference_free (helper->reference);
4938 helper->reference = NULL;
4944 move_to_cb (ModestMailOperation *mail_op,
4947 MoveToHelper *helper = (MoveToHelper *) user_data;
4949 /* Note that the operation could have failed, in that case do
4951 if (modest_mail_operation_get_status (mail_op) ==
4952 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4954 GObject *object = modest_mail_operation_get_source (mail_op);
4955 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4956 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4958 if (!modest_msg_view_window_select_next_message (self) &&
4959 !modest_msg_view_window_select_previous_message (self)) {
4960 /* No more messages to view, so close this window */
4961 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4963 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4964 gtk_tree_row_reference_valid (helper->reference)) {
4965 GtkWidget *header_view;
4967 GtkTreeSelection *sel;
4969 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4970 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4971 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4972 path = gtk_tree_row_reference_get_path (helper->reference);
4973 /* We need to unselect the previous one
4974 because we could be copying instead of
4976 gtk_tree_selection_unselect_all (sel);
4977 gtk_tree_selection_select_path (sel, path);
4978 gtk_tree_path_free (path);
4980 g_object_unref (object);
4982 /* Destroy the helper */
4983 move_to_helper_destroyer (helper);
4987 folder_move_to_cb (ModestMailOperation *mail_op,
4988 TnyFolder *new_folder,
4991 GtkWidget *folder_view;
4994 object = modest_mail_operation_get_source (mail_op);
4995 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4996 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4997 g_object_ref (folder_view);
4998 g_object_unref (object);
4999 move_to_cb (mail_op, user_data);
5000 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5001 g_object_unref (folder_view);
5005 msgs_move_to_cb (ModestMailOperation *mail_op,
5008 move_to_cb (mail_op, user_data);
5012 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5015 ModestWindow *main_window = NULL;
5017 /* Disable next automatic folder selection */
5018 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5019 FALSE); /* don't create */
5021 GObject *win = NULL;
5022 GtkWidget *folder_view = NULL;
5024 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5025 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5026 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5028 if (user_data && TNY_IS_FOLDER (user_data)) {
5029 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5030 TNY_FOLDER (user_data), FALSE);
5033 /* Show notification dialog only if the main window exists */
5034 win = modest_mail_operation_get_source (mail_op);
5035 modest_platform_run_information_dialog ((GtkWindow *) win,
5036 _("mail_in_ui_folder_move_target_error"),
5039 g_object_unref (win);
5044 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5053 gint pending_purges = 0;
5054 gboolean some_purged = FALSE;
5055 ModestWindow *win = MODEST_WINDOW (user_data);
5056 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5058 /* If there was any error */
5059 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5060 modest_window_mgr_unregister_header (mgr, header);
5064 /* Once the message has been retrieved for purging, we check if
5065 * it's all ok for purging */
5067 parts = tny_simple_list_new ();
5068 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5069 iter = tny_list_create_iterator (parts);
5071 while (!tny_iterator_is_done (iter)) {
5073 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5074 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5075 if (tny_mime_part_is_purged (part))
5082 g_object_unref (part);
5084 tny_iterator_next (iter);
5086 g_object_unref (iter);
5089 if (pending_purges>0) {
5091 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5093 if (response == GTK_RESPONSE_OK) {
5096 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5097 iter = tny_list_create_iterator (parts);
5098 while (!tny_iterator_is_done (iter)) {
5101 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5102 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5103 tny_mime_part_set_purged (part);
5106 g_object_unref (part);
5108 tny_iterator_next (iter);
5110 g_object_unref (iter);
5112 tny_msg_rewrite_cache (msg);
5114 gtk_widget_destroy (info);
5118 modest_window_mgr_unregister_header (mgr, header);
5120 g_object_unref (parts);
5124 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5125 ModestMainWindow *win)
5127 GtkWidget *header_view;
5128 TnyList *header_list;
5130 TnyHeaderFlags flags;
5131 ModestWindow *msg_view_window = NULL;
5134 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5136 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5137 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5139 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5141 g_warning ("%s: no header selected", __FUNCTION__);
5145 if (tny_list_get_length (header_list) == 1) {
5146 TnyIterator *iter = tny_list_create_iterator (header_list);
5147 header = TNY_HEADER (tny_iterator_get_current (iter));
5148 g_object_unref (iter);
5152 if (!header || !TNY_IS_HEADER(header)) {
5153 g_warning ("%s: header is not valid", __FUNCTION__);
5157 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5158 header, &msg_view_window);
5159 flags = tny_header_get_flags (header);
5160 if (!(flags & TNY_HEADER_FLAG_CACHED))
5163 if (msg_view_window != NULL)
5164 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5166 /* do nothing; uid was registered before, so window is probably on it's way */
5167 g_warning ("debug: header %p has already been registered", header);
5170 ModestMailOperation *mail_op = NULL;
5171 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5172 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5173 modest_ui_actions_disk_operations_error_handler,
5175 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5176 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5178 g_object_unref (mail_op);
5181 g_object_unref (header);
5183 g_object_unref (header_list);
5187 * Checks if we need a connection to do the transfer and if the user
5188 * wants to connect to complete it
5191 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5192 TnyFolderStore *src_folder,
5194 TnyFolder *dst_folder,
5195 gboolean delete_originals,
5196 gboolean *need_connection,
5199 TnyAccount *src_account;
5200 gint uncached_msgs = 0;
5202 uncached_msgs = header_list_count_uncached_msgs (headers);
5204 /* We don't need any further check if
5206 * 1- the source folder is local OR
5207 * 2- the device is already online
5209 if (!modest_tny_folder_store_is_remote (src_folder) ||
5210 tny_device_is_online (modest_runtime_get_device())) {
5211 *need_connection = FALSE;
5216 /* We must ask for a connection when
5218 * - the message(s) is not already cached OR
5219 * - the message(s) is cached but the leave_on_server setting
5220 * is FALSE (because we need to sync the source folder to
5221 * delete the message from the server (for IMAP we could do it
5222 * offline, it'll take place the next time we get a
5225 src_account = get_account_from_folder_store (src_folder);
5226 if (uncached_msgs > 0) {
5230 *need_connection = TRUE;
5231 num_headers = tny_list_get_length (headers);
5232 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5234 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5235 GTK_RESPONSE_CANCEL) {
5241 /* The transfer is possible and the user wants to */
5244 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5245 const gchar *account_name;
5246 gboolean leave_on_server;
5248 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5249 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5252 if (leave_on_server == TRUE) {
5253 *need_connection = FALSE;
5255 *need_connection = TRUE;
5258 *need_connection = FALSE;
5263 g_object_unref (src_account);
5267 xfer_messages_error_handler (ModestMailOperation *mail_op,
5270 ModestWindow *main_window = NULL;
5272 /* Disable next automatic folder selection */
5273 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5274 FALSE); /* don't create */
5276 GObject *win = modest_mail_operation_get_source (mail_op);
5277 modest_platform_run_information_dialog ((GtkWindow *) win,
5278 _("mail_in_ui_folder_move_target_error"),
5281 g_object_unref (win);
5283 move_to_helper_destroyer (user_data);
5287 TnyFolderStore *dst_folder;
5292 * Utility function that transfer messages from both the main window
5293 * and the msg view window when using the "Move to" dialog
5296 xfer_messages_performer (gboolean canceled,
5298 GtkWindow *parent_window,
5299 TnyAccount *account,
5302 ModestWindow *win = MODEST_WINDOW (parent_window);
5303 TnyAccount *dst_account = NULL;
5304 gboolean dst_forbids_message_add = FALSE;
5305 XferMsgsHelper *helper;
5306 MoveToHelper *movehelper;
5307 ModestMailOperation *mail_op;
5309 helper = (XferMsgsHelper *) user_data;
5311 if (canceled || err) {
5312 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5313 /* Show the proper error message */
5314 modest_ui_actions_on_account_connection_error (parent_window, account);
5319 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5321 /* tinymail will return NULL for local folders it seems */
5322 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5323 modest_tny_account_get_protocol_type (dst_account),
5324 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5325 g_object_unref (dst_account);
5327 if (dst_forbids_message_add) {
5328 modest_platform_information_banner (GTK_WIDGET (win),
5330 ngettext("mail_in_ui_folder_move_target_error",
5331 "mail_in_ui_folder_move_targets_error",
5332 tny_list_get_length (helper->headers)));
5336 movehelper = g_new0 (MoveToHelper, 1);
5337 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5338 _CS("ckct_nw_pasting"));
5339 if (movehelper->banner != NULL) {
5340 g_object_ref (movehelper->banner);
5341 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5344 if (MODEST_IS_MAIN_WINDOW (win)) {
5345 GtkWidget *header_view =
5346 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5347 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5348 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5351 /* Perform the mail operation */
5352 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5353 xfer_messages_error_handler,
5355 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5358 modest_mail_operation_xfer_msgs (mail_op,
5360 TNY_FOLDER (helper->dst_folder),
5365 g_object_unref (G_OBJECT (mail_op));
5367 g_object_unref (helper->dst_folder);
5368 g_object_unref (helper->headers);
5369 g_slice_free (XferMsgsHelper, helper);
5373 TnyFolder *src_folder;
5374 TnyFolderStore *dst_folder;
5375 gboolean delete_original;
5376 GtkWidget *folder_view;
5380 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5381 TnyAccount *account, gpointer user_data)
5383 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5384 GtkTreeSelection *sel;
5385 ModestMailOperation *mail_op = NULL;
5387 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5388 g_object_unref (G_OBJECT (info->src_folder));
5389 g_object_unref (G_OBJECT (info->dst_folder));
5394 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5395 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5396 _CS("ckct_nw_pasting"));
5397 if (helper->banner != NULL) {
5398 g_object_ref (helper->banner);
5399 gtk_widget_show (GTK_WIDGET(helper->banner));
5401 /* Clean folder on header view before moving it */
5402 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5403 gtk_tree_selection_unselect_all (sel);
5405 /* Let gtk events run. We need that the folder
5406 view frees its reference to the source
5407 folder *before* issuing the mail operation
5408 so we need the signal handler of selection
5409 changed to happen before the mail
5411 while (gtk_events_pending ())
5412 gtk_main_iteration (); */
5415 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5416 modest_ui_actions_move_folder_error_handler,
5417 info->src_folder, NULL);
5418 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5421 /* Select *after* the changes */
5422 /* TODO: this function hangs UI after transfer */
5423 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5424 /* TNY_FOLDER (src_folder), TRUE); */
5426 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5427 TNY_FOLDER (info->dst_folder), TRUE);
5428 modest_mail_operation_xfer_folder (mail_op,
5429 TNY_FOLDER (info->src_folder),
5431 info->delete_original,
5434 g_object_unref (G_OBJECT (info->src_folder));
5436 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5439 /* Unref mail operation */
5440 g_object_unref (G_OBJECT (mail_op));
5441 g_object_unref (G_OBJECT (info->dst_folder));
5446 get_account_from_folder_store (TnyFolderStore *folder_store)
5448 if (TNY_IS_ACCOUNT (folder_store))
5449 return g_object_ref (folder_store);
5451 return tny_folder_get_account (TNY_FOLDER (folder_store));
5455 * UI handler for the "Move to" action when invoked from the
5459 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5460 GtkWidget *folder_view,
5461 TnyFolderStore *dst_folder,
5462 ModestMainWindow *win)
5464 ModestHeaderView *header_view = NULL;
5465 TnyFolderStore *src_folder = NULL;
5467 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5469 /* Get the source folder */
5470 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5472 /* Get header view */
5473 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5475 /* Get folder or messages to transfer */
5476 if (gtk_widget_is_focus (folder_view)) {
5477 gboolean do_xfer = TRUE;
5479 /* Allow only to transfer folders to the local root folder */
5480 if (TNY_IS_ACCOUNT (dst_folder) &&
5481 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5482 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5484 } else if (!TNY_IS_FOLDER (src_folder)) {
5485 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5490 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5491 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5493 info->src_folder = g_object_ref (src_folder);
5494 info->dst_folder = g_object_ref (dst_folder);
5495 info->delete_original = TRUE;
5496 info->folder_view = folder_view;
5498 connect_info->callback = on_move_folder_cb;
5499 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5500 connect_info->data = info;
5502 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5503 TNY_FOLDER_STORE (src_folder),
5506 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5509 headers = modest_header_view_get_selected_headers(header_view);
5511 /* Transfer the messages */
5512 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5513 headers, TNY_FOLDER (dst_folder));
5515 g_object_unref (headers);
5519 g_object_unref (src_folder);
5524 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5525 TnyFolder *src_folder,
5527 TnyFolder *dst_folder)
5529 gboolean need_connection = TRUE;
5530 gboolean do_xfer = TRUE;
5531 XferMsgsHelper *helper;
5533 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5534 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5535 g_return_if_fail (TNY_IS_LIST (headers));
5537 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5538 headers, TNY_FOLDER (dst_folder),
5539 TRUE, &need_connection,
5542 /* If we don't want to transfer just return */
5546 /* Create the helper */
5547 helper = g_slice_new (XferMsgsHelper);
5548 helper->dst_folder = g_object_ref (dst_folder);
5549 helper->headers = g_object_ref (headers);
5551 if (need_connection) {
5552 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5553 connect_info->callback = xfer_messages_performer;
5554 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5555 connect_info->data = helper;
5557 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5558 TNY_FOLDER_STORE (src_folder),
5561 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5562 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5563 src_account, helper);
5564 g_object_unref (src_account);
5569 * UI handler for the "Move to" action when invoked from the
5570 * ModestMsgViewWindow
5573 modest_ui_actions_on_window_move_to (GtkAction *action,
5574 TnyFolderStore *dst_folder,
5577 TnyList *headers = NULL;
5578 TnyFolder *src_folder = NULL;
5580 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5582 /* Create header list */
5583 headers = get_selected_headers (MODEST_WINDOW (win));
5585 if (tny_list_get_length (headers) > 0) {
5586 TnyHeader *header = NULL;
5589 iter = tny_list_create_iterator (headers);
5590 header = (TnyHeader *) tny_iterator_get_current (iter);
5591 src_folder = tny_header_get_folder (header);
5593 g_object_unref (header);
5594 g_object_unref (iter);
5596 /* Transfer the messages */
5597 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5598 TNY_FOLDER (dst_folder));
5604 g_object_unref (src_folder);
5605 g_object_unref (headers);
5609 modest_ui_actions_on_move_to (GtkAction *action,
5612 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5614 TnyFolderStore *dst_folder = NULL;
5615 ModestMainWindow *main_window;
5617 g_return_if_fail (MODEST_IS_WINDOW (win));
5619 /* Get the main window if exists */
5620 if (MODEST_IS_MAIN_WINDOW (win))
5621 main_window = MODEST_MAIN_WINDOW (win);
5624 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5625 FALSE)); /* don't create */
5627 /* Get the folder view widget if exists */
5629 folder_view = modest_main_window_get_child_widget (main_window,
5630 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5634 /* Create and run the dialog */
5635 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5636 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5637 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5638 result = gtk_dialog_run (GTK_DIALOG(dialog));
5639 g_object_ref (tree_view);
5640 gtk_widget_destroy (dialog);
5642 if (result != GTK_RESPONSE_ACCEPT)
5645 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5646 /* Do window specific stuff */
5647 if (MODEST_IS_MAIN_WINDOW (win)) {
5648 modest_ui_actions_on_main_window_move_to (action,
5651 MODEST_MAIN_WINDOW (win));
5653 modest_ui_actions_on_window_move_to (action,
5655 MODEST_WINDOW (win));
5659 g_object_unref (dst_folder);
5663 * Calls #HeadersFunc for each header already selected in the main
5664 * window or the message currently being shown in the msg view window
5667 do_headers_action (ModestWindow *win,
5671 TnyList *headers_list = NULL;
5672 TnyIterator *iter = NULL;
5673 TnyHeader *header = NULL;
5674 TnyFolder *folder = NULL;
5677 headers_list = get_selected_headers (win);
5681 /* Get the folder */
5682 iter = tny_list_create_iterator (headers_list);
5683 header = TNY_HEADER (tny_iterator_get_current (iter));
5685 folder = tny_header_get_folder (header);
5686 g_object_unref (header);
5689 /* Call the function for each header */
5690 while (!tny_iterator_is_done (iter)) {
5691 header = TNY_HEADER (tny_iterator_get_current (iter));
5692 func (header, win, user_data);
5693 g_object_unref (header);
5694 tny_iterator_next (iter);
5697 /* Trick: do a poke status in order to speed up the signaling
5699 tny_folder_poke_status (folder);
5702 g_object_unref (folder);
5703 g_object_unref (iter);
5704 g_object_unref (headers_list);
5708 modest_ui_actions_view_attachment (GtkAction *action,
5709 ModestWindow *window)
5711 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5712 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5714 /* not supported window for this action */
5715 g_return_if_reached ();
5720 modest_ui_actions_save_attachments (GtkAction *action,
5721 ModestWindow *window)
5723 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5725 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5728 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5730 /* not supported window for this action */
5731 g_return_if_reached ();
5736 modest_ui_actions_remove_attachments (GtkAction *action,
5737 ModestWindow *window)
5739 if (MODEST_IS_MAIN_WINDOW (window)) {
5740 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5741 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5742 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5744 /* not supported window for this action */
5745 g_return_if_reached ();
5750 modest_ui_actions_on_settings (GtkAction *action,
5755 dialog = modest_platform_get_global_settings_dialog ();
5756 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5757 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5758 gtk_widget_show_all (dialog);
5760 gtk_dialog_run (GTK_DIALOG (dialog));
5762 gtk_widget_destroy (dialog);
5766 modest_ui_actions_on_help (GtkAction *action,
5769 /* Help app is not available at all in fremantle */
5770 #ifndef MODEST_TOOLKIT_HILDON2
5771 const gchar *help_id;
5773 g_return_if_fail (win && GTK_IS_WINDOW(win));
5775 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5778 modest_platform_show_help (GTK_WINDOW (win), help_id);
5783 modest_ui_actions_on_csm_help (GtkAction *action,
5786 /* Help app is not available at all in fremantle */
5787 #ifndef MODEST_TOOLKIT_HILDON2
5789 const gchar* help_id = NULL;
5790 GtkWidget *folder_view;
5791 TnyFolderStore *folder_store;
5793 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5795 /* Get selected folder */
5796 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5797 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5798 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5800 /* Switch help_id */
5801 if (folder_store && TNY_IS_FOLDER (folder_store))
5802 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5805 g_object_unref (folder_store);
5808 modest_platform_show_help (GTK_WINDOW (win), help_id);
5810 modest_ui_actions_on_help (action, win);
5815 retrieve_contents_cb (ModestMailOperation *mail_op,
5822 /* We only need this callback to show an error in case of
5823 memory low condition */
5824 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5828 retrieve_msg_contents_performer (gboolean canceled,
5830 GtkWindow *parent_window,
5831 TnyAccount *account,
5834 ModestMailOperation *mail_op;
5835 TnyList *headers = TNY_LIST (user_data);
5837 if (err || canceled) {
5838 check_memory_full_error ((GtkWidget *) parent_window, err);
5842 /* Create mail operation */
5843 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5844 modest_ui_actions_disk_operations_error_handler,
5846 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5847 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5850 g_object_unref (mail_op);
5852 g_object_unref (headers);
5853 g_object_unref (account);
5857 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5858 ModestWindow *window)
5860 TnyList *headers = NULL;
5861 TnyAccount *account = NULL;
5862 TnyIterator *iter = NULL;
5863 TnyHeader *header = NULL;
5864 TnyFolder *folder = NULL;
5867 headers = get_selected_headers (window);
5871 /* Pick the account */
5872 iter = tny_list_create_iterator (headers);
5873 header = TNY_HEADER (tny_iterator_get_current (iter));
5874 folder = tny_header_get_folder (header);
5875 account = tny_folder_get_account (folder);
5876 g_object_unref (folder);
5877 g_object_unref (header);
5878 g_object_unref (iter);
5880 /* Connect and perform the message retrieval */
5881 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5882 g_object_ref (account),
5883 retrieve_msg_contents_performer,
5884 g_object_ref (headers));
5887 g_object_unref (account);
5888 g_object_unref (headers);
5892 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5894 g_return_if_fail (MODEST_IS_WINDOW (window));
5897 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5901 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5903 g_return_if_fail (MODEST_IS_WINDOW (window));
5906 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5910 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5911 ModestWindow *window)
5913 g_return_if_fail (MODEST_IS_WINDOW (window));
5916 modest_ui_actions_check_menu_dimming_rules (window);
5920 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5921 ModestWindow *window)
5923 g_return_if_fail (MODEST_IS_WINDOW (window));
5926 modest_ui_actions_check_menu_dimming_rules (window);
5930 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5931 ModestWindow *window)
5933 g_return_if_fail (MODEST_IS_WINDOW (window));
5936 modest_ui_actions_check_menu_dimming_rules (window);
5940 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5941 ModestWindow *window)
5943 g_return_if_fail (MODEST_IS_WINDOW (window));
5946 modest_ui_actions_check_menu_dimming_rules (window);
5950 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5951 ModestWindow *window)
5953 g_return_if_fail (MODEST_IS_WINDOW (window));
5956 modest_ui_actions_check_menu_dimming_rules (window);
5960 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5961 ModestWindow *window)
5963 g_return_if_fail (MODEST_IS_WINDOW (window));
5966 modest_ui_actions_check_menu_dimming_rules (window);
5970 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5971 ModestWindow *window)
5973 g_return_if_fail (MODEST_IS_WINDOW (window));
5976 modest_ui_actions_check_menu_dimming_rules (window);
5980 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5981 ModestWindow *window)
5983 g_return_if_fail (MODEST_IS_WINDOW (window));
5986 modest_ui_actions_check_menu_dimming_rules (window);
5990 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5991 ModestWindow *window)
5993 g_return_if_fail (MODEST_IS_WINDOW (window));
5996 modest_ui_actions_check_menu_dimming_rules (window);
6000 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6002 g_return_if_fail (MODEST_IS_WINDOW (window));
6004 /* we check for low-mem; in that case, show a warning, and don't allow
6007 if (modest_platform_check_memory_low (window, TRUE))
6010 modest_platform_show_search_messages (GTK_WINDOW (window));
6014 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6016 g_return_if_fail (MODEST_IS_WINDOW (win));
6019 /* we check for low-mem; in that case, show a warning, and don't allow
6020 * for the addressbook
6022 if (modest_platform_check_memory_low (win, TRUE))
6026 modest_platform_show_addressbook (GTK_WINDOW (win));
6031 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
6032 ModestWindow *window)
6034 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6036 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
6040 on_send_receive_finished (ModestMailOperation *mail_op,
6043 GtkWidget *header_view, *folder_view;
6044 TnyFolderStore *folder_store;
6045 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6047 /* Set send/receive operation finished */
6048 modest_main_window_notify_send_receive_completed (main_win);
6050 /* Don't refresh the current folder if there were any errors */
6051 if (modest_mail_operation_get_status (mail_op) !=
6052 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6055 /* Refresh the current folder if we're viewing a window. We do
6056 this because the user won't be able to see the new mails in
6057 the selected folder after a Send&Receive because it only
6058 performs a poke_status, i.e, only the number of read/unread
6059 messages is updated, but the new headers are not
6061 folder_view = modest_main_window_get_child_widget (main_win,
6062 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6066 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6068 /* Do not need to refresh INBOX again because the
6069 update_account does it always automatically */
6070 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6071 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6072 ModestMailOperation *refresh_op;
6074 header_view = modest_main_window_get_child_widget (main_win,
6075 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6077 /* We do not need to set the contents style
6078 because it hasn't changed. We also do not
6079 need to save the widget status. Just force
6081 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6082 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6083 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6084 folder_refreshed_cb, main_win);
6085 g_object_unref (refresh_op);
6089 g_object_unref (folder_store);
6094 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6100 const gchar* server_name = NULL;
6101 TnyTransportAccount *server_account;
6102 gchar *message = NULL;
6104 /* Don't show anything if the user cancelled something or the
6105 * send receive request is not interactive. Authentication
6106 * errors are managed by the account store so no need to show
6107 * a dialog here again */
6108 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6109 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6110 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6114 /* Get the server name: */
6116 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6118 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6120 g_return_if_reached ();
6122 /* Show the appropriate message text for the GError: */
6123 switch (err->code) {
6124 case TNY_SERVICE_ERROR_CONNECT:
6125 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6127 case TNY_SERVICE_ERROR_SEND:
6128 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6130 case TNY_SERVICE_ERROR_UNAVAILABLE:
6131 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6134 g_warning ("%s: unexpected ERROR %d",
6135 __FUNCTION__, err->code);
6136 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6140 modest_platform_run_information_dialog (NULL, message, FALSE);
6142 g_object_unref (server_account);
6146 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6151 ModestMainWindow *main_window = NULL;
6152 ModestWindowMgr *mgr = NULL;
6153 GtkWidget *folder_view = NULL, *header_view = NULL;
6154 TnyFolderStore *selected_folder = NULL;
6155 TnyFolderType folder_type;
6157 mgr = modest_runtime_get_window_mgr ();
6158 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6159 FALSE));/* don't create */
6163 /* Check if selected folder is OUTBOX */
6164 folder_view = modest_main_window_get_child_widget (main_window,
6165 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6166 header_view = modest_main_window_get_child_widget (main_window,
6167 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6169 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6170 if (!TNY_IS_FOLDER (selected_folder))
6173 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6174 #if GTK_CHECK_VERSION(2, 8, 0)
6175 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6176 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6177 GtkTreeViewColumn *tree_column;
6179 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6180 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6182 gtk_tree_view_column_queue_resize (tree_column);
6185 gtk_widget_queue_draw (header_view);
6188 /* Rerun dimming rules, because the message could become deletable for example */
6189 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6190 MODEST_DIMMING_RULES_TOOLBAR);
6191 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6192 MODEST_DIMMING_RULES_MENU);
6196 if (selected_folder != NULL)
6197 g_object_unref (selected_folder);
6201 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6202 TnyAccount *account)
6204 ModestProtocolType protocol_type;
6205 ModestProtocol *protocol;
6206 gchar *error_note = NULL;
6208 protocol_type = modest_tny_account_get_protocol_type (account);
6209 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6212 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6213 if (error_note == NULL) {
6214 g_warning ("%s: This should not be reached", __FUNCTION__);
6216 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6217 g_free (error_note);
6222 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6226 TnyFolderStore *folder = NULL;
6227 TnyAccount *account = NULL;
6228 ModestProtocolType proto;
6229 ModestProtocol *protocol;
6230 TnyHeader *header = NULL;
6232 if (MODEST_IS_MAIN_WINDOW (win)) {
6233 GtkWidget *header_view;
6234 TnyList* headers = NULL;
6236 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6237 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6238 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6239 if (!headers || tny_list_get_length (headers) == 0) {
6241 g_object_unref (headers);
6244 iter = tny_list_create_iterator (headers);
6245 header = TNY_HEADER (tny_iterator_get_current (iter));
6246 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6247 g_object_unref (iter);
6248 g_object_unref (headers);
6249 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6250 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6251 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6254 /* Get the account type */
6255 account = tny_folder_get_account (TNY_FOLDER (folder));
6256 proto = modest_tny_account_get_protocol_type (account);
6257 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6260 subject = tny_header_dup_subject (header);
6261 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6265 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6269 g_object_unref (account);
6270 g_object_unref (folder);
6271 g_object_unref (header);
6277 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6278 const gchar *account_name,
6279 const gchar *account_title)
6281 ModestAccountMgr *account_mgr;
6284 ModestProtocol *protocol;
6285 gboolean removed = FALSE;
6287 g_return_val_if_fail (account_name, FALSE);
6288 g_return_val_if_fail (account_title, FALSE);
6290 account_mgr = modest_runtime_get_account_mgr();
6292 /* The warning text depends on the account type: */
6293 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6294 modest_account_mgr_get_store_protocol (account_mgr,
6296 txt = modest_protocol_get_translation (protocol,
6297 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6300 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6302 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6306 if (response == GTK_RESPONSE_OK) {
6307 /* Remove account. If it succeeds then it also removes
6308 the account from the ModestAccountView: */
6309 gboolean is_default = FALSE;
6310 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6311 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6313 g_free (default_account_name);
6315 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6317 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);