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>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #endif /* MODEST_PLATFORM_MAEMO */
55 #ifndef MODEST_TOOLKIT_GTK
56 #include "maemo/modest-hildon-includes.h"
57 #include "maemo/modest-connection-specific-smtp-window.h"
58 #endif /* !MODEST_TOOLKIT_GTK */
59 #include <modest-utils.h>
61 #include "widgets/modest-ui-constants.h"
62 #include <widgets/modest-main-window.h>
63 #include <widgets/modest-msg-view-window.h>
64 #include <widgets/modest-account-view-window.h>
65 #include <widgets/modest-details-dialog.h>
66 #include <widgets/modest-attachments-view.h>
67 #include "widgets/modest-folder-view.h"
68 #include "widgets/modest-global-settings-dialog.h"
69 #include "modest-account-mgr-helpers.h"
70 #include "modest-mail-operation.h"
71 #include "modest-text-utils.h"
73 #ifdef MODEST_HAVE_EASYSETUP
74 #ifdef MODEST_TOOLKIT_HILDON2
75 #include "modest-easysetup-wizard-dialog.h"
77 #include "easysetup/modest-easysetup-wizard-dialog.h"
79 #endif /* MODEST_HAVE_EASYSETUP */
81 #include <modest-widget-memory.h>
82 #include <tny-error.h>
83 #include <tny-simple-list.h>
84 #include <tny-msg-view.h>
85 #include <tny-device.h>
86 #include <tny-merge-folder.h>
88 #include <gtkhtml/gtkhtml.h>
90 #define MIN_FREE_SPACE 5 * 1024 * 1024
91 #define MOVE_FOLDER_OK_BUTTON "ok-button"
92 #define MOVE_FOLDER_NEW_BUTTON "new-button"
94 typedef struct _GetMsgAsyncHelper {
96 ModestMailOperation *mail_op;
103 typedef enum _ReplyForwardAction {
107 } ReplyForwardAction;
109 typedef struct _ReplyForwardHelper {
110 guint reply_forward_type;
111 ReplyForwardAction action;
113 GtkWidget *parent_window;
115 } ReplyForwardHelper;
117 typedef struct _MoveToHelper {
118 GtkTreeRowReference *reference;
122 typedef struct _PasteAsAttachmentHelper {
123 ModestMsgEditWindow *window;
125 } PasteAsAttachmentHelper;
129 * The do_headers_action uses this kind of functions to perform some
130 * action to each member of a list of headers
132 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
134 static void do_headers_action (ModestWindow *win,
138 static void open_msg_cb (ModestMailOperation *mail_op,
145 static void reply_forward_cb (ModestMailOperation *mail_op,
152 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
154 static void folder_refreshed_cb (ModestMailOperation *mail_op,
158 static void on_send_receive_finished (ModestMailOperation *mail_op,
161 static gint header_list_count_uncached_msgs (TnyList *header_list);
163 static gboolean connect_to_get_msg (ModestWindow *win,
164 gint num_of_uncached_msgs,
165 TnyAccount *account);
167 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
169 static void do_create_folder (GtkWindow *window,
170 TnyFolderStore *parent_folder,
171 const gchar *suggested_name);
173 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
175 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
178 * This function checks whether a TnyFolderStore is a pop account
181 remote_folder_has_leave_on_server (TnyFolderStore *folder)
186 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
188 account = get_account_from_folder_store (folder);
189 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
190 modest_tny_account_get_protocol_type (account)));
191 g_object_unref (account);
196 /* FIXME: this should be merged with the similar code in modest-account-view-window */
197 /* Show the account creation wizard dialog.
198 * returns: TRUE if an account was created. FALSE if the user cancelled.
201 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
203 gboolean result = FALSE;
205 gint dialog_response;
207 /* there is no such wizard yet */
208 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
209 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
211 /* always present a main window in the background
212 * we do it here, so we cannot end up with two wizards (as this
213 * function might be called in modest_window_mgr_get_main_window as well */
215 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
216 TRUE); /* create if not existent */
218 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
220 /* make sure the mainwindow is visible. We need to present the
221 wizard again to give it the focus back. show_all are needed
222 in order to get the widgets properly drawn (MainWindow main
223 paned won't be in its right position and the dialog will be
225 #ifndef MODEST_TOOLKIT_HILDON2
226 gtk_widget_show_all (GTK_WIDGET (win));
227 gtk_widget_show_all (GTK_WIDGET (wizard));
228 gtk_window_present (GTK_WINDOW (win));
229 gtk_window_present (GTK_WINDOW (wizard));
232 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
233 gtk_widget_destroy (GTK_WIDGET (wizard));
234 if (gtk_events_pending ())
235 gtk_main_iteration ();
237 if (dialog_response == GTK_RESPONSE_CANCEL) {
240 /* Check whether an account was created: */
241 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
248 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
251 const gchar *authors[] = {
252 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
255 about = gtk_about_dialog_new ();
256 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
257 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
258 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
259 _("Copyright (c) 2006, Nokia Corporation\n"
260 "All rights reserved."));
261 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
262 _("a modest e-mail client\n\n"
263 "design and implementation: Dirk-Jan C. Binnema\n"
264 "contributions from the fine people at KC and Ig\n"
265 "uses the tinymail email framework written by Philip van Hoof"));
266 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
267 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
268 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
269 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
271 gtk_dialog_run (GTK_DIALOG (about));
272 gtk_widget_destroy(about);
276 * Gets the list of currently selected messages. If the win is the
277 * main window, then it returns a newly allocated list of the headers
278 * selected in the header view. If win is the msg view window, then
279 * the value returned is a list with just a single header.
281 * The caller of this funcion must free the list.
284 get_selected_headers (ModestWindow *win)
286 if (MODEST_IS_MAIN_WINDOW(win)) {
287 GtkWidget *header_view;
289 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
290 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
291 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
293 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
294 /* for MsgViewWindows, we simply return a list with one element */
296 TnyList *list = NULL;
298 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
299 if (header != NULL) {
300 list = tny_simple_list_new ();
301 tny_list_prepend (list, G_OBJECT(header));
302 g_object_unref (G_OBJECT(header));
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 TnyList *header_list = NULL;
388 TnyIterator *iter = NULL;
389 TnyHeader *header = NULL;
390 gchar *message = NULL;
393 ModestWindowMgr *mgr;
394 GtkWidget *header_view = NULL;
396 g_return_if_fail (MODEST_IS_WINDOW(win));
398 /* Check first if the header view has the focus */
399 if (MODEST_IS_MAIN_WINDOW (win)) {
401 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
402 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
403 if (!gtk_widget_is_focus (header_view))
407 /* Get the headers, either from the header view (if win is the main window),
408 * or from the message view window: */
409 header_list = get_selected_headers (win);
410 if (!header_list) return;
412 /* Check if any of the headers are already opened, or in the process of being opened */
413 if (MODEST_IS_MAIN_WINDOW (win)) {
414 gint opened_headers = 0;
416 iter = tny_list_create_iterator (header_list);
417 mgr = modest_runtime_get_window_mgr ();
418 while (!tny_iterator_is_done (iter)) {
419 header = TNY_HEADER (tny_iterator_get_current (iter));
421 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
423 g_object_unref (header);
425 tny_iterator_next (iter);
427 g_object_unref (iter);
429 if (opened_headers > 0) {
432 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
435 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
438 g_object_unref (header_list);
444 if (tny_list_get_length(header_list) == 1) {
445 iter = tny_list_create_iterator (header_list);
446 header = TNY_HEADER (tny_iterator_get_current (iter));
449 subject = tny_header_dup_subject (header);
450 desc = g_strdup_printf ("%s", subject);
452 g_object_unref (header);
455 g_object_unref (iter);
457 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
458 tny_list_get_length(header_list)), desc);
460 /* Confirmation dialog */
461 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
465 if (response == GTK_RESPONSE_OK) {
466 ModestWindow *main_window = NULL;
467 ModestWindowMgr *mgr = NULL;
468 GtkTreeModel *model = NULL;
469 GtkTreeSelection *sel = NULL;
470 GList *sel_list = NULL, *tmp = NULL;
471 GtkTreeRowReference *next_row_reference = NULL;
472 GtkTreeRowReference *prev_row_reference = NULL;
473 GtkTreePath *next_path = NULL;
474 GtkTreePath *prev_path = NULL;
475 ModestMailOperation *mail_op = NULL;
477 /* Find last selected row */
478 if (MODEST_IS_MAIN_WINDOW (win)) {
479 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
480 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
481 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
482 for (tmp=sel_list; tmp; tmp=tmp->next) {
483 if (tmp->next == NULL) {
484 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
485 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
487 gtk_tree_path_prev (prev_path);
488 gtk_tree_path_next (next_path);
490 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
491 next_row_reference = gtk_tree_row_reference_new (model, next_path);
496 /* Disable window dimming management */
497 modest_window_disable_dimming (MODEST_WINDOW(win));
499 /* Remove each header. If it's a view window header_view == NULL */
500 mail_op = modest_mail_operation_new ((GObject *) win);
501 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
503 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
504 g_object_unref (mail_op);
506 /* Enable window dimming management */
508 gtk_tree_selection_unselect_all (sel);
510 modest_window_enable_dimming (MODEST_WINDOW(win));
512 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
513 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
515 /* Get main window */
516 mgr = modest_runtime_get_window_mgr ();
517 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
519 /* Move cursor to next row */
522 /* Select next or previous row */
523 if (gtk_tree_row_reference_valid (next_row_reference)) {
524 gtk_tree_selection_select_path (sel, next_path);
526 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
527 gtk_tree_selection_select_path (sel, prev_path);
531 if (next_row_reference != NULL)
532 gtk_tree_row_reference_free (next_row_reference);
533 if (next_path != NULL)
534 gtk_tree_path_free (next_path);
535 if (prev_row_reference != NULL)
536 gtk_tree_row_reference_free (prev_row_reference);
537 if (prev_path != NULL)
538 gtk_tree_path_free (prev_path);
541 /* Update toolbar dimming state */
543 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
544 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
548 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
549 g_list_free (sel_list);
555 g_object_unref (header_list);
561 /* delete either message or folder, based on where we are */
563 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
565 g_return_if_fail (MODEST_IS_WINDOW(win));
567 /* Check first if the header view has the focus */
568 if (MODEST_IS_MAIN_WINDOW (win)) {
570 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
571 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
572 if (gtk_widget_is_focus (w)) {
573 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
577 modest_ui_actions_on_delete_message (action, win);
581 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
583 ModestWindowMgr *mgr = NULL;
585 #ifdef MODEST_PLATFORM_MAEMO
586 modest_osso_save_state();
587 #endif /* MODEST_PLATFORM_MAEMO */
589 g_debug ("closing down, clearing %d item(s) from operation queue",
590 modest_mail_operation_queue_num_elements
591 (modest_runtime_get_mail_operation_queue()));
593 /* cancel all outstanding operations */
594 modest_mail_operation_queue_cancel_all
595 (modest_runtime_get_mail_operation_queue());
597 g_debug ("queue has been cleared");
600 /* Check if there are opened editing windows */
601 mgr = modest_runtime_get_window_mgr ();
602 modest_window_mgr_close_all_windows (mgr);
604 /* note: when modest-tny-account-store is finalized,
605 it will automatically set all network connections
608 /* gtk_main_quit (); */
612 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
616 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
618 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
619 /* gtk_widget_destroy (GTK_WIDGET (win)); */
620 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
621 /* gboolean ret_value; */
622 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
623 /* } else if (MODEST_IS_WINDOW (win)) { */
624 /* gtk_widget_destroy (GTK_WIDGET (win)); */
626 /* g_return_if_reached (); */
631 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
633 GtkClipboard *clipboard = NULL;
634 gchar *selection = NULL;
636 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
637 selection = gtk_clipboard_wait_for_text (clipboard);
639 /* Question: why is the clipboard being used here?
640 * It doesn't really make a lot of sense. */
644 modest_address_book_add_address (selection);
650 modest_ui_actions_on_accounts (GtkAction *action,
653 /* This is currently only implemented for Maemo */
654 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
655 if (!modest_ui_actions_run_account_setup_wizard (win))
656 g_debug ("%s: wizard was already running", __FUNCTION__);
660 /* Show the list of accounts */
661 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
663 /* The accounts dialog must be modal */
664 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
665 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
670 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
672 /* This is currently only implemented for Maemo,
673 * because it requires an API (libconic) to detect different connection
676 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
678 /* Create the window if necessary: */
679 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
680 modest_connection_specific_smtp_window_fill_with_connections (
681 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
682 modest_runtime_get_account_mgr());
684 /* Show the window: */
685 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
686 GTK_WINDOW (specific_window), (GtkWindow *) win);
687 gtk_widget_show (specific_window);
688 #endif /* !MODEST_TOOLKIT_GTK */
692 modest_ui_actions_compose_msg(ModestWindow *win,
695 const gchar *bcc_str,
696 const gchar *subject_str,
697 const gchar *body_str,
699 gboolean set_as_modified)
701 gchar *account_name = NULL;
703 TnyAccount *account = NULL;
704 TnyFolder *folder = NULL;
705 gchar *from_str = NULL, *signature = NULL, *body = NULL;
706 gboolean use_signature = FALSE;
707 ModestWindow *msg_win = NULL;
708 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
709 ModestTnyAccountStore *store = modest_runtime_get_account_store();
710 GnomeVFSFileSize total_size, allowed_size;
712 /* we check for low-mem; in that case, show a warning, and don't allow
713 * composing a message with attachments
715 if (attachments && modest_platform_check_memory_low (win, TRUE))
718 #ifdef MODEST_TOOLKIT_HILDON2
719 account_name = g_strdup (modest_window_get_active_account(win));
722 account_name = modest_account_mgr_get_default_account(mgr);
725 g_printerr ("modest: no account found\n");
728 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
730 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
733 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
735 g_printerr ("modest: failed to find Drafts folder\n");
738 from_str = modest_account_mgr_get_from_string (mgr, account_name);
740 g_printerr ("modest: failed get from string for '%s'\n", account_name);
744 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
745 if (body_str != NULL) {
746 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
748 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
751 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
753 g_printerr ("modest: failed to create new msg\n");
757 /* Create and register edit window */
758 /* This is destroyed by TODO. */
760 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
761 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
763 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL);
764 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
765 gtk_widget_show_all (GTK_WIDGET (msg_win));
767 while (attachments) {
769 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
770 attachments->data, allowed_size);
772 if (total_size > allowed_size) {
773 g_warning ("%s: total size: %u",
774 __FUNCTION__, (unsigned int)total_size);
777 allowed_size -= total_size;
779 attachments = g_slist_next(attachments);
786 g_free (account_name);
788 g_object_unref (G_OBJECT(account));
790 g_object_unref (G_OBJECT(folder));
792 g_object_unref (G_OBJECT(msg));
796 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
798 /* if there are no accounts yet, just show the wizard */
799 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
800 if (!modest_ui_actions_run_account_setup_wizard (win))
803 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
808 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
812 ModestMailOperationStatus status;
814 /* If there is no message or the operation was not successful */
815 status = modest_mail_operation_get_status (mail_op);
816 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
819 /* If it's a memory low issue, then show a banner */
820 error = modest_mail_operation_get_error (mail_op);
821 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
822 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
823 GObject *source = modest_mail_operation_get_source (mail_op);
824 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
825 dgettext("ke-recv","memr_ib_operation_disabled"),
827 g_object_unref (source);
830 /* Remove the header from the preregistered uids */
831 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
849 OpenMsgBannerInfo *banner_info;
850 GHashTable *row_refs_per_header;
854 open_msg_banner_idle (gpointer userdata)
856 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
858 gdk_threads_enter ();
859 banner_info->idle_handler = 0;
860 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
862 g_object_ref (banner_info->banner);
864 gdk_threads_leave ();
871 open_msg_cb (ModestMailOperation *mail_op,
878 ModestWindowMgr *mgr = NULL;
879 ModestWindow *parent_win = NULL;
880 ModestWindow *win = NULL;
881 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
882 gchar *account = NULL;
884 gboolean open_in_editor = FALSE;
885 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
887 /* Do nothing if there was any problem with the mail
888 operation. The error will be shown by the error_handler of
889 the mail operation */
890 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
893 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
894 folder = tny_header_get_folder (header);
896 /* Mark header as read */
897 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
899 /* Gets folder type (OUTBOX headers will be opened in edit window */
900 if (modest_tny_folder_is_local_folder (folder)) {
901 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
902 if (folder_type == TNY_FOLDER_TYPE_INVALID)
903 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
907 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
908 TnyTransportAccount *traccount = NULL;
909 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
910 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
912 ModestTnySendQueue *send_queue = NULL;
913 ModestTnySendQueueStatus status;
915 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
916 TNY_ACCOUNT(traccount)));
917 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
918 if (TNY_IS_SEND_QUEUE (send_queue)) {
919 msg_id = modest_tny_send_queue_get_msg_id (header);
920 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
921 /* Only open messages in outbox with the editor if they are in Failed state */
922 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
923 open_in_editor = TRUE;
927 g_object_unref(traccount);
929 g_warning("Cannot get transport account for message in outbox!!");
931 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
932 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
937 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
939 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
941 if (open_in_editor) {
942 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
943 gchar *from_header = NULL, *acc_name;
945 from_header = tny_header_dup_from (header);
947 /* we cannot edit without a valid account... */
948 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
949 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
950 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
952 g_free (from_header);
957 acc_name = modest_utils_get_account_name_from_recipient (from_header);
958 g_free (from_header);
964 win = modest_msg_edit_window_new (msg, account, TRUE);
966 gchar *uid = modest_tny_folder_get_header_unique_id (header);
968 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
969 GtkTreeRowReference *row_reference;
971 row_reference = (GtkTreeRowReference *) g_hash_table_lookup (helper->row_refs_per_header, header);
973 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
974 helper->model, row_reference);
976 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
981 /* Register and show new window */
983 mgr = modest_runtime_get_window_mgr ();
984 modest_window_mgr_register_window (mgr, win, NULL);
985 gtk_widget_show_all (GTK_WIDGET(win));
988 /* Update toolbar dimming state */
989 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
990 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
996 g_object_unref (parent_win);
997 g_object_unref (folder);
1001 is_memory_full_error (GError *error)
1003 gboolean enough_free_space = TRUE;
1004 GnomeVFSURI *cache_dir_uri;
1005 const gchar *cache_dir;
1006 GnomeVFSFileSize free_space;
1008 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1009 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1010 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1011 if (free_space < MIN_FREE_SPACE)
1012 enough_free_space = FALSE;
1014 gnome_vfs_uri_unref (cache_dir_uri);
1016 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1017 /* When asking for a mail and no space left on device
1018 tinymail returns this error */
1019 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1020 /* When the folder summary could not be read or
1022 error->code == TNY_IO_ERROR_WRITE ||
1023 error->code == TNY_IO_ERROR_READ) &&
1024 !enough_free_space) {
1032 check_memory_full_error (GtkWidget *parent_window, GError *err)
1037 if (is_memory_full_error (err))
1038 modest_platform_information_banner (parent_window,
1039 NULL, dgettext("ke-recv",
1040 "cerm_device_memory_full"));
1041 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1042 /* If the account was created in memory full
1043 conditions then tinymail won't be able to
1044 connect so it'll return this error code */
1045 modest_platform_information_banner (parent_window,
1046 NULL, _("emev_ui_imap_inbox_select_error"));
1054 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1057 const GError *error;
1058 GObject *win = NULL;
1059 ModestMailOperationStatus status;
1061 win = modest_mail_operation_get_source (mail_op);
1062 error = modest_mail_operation_get_error (mail_op);
1063 status = modest_mail_operation_get_status (mail_op);
1065 /* If the mail op has been cancelled then it's not an error:
1066 don't show any message */
1067 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1068 if (is_memory_full_error ((GError *) error)) {
1069 modest_platform_information_banner ((GtkWidget *) win,
1070 NULL, dgettext("ke-recv",
1071 "cerm_device_memory_full"));
1072 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1073 modest_platform_information_banner ((GtkWidget *) win,
1074 NULL, _("emev_ui_imap_inbox_select_error"));
1075 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1076 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1077 modest_platform_information_banner ((GtkWidget *) win,
1078 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1079 } else if (user_data) {
1080 modest_platform_information_banner ((GtkWidget *) win,
1086 g_object_unref (win);
1090 * Returns the account a list of headers belongs to. It returns a
1091 * *new* reference so don't forget to unref it
1094 get_account_from_header_list (TnyList *headers)
1096 TnyAccount *account = NULL;
1098 if (tny_list_get_length (headers) > 0) {
1099 TnyIterator *iter = tny_list_create_iterator (headers);
1100 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1101 TnyFolder *folder = tny_header_get_folder (header);
1104 g_object_unref (header);
1106 while (!tny_iterator_is_done (iter)) {
1107 header = TNY_HEADER (tny_iterator_get_current (iter));
1108 folder = tny_header_get_folder (header);
1111 g_object_unref (header);
1113 tny_iterator_next (iter);
1118 account = tny_folder_get_account (folder);
1119 g_object_unref (folder);
1123 g_object_unref (header);
1125 g_object_unref (iter);
1131 foreach_unregister_headers (gpointer data,
1134 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1135 TnyHeader *header = TNY_HEADER (data);
1137 modest_window_mgr_unregister_header (mgr, header);
1141 open_msgs_helper_destroyer (gpointer user_data)
1143 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1145 if (helper->banner_info) {
1146 g_free (helper->banner_info->message);
1147 if (helper->banner_info->idle_handler > 0) {
1148 g_source_remove (helper->banner_info->idle_handler);
1149 helper->banner_info->idle_handler = 0;
1151 if (helper->banner_info->banner != NULL) {
1152 gtk_widget_destroy (helper->banner_info->banner);
1153 g_object_unref (helper->banner_info->banner);
1154 helper->banner_info->banner = NULL;
1156 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1157 helper->banner_info = NULL;
1159 g_object_unref (helper->model);
1160 g_object_unref (helper->headers);
1161 g_hash_table_destroy (helper->row_refs_per_header);
1162 g_slice_free (OpenMsgHelper, helper);
1166 open_msgs_performer(gboolean canceled,
1168 GtkWindow *parent_window,
1169 TnyAccount *account,
1172 ModestMailOperation *mail_op = NULL;
1174 ModestProtocolType proto;
1175 TnyList *not_opened_headers;
1176 TnyConnectionStatus status;
1177 gboolean show_open_draft = FALSE;
1178 OpenMsgHelper *helper = NULL;
1180 helper = (OpenMsgHelper *) user_data;
1181 not_opened_headers = helper->headers;
1183 status = tny_account_get_connection_status (account);
1184 if (err || canceled) {
1185 /* Unregister the already registered headers */
1186 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1187 modest_runtime_get_window_mgr ());
1188 /* Free the helper */
1189 open_msgs_helper_destroyer (helper);
1191 /* In memory full conditions we could get this error here */
1192 check_memory_full_error ((GtkWidget *) parent_window, err);
1197 /* Get the error message depending on the protocol */
1198 proto = modest_tny_account_get_protocol_type (account);
1199 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1200 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1203 /* Create the error messages */
1204 if (tny_list_get_length (not_opened_headers) == 1) {
1205 ModestProtocol *protocol;
1206 ModestProtocolRegistry *protocol_registry;
1211 protocol_registry = modest_runtime_get_protocol_registry ();
1212 iter = tny_list_create_iterator (not_opened_headers);
1213 header = TNY_HEADER (tny_iterator_get_current (iter));
1214 subject = tny_header_dup_subject (header);
1216 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1217 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1219 g_object_unref (header);
1220 g_object_unref (iter);
1222 if (error_msg == NULL) {
1223 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1226 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1228 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1232 TnyFolderType folder_type;
1234 iter = tny_list_create_iterator (not_opened_headers);
1235 header = TNY_HEADER (tny_iterator_get_current (iter));
1236 folder = tny_header_get_folder (header);
1237 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1238 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1239 g_object_unref (folder);
1240 g_object_unref (header);
1241 g_object_unref (iter);
1244 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1247 /* Create the mail operation */
1249 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1250 modest_ui_actions_disk_operations_error_handler,
1252 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1255 if (show_open_draft) {
1256 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1257 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1258 helper->banner_info->banner = NULL;
1259 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1260 helper->banner_info);
1263 modest_mail_operation_get_msgs_full (mail_op,
1267 open_msgs_helper_destroyer);
1272 g_object_unref (mail_op);
1273 g_object_unref (account);
1277 * This function is used by both modest_ui_actions_on_open and
1278 * modest_ui_actions_on_header_activated. This way we always do the
1279 * same when trying to open messages.
1282 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1284 ModestWindowMgr *mgr = NULL;
1285 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1286 TnyList *not_opened_headers = NULL;
1287 TnyHeaderFlags flags = 0;
1288 TnyAccount *account;
1289 gint uncached_msgs = 0;
1290 GtkWidget *header_view;
1291 GtkTreeModel *model;
1292 GHashTable *refs_for_headers;
1293 OpenMsgHelper *helper;
1294 GtkTreeSelection *sel;
1295 GList *sel_list = NULL, *sel_list_iter = NULL;
1297 g_return_if_fail (headers != NULL);
1299 /* Check that only one message is selected for opening */
1300 if (tny_list_get_length (headers) != 1) {
1301 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1302 NULL, _("mcen_ib_select_one_message"));
1306 mgr = modest_runtime_get_window_mgr ();
1307 iter = tny_list_create_iterator (headers);
1309 /* Get the account */
1310 account = get_account_from_header_list (headers);
1315 /* Get the selections, we need to get the references to the
1316 rows here because the treeview/model could dissapear (the
1317 user might want to select another folder)*/
1318 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1319 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1320 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1321 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
1322 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1323 refs_for_headers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
1324 (GDestroyNotify) gtk_tree_row_reference_free);
1326 /* Look if we already have a message view for each header. If
1327 true, then remove the header from the list of headers to
1329 sel_list_iter = sel_list;
1330 not_opened_headers = tny_simple_list_new ();
1331 while (!tny_iterator_is_done (iter) && sel_list_iter) {
1333 ModestWindow *window = NULL;
1334 TnyHeader *header = NULL;
1335 gboolean found = FALSE;
1337 header = TNY_HEADER (tny_iterator_get_current (iter));
1339 flags = tny_header_get_flags (header);
1342 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1344 /* Do not open again the message and present the
1345 window to the user */
1348 #ifndef MODEST_TOOLKIT_HILDON2
1349 gtk_window_present (GTK_WINDOW (window));
1352 /* the header has been registered already, we don't do
1353 * anything but wait for the window to come up*/
1354 g_debug ("header %p already registered, waiting for window", header);
1357 GtkTreeRowReference *row_reference;
1359 tny_list_append (not_opened_headers, G_OBJECT (header));
1360 /* Create a new row reference and add it to the hash table */
1361 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list_iter->data);
1362 g_hash_table_insert (refs_for_headers, header, row_reference);
1366 g_object_unref (header);
1369 tny_iterator_next (iter);
1370 sel_list_iter = g_list_next (sel_list_iter);
1372 g_object_unref (iter);
1374 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1375 g_list_free (sel_list);
1377 /* Open each message */
1378 if (tny_list_get_length (not_opened_headers) == 0) {
1379 g_hash_table_destroy (refs_for_headers);
1383 /* If some messages would have to be downloaded, ask the user to
1384 * make a connection. It's generally easier to do this here (in the mainloop)
1385 * than later in a thread:
1387 if (tny_list_get_length (not_opened_headers) > 0) {
1388 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1390 if (uncached_msgs > 0) {
1391 /* Allways download if we are online. */
1392 if (!tny_device_is_online (modest_runtime_get_device ())) {
1395 /* If ask for user permission to download the messages */
1396 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1397 ngettext("mcen_nc_get_msg",
1401 /* End if the user does not want to continue */
1402 if (response == GTK_RESPONSE_CANCEL) {
1403 g_hash_table_destroy (refs_for_headers);
1410 /* Register the headers before actually creating the windows: */
1411 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1412 while (!tny_iterator_is_done (iter_not_opened)) {
1413 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1415 modest_window_mgr_register_header (mgr, header, NULL);
1416 g_object_unref (header);
1418 tny_iterator_next (iter_not_opened);
1420 g_object_unref (iter_not_opened);
1421 iter_not_opened = NULL;
1423 /* Create the helper. We need to get a reference to the model
1424 here because it could change while the message is readed
1425 (the user could switch between folders) */
1426 helper = g_slice_new (OpenMsgHelper);
1427 helper->model = g_object_ref (model);
1428 helper->headers = g_object_ref (not_opened_headers);
1429 helper->row_refs_per_header = refs_for_headers;
1430 helper->banner_info = NULL;
1432 /* Connect to the account and perform */
1433 if (uncached_msgs > 0) {
1434 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1435 open_msgs_performer, helper);
1437 /* Call directly the performer, do not need to connect */
1438 open_msgs_performer (FALSE, NULL, (GtkWindow *) win,
1439 g_object_ref (account), helper);
1444 g_object_unref (account);
1445 if (not_opened_headers)
1446 g_object_unref (not_opened_headers);
1450 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1454 /* we check for low-mem; in that case, show a warning, and don't allow
1457 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1461 headers = get_selected_headers (win);
1466 open_msgs_from_headers (headers, win);
1468 g_object_unref(headers);
1471 static ReplyForwardHelper*
1472 create_reply_forward_helper (ReplyForwardAction action,
1474 guint reply_forward_type,
1477 ReplyForwardHelper *rf_helper = NULL;
1478 const gchar *active_acc = modest_window_get_active_account (win);
1480 rf_helper = g_slice_new0 (ReplyForwardHelper);
1481 rf_helper->reply_forward_type = reply_forward_type;
1482 rf_helper->action = action;
1483 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1484 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1485 rf_helper->account_name = (active_acc) ?
1486 g_strdup (active_acc) :
1487 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1493 free_reply_forward_helper (gpointer data)
1495 ReplyForwardHelper *helper;
1497 helper = (ReplyForwardHelper *) data;
1498 g_free (helper->account_name);
1500 g_object_unref (helper->header);
1501 g_slice_free (ReplyForwardHelper, helper);
1505 reply_forward_cb (ModestMailOperation *mail_op,
1512 TnyMsg *new_msg = NULL;
1513 ReplyForwardHelper *rf_helper;
1514 ModestWindow *msg_win = NULL;
1515 ModestEditType edit_type;
1517 TnyAccount *account = NULL;
1518 ModestWindowMgr *mgr = NULL;
1519 gchar *signature = NULL;
1520 gboolean use_signature;
1522 /* If there was any error. The mail operation could be NULL,
1523 this means that we already have the message downloaded and
1524 that we didn't do a mail operation to retrieve it */
1525 rf_helper = (ReplyForwardHelper *) user_data;
1526 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1529 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1530 rf_helper->account_name);
1531 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1532 rf_helper->account_name,
1535 /* Create reply mail */
1536 switch (rf_helper->action) {
1539 modest_tny_msg_create_reply_msg (msg, header, from,
1540 (use_signature) ? signature : NULL,
1541 rf_helper->reply_forward_type,
1542 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1544 case ACTION_REPLY_TO_ALL:
1546 modest_tny_msg_create_reply_msg (msg, header, from,
1547 (use_signature) ? signature : NULL,
1548 rf_helper->reply_forward_type,
1549 MODEST_TNY_MSG_REPLY_MODE_ALL);
1550 edit_type = MODEST_EDIT_TYPE_REPLY;
1552 case ACTION_FORWARD:
1554 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1555 rf_helper->reply_forward_type);
1556 edit_type = MODEST_EDIT_TYPE_FORWARD;
1559 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1561 g_return_if_reached ();
1569 g_warning ("%s: failed to create message\n", __FUNCTION__);
1573 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1574 rf_helper->account_name,
1575 TNY_ACCOUNT_TYPE_STORE);
1577 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1581 /* Create and register the windows */
1582 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1583 mgr = modest_runtime_get_window_mgr ();
1584 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1586 if (rf_helper->parent_window != NULL) {
1587 gdouble parent_zoom;
1589 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1590 modest_window_set_zoom (msg_win, parent_zoom);
1593 /* Show edit window */
1594 gtk_widget_show_all (GTK_WIDGET (msg_win));
1597 /* We always unregister the header because the message is
1598 forwarded or replied so the original one is no longer
1600 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1603 g_object_unref (G_OBJECT (new_msg));
1605 g_object_unref (G_OBJECT (account));
1606 free_reply_forward_helper (rf_helper);
1609 /* Checks a list of headers. If any of them are not currently
1610 * downloaded (CACHED) then returns TRUE else returns FALSE.
1613 header_list_count_uncached_msgs (TnyList *header_list)
1616 gint uncached_messages = 0;
1618 iter = tny_list_create_iterator (header_list);
1619 while (!tny_iterator_is_done (iter)) {
1622 header = TNY_HEADER (tny_iterator_get_current (iter));
1624 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1625 uncached_messages ++;
1626 g_object_unref (header);
1629 tny_iterator_next (iter);
1631 g_object_unref (iter);
1633 return uncached_messages;
1636 /* Returns FALSE if the user does not want to download the
1637 * messages. Returns TRUE if the user allowed the download.
1640 connect_to_get_msg (ModestWindow *win,
1641 gint num_of_uncached_msgs,
1642 TnyAccount *account)
1644 GtkResponseType response;
1646 /* Allways download if we are online. */
1647 if (tny_device_is_online (modest_runtime_get_device ()))
1650 /* If offline, then ask for user permission to download the messages */
1651 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1652 ngettext("mcen_nc_get_msg",
1654 num_of_uncached_msgs));
1656 if (response == GTK_RESPONSE_CANCEL)
1659 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1663 reply_forward_performer (gboolean canceled,
1665 GtkWindow *parent_window,
1666 TnyAccount *account,
1669 ReplyForwardHelper *rf_helper = NULL;
1670 ModestMailOperation *mail_op;
1672 rf_helper = (ReplyForwardHelper *) user_data;
1674 if (canceled || err) {
1675 free_reply_forward_helper (rf_helper);
1679 /* Retrieve the message */
1680 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1681 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1682 modest_ui_actions_disk_operations_error_handler,
1684 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1685 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1688 g_object_unref(mail_op);
1692 * Common code for the reply and forward actions
1695 reply_forward (ReplyForwardAction action, ModestWindow *win)
1697 ReplyForwardHelper *rf_helper = NULL;
1698 guint reply_forward_type;
1700 g_return_if_fail (MODEST_IS_WINDOW(win));
1702 /* we check for low-mem; in that case, show a warning, and don't allow
1703 * reply/forward (because it could potentially require a lot of memory */
1704 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1708 /* we need an account when editing */
1709 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1710 if (!modest_ui_actions_run_account_setup_wizard (win))
1714 reply_forward_type =
1715 modest_conf_get_int (modest_runtime_get_conf (),
1716 (action == ACTION_FORWARD) ?
1717 MODEST_CONF_FORWARD_TYPE :
1718 MODEST_CONF_REPLY_TYPE,
1721 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1723 TnyHeader *header = NULL;
1724 /* Get header and message. Do not free them here, the
1725 reply_forward_cb must do it */
1726 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1727 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1729 if (msg && header) {
1731 rf_helper = create_reply_forward_helper (action, win,
1732 reply_forward_type, header);
1733 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1735 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1739 g_object_unref (msg);
1741 g_object_unref (header);
1743 TnyHeader *header = NULL;
1745 gboolean do_retrieve = TRUE;
1746 TnyList *header_list = NULL;
1748 header_list = get_selected_headers (win);
1751 /* Check that only one message is selected for replying */
1752 if (tny_list_get_length (header_list) != 1) {
1753 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1754 NULL, _("mcen_ib_select_one_message"));
1755 g_object_unref (header_list);
1759 /* Only reply/forward to one message */
1760 iter = tny_list_create_iterator (header_list);
1761 header = TNY_HEADER (tny_iterator_get_current (iter));
1762 g_object_unref (iter);
1764 /* Retrieve messages */
1765 do_retrieve = (action == ACTION_FORWARD) ||
1766 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1769 TnyAccount *account = NULL;
1770 TnyFolder *folder = NULL;
1771 gdouble download = TRUE;
1772 guint uncached_msgs = 0;
1774 folder = tny_header_get_folder (header);
1776 goto do_retrieve_frees;
1777 account = tny_folder_get_account (folder);
1779 goto do_retrieve_frees;
1781 uncached_msgs = header_list_count_uncached_msgs (header_list);
1783 if (uncached_msgs > 0) {
1784 /* Allways download if we are online. */
1785 if (!tny_device_is_online (modest_runtime_get_device ())) {
1788 /* If ask for user permission to download the messages */
1789 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1790 ngettext("mcen_nc_get_msg",
1794 /* End if the user does not want to continue */
1795 if (response == GTK_RESPONSE_CANCEL)
1802 rf_helper = create_reply_forward_helper (action, win,
1803 reply_forward_type, header);
1804 if (uncached_msgs > 0) {
1805 modest_platform_connect_and_perform (GTK_WINDOW (win),
1807 reply_forward_performer,
1810 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1811 account, rf_helper);
1816 g_object_unref (account);
1818 g_object_unref (folder);
1820 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1823 g_object_unref (header_list);
1824 g_object_unref (header);
1829 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1831 g_return_if_fail (MODEST_IS_WINDOW(win));
1833 reply_forward (ACTION_REPLY, win);
1837 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1839 g_return_if_fail (MODEST_IS_WINDOW(win));
1841 reply_forward (ACTION_FORWARD, win);
1845 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1847 g_return_if_fail (MODEST_IS_WINDOW(win));
1849 reply_forward (ACTION_REPLY_TO_ALL, win);
1853 modest_ui_actions_on_next (GtkAction *action,
1854 ModestWindow *window)
1856 if (MODEST_IS_MAIN_WINDOW (window)) {
1857 GtkWidget *header_view;
1859 header_view = modest_main_window_get_child_widget (
1860 MODEST_MAIN_WINDOW(window),
1861 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1865 modest_header_view_select_next (
1866 MODEST_HEADER_VIEW(header_view));
1867 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1868 modest_msg_view_window_select_next_message (
1869 MODEST_MSG_VIEW_WINDOW (window));
1871 g_return_if_reached ();
1876 modest_ui_actions_on_prev (GtkAction *action,
1877 ModestWindow *window)
1879 g_return_if_fail (MODEST_IS_WINDOW(window));
1881 if (MODEST_IS_MAIN_WINDOW (window)) {
1882 GtkWidget *header_view;
1883 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1884 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1888 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1889 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1890 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1892 g_return_if_reached ();
1897 modest_ui_actions_on_sort (GtkAction *action,
1898 ModestWindow *window)
1900 g_return_if_fail (MODEST_IS_WINDOW(window));
1902 if (MODEST_IS_MAIN_WINDOW (window)) {
1903 GtkWidget *header_view;
1904 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1905 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1907 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1912 /* Show sorting dialog */
1913 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1918 new_messages_arrived (ModestMailOperation *self,
1919 TnyList *new_headers,
1923 gboolean show_visual_notifications;
1925 source = modest_mail_operation_get_source (self);
1926 show_visual_notifications = (source) ? FALSE : TRUE;
1928 g_object_unref (source);
1930 /* Notify new messages have been downloaded. If the
1931 send&receive was invoked by the user then do not show any
1932 visual notification, only play a sound and activate the LED
1933 (for the Maemo version) */
1934 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1935 modest_platform_on_new_headers_received (new_headers,
1936 show_visual_notifications);
1941 retrieve_all_messages_cb (GObject *source,
1943 guint retrieve_limit)
1949 window = GTK_WINDOW (source);
1950 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1951 num_msgs, retrieve_limit);
1953 /* Ask the user if they want to retrieve all the messages */
1955 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1956 _("mcen_bd_get_all"),
1957 _("mcen_bd_newest_only"));
1958 /* Free and return */
1960 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1964 TnyAccount *account;
1966 gchar *account_name;
1967 gboolean poke_status;
1968 gboolean interactive;
1969 ModestMailOperation *mail_op;
1973 do_send_receive_performer (gboolean canceled,
1975 GtkWindow *parent_window,
1976 TnyAccount *account,
1979 SendReceiveInfo *info;
1981 info = (SendReceiveInfo *) user_data;
1983 if (err || canceled) {
1984 /* In memory full conditions we could get this error here */
1985 check_memory_full_error ((GtkWidget *) parent_window, err);
1987 if (info->mail_op) {
1988 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
1994 /* Set send/receive operation in progress */
1995 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
1996 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
1999 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2000 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2001 G_CALLBACK (on_send_receive_finished),
2004 /* Send & receive. */
2005 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2006 (info->win) ? retrieve_all_messages_cb : NULL,
2007 new_messages_arrived, info->win);
2012 g_object_unref (G_OBJECT (info->mail_op));
2013 if (info->account_name)
2014 g_free (info->account_name);
2016 g_object_unref (info->win);
2018 g_object_unref (info->account);
2019 g_slice_free (SendReceiveInfo, info);
2023 * This function performs the send & receive required actions. The
2024 * window is used to create the mail operation. Typically it should
2025 * always be the main window, but we pass it as argument in order to
2029 modest_ui_actions_do_send_receive (const gchar *account_name,
2030 gboolean force_connection,
2031 gboolean poke_status,
2032 gboolean interactive,
2035 gchar *acc_name = NULL;
2036 SendReceiveInfo *info;
2037 ModestTnyAccountStore *acc_store;
2039 /* If no account name was provided then get the current account, and if
2040 there is no current account then pick the default one: */
2041 if (!account_name) {
2043 acc_name = g_strdup (modest_window_get_active_account (win));
2045 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2047 g_printerr ("modest: cannot get default account\n");
2051 acc_name = g_strdup (account_name);
2054 acc_store = modest_runtime_get_account_store ();
2056 /* Create the info for the connect and perform */
2057 info = g_slice_new (SendReceiveInfo);
2058 info->account_name = acc_name;
2059 info->win = (win) ? g_object_ref (win) : NULL;
2060 info->poke_status = poke_status;
2061 info->interactive = interactive;
2062 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2063 TNY_ACCOUNT_TYPE_STORE);
2064 /* We need to create the operation here, because otherwise it
2065 could happen that the queue emits the queue-empty signal
2066 while we're trying to connect the account */
2067 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2068 modest_ui_actions_disk_operations_error_handler,
2070 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2072 /* Invoke the connect and perform */
2073 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2074 force_connection, info->account,
2075 do_send_receive_performer, info);
2080 modest_ui_actions_do_cancel_send (const gchar *account_name,
2083 TnyTransportAccount *transport_account;
2084 TnySendQueue *send_queue = NULL;
2085 GError *error = NULL;
2087 /* Get transport account */
2089 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2090 (modest_runtime_get_account_store(),
2092 TNY_ACCOUNT_TYPE_TRANSPORT));
2093 if (!transport_account) {
2094 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2099 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2100 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2101 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2102 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2103 "modest: could not find send queue for account\n");
2105 /* Cancel the current send */
2106 tny_account_cancel (TNY_ACCOUNT (transport_account));
2108 /* Suspend all pending messages */
2109 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2113 if (transport_account != NULL)
2114 g_object_unref (G_OBJECT (transport_account));
2118 modest_ui_actions_cancel_send_all (ModestWindow *win)
2120 GSList *account_names, *iter;
2122 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2125 iter = account_names;
2127 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2128 iter = g_slist_next (iter);
2131 modest_account_mgr_free_account_names (account_names);
2132 account_names = NULL;
2136 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2139 /* Check if accounts exist */
2140 gboolean accounts_exist =
2141 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2143 /* If not, allow the user to create an account before trying to send/receive. */
2144 if (!accounts_exist)
2145 modest_ui_actions_on_accounts (NULL, win);
2147 /* Cancel all sending operaitons */
2148 modest_ui_actions_cancel_send_all (win);
2152 * Refreshes all accounts. This function will be used by automatic
2156 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2157 gboolean force_connection,
2158 gboolean poke_status,
2159 gboolean interactive)
2161 GSList *account_names, *iter;
2163 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2166 iter = account_names;
2168 modest_ui_actions_do_send_receive ((const char*) iter->data,
2170 poke_status, interactive, win);
2171 iter = g_slist_next (iter);
2174 modest_account_mgr_free_account_names (account_names);
2175 account_names = NULL;
2179 * Handler of the click on Send&Receive button in the main toolbar
2182 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2184 /* Check if accounts exist */
2185 gboolean accounts_exist;
2188 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2190 /* If not, allow the user to create an account before trying to send/receive. */
2191 if (!accounts_exist)
2192 modest_ui_actions_on_accounts (NULL, win);
2194 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2195 if (MODEST_IS_MAIN_WINDOW (win)) {
2196 GtkWidget *folder_view;
2197 TnyFolderStore *folder_store;
2200 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2201 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2205 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2208 g_object_unref (folder_store);
2211 /* Refresh the active account. Force the connection if needed
2212 and poke the status of all folders */
2213 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2218 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2221 GtkWidget *header_view;
2223 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2225 header_view = modest_main_window_get_child_widget (main_window,
2226 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2230 conf = modest_runtime_get_conf ();
2232 /* what is saved/restored is depending on the style; thus; we save with
2233 * old style, then update the style, and restore for this new style
2235 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2237 if (modest_header_view_get_style
2238 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2239 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2240 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2242 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2243 MODEST_HEADER_VIEW_STYLE_DETAILS);
2245 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2246 MODEST_CONF_HEADER_VIEW_KEY);
2251 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2253 ModestMainWindow *main_window)
2255 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2256 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2258 /* in the case the folder is empty, show the empty folder message and focus
2260 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2261 if (modest_header_view_is_empty (header_view)) {
2262 TnyFolder *folder = modest_header_view_get_folder (header_view);
2263 GtkWidget *folder_view =
2264 modest_main_window_get_child_widget (main_window,
2265 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2266 if (folder != NULL) {
2267 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2268 g_object_unref (folder);
2270 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2274 /* If no header has been selected then exit */
2279 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2280 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2282 /* Update toolbar dimming state */
2283 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2284 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2288 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2290 ModestMainWindow *main_window)
2293 GtkWidget *open_widget;
2295 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2300 if (modest_header_view_count_selected_headers (header_view) > 1) {
2301 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2305 /* we check for low-mem; in that case, show a warning, and don't allow
2306 * activating headers
2308 if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE))
2311 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2312 open_widget = modest_window_get_action_widget (MODEST_WINDOW (main_window), "/MenuBar/EmailMenu/EmailOpenMenu");
2313 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2316 headers = modest_header_view_get_selected_headers (header_view);
2318 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2320 g_object_unref (headers);
2324 set_active_account_from_tny_account (TnyAccount *account,
2325 ModestWindow *window)
2327 const gchar *server_acc_name = tny_account_get_id (account);
2329 /* We need the TnyAccount provided by the
2330 account store because that is the one that
2331 knows the name of the Modest account */
2332 TnyAccount *modest_server_account = modest_server_account =
2333 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2334 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2336 if (!modest_server_account) {
2337 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2341 /* Update active account, but only if it's not a pseudo-account */
2342 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2343 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2344 const gchar *modest_acc_name =
2345 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2346 if (modest_acc_name)
2347 modest_window_set_active_account (window, modest_acc_name);
2350 g_object_unref (modest_server_account);
2355 folder_refreshed_cb (ModestMailOperation *mail_op,
2359 ModestMainWindow *win = NULL;
2360 GtkWidget *folder_view;
2361 const GError *error;
2363 g_return_if_fail (TNY_IS_FOLDER (folder));
2365 win = MODEST_MAIN_WINDOW (user_data);
2367 /* Check if the operation failed due to memory low conditions */
2368 error = modest_mail_operation_get_error (mail_op);
2369 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2370 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2371 modest_platform_run_information_dialog (GTK_WINDOW (win),
2372 dgettext("ke-recv","memr_ib_operation_disabled"),
2378 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2381 TnyFolderStore *current_folder;
2383 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2384 if (current_folder) {
2385 gboolean different = ((TnyFolderStore *) folder != current_folder);
2386 g_object_unref (current_folder);
2392 /* Check if folder is empty and set headers view contents style */
2393 if (tny_folder_get_all_count (folder) == 0)
2394 modest_main_window_set_contents_style (win,
2395 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2400 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2401 TnyFolderStore *folder_store,
2403 ModestMainWindow *main_window)
2406 GtkWidget *header_view;
2408 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2410 header_view = modest_main_window_get_child_widget(main_window,
2411 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2415 conf = modest_runtime_get_conf ();
2417 if (TNY_IS_ACCOUNT (folder_store)) {
2419 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2421 /* Show account details */
2422 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2425 if (TNY_IS_FOLDER (folder_store) && selected) {
2426 TnyAccount *account;
2427 const gchar *account_name = NULL;
2429 /* Update the active account */
2430 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2432 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2434 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2435 g_object_unref (account);
2439 /* Set the header style by default, it could
2440 be changed later by the refresh callback to
2442 modest_main_window_set_contents_style (main_window,
2443 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2445 /* Set folder on header view. This function
2446 will call tny_folder_refresh_async so we
2447 pass a callback that will be called when
2448 finished. We use that callback to set the
2449 empty view if there are no messages */
2450 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2451 TNY_FOLDER (folder_store),
2453 folder_refreshed_cb,
2456 /* Restore configuration. We need to do this
2457 *after* the set_folder because the widget
2458 memory asks the header view about its
2460 modest_widget_memory_restore (modest_runtime_get_conf (),
2461 G_OBJECT(header_view),
2462 MODEST_CONF_HEADER_VIEW_KEY);
2464 /* No need to save the header view
2465 configuration for Maemo because it only
2466 saves the sorting stuff and that it's
2467 already being done by the sort
2468 dialog. Remove it when the GNOME version
2469 has the same behaviour */
2470 #ifdef MODEST_TOOLKIT_GTK
2471 if (modest_main_window_get_contents_style (main_window) ==
2472 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2473 modest_widget_memory_save (conf, G_OBJECT (header_view),
2474 MODEST_CONF_HEADER_VIEW_KEY);
2476 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2480 /* Update dimming state */
2481 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2482 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2486 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2493 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2495 online = tny_device_is_online (modest_runtime_get_device());
2498 /* already online -- the item is simply not there... */
2499 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2501 GTK_MESSAGE_WARNING,
2503 _("The %s you selected cannot be found"),
2505 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2506 gtk_dialog_run (GTK_DIALOG(dialog));
2508 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2511 _("mcen_bd_dialog_cancel"),
2512 GTK_RESPONSE_REJECT,
2513 _("mcen_bd_dialog_ok"),
2514 GTK_RESPONSE_ACCEPT,
2516 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2517 "Do you want to get online?"), item);
2518 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2519 gtk_label_new (txt), FALSE, FALSE, 0);
2520 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2523 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2524 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2525 /* TODO: Comment about why is this commented out: */
2526 /* modest_platform_connect_and_wait (); */
2529 gtk_widget_destroy (dialog);
2533 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2536 /* g_message ("%s %s", __FUNCTION__, link); */
2541 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2544 modest_platform_activate_uri (link);
2548 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2551 modest_platform_show_uri_popup (link);
2555 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2558 /* we check for low-mem; in that case, show a warning, and don't allow
2559 * viewing attachments
2561 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2564 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2568 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2569 const gchar *address,
2572 /* g_message ("%s %s", __FUNCTION__, address); */
2576 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2577 TnyMsg *saved_draft,
2580 ModestMsgEditWindow *edit_window;
2581 ModestMainWindow *win;
2583 /* FIXME. Make the header view sensitive again. This is a
2584 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2586 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2587 modest_runtime_get_window_mgr(), FALSE));
2589 GtkWidget *hdrview = modest_main_window_get_child_widget(
2590 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2591 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2594 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2596 /* Set draft is there was no error */
2597 if (!modest_mail_operation_get_error (mail_op))
2598 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2600 g_object_unref(edit_window);
2604 enough_space_for_message (ModestMsgEditWindow *edit_window,
2607 TnyAccountStore *acc_store;
2608 guint64 available_disk, expected_size;
2613 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2614 available_disk = modest_utils_get_available_space (NULL);
2615 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2616 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2621 /* Double check: memory full condition or message too big */
2622 if (available_disk < MIN_FREE_SPACE ||
2623 expected_size > available_disk) {
2625 modest_platform_information_banner (NULL, NULL,
2627 "cerm_device_memory_full"));
2632 * djcb: if we're in low-memory state, we only allow for
2633 * saving messages smaller than
2634 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2635 * should still allow for sending anything critical...
2637 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2638 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2642 * djcb: we also make sure that the attachments are smaller than the max size
2643 * this is for the case where we'd try to forward a message with attachments
2644 * bigger than our max allowed size, or sending an message from drafts which
2645 * somehow got past our checks when attaching.
2647 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2648 modest_platform_run_information_dialog (
2649 GTK_WINDOW(edit_window),
2650 dgettext("ke-recv","memr_ib_operation_disabled"),
2659 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2661 TnyTransportAccount *transport_account;
2662 ModestMailOperation *mail_operation;
2664 gchar *account_name, *from;
2665 ModestAccountMgr *account_mgr;
2666 gboolean had_error = FALSE;
2667 ModestMainWindow *win;
2669 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2671 data = modest_msg_edit_window_get_msg_data (edit_window);
2674 if (!enough_space_for_message (edit_window, data)) {
2675 modest_msg_edit_window_free_msg_data (edit_window, data);
2679 account_name = g_strdup (data->account_name);
2680 account_mgr = modest_runtime_get_account_mgr();
2682 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2684 account_name = modest_account_mgr_get_default_account (account_mgr);
2685 if (!account_name) {
2686 g_printerr ("modest: no account found\n");
2687 modest_msg_edit_window_free_msg_data (edit_window, data);
2691 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2692 account_name = g_strdup (data->account_name);
2696 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2697 (modest_runtime_get_account_store (),
2699 TNY_ACCOUNT_TYPE_TRANSPORT));
2700 if (!transport_account) {
2701 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2702 g_free (account_name);
2703 modest_msg_edit_window_free_msg_data (edit_window, data);
2706 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2708 /* Create the mail operation */
2709 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2711 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2713 modest_mail_operation_save_to_drafts (mail_operation,
2725 data->priority_flags,
2726 on_save_to_drafts_cb,
2727 g_object_ref(edit_window));
2729 /* Use the main window as the parent of the banner, if the
2730 main window does not exist it won't be shown, if the parent
2731 window exists then it's properly shown. We don't use the
2732 editor window because it could be closed (save to drafts
2733 could happen after closing the window */
2734 win = (ModestMainWindow *)
2735 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2737 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2738 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2741 modest_msg_edit_window_set_modified (edit_window, FALSE);
2745 g_free (account_name);
2746 g_object_unref (G_OBJECT (transport_account));
2747 g_object_unref (G_OBJECT (mail_operation));
2749 modest_msg_edit_window_free_msg_data (edit_window, data);
2752 * If the drafts folder is selected then make the header view
2753 * insensitive while the message is being saved to drafts
2754 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2755 * is not very clean but it avoids letting the drafts folder
2756 * in an inconsistent state: the user could edit the message
2757 * being saved and undesirable things would happen.
2758 * In the average case the user won't notice anything at
2759 * all. In the worst case (the user is editing a really big
2760 * file from Drafts) the header view will be insensitive
2761 * during the saving process (10 or 20 seconds, depending on
2762 * the message). Anyway this is just a quick workaround: once
2763 * we find a better solution it should be removed
2764 * See NB#65125 (commend #18) for details.
2766 if (!had_error && win != NULL) {
2767 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2768 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2770 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2772 if (modest_tny_folder_is_local_folder(folder)) {
2773 TnyFolderType folder_type;
2774 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2775 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2776 GtkWidget *hdrview = modest_main_window_get_child_widget(
2777 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2778 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2782 if (folder != NULL) g_object_unref(folder);
2789 /* For instance, when clicking the Send toolbar button when editing a message: */
2791 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2793 TnyTransportAccount *transport_account = NULL;
2794 gboolean had_error = FALSE;
2796 ModestAccountMgr *account_mgr;
2797 gchar *account_name;
2799 ModestMailOperation *mail_operation;
2801 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2803 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2806 data = modest_msg_edit_window_get_msg_data (edit_window);
2809 if (!enough_space_for_message (edit_window, data)) {
2810 modest_msg_edit_window_free_msg_data (edit_window, data);
2814 account_mgr = modest_runtime_get_account_mgr();
2815 account_name = g_strdup (data->account_name);
2817 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2820 account_name = modest_account_mgr_get_default_account (account_mgr);
2822 if (!account_name) {
2823 modest_msg_edit_window_free_msg_data (edit_window, data);
2824 /* Run account setup wizard */
2825 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2830 /* Get the currently-active transport account for this modest account: */
2831 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2833 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2834 (modest_runtime_get_account_store (),
2835 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2838 if (!transport_account) {
2839 modest_msg_edit_window_free_msg_data (edit_window, data);
2840 /* Run account setup wizard */
2841 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2846 /* Create the mail operation */
2847 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2848 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2849 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2851 modest_mail_operation_send_new_mail (mail_operation,
2863 data->priority_flags);
2865 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2866 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2869 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2870 const GError *error = modest_mail_operation_get_error (mail_operation);
2871 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2872 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2873 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2874 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2881 g_free (account_name);
2882 g_object_unref (G_OBJECT (transport_account));
2883 g_object_unref (G_OBJECT (mail_operation));
2885 modest_msg_edit_window_free_msg_data (edit_window, data);
2888 modest_msg_edit_window_set_sent (edit_window, TRUE);
2890 /* Save settings and close the window: */
2891 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2898 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2899 ModestMsgEditWindow *window)
2901 ModestMsgEditFormatState *format_state = NULL;
2903 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2904 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2906 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2909 format_state = modest_msg_edit_window_get_format_state (window);
2910 g_return_if_fail (format_state != NULL);
2912 format_state->bold = gtk_toggle_action_get_active (action);
2913 modest_msg_edit_window_set_format_state (window, format_state);
2914 g_free (format_state);
2919 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2920 ModestMsgEditWindow *window)
2922 ModestMsgEditFormatState *format_state = NULL;
2924 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2925 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2927 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2930 format_state = modest_msg_edit_window_get_format_state (window);
2931 g_return_if_fail (format_state != NULL);
2933 format_state->italics = gtk_toggle_action_get_active (action);
2934 modest_msg_edit_window_set_format_state (window, format_state);
2935 g_free (format_state);
2940 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2941 ModestMsgEditWindow *window)
2943 ModestMsgEditFormatState *format_state = NULL;
2945 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2946 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2948 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2951 format_state = modest_msg_edit_window_get_format_state (window);
2952 g_return_if_fail (format_state != NULL);
2954 format_state->bullet = gtk_toggle_action_get_active (action);
2955 modest_msg_edit_window_set_format_state (window, format_state);
2956 g_free (format_state);
2961 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2962 GtkRadioAction *selected,
2963 ModestMsgEditWindow *window)
2965 ModestMsgEditFormatState *format_state = NULL;
2966 GtkJustification value;
2968 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2970 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2973 value = gtk_radio_action_get_current_value (selected);
2975 format_state = modest_msg_edit_window_get_format_state (window);
2976 g_return_if_fail (format_state != NULL);
2978 format_state->justification = value;
2979 modest_msg_edit_window_set_format_state (window, format_state);
2980 g_free (format_state);
2984 modest_ui_actions_on_select_editor_color (GtkAction *action,
2985 ModestMsgEditWindow *window)
2987 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2988 g_return_if_fail (GTK_IS_ACTION (action));
2990 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2993 modest_msg_edit_window_select_color (window);
2997 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2998 ModestMsgEditWindow *window)
3000 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3001 g_return_if_fail (GTK_IS_ACTION (action));
3003 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3006 modest_msg_edit_window_select_background_color (window);
3010 modest_ui_actions_on_insert_image (GtkAction *action,
3011 ModestMsgEditWindow *window)
3013 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3014 g_return_if_fail (GTK_IS_ACTION (action));
3017 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3020 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3023 modest_msg_edit_window_insert_image (window);
3027 modest_ui_actions_on_attach_file (GtkAction *action,
3028 ModestMsgEditWindow *window)
3030 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3031 g_return_if_fail (GTK_IS_ACTION (action));
3033 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3036 modest_msg_edit_window_offer_attach_file (window);
3040 modest_ui_actions_on_remove_attachments (GtkAction *action,
3041 ModestMsgEditWindow *window)
3043 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3044 g_return_if_fail (GTK_IS_ACTION (action));
3046 modest_msg_edit_window_remove_attachments (window, NULL);
3050 #ifndef MODEST_TOOLKIT_GTK
3055 TnyFolderStore *folder;
3056 } CreateFolderHelper;
3059 show_create_folder_in_timeout (gpointer data)
3061 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3063 /* Remove the timeout ASAP, we can not wait until the dialog
3064 is shown because it could take a lot of time and so the
3065 timeout could be called twice or more times */
3066 g_source_remove (helper->handler);
3068 gdk_threads_enter ();
3069 do_create_folder (helper->win, helper->folder, helper->name);
3070 gdk_threads_leave ();
3072 g_object_unref (helper->win);
3073 g_object_unref (helper->folder);
3074 g_free (helper->name);
3075 g_slice_free (CreateFolderHelper, helper);
3082 do_create_folder_cb (ModestMailOperation *mail_op,
3083 TnyFolderStore *parent_folder,
3084 TnyFolder *new_folder,
3087 gchar *suggested_name = (gchar *) user_data;
3088 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3090 if (modest_mail_operation_get_error (mail_op)) {
3092 /* Show an error. If there was some problem writing to
3093 disk, show it, otherwise show the generic folder
3094 create error. We do it here and not in an error
3095 handler because the call to do_create_folder will
3096 stop the main loop in a gtk_dialog_run and then,
3097 the message won't be shown until that dialog is
3099 modest_ui_actions_disk_operations_error_handler (mail_op,
3100 _("mail_in_ui_folder_create_error"));
3102 /* Try again. Do *NOT* show any error because the mail
3103 operations system will do it for us because we
3104 created the mail_op with new_with_error_handler */
3105 #ifndef MODEST_TOOLKIT_GTK
3106 CreateFolderHelper *helper;
3107 helper = g_slice_new0 (CreateFolderHelper);
3108 helper->name = g_strdup (suggested_name);
3109 helper->folder = g_object_ref (parent_folder);
3110 helper->win = g_object_ref (source_win);
3112 /* Ugly but neccesary stuff. The problem is that the
3113 dialog when is shown calls a function that destroys
3114 all the temporary windows, so the banner is
3116 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3118 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3121 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3122 * FIXME: any other? */
3123 GtkWidget *folder_view;
3125 if (MODEST_IS_MAIN_WINDOW(source_win))
3127 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3128 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3131 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3133 /* Select the newly created folder. It could happen
3134 that the widget is no longer there (i.e. the window
3135 has been destroyed, so we need to check this */
3137 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3139 g_object_unref (new_folder);
3141 /* Free. Note that the first time it'll be NULL so noop */
3142 g_free (suggested_name);
3143 g_object_unref (source_win);
3147 do_create_folder (GtkWindow *parent_window,
3148 TnyFolderStore *parent_folder,
3149 const gchar *suggested_name)
3152 gchar *folder_name = NULL;
3154 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3156 (gchar *) suggested_name,
3159 if (result == GTK_RESPONSE_ACCEPT) {
3160 ModestMailOperation *mail_op;
3162 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3163 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3165 modest_mail_operation_create_folder (mail_op,
3167 (const gchar *) folder_name,
3168 do_create_folder_cb,
3170 g_object_unref (mail_op);
3175 create_folder_performer (gboolean canceled,
3177 GtkWindow *parent_window,
3178 TnyAccount *account,
3181 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3183 if (canceled || err) {
3184 /* In memory full conditions we could get this error here */
3185 check_memory_full_error ((GtkWidget *) parent_window, err);
3189 /* Run the new folder dialog */
3190 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3193 g_object_unref (parent_folder);
3197 modest_ui_actions_create_folder(GtkWidget *parent_window,
3198 GtkWidget *folder_view)
3200 TnyFolderStore *parent_folder;
3202 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3204 if (parent_folder) {
3205 /* The parent folder will be freed in the callback */
3206 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3209 create_folder_performer,
3215 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3217 GtkWidget *folder_view;
3219 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3221 folder_view = modest_main_window_get_child_widget (main_window,
3222 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3226 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3230 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3233 const GError *error = NULL;
3234 const gchar *message = NULL;
3236 /* Get error message */
3237 error = modest_mail_operation_get_error (mail_op);
3239 g_return_if_reached ();
3241 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3242 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3243 message = _CS("ckdg_ib_folder_already_exists");
3244 } else if (error->domain == TNY_ERROR_DOMAIN &&
3245 error->code == TNY_SERVICE_ERROR_STATE) {
3246 /* This means that the folder is already in use (a
3247 message is opened for example */
3248 message = _("emev_ni_internal_error");
3250 message = _("emev_ib_ui_imap_unable_to_rename");
3253 /* We don't set a parent for the dialog because the dialog
3254 will be destroyed so the banner won't appear */
3255 modest_platform_information_banner (NULL, NULL, message);
3259 TnyFolderStore *folder;
3264 on_rename_folder_cb (ModestMailOperation *mail_op,
3265 TnyFolder *new_folder,
3268 ModestFolderView *folder_view;
3270 /* If the window was closed when renaming a folder this could
3272 if (!MODEST_IS_FOLDER_VIEW (user_data))
3275 folder_view = MODEST_FOLDER_VIEW (user_data);
3276 /* Note that if the rename fails new_folder will be NULL */
3278 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3280 modest_folder_view_select_first_inbox_or_local (folder_view);
3282 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3286 on_rename_folder_performer (gboolean canceled,
3288 GtkWindow *parent_window,
3289 TnyAccount *account,
3292 ModestMailOperation *mail_op = NULL;
3293 GtkTreeSelection *sel = NULL;
3294 GtkWidget *folder_view = NULL;
3295 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3297 if (canceled || err) {
3298 /* In memory full conditions we could get this error here */
3299 check_memory_full_error ((GtkWidget *) parent_window, err);
3300 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3302 folder_view = modest_main_window_get_child_widget (
3303 MODEST_MAIN_WINDOW (parent_window),
3304 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3307 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3308 modest_ui_actions_rename_folder_error_handler,
3309 parent_window, NULL);
3311 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3314 /* Clear the headers view */
3315 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3316 gtk_tree_selection_unselect_all (sel);
3318 /* Actually rename the folder */
3319 modest_mail_operation_rename_folder (mail_op,
3320 TNY_FOLDER (data->folder),
3321 (const gchar *) (data->new_name),
3322 on_rename_folder_cb,
3324 g_object_unref (data->folder);
3325 g_object_unref (mail_op);
3328 g_free (data->new_name);
3333 modest_ui_actions_on_rename_folder (GtkAction *action,
3334 ModestMainWindow *main_window)
3336 TnyFolderStore *folder;
3337 GtkWidget *folder_view;
3338 GtkWidget *header_view;
3340 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3342 folder_view = modest_main_window_get_child_widget (main_window,
3343 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3347 header_view = modest_main_window_get_child_widget (main_window,
3348 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3353 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3358 if (TNY_IS_FOLDER (folder)) {
3361 const gchar *current_name;
3362 TnyFolderStore *parent;
3363 gboolean do_rename = TRUE;
3365 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3366 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3367 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3368 parent, current_name,
3370 g_object_unref (parent);
3372 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3375 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3376 rename_folder_data->folder = g_object_ref (folder);
3377 rename_folder_data->new_name = folder_name;
3378 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3379 folder, on_rename_folder_performer, rename_folder_data);
3382 g_object_unref (folder);
3386 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3389 GObject *win = modest_mail_operation_get_source (mail_op);
3391 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3392 _("mail_in_ui_folder_delete_error"),
3394 g_object_unref (win);
3398 TnyFolderStore *folder;
3399 gboolean move_to_trash;
3403 on_delete_folder_cb (gboolean canceled,
3405 GtkWindow *parent_window,
3406 TnyAccount *account,
3409 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3410 GtkWidget *folder_view;
3411 ModestMailOperation *mail_op;
3412 GtkTreeSelection *sel;
3414 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3415 g_object_unref (G_OBJECT (info->folder));
3420 folder_view = modest_main_window_get_child_widget (
3421 MODEST_MAIN_WINDOW (parent_window),
3422 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3424 /* Unselect the folder before deleting it to free the headers */
3425 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3426 gtk_tree_selection_unselect_all (sel);
3428 /* Create the mail operation */
3430 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3431 modest_ui_actions_delete_folder_error_handler,
3434 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3436 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3438 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3440 g_object_unref (G_OBJECT (mail_op));
3441 g_object_unref (G_OBJECT (info->folder));
3446 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3448 TnyFolderStore *folder;
3449 GtkWidget *folder_view;
3453 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3455 folder_view = modest_main_window_get_child_widget (main_window,
3456 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3460 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3462 /* Show an error if it's an account */
3463 if (!TNY_IS_FOLDER (folder)) {
3464 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3465 _("mail_in_ui_folder_delete_error"),
3467 g_object_unref (G_OBJECT (folder));
3472 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3473 tny_folder_get_name (TNY_FOLDER (folder)));
3474 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3475 (const gchar *) message);
3478 if (response == GTK_RESPONSE_OK) {
3479 DeleteFolderInfo *info;
3480 info = g_new0(DeleteFolderInfo, 1);
3481 info->folder = folder;
3482 info->move_to_trash = move_to_trash;
3483 g_object_ref (G_OBJECT (info->folder));
3484 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3485 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3487 TNY_FOLDER_STORE (account),
3488 on_delete_folder_cb, info);
3489 g_object_unref (account);
3491 g_object_unref (G_OBJECT (folder));
3495 modest_ui_actions_on_delete_folder (GtkAction *action,
3496 ModestMainWindow *main_window)
3498 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3500 delete_folder (main_window, FALSE);
3504 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3506 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3508 delete_folder (main_window, TRUE);
3512 typedef struct _PasswordDialogFields {
3513 GtkWidget *username;
3514 GtkWidget *password;
3516 } PasswordDialogFields;
3519 password_dialog_check_field (GtkEditable *editable,
3520 PasswordDialogFields *fields)
3523 gboolean any_value_empty = FALSE;
3525 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3526 if ((value == NULL) || value[0] == '\0') {
3527 any_value_empty = TRUE;
3529 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3530 if ((value == NULL) || value[0] == '\0') {
3531 any_value_empty = TRUE;
3533 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3537 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3538 const gchar* server_account_name,
3543 ModestMainWindow *main_window)
3545 g_return_if_fail(server_account_name);
3546 gboolean completed = FALSE;
3547 PasswordDialogFields *fields = NULL;
3549 /* Initalize output parameters: */
3556 #ifndef MODEST_TOOLKIT_GTK
3557 /* Maemo uses a different (awkward) button order,
3558 * It should probably just use gtk_alternative_dialog_button_order ().
3560 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3563 _("mcen_bd_dialog_ok"),
3564 GTK_RESPONSE_ACCEPT,
3565 _("mcen_bd_dialog_cancel"),
3566 GTK_RESPONSE_REJECT,
3569 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3573 GTK_RESPONSE_REJECT,
3575 GTK_RESPONSE_ACCEPT,
3577 #endif /* !MODEST_TOOLKIT_GTK */
3579 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3581 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3582 modest_runtime_get_account_mgr(), server_account_name);
3583 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3584 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3590 /* This causes a warning because the logical ID has no %s in it,
3591 * though the translation does, but there is not much we can do about that: */
3592 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3593 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3596 g_free (server_name);
3600 gchar *initial_username = modest_account_mgr_get_server_account_username (
3601 modest_runtime_get_account_mgr(), server_account_name);
3603 GtkWidget *entry_username = gtk_entry_new ();
3604 if (initial_username)
3605 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3606 /* Dim this if a connection has ever succeeded with this username,
3607 * as per the UI spec: */
3608 /* const gboolean username_known = */
3609 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3610 /* modest_runtime_get_account_mgr(), server_account_name); */
3611 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3613 /* We drop the username sensitive code and disallow changing it here
3614 * as tinymail does not support really changing the username in the callback
3616 gtk_widget_set_sensitive (entry_username, FALSE);
3618 #ifndef MODEST_TOOLKIT_GTK
3619 /* Auto-capitalization is the default, so let's turn it off: */
3620 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3622 /* Create a size group to be used by all captions.
3623 * Note that HildonCaption does not create a default size group if we do not specify one.
3624 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3625 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3627 GtkWidget *caption = hildon_caption_new (sizegroup,
3628 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3629 gtk_widget_show (entry_username);
3630 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3631 FALSE, FALSE, MODEST_MARGIN_HALF);
3632 gtk_widget_show (caption);
3634 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3636 #endif /* !MODEST_TOOLKIT_GTK */
3639 GtkWidget *entry_password = gtk_entry_new ();
3640 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3641 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3643 #ifndef MODEST_TOOLKIT_GTK
3644 /* Auto-capitalization is the default, so let's turn it off: */
3645 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3646 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3648 caption = hildon_caption_new (sizegroup,
3649 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3650 gtk_widget_show (entry_password);
3651 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3652 FALSE, FALSE, MODEST_MARGIN_HALF);
3653 gtk_widget_show (caption);
3654 g_object_unref (sizegroup);
3656 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3658 #endif /* !MODEST_TOOLKIT_GTK */
3660 if (initial_username != NULL)
3661 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3663 /* This is not in the Maemo UI spec:
3664 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3665 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3669 fields = g_slice_new0 (PasswordDialogFields);
3670 fields->username = entry_username;
3671 fields->password = entry_password;
3672 fields->dialog = dialog;
3674 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3675 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3676 password_dialog_check_field (NULL, fields);
3678 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3680 while (!completed) {
3682 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3684 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3686 /* Note that an empty field becomes the "" string */
3687 if (*username && strlen (*username) > 0) {
3688 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3689 server_account_name,
3693 const gboolean username_was_changed =
3694 (strcmp (*username, initial_username) != 0);
3695 if (username_was_changed) {
3696 g_warning ("%s: tinymail does not yet support changing the "
3697 "username in the get_password() callback.\n", __FUNCTION__);
3701 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3702 _("mcen_ib_username_pw_incorrect"));
3708 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3710 /* We do not save the password in the configuration,
3711 * because this function is only called for passwords that should
3712 * not be remembered:
3713 modest_server_account_set_password (
3714 modest_runtime_get_account_mgr(), server_account_name,
3721 /* Set parent to NULL or the banner will disappear with its parent dialog */
3722 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3733 /* This is not in the Maemo UI spec:
3734 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3740 gtk_widget_destroy (dialog);
3741 g_slice_free (PasswordDialogFields, fields);
3743 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3747 modest_ui_actions_on_cut (GtkAction *action,
3748 ModestWindow *window)
3750 GtkWidget *focused_widget;
3751 GtkClipboard *clipboard;
3753 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3754 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3755 if (GTK_IS_EDITABLE (focused_widget)) {
3756 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3757 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3758 gtk_clipboard_store (clipboard);
3759 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3760 GtkTextBuffer *buffer;
3762 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3763 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3764 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3765 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3766 gtk_clipboard_store (clipboard);
3768 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3769 TnyList *header_list = modest_header_view_get_selected_headers (
3770 MODEST_HEADER_VIEW (focused_widget));
3771 gboolean continue_download = FALSE;
3772 gint num_of_unc_msgs;
3774 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3776 if (num_of_unc_msgs) {
3777 TnyAccount *account = get_account_from_header_list (header_list);
3779 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3780 g_object_unref (account);
3784 if (num_of_unc_msgs == 0 || continue_download) {
3785 /* modest_platform_information_banner (
3786 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3787 modest_header_view_cut_selection (
3788 MODEST_HEADER_VIEW (focused_widget));
3791 g_object_unref (header_list);
3792 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3793 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3798 modest_ui_actions_on_copy (GtkAction *action,
3799 ModestWindow *window)
3801 GtkClipboard *clipboard;
3802 GtkWidget *focused_widget;
3803 gboolean copied = TRUE;
3805 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3806 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3808 if (GTK_IS_LABEL (focused_widget)) {
3810 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3811 gtk_clipboard_set_text (clipboard, selection, -1);
3813 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3814 gtk_clipboard_store (clipboard);
3815 } else if (GTK_IS_EDITABLE (focused_widget)) {
3816 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3817 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3818 gtk_clipboard_store (clipboard);
3819 } else if (GTK_IS_HTML (focused_widget)) {
3822 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3823 if ((sel == NULL) || (sel[0] == '\0')) {
3826 gtk_html_copy (GTK_HTML (focused_widget));
3827 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3828 gtk_clipboard_store (clipboard);
3830 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3831 GtkTextBuffer *buffer;
3832 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3833 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3834 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3835 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3836 gtk_clipboard_store (clipboard);
3838 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3839 TnyList *header_list = modest_header_view_get_selected_headers (
3840 MODEST_HEADER_VIEW (focused_widget));
3841 gboolean continue_download = FALSE;
3842 gint num_of_unc_msgs;
3844 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3846 if (num_of_unc_msgs) {
3847 TnyAccount *account = get_account_from_header_list (header_list);
3849 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3850 g_object_unref (account);
3854 if (num_of_unc_msgs == 0 || continue_download) {
3855 modest_platform_information_banner (
3856 NULL, NULL, _CS("mcen_ib_getting_items"));
3857 modest_header_view_copy_selection (
3858 MODEST_HEADER_VIEW (focused_widget));
3862 g_object_unref (header_list);
3864 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3865 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3868 /* Show information banner if there was a copy to clipboard */
3870 modest_platform_information_banner (
3871 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3875 modest_ui_actions_on_undo (GtkAction *action,
3876 ModestWindow *window)
3878 ModestEmailClipboard *clipboard = NULL;
3880 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3881 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3882 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3883 /* Clear clipboard source */
3884 clipboard = modest_runtime_get_email_clipboard ();
3885 modest_email_clipboard_clear (clipboard);
3888 g_return_if_reached ();
3893 modest_ui_actions_on_redo (GtkAction *action,
3894 ModestWindow *window)
3896 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3897 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3900 g_return_if_reached ();
3906 destroy_information_note (ModestMailOperation *mail_op,
3909 /* destroy information note */
3910 gtk_widget_destroy (GTK_WIDGET(user_data));
3914 destroy_folder_information_note (ModestMailOperation *mail_op,
3915 TnyFolder *new_folder,
3918 /* destroy information note */
3919 gtk_widget_destroy (GTK_WIDGET(user_data));
3924 paste_as_attachment_free (gpointer data)
3926 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3928 if (helper->banner) {
3929 gtk_widget_destroy (helper->banner);
3930 g_object_unref (helper->banner);
3936 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3941 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3942 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3947 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3952 modest_ui_actions_on_paste (GtkAction *action,
3953 ModestWindow *window)
3955 GtkWidget *focused_widget = NULL;
3956 GtkWidget *inf_note = NULL;
3957 ModestMailOperation *mail_op = NULL;
3959 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3960 if (GTK_IS_EDITABLE (focused_widget)) {
3961 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3962 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3963 ModestEmailClipboard *e_clipboard = NULL;
3964 e_clipboard = modest_runtime_get_email_clipboard ();
3965 if (modest_email_clipboard_cleared (e_clipboard)) {
3966 GtkTextBuffer *buffer;
3967 GtkClipboard *clipboard;
3969 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3970 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3971 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3972 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3973 ModestMailOperation *mail_op;
3974 TnyFolder *src_folder;
3977 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3978 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3979 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3980 _CS("ckct_nw_pasting"));
3981 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3982 mail_op = modest_mail_operation_new (G_OBJECT (window));
3983 if (helper->banner != NULL) {
3984 g_object_ref (G_OBJECT (helper->banner));
3985 gtk_widget_show (GTK_WIDGET (helper->banner));
3989 modest_mail_operation_get_msgs_full (mail_op,
3991 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3993 paste_as_attachment_free);
3996 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3997 ModestEmailClipboard *clipboard = NULL;
3998 TnyFolder *src_folder = NULL;
3999 TnyFolderStore *folder_store = NULL;
4000 TnyList *data = NULL;
4001 gboolean delete = FALSE;
4003 /* Check clipboard source */
4004 clipboard = modest_runtime_get_email_clipboard ();
4005 if (modest_email_clipboard_cleared (clipboard))
4008 /* Get elements to paste */
4009 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4011 /* Create a new mail operation */
4012 mail_op = modest_mail_operation_new (G_OBJECT(window));
4014 /* Get destination folder */
4015 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4017 /* transfer messages */
4021 /* Ask for user confirmation */
4023 modest_ui_actions_msgs_move_to_confirmation (window,
4024 TNY_FOLDER (folder_store),
4028 if (response == GTK_RESPONSE_OK) {
4029 /* Launch notification */
4030 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4031 _CS("ckct_nw_pasting"));
4032 if (inf_note != NULL) {
4033 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4034 gtk_widget_show (GTK_WIDGET(inf_note));
4037 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4038 modest_mail_operation_xfer_msgs (mail_op,
4040 TNY_FOLDER (folder_store),
4042 destroy_information_note,
4045 g_object_unref (mail_op);
4048 } else if (src_folder != NULL) {
4049 /* Launch notification */
4050 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4051 _CS("ckct_nw_pasting"));
4052 if (inf_note != NULL) {
4053 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4054 gtk_widget_show (GTK_WIDGET(inf_note));
4057 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4058 modest_mail_operation_xfer_folder (mail_op,
4062 destroy_folder_information_note,
4068 g_object_unref (data);
4069 if (src_folder != NULL)
4070 g_object_unref (src_folder);
4071 if (folder_store != NULL)
4072 g_object_unref (folder_store);
4078 modest_ui_actions_on_select_all (GtkAction *action,
4079 ModestWindow *window)
4081 GtkWidget *focused_widget;
4083 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4084 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4085 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4086 } else if (GTK_IS_LABEL (focused_widget)) {
4087 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4088 } else if (GTK_IS_EDITABLE (focused_widget)) {
4089 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4090 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4091 GtkTextBuffer *buffer;
4092 GtkTextIter start, end;
4094 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4095 gtk_text_buffer_get_start_iter (buffer, &start);
4096 gtk_text_buffer_get_end_iter (buffer, &end);
4097 gtk_text_buffer_select_range (buffer, &start, &end);
4098 } else if (GTK_IS_HTML (focused_widget)) {
4099 gtk_html_select_all (GTK_HTML (focused_widget));
4100 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4101 GtkWidget *header_view = focused_widget;
4102 GtkTreeSelection *selection = NULL;
4104 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4105 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4106 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4109 /* Disable window dimming management */
4110 modest_window_disable_dimming (MODEST_WINDOW(window));
4112 /* Select all messages */
4113 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4114 gtk_tree_selection_select_all (selection);
4116 /* Set focuse on header view */
4117 gtk_widget_grab_focus (header_view);
4119 /* Enable window dimming management */
4120 modest_window_enable_dimming (MODEST_WINDOW(window));
4121 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4122 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4128 modest_ui_actions_on_mark_as_read (GtkAction *action,
4129 ModestWindow *window)
4131 g_return_if_fail (MODEST_IS_WINDOW(window));
4133 /* Mark each header as read */
4134 do_headers_action (window, headers_action_mark_as_read, NULL);
4138 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4139 ModestWindow *window)
4141 g_return_if_fail (MODEST_IS_WINDOW(window));
4143 /* Mark each header as read */
4144 do_headers_action (window, headers_action_mark_as_unread, NULL);
4148 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4149 GtkRadioAction *selected,
4150 ModestWindow *window)
4154 value = gtk_radio_action_get_current_value (selected);
4155 if (MODEST_IS_WINDOW (window)) {
4156 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4161 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4162 GtkRadioAction *selected,
4163 ModestWindow *window)
4165 TnyHeaderFlags flags;
4166 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4168 flags = gtk_radio_action_get_current_value (selected);
4169 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4173 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4174 GtkRadioAction *selected,
4175 ModestWindow *window)
4179 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4181 file_format = gtk_radio_action_get_current_value (selected);
4182 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4187 modest_ui_actions_on_zoom_plus (GtkAction *action,
4188 ModestWindow *window)
4190 g_return_if_fail (MODEST_IS_WINDOW (window));
4192 modest_window_zoom_plus (MODEST_WINDOW (window));
4196 modest_ui_actions_on_zoom_minus (GtkAction *action,
4197 ModestWindow *window)
4199 g_return_if_fail (MODEST_IS_WINDOW (window));
4201 modest_window_zoom_minus (MODEST_WINDOW (window));
4205 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4206 ModestWindow *window)
4208 ModestWindowMgr *mgr;
4209 gboolean fullscreen, active;
4210 g_return_if_fail (MODEST_IS_WINDOW (window));
4212 mgr = modest_runtime_get_window_mgr ();
4214 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4215 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4217 if (active != fullscreen) {
4218 modest_window_mgr_set_fullscreen_mode (mgr, active);
4219 #ifndef MODEST_TOOLKIT_HILDON2
4220 gtk_window_present (GTK_WINDOW (window));
4226 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4227 ModestWindow *window)
4229 ModestWindowMgr *mgr;
4230 gboolean fullscreen;
4232 g_return_if_fail (MODEST_IS_WINDOW (window));
4234 mgr = modest_runtime_get_window_mgr ();
4235 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4236 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4238 #ifndef MODEST_TOOLKIT_HILDON2
4239 gtk_window_present (GTK_WINDOW (window));
4244 * Used by modest_ui_actions_on_details to call do_headers_action
4247 headers_action_show_details (TnyHeader *header,
4248 ModestWindow *window,
4255 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
4258 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) window);
4259 gtk_widget_show_all (dialog);
4261 g_signal_connect_swapped (dialog, "response",
4262 G_CALLBACK (gtk_widget_destroy),
4267 * Show the folder details in a ModestDetailsDialog widget
4270 show_folder_details (TnyFolder *folder,
4276 dialog = modest_details_dialog_new_with_folder (window, folder);
4279 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4280 gtk_widget_show_all (dialog);
4281 gtk_dialog_run (GTK_DIALOG (dialog));
4283 gtk_widget_destroy (dialog);
4287 * Show the header details in a ModestDetailsDialog widget
4290 modest_ui_actions_on_details (GtkAction *action,
4293 TnyList * headers_list;
4297 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4300 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4303 g_object_unref (msg);
4305 headers_list = get_selected_headers (win);
4309 iter = tny_list_create_iterator (headers_list);
4311 header = TNY_HEADER (tny_iterator_get_current (iter));
4313 headers_action_show_details (header, win, NULL);
4314 g_object_unref (header);
4317 g_object_unref (iter);
4318 g_object_unref (headers_list);
4320 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4321 GtkWidget *folder_view, *header_view;
4323 /* Check which widget has the focus */
4324 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4325 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4326 if (gtk_widget_is_focus (folder_view)) {
4327 TnyFolderStore *folder_store
4328 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4329 if (!folder_store) {
4330 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4333 /* Show only when it's a folder */
4334 /* This function should not be called for account items,
4335 * because we dim the menu item for them. */
4336 if (TNY_IS_FOLDER (folder_store)) {
4337 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
4340 g_object_unref (folder_store);
4343 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4344 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4345 /* Show details of each header */
4346 do_headers_action (win, headers_action_show_details, header_view);
4352 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4353 ModestMsgEditWindow *window)
4355 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4357 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4361 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4362 ModestMsgEditWindow *window)
4364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4366 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4370 modest_ui_actions_toggle_folders_view (GtkAction *action,
4371 ModestMainWindow *main_window)
4373 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4375 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4376 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4378 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4382 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4383 ModestWindow *window)
4385 gboolean active, fullscreen = FALSE;
4386 ModestWindowMgr *mgr;
4388 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4390 /* Check if we want to toggle the toolbar vuew in fullscreen
4392 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4393 "ViewShowToolbarFullScreen")) {
4397 /* Toggle toolbar */
4398 mgr = modest_runtime_get_window_mgr ();
4399 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4403 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4404 ModestMsgEditWindow *window)
4406 modest_msg_edit_window_select_font (window);
4411 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4412 const gchar *display_name,
4415 /* don't update the display name if it was already set;
4416 * updating the display name apparently is expensive */
4417 const gchar* old_name = gtk_window_get_title (window);
4419 if (display_name == NULL)
4422 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4423 return; /* don't do anything */
4425 /* This is usually used to change the title of the main window, which
4426 * is the one that holds the folder view. Note that this change can
4427 * happen even when the widget doesn't have the focus. */
4428 gtk_window_set_title (window, display_name);
4433 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4435 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4436 modest_msg_edit_window_select_contacts (window);
4440 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4442 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4443 modest_msg_edit_window_check_names (window, FALSE);
4447 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4449 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4450 GTK_WIDGET (user_data));
4454 * This function is used to track changes in the selection of the
4455 * folder view that is inside the "move to" dialog to enable/disable
4456 * the OK button because we do not want the user to select a disallowed
4457 * destination for a folder.
4458 * The user also not desired to be able to use NEW button on items where
4459 * folder creation is not possibel.
4462 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4463 TnyFolderStore *folder_store,
4467 GtkWidget *dialog = NULL;
4468 GtkWidget *ok_button = NULL, *new_button = NULL;
4469 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4470 gboolean moving_folder = FALSE;
4471 gboolean is_local_account = TRUE;
4472 GtkWidget *folder_view = NULL;
4473 ModestTnyFolderRules rules;
4475 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4480 /* Get the OK button */
4481 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4485 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4486 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4488 /* check if folder_store is an remote account */
4489 if (TNY_IS_ACCOUNT (folder_store)) {
4490 TnyAccount *local_account = NULL;
4491 TnyAccount *mmc_account = NULL;
4492 ModestTnyAccountStore *account_store = NULL;
4494 account_store = modest_runtime_get_account_store ();
4495 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4496 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4498 if ((gpointer) local_account != (gpointer) folder_store &&
4499 (gpointer) mmc_account != (gpointer) folder_store) {
4500 ModestProtocolType proto;
4501 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4502 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4503 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4505 is_local_account = FALSE;
4506 /* New button should be dimmed on remote
4508 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4510 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4512 g_object_unref (local_account);
4513 g_object_unref (mmc_account);
4516 /* Check the target folder rules */
4517 if (TNY_IS_FOLDER (folder_store)) {
4518 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4519 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4520 ok_sensitive = FALSE;
4521 new_sensitive = FALSE;
4526 /* Check if we're moving a folder */
4527 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4528 /* Get the widgets */
4529 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4530 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4531 if (gtk_widget_is_focus (folder_view))
4532 moving_folder = TRUE;
4535 if (moving_folder) {
4536 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4538 /* Get the folder to move */
4539 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4541 /* Check that we're not moving to the same folder */
4542 if (TNY_IS_FOLDER (moved_folder)) {
4543 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4544 if (parent == folder_store)
4545 ok_sensitive = FALSE;
4546 g_object_unref (parent);
4549 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4550 /* Do not allow to move to an account unless it's the
4551 local folders account */
4552 if (!is_local_account)
4553 ok_sensitive = FALSE;
4556 if (ok_sensitive && (moved_folder == folder_store)) {
4557 /* Do not allow to move to itself */
4558 ok_sensitive = FALSE;
4560 g_object_unref (moved_folder);
4562 TnyFolder *src_folder = NULL;
4564 /* Moving a message */
4565 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4567 TnyHeader *header = NULL;
4568 header = modest_msg_view_window_get_header
4569 (MODEST_MSG_VIEW_WINDOW (user_data));
4570 if (!TNY_IS_HEADER(header))
4571 g_warning ("%s: could not get source header", __FUNCTION__);
4573 src_folder = tny_header_get_folder (header);
4576 g_object_unref (header);
4579 TNY_FOLDER (modest_folder_view_get_selected
4580 (MODEST_FOLDER_VIEW (folder_view)));
4583 if (TNY_IS_FOLDER(src_folder)) {
4584 /* Do not allow to move the msg to the same folder */
4585 /* Do not allow to move the msg to an account */
4586 if ((gpointer) src_folder == (gpointer) folder_store ||
4587 TNY_IS_ACCOUNT (folder_store))
4588 ok_sensitive = FALSE;
4589 g_object_unref (src_folder);
4591 g_warning ("%s: could not get source folder", __FUNCTION__);
4595 /* Set sensitivity of the OK button */
4596 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4597 /* Set sensitivity of the NEW button */
4598 gtk_widget_set_sensitive (new_button, new_sensitive);
4602 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4605 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4607 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4608 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4612 create_move_to_dialog (GtkWindow *win,
4613 GtkWidget *folder_view,
4614 GtkWidget **tree_view)
4616 GtkWidget *dialog, *scroll;
4617 GtkWidget *new_button, *ok_button;
4619 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4621 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4624 #ifndef MODEST_TOOLKIT_GTK
4625 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4626 /* We do this manually so GTK+ does not associate a response ID for
4628 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4629 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4630 gtk_widget_show (new_button);
4631 #ifndef MODEST_TOOLKIT_HILDON2
4632 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4635 /* We do this manually so GTK+ does not associate a response ID for
4637 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4638 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4639 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4640 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4641 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4642 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4643 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4645 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4646 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4648 /* Create scrolled window */
4649 scroll = gtk_scrolled_window_new (NULL, NULL);
4650 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4651 GTK_POLICY_AUTOMATIC,
4652 GTK_POLICY_AUTOMATIC);
4654 #ifdef MODEST_TOOLKIT_GTK
4655 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4658 /* Create folder view */
4659 *tree_view = modest_platform_create_folder_view (NULL);
4661 /* Track changes in the selection to
4662 * disable the OK button whenever "Move to" is not possible
4663 * disbale NEW button whenever New is not possible */
4664 g_signal_connect (*tree_view,
4665 "folder_selection_changed",
4666 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4669 /* Listen to clicks on New button */
4670 g_signal_connect (G_OBJECT (new_button),
4672 G_CALLBACK(create_move_to_dialog_on_new_folder),
4675 /* It could happen that we're trying to move a message from a
4676 window (msg window for example) after the main window was
4677 closed, so we can not just get the model of the folder
4679 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4680 const gchar *visible_id = NULL;
4682 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4683 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4684 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4685 MODEST_FOLDER_VIEW(*tree_view));
4688 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4690 /* Show the same account than the one that is shown in the main window */
4691 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4694 const gchar *active_account_name = NULL;
4695 ModestAccountMgr *mgr = NULL;
4696 ModestAccountSettings *settings = NULL;
4697 ModestServerAccountSettings *store_settings = NULL;
4699 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4700 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4701 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4702 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4704 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4705 mgr = modest_runtime_get_account_mgr ();
4706 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4709 const gchar *store_account_name;
4710 store_settings = modest_account_settings_get_store_settings (settings);
4711 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4713 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4714 store_account_name);
4715 g_object_unref (store_settings);
4716 g_object_unref (settings);
4720 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4721 * get_folder_view_from_move_to_dialog
4722 * (see above) later (needed for focus handling)
4724 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4727 /* Hide special folders */
4728 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4730 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4732 /* Add scroll to dialog */
4733 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4734 scroll, TRUE, TRUE, 0);
4736 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4737 #ifndef MODEST_TOOLKIT_GTK
4738 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4740 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4749 * Shows a confirmation dialog to the user when we're moving messages
4750 * from a remote server to the local storage. Returns the dialog
4751 * response. If it's other kind of movement then it always returns
4754 * This one is used by the next functions:
4755 * modest_ui_actions_on_paste - commented out
4756 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4759 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4760 TnyFolder *dest_folder,
4764 gint response = GTK_RESPONSE_OK;
4765 TnyAccount *account = NULL;
4766 TnyFolder *src_folder = NULL;
4767 TnyIterator *iter = NULL;
4768 TnyHeader *header = NULL;
4770 /* return with OK if the destination is a remote folder */
4771 if (modest_tny_folder_is_remote_folder (dest_folder))
4772 return GTK_RESPONSE_OK;
4774 /* Get source folder */
4775 iter = tny_list_create_iterator (headers);
4776 header = TNY_HEADER (tny_iterator_get_current (iter));
4778 src_folder = tny_header_get_folder (header);
4779 g_object_unref (header);
4781 g_object_unref (iter);
4783 /* if no src_folder, message may be an attahcment */
4784 if (src_folder == NULL)
4785 return GTK_RESPONSE_CANCEL;
4787 /* If the source is a local or MMC folder */
4788 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4789 g_object_unref (src_folder);
4790 return GTK_RESPONSE_OK;
4793 /* Get the account */
4794 account = tny_folder_get_account (src_folder);
4796 /* now if offline we ask the user */
4797 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4798 response = GTK_RESPONSE_OK;
4800 response = GTK_RESPONSE_CANCEL;
4803 g_object_unref (src_folder);
4804 g_object_unref (account);
4810 move_to_helper_destroyer (gpointer user_data)
4812 MoveToHelper *helper = (MoveToHelper *) user_data;
4814 /* Close the "Pasting" information banner */
4815 if (helper->banner) {
4816 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4817 g_object_unref (helper->banner);
4819 if (helper->reference != NULL)
4820 gtk_tree_row_reference_free (helper->reference);
4825 move_to_cb (ModestMailOperation *mail_op,
4828 MoveToHelper *helper = (MoveToHelper *) user_data;
4830 /* Note that the operation could have failed, in that case do
4832 if (modest_mail_operation_get_status (mail_op) ==
4833 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4835 GObject *object = modest_mail_operation_get_source (mail_op);
4836 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4837 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4839 if (!modest_msg_view_window_select_next_message (self) &&
4840 !modest_msg_view_window_select_previous_message (self)) {
4841 /* No more messages to view, so close this window */
4842 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4844 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4845 GtkWidget *header_view;
4847 GtkTreeSelection *sel;
4849 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4850 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4851 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4852 path = gtk_tree_row_reference_get_path (helper->reference);
4853 /* We need to unselect the previous one
4854 because we could be copying instead of
4856 gtk_tree_selection_unselect_all (sel);
4857 gtk_tree_selection_select_path (sel, path);
4858 gtk_tree_path_free (path);
4860 g_object_unref (object);
4862 /* Destroy the helper */
4863 move_to_helper_destroyer (helper);
4867 folder_move_to_cb (ModestMailOperation *mail_op,
4868 TnyFolder *new_folder,
4871 GtkWidget *folder_view;
4874 object = modest_mail_operation_get_source (mail_op);
4875 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4876 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4877 g_object_ref (folder_view);
4878 g_object_unref (object);
4879 move_to_cb (mail_op, user_data);
4880 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4881 g_object_unref (folder_view);
4885 msgs_move_to_cb (ModestMailOperation *mail_op,
4888 move_to_cb (mail_op, user_data);
4892 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4895 ModestWindow *main_window = NULL;
4897 /* Disable next automatic folder selection */
4898 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4899 FALSE); /* don't create */
4901 GObject *win = NULL;
4902 GtkWidget *folder_view = NULL;
4904 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4905 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4906 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4908 if (user_data && TNY_IS_FOLDER (user_data)) {
4909 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4910 TNY_FOLDER (user_data), FALSE);
4913 /* Show notification dialog only if the main window exists */
4914 win = modest_mail_operation_get_source (mail_op);
4915 modest_platform_run_information_dialog ((GtkWindow *) win,
4916 _("mail_in_ui_folder_move_target_error"),
4919 g_object_unref (win);
4924 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4933 gint pending_purges = 0;
4934 gboolean some_purged = FALSE;
4935 ModestWindow *win = MODEST_WINDOW (user_data);
4936 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4938 /* If there was any error */
4939 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4940 modest_window_mgr_unregister_header (mgr, header);
4944 /* Once the message has been retrieved for purging, we check if
4945 * it's all ok for purging */
4947 parts = tny_simple_list_new ();
4948 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4949 iter = tny_list_create_iterator (parts);
4951 while (!tny_iterator_is_done (iter)) {
4953 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4954 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4955 if (tny_mime_part_is_purged (part))
4962 g_object_unref (part);
4964 tny_iterator_next (iter);
4966 g_object_unref (iter);
4969 if (pending_purges>0) {
4971 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4973 if (response == GTK_RESPONSE_OK) {
4976 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_ib_removing_attachment"));
4977 iter = tny_list_create_iterator (parts);
4978 while (!tny_iterator_is_done (iter)) {
4981 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4982 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4983 tny_mime_part_set_purged (part);
4986 g_object_unref (part);
4988 tny_iterator_next (iter);
4990 g_object_unref (iter);
4992 tny_msg_rewrite_cache (msg);
4994 gtk_widget_destroy (info);
4998 modest_window_mgr_unregister_header (mgr, header);
5000 g_object_unref (parts);
5004 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5005 ModestMainWindow *win)
5007 GtkWidget *header_view;
5008 TnyList *header_list;
5010 TnyHeaderFlags flags;
5011 ModestWindow *msg_view_window = NULL;
5014 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5016 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5017 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5019 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5021 g_warning ("%s: no header selected", __FUNCTION__);
5025 if (tny_list_get_length (header_list) == 1) {
5026 TnyIterator *iter = tny_list_create_iterator (header_list);
5027 header = TNY_HEADER (tny_iterator_get_current (iter));
5028 g_object_unref (iter);
5032 if (!header || !TNY_IS_HEADER(header)) {
5033 g_warning ("%s: header is not valid", __FUNCTION__);
5037 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5038 header, &msg_view_window);
5039 flags = tny_header_get_flags (header);
5040 if (!(flags & TNY_HEADER_FLAG_CACHED))
5043 if (msg_view_window != NULL)
5044 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5046 /* do nothing; uid was registered before, so window is probably on it's way */
5047 g_warning ("debug: header %p has already been registered", header);
5050 ModestMailOperation *mail_op = NULL;
5051 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5052 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5053 modest_ui_actions_disk_operations_error_handler,
5055 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5056 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5058 g_object_unref (mail_op);
5061 g_object_unref (header);
5063 g_object_unref (header_list);
5067 * Checks if we need a connection to do the transfer and if the user
5068 * wants to connect to complete it
5071 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5072 TnyFolderStore *src_folder,
5074 TnyFolder *dst_folder,
5075 gboolean delete_originals,
5076 gboolean *need_connection,
5079 TnyAccount *src_account;
5080 gint uncached_msgs = 0;
5082 uncached_msgs = header_list_count_uncached_msgs (headers);
5084 /* We don't need any further check if
5086 * 1- the source folder is local OR
5087 * 2- the device is already online
5089 if (!modest_tny_folder_store_is_remote (src_folder) ||
5090 tny_device_is_online (modest_runtime_get_device())) {
5091 *need_connection = FALSE;
5096 /* We must ask for a connection when
5098 * - the message(s) is not already cached OR
5099 * - the message(s) is cached but the leave_on_server setting
5100 * is FALSE (because we need to sync the source folder to
5101 * delete the message from the server (for IMAP we could do it
5102 * offline, it'll take place the next time we get a
5105 src_account = get_account_from_folder_store (src_folder);
5106 if (uncached_msgs > 0) {
5110 *need_connection = TRUE;
5111 num_headers = tny_list_get_length (headers);
5112 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5114 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5115 GTK_RESPONSE_CANCEL) {
5121 /* The transfer is possible and the user wants to */
5124 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5125 const gchar *account_name;
5126 gboolean leave_on_server;
5128 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5129 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5132 if (leave_on_server == TRUE) {
5133 *need_connection = FALSE;
5135 *need_connection = TRUE;
5138 *need_connection = FALSE;
5143 g_object_unref (src_account);
5147 xfer_messages_error_handler (ModestMailOperation *mail_op,
5150 ModestWindow *main_window = NULL;
5152 /* Disable next automatic folder selection */
5153 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5154 FALSE); /* don't create */
5156 GObject *win = modest_mail_operation_get_source (mail_op);
5157 modest_platform_run_information_dialog ((GtkWindow *) win,
5158 _("mail_in_ui_folder_move_target_error"),
5161 g_object_unref (win);
5163 move_to_helper_destroyer (user_data);
5167 TnyFolderStore *dst_folder;
5172 * Utility function that transfer messages from both the main window
5173 * and the msg view window when using the "Move to" dialog
5176 xfer_messages_performer (gboolean canceled,
5178 GtkWindow *parent_window,
5179 TnyAccount *account,
5182 ModestWindow *win = MODEST_WINDOW (parent_window);
5183 TnyAccount *dst_account = NULL;
5184 gboolean dst_forbids_message_add = FALSE;
5185 XferMsgsHelper *helper;
5186 MoveToHelper *movehelper;
5187 ModestMailOperation *mail_op;
5189 helper = (XferMsgsHelper *) user_data;
5191 if (canceled || err) {
5192 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5193 /* Show the proper error message */
5194 modest_ui_actions_on_account_connection_error (parent_window, account);
5199 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5201 /* tinymail will return NULL for local folders it seems */
5202 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5203 modest_tny_account_get_protocol_type (dst_account),
5204 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5205 g_object_unref (dst_account);
5207 if (dst_forbids_message_add) {
5208 modest_platform_information_banner (GTK_WIDGET (win),
5210 ngettext("mail_in_ui_folder_move_target_error",
5211 "mail_in_ui_folder_move_targets_error",
5212 tny_list_get_length (helper->headers)));
5216 movehelper = g_new0 (MoveToHelper, 1);
5217 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5218 _CS("ckct_nw_pasting"));
5219 if (movehelper->banner != NULL) {
5220 g_object_ref (movehelper->banner);
5221 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5224 if (MODEST_IS_MAIN_WINDOW (win)) {
5225 GtkWidget *header_view =
5226 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5227 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5228 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5231 /* Perform the mail operation */
5232 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5233 xfer_messages_error_handler,
5235 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5238 modest_mail_operation_xfer_msgs (mail_op,
5240 TNY_FOLDER (helper->dst_folder),
5245 g_object_unref (G_OBJECT (mail_op));
5247 g_object_unref (helper->dst_folder);
5248 g_object_unref (helper->headers);
5249 g_slice_free (XferMsgsHelper, helper);
5253 TnyFolder *src_folder;
5254 TnyFolderStore *dst_folder;
5255 gboolean delete_original;
5256 GtkWidget *folder_view;
5260 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5261 TnyAccount *account, gpointer user_data)
5263 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5264 GtkTreeSelection *sel;
5265 ModestMailOperation *mail_op = NULL;
5267 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5268 g_object_unref (G_OBJECT (info->src_folder));
5269 g_object_unref (G_OBJECT (info->dst_folder));
5274 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5275 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5276 _CS("ckct_nw_pasting"));
5277 if (helper->banner != NULL) {
5278 g_object_ref (helper->banner);
5279 gtk_widget_show (GTK_WIDGET(helper->banner));
5281 /* Clean folder on header view before moving it */
5282 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5283 gtk_tree_selection_unselect_all (sel);
5285 /* Let gtk events run. We need that the folder
5286 view frees its reference to the source
5287 folder *before* issuing the mail operation
5288 so we need the signal handler of selection
5289 changed to happen before the mail
5291 while (gtk_events_pending ())
5292 gtk_main_iteration (); */
5295 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5296 modest_ui_actions_move_folder_error_handler,
5297 info->src_folder, NULL);
5298 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5301 /* Select *after* the changes */
5302 /* TODO: this function hangs UI after transfer */
5303 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5304 /* TNY_FOLDER (src_folder), TRUE); */
5306 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5307 TNY_FOLDER (info->dst_folder), TRUE);
5308 modest_mail_operation_xfer_folder (mail_op,
5309 TNY_FOLDER (info->src_folder),
5311 info->delete_original,
5314 g_object_unref (G_OBJECT (info->src_folder));
5316 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5319 /* Unref mail operation */
5320 g_object_unref (G_OBJECT (mail_op));
5321 g_object_unref (G_OBJECT (info->dst_folder));
5326 get_account_from_folder_store (TnyFolderStore *folder_store)
5328 if (TNY_IS_ACCOUNT (folder_store))
5329 return g_object_ref (folder_store);
5331 return tny_folder_get_account (TNY_FOLDER (folder_store));
5335 * UI handler for the "Move to" action when invoked from the
5339 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5340 GtkWidget *folder_view,
5341 TnyFolderStore *dst_folder,
5342 ModestMainWindow *win)
5344 ModestHeaderView *header_view = NULL;
5345 TnyFolderStore *src_folder = NULL;
5347 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5349 /* Get the source folder */
5350 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5352 /* Get header view */
5353 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5355 /* Get folder or messages to transfer */
5356 if (gtk_widget_is_focus (folder_view)) {
5357 gboolean do_xfer = TRUE;
5359 /* Allow only to transfer folders to the local root folder */
5360 if (TNY_IS_ACCOUNT (dst_folder) &&
5361 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5362 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5364 } else if (!TNY_IS_FOLDER (src_folder)) {
5365 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5370 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5371 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5373 info->src_folder = g_object_ref (src_folder);
5374 info->dst_folder = g_object_ref (dst_folder);
5375 info->delete_original = TRUE;
5376 info->folder_view = folder_view;
5378 connect_info->callback = on_move_folder_cb;
5379 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5380 connect_info->data = info;
5382 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5383 TNY_FOLDER_STORE (src_folder),
5386 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5389 headers = modest_header_view_get_selected_headers(header_view);
5391 /* Transfer the messages */
5392 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5393 headers, TNY_FOLDER (dst_folder));
5395 g_object_unref (headers);
5399 g_object_unref (src_folder);
5404 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5405 TnyFolder *src_folder,
5407 TnyFolder *dst_folder)
5409 gboolean need_connection = TRUE;
5410 gboolean do_xfer = TRUE;
5411 XferMsgsHelper *helper;
5413 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5414 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5415 g_return_if_fail (TNY_IS_LIST (headers));
5417 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5418 headers, TNY_FOLDER (dst_folder),
5419 TRUE, &need_connection,
5422 /* If we don't want to transfer just return */
5426 /* Create the helper */
5427 helper = g_slice_new (XferMsgsHelper);
5428 helper->dst_folder = g_object_ref (dst_folder);
5429 helper->headers = g_object_ref (headers);
5431 if (need_connection) {
5432 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5433 connect_info->callback = xfer_messages_performer;
5434 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5435 connect_info->data = helper;
5437 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5438 TNY_FOLDER_STORE (src_folder),
5441 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5442 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5443 src_account, helper);
5444 g_object_unref (src_account);
5449 * UI handler for the "Move to" action when invoked from the
5450 * ModestMsgViewWindow
5453 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5454 TnyFolderStore *dst_folder,
5455 ModestMsgViewWindow *win)
5457 TnyList *headers = NULL;
5458 TnyHeader *header = NULL;
5459 TnyFolder *src_folder = NULL;
5461 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5463 /* Create header list */
5464 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5465 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5466 headers = tny_simple_list_new ();
5467 tny_list_append (headers, G_OBJECT (header));
5469 /* Transfer the messages */
5470 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5471 TNY_FOLDER (dst_folder));
5474 g_object_unref (src_folder);
5475 g_object_unref (header);
5476 g_object_unref (headers);
5480 modest_ui_actions_on_move_to (GtkAction *action,
5483 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5485 TnyFolderStore *dst_folder = NULL;
5486 ModestMainWindow *main_window;
5488 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5489 MODEST_IS_MSG_VIEW_WINDOW (win));
5491 /* Get the main window if exists */
5492 if (MODEST_IS_MAIN_WINDOW (win))
5493 main_window = MODEST_MAIN_WINDOW (win);
5496 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5497 FALSE)); /* don't create */
5499 /* Get the folder view widget if exists */
5501 folder_view = modest_main_window_get_child_widget (main_window,
5502 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5506 /* Create and run the dialog */
5507 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5508 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5509 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5510 result = gtk_dialog_run (GTK_DIALOG(dialog));
5511 g_object_ref (tree_view);
5512 gtk_widget_destroy (dialog);
5514 if (result != GTK_RESPONSE_ACCEPT)
5517 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5518 /* Do window specific stuff */
5519 if (MODEST_IS_MAIN_WINDOW (win)) {
5520 modest_ui_actions_on_main_window_move_to (action,
5523 MODEST_MAIN_WINDOW (win));
5525 modest_ui_actions_on_msg_view_window_move_to (action,
5527 MODEST_MSG_VIEW_WINDOW (win));
5531 g_object_unref (dst_folder);
5535 * Calls #HeadersFunc for each header already selected in the main
5536 * window or the message currently being shown in the msg view window
5539 do_headers_action (ModestWindow *win,
5543 TnyList *headers_list = NULL;
5544 TnyIterator *iter = NULL;
5545 TnyHeader *header = NULL;
5546 TnyFolder *folder = NULL;
5549 headers_list = get_selected_headers (win);
5553 /* Get the folder */
5554 iter = tny_list_create_iterator (headers_list);
5555 header = TNY_HEADER (tny_iterator_get_current (iter));
5557 folder = tny_header_get_folder (header);
5558 g_object_unref (header);
5561 /* Call the function for each header */
5562 while (!tny_iterator_is_done (iter)) {
5563 header = TNY_HEADER (tny_iterator_get_current (iter));
5564 func (header, win, user_data);
5565 g_object_unref (header);
5566 tny_iterator_next (iter);
5569 /* Trick: do a poke status in order to speed up the signaling
5571 tny_folder_poke_status (folder);
5574 g_object_unref (folder);
5575 g_object_unref (iter);
5576 g_object_unref (headers_list);
5580 modest_ui_actions_view_attachment (GtkAction *action,
5581 ModestWindow *window)
5583 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5584 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5586 /* not supported window for this action */
5587 g_return_if_reached ();
5592 modest_ui_actions_save_attachments (GtkAction *action,
5593 ModestWindow *window)
5595 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5597 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5600 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5602 /* not supported window for this action */
5603 g_return_if_reached ();
5608 modest_ui_actions_remove_attachments (GtkAction *action,
5609 ModestWindow *window)
5611 if (MODEST_IS_MAIN_WINDOW (window)) {
5612 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5613 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5614 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5616 /* not supported window for this action */
5617 g_return_if_reached ();
5622 modest_ui_actions_on_settings (GtkAction *action,
5627 dialog = modest_platform_get_global_settings_dialog ();
5628 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5629 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5630 gtk_widget_show_all (dialog);
5632 gtk_dialog_run (GTK_DIALOG (dialog));
5634 gtk_widget_destroy (dialog);
5638 modest_ui_actions_on_help (GtkAction *action,
5641 const gchar *help_id;
5643 g_return_if_fail (win && GTK_IS_WINDOW(win));
5645 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5648 modest_platform_show_help (GTK_WINDOW (win), help_id);
5652 modest_ui_actions_on_csm_help (GtkAction *action,
5655 const gchar* help_id = NULL;
5656 GtkWidget *folder_view;
5657 TnyFolderStore *folder_store;
5659 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5661 /* Get selected folder */
5662 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5663 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5664 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5666 /* Switch help_id */
5667 if (folder_store && TNY_IS_FOLDER (folder_store))
5668 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5671 g_object_unref (folder_store);
5674 modest_platform_show_help (GTK_WINDOW (win), help_id);
5676 modest_ui_actions_on_help (action, win);
5680 retrieve_contents_cb (ModestMailOperation *mail_op,
5687 /* We only need this callback to show an error in case of
5688 memory low condition */
5689 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5693 retrieve_msg_contents_performer (gboolean canceled,
5695 GtkWindow *parent_window,
5696 TnyAccount *account,
5699 ModestMailOperation *mail_op;
5700 TnyList *headers = TNY_LIST (user_data);
5702 if (err || canceled) {
5703 check_memory_full_error ((GtkWidget *) parent_window, err);
5707 /* Create mail operation */
5708 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5709 modest_ui_actions_disk_operations_error_handler,
5711 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5712 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5715 g_object_unref (mail_op);
5717 g_object_unref (headers);
5718 g_object_unref (account);
5722 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5723 ModestWindow *window)
5725 TnyList *headers = NULL;
5726 TnyAccount *account = NULL;
5727 TnyIterator *iter = NULL;
5728 TnyHeader *header = NULL;
5729 TnyFolder *folder = NULL;
5732 headers = get_selected_headers (window);
5736 /* Pick the account */
5737 iter = tny_list_create_iterator (headers);
5738 header = TNY_HEADER (tny_iterator_get_current (iter));
5739 folder = tny_header_get_folder (header);
5740 account = tny_folder_get_account (folder);
5741 g_object_unref (folder);
5742 g_object_unref (header);
5743 g_object_unref (iter);
5745 /* Connect and perform the message retrieval */
5746 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5747 g_object_ref (account),
5748 retrieve_msg_contents_performer,
5749 g_object_ref (headers));
5752 g_object_unref (account);
5753 g_object_unref (headers);
5757 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5759 g_return_if_fail (MODEST_IS_WINDOW (window));
5762 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5766 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5768 g_return_if_fail (MODEST_IS_WINDOW (window));
5771 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5775 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5776 ModestWindow *window)
5778 g_return_if_fail (MODEST_IS_WINDOW (window));
5781 modest_ui_actions_check_menu_dimming_rules (window);
5785 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5786 ModestWindow *window)
5788 g_return_if_fail (MODEST_IS_WINDOW (window));
5791 modest_ui_actions_check_menu_dimming_rules (window);
5795 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5796 ModestWindow *window)
5798 g_return_if_fail (MODEST_IS_WINDOW (window));
5801 modest_ui_actions_check_menu_dimming_rules (window);
5805 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5806 ModestWindow *window)
5808 g_return_if_fail (MODEST_IS_WINDOW (window));
5811 modest_ui_actions_check_menu_dimming_rules (window);
5815 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5816 ModestWindow *window)
5818 g_return_if_fail (MODEST_IS_WINDOW (window));
5821 modest_ui_actions_check_menu_dimming_rules (window);
5825 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5826 ModestWindow *window)
5828 g_return_if_fail (MODEST_IS_WINDOW (window));
5831 modest_ui_actions_check_menu_dimming_rules (window);
5835 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5836 ModestWindow *window)
5838 g_return_if_fail (MODEST_IS_WINDOW (window));
5841 modest_ui_actions_check_menu_dimming_rules (window);
5845 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5846 ModestWindow *window)
5848 g_return_if_fail (MODEST_IS_WINDOW (window));
5851 modest_ui_actions_check_menu_dimming_rules (window);
5855 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5856 ModestWindow *window)
5858 g_return_if_fail (MODEST_IS_WINDOW (window));
5861 modest_ui_actions_check_menu_dimming_rules (window);
5865 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5867 g_return_if_fail (MODEST_IS_WINDOW (window));
5869 /* we check for low-mem; in that case, show a warning, and don't allow
5872 if (modest_platform_check_memory_low (window, TRUE))
5875 modest_platform_show_search_messages (GTK_WINDOW (window));
5879 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5881 g_return_if_fail (MODEST_IS_WINDOW (win));
5884 /* we check for low-mem; in that case, show a warning, and don't allow
5885 * for the addressbook
5887 if (modest_platform_check_memory_low (win, TRUE))
5891 modest_platform_show_addressbook (GTK_WINDOW (win));
5896 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5897 ModestWindow *window)
5899 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5901 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5905 on_send_receive_finished (ModestMailOperation *mail_op,
5908 GtkWidget *header_view, *folder_view;
5909 TnyFolderStore *folder_store;
5910 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5912 /* Set send/receive operation finished */
5913 modest_main_window_notify_send_receive_completed (main_win);
5915 /* Don't refresh the current folder if there were any errors */
5916 if (modest_mail_operation_get_status (mail_op) !=
5917 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5920 /* Refresh the current folder if we're viewing a window. We do
5921 this because the user won't be able to see the new mails in
5922 the selected folder after a Send&Receive because it only
5923 performs a poke_status, i.e, only the number of read/unread
5924 messages is updated, but the new headers are not
5926 folder_view = modest_main_window_get_child_widget (main_win,
5927 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5931 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5933 /* Do not need to refresh INBOX again because the
5934 update_account does it always automatically */
5935 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5936 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5937 ModestMailOperation *refresh_op;
5939 header_view = modest_main_window_get_child_widget (main_win,
5940 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5942 /* We do not need to set the contents style
5943 because it hasn't changed. We also do not
5944 need to save the widget status. Just force
5946 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5947 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5948 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5949 folder_refreshed_cb, main_win);
5950 g_object_unref (refresh_op);
5954 g_object_unref (folder_store);
5959 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5965 const gchar* server_name = NULL;
5966 TnyTransportAccount *server_account;
5967 gchar *message = NULL;
5969 /* Don't show anything if the user cancelled something or the
5970 * send receive request is not interactive. Authentication
5971 * errors are managed by the account store so no need to show
5972 * a dialog here again */
5973 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5974 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5975 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5979 /* Get the server name: */
5981 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5983 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5985 g_return_if_reached ();
5987 /* Show the appropriate message text for the GError: */
5988 switch (err->code) {
5989 case TNY_SERVICE_ERROR_CONNECT:
5990 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5992 case TNY_SERVICE_ERROR_SEND:
5993 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
5995 case TNY_SERVICE_ERROR_UNAVAILABLE:
5996 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5999 g_warning ("%s: unexpected ERROR %d",
6000 __FUNCTION__, err->code);
6001 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6005 modest_platform_run_information_dialog (NULL, message, FALSE);
6007 g_object_unref (server_account);
6011 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6016 ModestMainWindow *main_window = NULL;
6017 ModestWindowMgr *mgr = NULL;
6018 GtkWidget *folder_view = NULL, *header_view = NULL;
6019 TnyFolderStore *selected_folder = NULL;
6020 TnyFolderType folder_type;
6022 mgr = modest_runtime_get_window_mgr ();
6023 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6024 FALSE));/* don't create */
6028 /* Check if selected folder is OUTBOX */
6029 folder_view = modest_main_window_get_child_widget (main_window,
6030 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6031 header_view = modest_main_window_get_child_widget (main_window,
6032 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6034 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6035 if (!TNY_IS_FOLDER (selected_folder))
6038 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6039 #if GTK_CHECK_VERSION(2, 8, 0)
6040 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6041 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6042 GtkTreeViewColumn *tree_column;
6044 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6045 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6047 gtk_tree_view_column_queue_resize (tree_column);
6050 gtk_widget_queue_draw (header_view);
6053 /* Rerun dimming rules, because the message could become deletable for example */
6054 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6055 MODEST_DIMMING_RULES_TOOLBAR);
6056 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6057 MODEST_DIMMING_RULES_MENU);
6061 if (selected_folder != NULL)
6062 g_object_unref (selected_folder);
6066 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6067 TnyAccount *account)
6069 ModestProtocolType protocol_type;
6070 ModestProtocol *protocol;
6071 gchar *error_note = NULL;
6073 protocol_type = modest_tny_account_get_protocol_type (account);
6074 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6077 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6078 if (error_note == NULL) {
6079 g_warning ("%s: This should not be reached", __FUNCTION__);
6081 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6082 g_free (error_note);
6087 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6091 TnyFolderStore *folder = NULL;
6092 TnyAccount *account = NULL;
6093 ModestProtocolType proto;
6094 ModestProtocol *protocol;
6095 TnyHeader *header = NULL;
6097 if (MODEST_IS_MAIN_WINDOW (win)) {
6098 GtkWidget *header_view;
6099 TnyList* headers = NULL;
6101 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6102 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6103 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6104 if (!headers || tny_list_get_length (headers) == 0) {
6106 g_object_unref (headers);
6109 iter = tny_list_create_iterator (headers);
6110 header = TNY_HEADER (tny_iterator_get_current (iter));
6111 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6112 g_object_unref (iter);
6113 g_object_unref (headers);
6114 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6115 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6116 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6119 /* Get the account type */
6120 account = tny_folder_get_account (TNY_FOLDER (folder));
6121 proto = modest_tny_account_get_protocol_type (account);
6122 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6125 subject = tny_header_dup_subject (header);
6126 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6129 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6133 g_object_unref (account);
6134 g_object_unref (folder);
6135 g_object_unref (header);