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 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL)) {
764 gtk_widget_destroy (GTK_WIDGET (msg_win));
767 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
768 gtk_widget_show_all (GTK_WIDGET (msg_win));
770 while (attachments) {
772 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
773 attachments->data, allowed_size);
775 if (total_size > allowed_size) {
776 g_warning ("%s: total size: %u",
777 __FUNCTION__, (unsigned int)total_size);
780 allowed_size -= total_size;
782 attachments = g_slist_next(attachments);
789 g_free (account_name);
791 g_object_unref (G_OBJECT(account));
793 g_object_unref (G_OBJECT(folder));
795 g_object_unref (G_OBJECT(msg));
799 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
801 /* if there are no accounts yet, just show the wizard */
802 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
803 if (!modest_ui_actions_run_account_setup_wizard (win))
806 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
811 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
815 ModestMailOperationStatus status;
817 /* If there is no message or the operation was not successful */
818 status = modest_mail_operation_get_status (mail_op);
819 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
822 /* If it's a memory low issue, then show a banner */
823 error = modest_mail_operation_get_error (mail_op);
824 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
825 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
826 GObject *source = modest_mail_operation_get_source (mail_op);
827 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
828 dgettext("ke-recv","memr_ib_operation_disabled"),
830 g_object_unref (source);
833 /* Remove the header from the preregistered uids */
834 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
852 OpenMsgBannerInfo *banner_info;
853 GHashTable *row_refs_per_header;
857 open_msg_banner_idle (gpointer userdata)
859 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
861 gdk_threads_enter ();
862 banner_info->idle_handler = 0;
863 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
865 g_object_ref (banner_info->banner);
867 gdk_threads_leave ();
874 open_msg_cb (ModestMailOperation *mail_op,
881 ModestWindowMgr *mgr = NULL;
882 ModestWindow *parent_win = NULL;
883 ModestWindow *win = NULL;
884 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
885 gchar *account = NULL;
887 gboolean open_in_editor = FALSE;
888 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
890 /* Do nothing if there was any problem with the mail
891 operation. The error will be shown by the error_handler of
892 the mail operation */
893 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
896 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
897 folder = tny_header_get_folder (header);
899 /* Mark header as read */
900 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
902 /* Gets folder type (OUTBOX headers will be opened in edit window */
903 if (modest_tny_folder_is_local_folder (folder)) {
904 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
905 if (folder_type == TNY_FOLDER_TYPE_INVALID)
906 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
910 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
911 TnyTransportAccount *traccount = NULL;
912 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
913 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
915 ModestTnySendQueue *send_queue = NULL;
916 ModestTnySendQueueStatus status;
918 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
919 TNY_ACCOUNT(traccount)));
920 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
921 if (TNY_IS_SEND_QUEUE (send_queue)) {
922 msg_id = modest_tny_send_queue_get_msg_id (header);
923 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
924 /* Only open messages in outbox with the editor if they are in Failed state */
925 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
926 open_in_editor = TRUE;
930 g_object_unref(traccount);
932 g_warning("Cannot get transport account for message in outbox!!");
934 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
935 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
940 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
942 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
944 if (open_in_editor) {
945 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
946 gchar *from_header = NULL, *acc_name;
948 from_header = tny_header_dup_from (header);
950 /* we cannot edit without a valid account... */
951 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
952 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
953 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
955 g_free (from_header);
960 acc_name = modest_utils_get_account_name_from_recipient (from_header);
961 g_free (from_header);
967 win = modest_msg_edit_window_new (msg, account, TRUE);
969 gchar *uid = modest_tny_folder_get_header_unique_id (header);
971 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
972 GtkTreeRowReference *row_reference;
974 row_reference = (GtkTreeRowReference *) g_hash_table_lookup (helper->row_refs_per_header, header);
976 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
977 helper->model, row_reference);
979 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
984 /* Register and show new window */
986 mgr = modest_runtime_get_window_mgr ();
987 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
988 gtk_widget_destroy (GTK_WIDGET (win));
991 gtk_widget_show_all (GTK_WIDGET(win));
994 /* Update toolbar dimming state */
995 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
996 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1002 g_object_unref (parent_win);
1003 g_object_unref (folder);
1007 is_memory_full_error (GError *error)
1009 gboolean enough_free_space = TRUE;
1010 GnomeVFSURI *cache_dir_uri;
1011 const gchar *cache_dir;
1012 GnomeVFSFileSize free_space;
1014 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1015 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1016 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1017 if (free_space < MIN_FREE_SPACE)
1018 enough_free_space = FALSE;
1020 gnome_vfs_uri_unref (cache_dir_uri);
1022 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1023 /* When asking for a mail and no space left on device
1024 tinymail returns this error */
1025 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1026 /* When the folder summary could not be read or
1028 error->code == TNY_IO_ERROR_WRITE ||
1029 error->code == TNY_IO_ERROR_READ) &&
1030 !enough_free_space) {
1038 check_memory_full_error (GtkWidget *parent_window, GError *err)
1043 if (is_memory_full_error (err))
1044 modest_platform_information_banner (parent_window,
1045 NULL, dgettext("ke-recv",
1046 "cerm_device_memory_full"));
1047 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1048 /* If the account was created in memory full
1049 conditions then tinymail won't be able to
1050 connect so it'll return this error code */
1051 modest_platform_information_banner (parent_window,
1052 NULL, _("emev_ui_imap_inbox_select_error"));
1060 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1063 const GError *error;
1064 GObject *win = NULL;
1065 ModestMailOperationStatus status;
1067 win = modest_mail_operation_get_source (mail_op);
1068 error = modest_mail_operation_get_error (mail_op);
1069 status = modest_mail_operation_get_status (mail_op);
1071 /* If the mail op has been cancelled then it's not an error:
1072 don't show any message */
1073 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1074 if (is_memory_full_error ((GError *) error)) {
1075 modest_platform_information_banner ((GtkWidget *) win,
1076 NULL, dgettext("ke-recv",
1077 "cerm_device_memory_full"));
1078 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1079 modest_platform_information_banner ((GtkWidget *) win,
1080 NULL, _("emev_ui_imap_inbox_select_error"));
1081 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1082 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1083 modest_platform_information_banner ((GtkWidget *) win,
1084 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1085 } else if (user_data) {
1086 modest_platform_information_banner ((GtkWidget *) win,
1092 g_object_unref (win);
1096 * Returns the account a list of headers belongs to. It returns a
1097 * *new* reference so don't forget to unref it
1100 get_account_from_header_list (TnyList *headers)
1102 TnyAccount *account = NULL;
1104 if (tny_list_get_length (headers) > 0) {
1105 TnyIterator *iter = tny_list_create_iterator (headers);
1106 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1107 TnyFolder *folder = tny_header_get_folder (header);
1110 g_object_unref (header);
1112 while (!tny_iterator_is_done (iter)) {
1113 header = TNY_HEADER (tny_iterator_get_current (iter));
1114 folder = tny_header_get_folder (header);
1117 g_object_unref (header);
1119 tny_iterator_next (iter);
1124 account = tny_folder_get_account (folder);
1125 g_object_unref (folder);
1129 g_object_unref (header);
1131 g_object_unref (iter);
1137 foreach_unregister_headers (gpointer data,
1140 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1141 TnyHeader *header = TNY_HEADER (data);
1143 modest_window_mgr_unregister_header (mgr, header);
1147 open_msgs_helper_destroyer (gpointer user_data)
1149 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1151 if (helper->banner_info) {
1152 g_free (helper->banner_info->message);
1153 if (helper->banner_info->idle_handler > 0) {
1154 g_source_remove (helper->banner_info->idle_handler);
1155 helper->banner_info->idle_handler = 0;
1157 if (helper->banner_info->banner != NULL) {
1158 gtk_widget_destroy (helper->banner_info->banner);
1159 g_object_unref (helper->banner_info->banner);
1160 helper->banner_info->banner = NULL;
1162 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1163 helper->banner_info = NULL;
1165 g_object_unref (helper->model);
1166 g_object_unref (helper->headers);
1167 g_hash_table_destroy (helper->row_refs_per_header);
1168 g_slice_free (OpenMsgHelper, helper);
1172 open_msgs_performer(gboolean canceled,
1174 GtkWindow *parent_window,
1175 TnyAccount *account,
1178 ModestMailOperation *mail_op = NULL;
1180 ModestProtocolType proto;
1181 TnyList *not_opened_headers;
1182 TnyConnectionStatus status;
1183 gboolean show_open_draft = FALSE;
1184 OpenMsgHelper *helper = NULL;
1186 helper = (OpenMsgHelper *) user_data;
1187 not_opened_headers = helper->headers;
1189 status = tny_account_get_connection_status (account);
1190 if (err || canceled) {
1191 /* Unregister the already registered headers */
1192 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1193 modest_runtime_get_window_mgr ());
1194 /* Free the helper */
1195 open_msgs_helper_destroyer (helper);
1197 /* In memory full conditions we could get this error here */
1198 check_memory_full_error ((GtkWidget *) parent_window, err);
1203 /* Get the error message depending on the protocol */
1204 proto = modest_tny_account_get_protocol_type (account);
1205 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1206 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1209 /* Create the error messages */
1210 if (tny_list_get_length (not_opened_headers) == 1) {
1211 ModestProtocol *protocol;
1212 ModestProtocolRegistry *protocol_registry;
1217 protocol_registry = modest_runtime_get_protocol_registry ();
1218 iter = tny_list_create_iterator (not_opened_headers);
1219 header = TNY_HEADER (tny_iterator_get_current (iter));
1220 subject = tny_header_dup_subject (header);
1222 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1223 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1225 g_object_unref (header);
1226 g_object_unref (iter);
1228 if (error_msg == NULL) {
1229 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1232 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1234 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1238 TnyFolderType folder_type;
1240 iter = tny_list_create_iterator (not_opened_headers);
1241 header = TNY_HEADER (tny_iterator_get_current (iter));
1242 folder = tny_header_get_folder (header);
1243 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1244 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1245 g_object_unref (folder);
1246 g_object_unref (header);
1247 g_object_unref (iter);
1250 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1253 /* Create the mail operation */
1255 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1256 modest_ui_actions_disk_operations_error_handler,
1258 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1261 if (show_open_draft) {
1262 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1263 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1264 helper->banner_info->banner = NULL;
1265 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1266 helper->banner_info);
1269 modest_mail_operation_get_msgs_full (mail_op,
1273 open_msgs_helper_destroyer);
1278 g_object_unref (mail_op);
1279 g_object_unref (account);
1283 * This function is used by both modest_ui_actions_on_open and
1284 * modest_ui_actions_on_header_activated. This way we always do the
1285 * same when trying to open messages.
1288 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1290 ModestWindowMgr *mgr = NULL;
1291 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1292 TnyList *not_opened_headers = NULL;
1293 TnyHeaderFlags flags = 0;
1294 TnyAccount *account;
1295 gint uncached_msgs = 0;
1296 GtkWidget *header_view;
1297 GtkTreeModel *model;
1298 GHashTable *refs_for_headers;
1299 OpenMsgHelper *helper;
1300 GtkTreeSelection *sel;
1301 GList *sel_list = NULL, *sel_list_iter = NULL;
1303 g_return_if_fail (headers != NULL);
1305 /* Check that only one message is selected for opening */
1306 if (tny_list_get_length (headers) != 1) {
1307 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1308 NULL, _("mcen_ib_select_one_message"));
1312 mgr = modest_runtime_get_window_mgr ();
1313 iter = tny_list_create_iterator (headers);
1315 /* Get the account */
1316 account = get_account_from_header_list (headers);
1321 /* Get the selections, we need to get the references to the
1322 rows here because the treeview/model could dissapear (the
1323 user might want to select another folder)*/
1324 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1325 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1326 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1327 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
1328 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1329 refs_for_headers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
1330 (GDestroyNotify) gtk_tree_row_reference_free);
1332 /* Look if we already have a message view for each header. If
1333 true, then remove the header from the list of headers to
1335 sel_list_iter = sel_list;
1336 not_opened_headers = tny_simple_list_new ();
1337 while (!tny_iterator_is_done (iter) && sel_list_iter) {
1339 ModestWindow *window = NULL;
1340 TnyHeader *header = NULL;
1341 gboolean found = FALSE;
1343 header = TNY_HEADER (tny_iterator_get_current (iter));
1345 flags = tny_header_get_flags (header);
1348 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1350 /* Do not open again the message and present the
1351 window to the user */
1354 #ifndef MODEST_TOOLKIT_HILDON2
1355 gtk_window_present (GTK_WINDOW (window));
1358 /* the header has been registered already, we don't do
1359 * anything but wait for the window to come up*/
1360 g_debug ("header %p already registered, waiting for window", header);
1363 GtkTreeRowReference *row_reference;
1365 tny_list_append (not_opened_headers, G_OBJECT (header));
1366 /* Create a new row reference and add it to the hash table */
1367 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list_iter->data);
1368 g_hash_table_insert (refs_for_headers, header, row_reference);
1372 g_object_unref (header);
1375 tny_iterator_next (iter);
1376 sel_list_iter = g_list_next (sel_list_iter);
1378 g_object_unref (iter);
1380 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1381 g_list_free (sel_list);
1383 /* Open each message */
1384 if (tny_list_get_length (not_opened_headers) == 0) {
1385 g_hash_table_destroy (refs_for_headers);
1389 /* If some messages would have to be downloaded, ask the user to
1390 * make a connection. It's generally easier to do this here (in the mainloop)
1391 * than later in a thread:
1393 if (tny_list_get_length (not_opened_headers) > 0) {
1394 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1396 if (uncached_msgs > 0) {
1397 /* Allways download if we are online. */
1398 if (!tny_device_is_online (modest_runtime_get_device ())) {
1401 /* If ask for user permission to download the messages */
1402 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1403 ngettext("mcen_nc_get_msg",
1407 /* End if the user does not want to continue */
1408 if (response == GTK_RESPONSE_CANCEL) {
1409 g_hash_table_destroy (refs_for_headers);
1416 /* Register the headers before actually creating the windows: */
1417 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1418 while (!tny_iterator_is_done (iter_not_opened)) {
1419 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1421 modest_window_mgr_register_header (mgr, header, NULL);
1422 g_object_unref (header);
1424 tny_iterator_next (iter_not_opened);
1426 g_object_unref (iter_not_opened);
1427 iter_not_opened = NULL;
1429 /* Create the helper. We need to get a reference to the model
1430 here because it could change while the message is readed
1431 (the user could switch between folders) */
1432 helper = g_slice_new (OpenMsgHelper);
1433 helper->model = g_object_ref (model);
1434 helper->headers = g_object_ref (not_opened_headers);
1435 helper->row_refs_per_header = refs_for_headers;
1436 helper->banner_info = NULL;
1438 /* Connect to the account and perform */
1439 if (uncached_msgs > 0) {
1440 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1441 open_msgs_performer, helper);
1443 /* Call directly the performer, do not need to connect */
1444 open_msgs_performer (FALSE, NULL, (GtkWindow *) win,
1445 g_object_ref (account), helper);
1450 g_object_unref (account);
1451 if (not_opened_headers)
1452 g_object_unref (not_opened_headers);
1456 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1460 /* we check for low-mem; in that case, show a warning, and don't allow
1463 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1467 headers = get_selected_headers (win);
1472 open_msgs_from_headers (headers, win);
1474 g_object_unref(headers);
1477 static ReplyForwardHelper*
1478 create_reply_forward_helper (ReplyForwardAction action,
1480 guint reply_forward_type,
1483 ReplyForwardHelper *rf_helper = NULL;
1484 const gchar *active_acc = modest_window_get_active_account (win);
1486 rf_helper = g_slice_new0 (ReplyForwardHelper);
1487 rf_helper->reply_forward_type = reply_forward_type;
1488 rf_helper->action = action;
1489 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1490 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1491 rf_helper->account_name = (active_acc) ?
1492 g_strdup (active_acc) :
1493 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1499 free_reply_forward_helper (gpointer data)
1501 ReplyForwardHelper *helper;
1503 helper = (ReplyForwardHelper *) data;
1504 g_free (helper->account_name);
1506 g_object_unref (helper->header);
1507 g_slice_free (ReplyForwardHelper, helper);
1511 reply_forward_cb (ModestMailOperation *mail_op,
1518 TnyMsg *new_msg = NULL;
1519 ReplyForwardHelper *rf_helper;
1520 ModestWindow *msg_win = NULL;
1521 ModestEditType edit_type;
1523 TnyAccount *account = NULL;
1524 ModestWindowMgr *mgr = NULL;
1525 gchar *signature = NULL;
1526 gboolean use_signature;
1528 /* If there was any error. The mail operation could be NULL,
1529 this means that we already have the message downloaded and
1530 that we didn't do a mail operation to retrieve it */
1531 rf_helper = (ReplyForwardHelper *) user_data;
1532 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1535 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1536 rf_helper->account_name);
1537 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1538 rf_helper->account_name,
1541 /* Create reply mail */
1542 switch (rf_helper->action) {
1545 modest_tny_msg_create_reply_msg (msg, header, from,
1546 (use_signature) ? signature : NULL,
1547 rf_helper->reply_forward_type,
1548 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1550 case ACTION_REPLY_TO_ALL:
1552 modest_tny_msg_create_reply_msg (msg, header, from,
1553 (use_signature) ? signature : NULL,
1554 rf_helper->reply_forward_type,
1555 MODEST_TNY_MSG_REPLY_MODE_ALL);
1556 edit_type = MODEST_EDIT_TYPE_REPLY;
1558 case ACTION_FORWARD:
1560 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1561 rf_helper->reply_forward_type);
1562 edit_type = MODEST_EDIT_TYPE_FORWARD;
1565 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1567 g_return_if_reached ();
1575 g_warning ("%s: failed to create message\n", __FUNCTION__);
1579 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1580 rf_helper->account_name,
1581 TNY_ACCOUNT_TYPE_STORE);
1583 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1587 /* Create and register the windows */
1588 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1589 mgr = modest_runtime_get_window_mgr ();
1590 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1592 if (rf_helper->parent_window != NULL) {
1593 gdouble parent_zoom;
1595 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1596 modest_window_set_zoom (msg_win, parent_zoom);
1599 /* Show edit window */
1600 gtk_widget_show_all (GTK_WIDGET (msg_win));
1603 /* We always unregister the header because the message is
1604 forwarded or replied so the original one is no longer
1606 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1609 g_object_unref (G_OBJECT (new_msg));
1611 g_object_unref (G_OBJECT (account));
1612 free_reply_forward_helper (rf_helper);
1615 /* Checks a list of headers. If any of them are not currently
1616 * downloaded (CACHED) then returns TRUE else returns FALSE.
1619 header_list_count_uncached_msgs (TnyList *header_list)
1622 gint uncached_messages = 0;
1624 iter = tny_list_create_iterator (header_list);
1625 while (!tny_iterator_is_done (iter)) {
1628 header = TNY_HEADER (tny_iterator_get_current (iter));
1630 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1631 uncached_messages ++;
1632 g_object_unref (header);
1635 tny_iterator_next (iter);
1637 g_object_unref (iter);
1639 return uncached_messages;
1642 /* Returns FALSE if the user does not want to download the
1643 * messages. Returns TRUE if the user allowed the download.
1646 connect_to_get_msg (ModestWindow *win,
1647 gint num_of_uncached_msgs,
1648 TnyAccount *account)
1650 GtkResponseType response;
1652 /* Allways download if we are online. */
1653 if (tny_device_is_online (modest_runtime_get_device ()))
1656 /* If offline, then ask for user permission to download the messages */
1657 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1658 ngettext("mcen_nc_get_msg",
1660 num_of_uncached_msgs));
1662 if (response == GTK_RESPONSE_CANCEL)
1665 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1669 reply_forward_performer (gboolean canceled,
1671 GtkWindow *parent_window,
1672 TnyAccount *account,
1675 ReplyForwardHelper *rf_helper = NULL;
1676 ModestMailOperation *mail_op;
1678 rf_helper = (ReplyForwardHelper *) user_data;
1680 if (canceled || err) {
1681 free_reply_forward_helper (rf_helper);
1685 /* Retrieve the message */
1686 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1687 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1688 modest_ui_actions_disk_operations_error_handler,
1690 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1691 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1694 g_object_unref(mail_op);
1698 * Common code for the reply and forward actions
1701 reply_forward (ReplyForwardAction action, ModestWindow *win)
1703 ReplyForwardHelper *rf_helper = NULL;
1704 guint reply_forward_type;
1706 g_return_if_fail (MODEST_IS_WINDOW(win));
1708 /* we check for low-mem; in that case, show a warning, and don't allow
1709 * reply/forward (because it could potentially require a lot of memory */
1710 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1714 /* we need an account when editing */
1715 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1716 if (!modest_ui_actions_run_account_setup_wizard (win))
1720 reply_forward_type =
1721 modest_conf_get_int (modest_runtime_get_conf (),
1722 (action == ACTION_FORWARD) ?
1723 MODEST_CONF_FORWARD_TYPE :
1724 MODEST_CONF_REPLY_TYPE,
1727 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1729 TnyHeader *header = NULL;
1730 /* Get header and message. Do not free them here, the
1731 reply_forward_cb must do it */
1732 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1733 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1735 if (msg && header) {
1737 rf_helper = create_reply_forward_helper (action, win,
1738 reply_forward_type, header);
1739 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1741 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1745 g_object_unref (msg);
1747 g_object_unref (header);
1749 TnyHeader *header = NULL;
1751 gboolean do_retrieve = TRUE;
1752 TnyList *header_list = NULL;
1754 header_list = get_selected_headers (win);
1757 /* Check that only one message is selected for replying */
1758 if (tny_list_get_length (header_list) != 1) {
1759 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1760 NULL, _("mcen_ib_select_one_message"));
1761 g_object_unref (header_list);
1765 /* Only reply/forward to one message */
1766 iter = tny_list_create_iterator (header_list);
1767 header = TNY_HEADER (tny_iterator_get_current (iter));
1768 g_object_unref (iter);
1770 /* Retrieve messages */
1771 do_retrieve = (action == ACTION_FORWARD) ||
1772 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1775 TnyAccount *account = NULL;
1776 TnyFolder *folder = NULL;
1777 gdouble download = TRUE;
1778 guint uncached_msgs = 0;
1780 folder = tny_header_get_folder (header);
1782 goto do_retrieve_frees;
1783 account = tny_folder_get_account (folder);
1785 goto do_retrieve_frees;
1787 uncached_msgs = header_list_count_uncached_msgs (header_list);
1789 if (uncached_msgs > 0) {
1790 /* Allways download if we are online. */
1791 if (!tny_device_is_online (modest_runtime_get_device ())) {
1794 /* If ask for user permission to download the messages */
1795 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1796 ngettext("mcen_nc_get_msg",
1800 /* End if the user does not want to continue */
1801 if (response == GTK_RESPONSE_CANCEL)
1808 rf_helper = create_reply_forward_helper (action, win,
1809 reply_forward_type, header);
1810 if (uncached_msgs > 0) {
1811 modest_platform_connect_and_perform (GTK_WINDOW (win),
1813 reply_forward_performer,
1816 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1817 account, rf_helper);
1822 g_object_unref (account);
1824 g_object_unref (folder);
1826 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1829 g_object_unref (header_list);
1830 g_object_unref (header);
1835 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1837 g_return_if_fail (MODEST_IS_WINDOW(win));
1839 reply_forward (ACTION_REPLY, win);
1843 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1845 g_return_if_fail (MODEST_IS_WINDOW(win));
1847 reply_forward (ACTION_FORWARD, win);
1851 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1853 g_return_if_fail (MODEST_IS_WINDOW(win));
1855 reply_forward (ACTION_REPLY_TO_ALL, win);
1859 modest_ui_actions_on_next (GtkAction *action,
1860 ModestWindow *window)
1862 if (MODEST_IS_MAIN_WINDOW (window)) {
1863 GtkWidget *header_view;
1865 header_view = modest_main_window_get_child_widget (
1866 MODEST_MAIN_WINDOW(window),
1867 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1871 modest_header_view_select_next (
1872 MODEST_HEADER_VIEW(header_view));
1873 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1874 modest_msg_view_window_select_next_message (
1875 MODEST_MSG_VIEW_WINDOW (window));
1877 g_return_if_reached ();
1882 modest_ui_actions_on_prev (GtkAction *action,
1883 ModestWindow *window)
1885 g_return_if_fail (MODEST_IS_WINDOW(window));
1887 if (MODEST_IS_MAIN_WINDOW (window)) {
1888 GtkWidget *header_view;
1889 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1890 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1894 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1895 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1896 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1898 g_return_if_reached ();
1903 modest_ui_actions_on_sort (GtkAction *action,
1904 ModestWindow *window)
1906 g_return_if_fail (MODEST_IS_WINDOW(window));
1908 if (MODEST_IS_MAIN_WINDOW (window)) {
1909 GtkWidget *header_view;
1910 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1911 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1913 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1918 /* Show sorting dialog */
1919 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1924 new_messages_arrived (ModestMailOperation *self,
1925 TnyList *new_headers,
1929 gboolean show_visual_notifications;
1931 source = modest_mail_operation_get_source (self);
1932 show_visual_notifications = (source) ? FALSE : TRUE;
1934 g_object_unref (source);
1936 /* Notify new messages have been downloaded. If the
1937 send&receive was invoked by the user then do not show any
1938 visual notification, only play a sound and activate the LED
1939 (for the Maemo version) */
1940 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1941 modest_platform_on_new_headers_received (new_headers,
1942 show_visual_notifications);
1947 retrieve_all_messages_cb (GObject *source,
1949 guint retrieve_limit)
1955 window = GTK_WINDOW (source);
1956 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1957 num_msgs, retrieve_limit);
1959 /* Ask the user if they want to retrieve all the messages */
1961 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1962 _("mcen_bd_get_all"),
1963 _("mcen_bd_newest_only"));
1964 /* Free and return */
1966 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1970 TnyAccount *account;
1972 gchar *account_name;
1973 gboolean poke_status;
1974 gboolean interactive;
1975 ModestMailOperation *mail_op;
1979 do_send_receive_performer (gboolean canceled,
1981 GtkWindow *parent_window,
1982 TnyAccount *account,
1985 SendReceiveInfo *info;
1987 info = (SendReceiveInfo *) user_data;
1989 if (err || canceled) {
1990 /* In memory full conditions we could get this error here */
1991 check_memory_full_error ((GtkWidget *) parent_window, err);
1993 if (info->mail_op) {
1994 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2000 /* Set send/receive operation in progress */
2001 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2002 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2005 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2006 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2007 G_CALLBACK (on_send_receive_finished),
2010 /* Send & receive. */
2011 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2012 (info->win) ? retrieve_all_messages_cb : NULL,
2013 new_messages_arrived, info->win);
2018 g_object_unref (G_OBJECT (info->mail_op));
2019 if (info->account_name)
2020 g_free (info->account_name);
2022 g_object_unref (info->win);
2024 g_object_unref (info->account);
2025 g_slice_free (SendReceiveInfo, info);
2029 * This function performs the send & receive required actions. The
2030 * window is used to create the mail operation. Typically it should
2031 * always be the main window, but we pass it as argument in order to
2035 modest_ui_actions_do_send_receive (const gchar *account_name,
2036 gboolean force_connection,
2037 gboolean poke_status,
2038 gboolean interactive,
2041 gchar *acc_name = NULL;
2042 SendReceiveInfo *info;
2043 ModestTnyAccountStore *acc_store;
2045 /* If no account name was provided then get the current account, and if
2046 there is no current account then pick the default one: */
2047 if (!account_name) {
2049 acc_name = g_strdup (modest_window_get_active_account (win));
2051 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2053 g_printerr ("modest: cannot get default account\n");
2057 acc_name = g_strdup (account_name);
2060 acc_store = modest_runtime_get_account_store ();
2062 /* Create the info for the connect and perform */
2063 info = g_slice_new (SendReceiveInfo);
2064 info->account_name = acc_name;
2065 info->win = (win) ? g_object_ref (win) : NULL;
2066 info->poke_status = poke_status;
2067 info->interactive = interactive;
2068 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2069 TNY_ACCOUNT_TYPE_STORE);
2070 /* We need to create the operation here, because otherwise it
2071 could happen that the queue emits the queue-empty signal
2072 while we're trying to connect the account */
2073 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2074 modest_ui_actions_disk_operations_error_handler,
2076 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2078 /* Invoke the connect and perform */
2079 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2080 force_connection, info->account,
2081 do_send_receive_performer, info);
2086 modest_ui_actions_do_cancel_send (const gchar *account_name,
2089 TnyTransportAccount *transport_account;
2090 TnySendQueue *send_queue = NULL;
2091 GError *error = NULL;
2093 /* Get transport account */
2095 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2096 (modest_runtime_get_account_store(),
2098 TNY_ACCOUNT_TYPE_TRANSPORT));
2099 if (!transport_account) {
2100 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2105 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2106 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2107 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2108 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2109 "modest: could not find send queue for account\n");
2111 /* Cancel the current send */
2112 tny_account_cancel (TNY_ACCOUNT (transport_account));
2114 /* Suspend all pending messages */
2115 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2119 if (transport_account != NULL)
2120 g_object_unref (G_OBJECT (transport_account));
2124 modest_ui_actions_cancel_send_all (ModestWindow *win)
2126 GSList *account_names, *iter;
2128 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2131 iter = account_names;
2133 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2134 iter = g_slist_next (iter);
2137 modest_account_mgr_free_account_names (account_names);
2138 account_names = NULL;
2142 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2145 /* Check if accounts exist */
2146 gboolean accounts_exist =
2147 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2149 /* If not, allow the user to create an account before trying to send/receive. */
2150 if (!accounts_exist)
2151 modest_ui_actions_on_accounts (NULL, win);
2153 /* Cancel all sending operaitons */
2154 modest_ui_actions_cancel_send_all (win);
2158 * Refreshes all accounts. This function will be used by automatic
2162 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2163 gboolean force_connection,
2164 gboolean poke_status,
2165 gboolean interactive)
2167 GSList *account_names, *iter;
2169 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2172 iter = account_names;
2174 modest_ui_actions_do_send_receive ((const char*) iter->data,
2176 poke_status, interactive, win);
2177 iter = g_slist_next (iter);
2180 modest_account_mgr_free_account_names (account_names);
2181 account_names = NULL;
2185 * Handler of the click on Send&Receive button in the main toolbar
2188 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2190 /* Check if accounts exist */
2191 gboolean accounts_exist;
2194 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2196 /* If not, allow the user to create an account before trying to send/receive. */
2197 if (!accounts_exist)
2198 modest_ui_actions_on_accounts (NULL, win);
2200 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2201 if (MODEST_IS_MAIN_WINDOW (win)) {
2202 GtkWidget *folder_view;
2203 TnyFolderStore *folder_store;
2206 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2207 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2211 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2214 g_object_unref (folder_store);
2217 /* Refresh the active account. Force the connection if needed
2218 and poke the status of all folders */
2219 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2224 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2227 GtkWidget *header_view;
2229 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2231 header_view = modest_main_window_get_child_widget (main_window,
2232 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2236 conf = modest_runtime_get_conf ();
2238 /* what is saved/restored is depending on the style; thus; we save with
2239 * old style, then update the style, and restore for this new style
2241 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2243 if (modest_header_view_get_style
2244 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2245 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2246 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2248 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2249 MODEST_HEADER_VIEW_STYLE_DETAILS);
2251 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2252 MODEST_CONF_HEADER_VIEW_KEY);
2257 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2259 ModestMainWindow *main_window)
2261 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2262 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2264 /* in the case the folder is empty, show the empty folder message and focus
2266 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2267 if (modest_header_view_is_empty (header_view)) {
2268 TnyFolder *folder = modest_header_view_get_folder (header_view);
2269 GtkWidget *folder_view =
2270 modest_main_window_get_child_widget (main_window,
2271 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2272 if (folder != NULL) {
2273 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2274 g_object_unref (folder);
2276 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2280 /* If no header has been selected then exit */
2285 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2286 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2288 /* Update toolbar dimming state */
2289 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2290 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2294 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2296 ModestMainWindow *main_window)
2299 GtkWidget *open_widget;
2301 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2306 if (modest_header_view_count_selected_headers (header_view) > 1) {
2307 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2311 /* we check for low-mem; in that case, show a warning, and don't allow
2312 * activating headers
2314 if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE))
2317 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2318 open_widget = modest_window_get_action_widget (MODEST_WINDOW (main_window), "/MenuBar/EmailMenu/EmailOpenMenu");
2319 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2322 headers = modest_header_view_get_selected_headers (header_view);
2324 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2326 g_object_unref (headers);
2330 set_active_account_from_tny_account (TnyAccount *account,
2331 ModestWindow *window)
2333 const gchar *server_acc_name = tny_account_get_id (account);
2335 /* We need the TnyAccount provided by the
2336 account store because that is the one that
2337 knows the name of the Modest account */
2338 TnyAccount *modest_server_account = modest_server_account =
2339 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2340 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2342 if (!modest_server_account) {
2343 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2347 /* Update active account, but only if it's not a pseudo-account */
2348 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2349 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2350 const gchar *modest_acc_name =
2351 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2352 if (modest_acc_name)
2353 modest_window_set_active_account (window, modest_acc_name);
2356 g_object_unref (modest_server_account);
2361 folder_refreshed_cb (ModestMailOperation *mail_op,
2365 ModestMainWindow *win = NULL;
2366 GtkWidget *folder_view;
2367 const GError *error;
2369 g_return_if_fail (TNY_IS_FOLDER (folder));
2371 win = MODEST_MAIN_WINDOW (user_data);
2373 /* Check if the operation failed due to memory low conditions */
2374 error = modest_mail_operation_get_error (mail_op);
2375 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2376 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2377 modest_platform_run_information_dialog (GTK_WINDOW (win),
2378 dgettext("ke-recv","memr_ib_operation_disabled"),
2384 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2387 TnyFolderStore *current_folder;
2389 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2390 if (current_folder) {
2391 gboolean different = ((TnyFolderStore *) folder != current_folder);
2392 g_object_unref (current_folder);
2398 /* Check if folder is empty and set headers view contents style */
2399 if (tny_folder_get_all_count (folder) == 0)
2400 modest_main_window_set_contents_style (win,
2401 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2406 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2407 TnyFolderStore *folder_store,
2409 ModestMainWindow *main_window)
2412 GtkWidget *header_view;
2414 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2416 header_view = modest_main_window_get_child_widget(main_window,
2417 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2421 conf = modest_runtime_get_conf ();
2423 if (TNY_IS_ACCOUNT (folder_store)) {
2425 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2427 /* Show account details */
2428 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2431 if (TNY_IS_FOLDER (folder_store) && selected) {
2432 TnyAccount *account;
2433 const gchar *account_name = NULL;
2435 /* Update the active account */
2436 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2438 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2440 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2441 g_object_unref (account);
2445 /* Set the header style by default, it could
2446 be changed later by the refresh callback to
2448 modest_main_window_set_contents_style (main_window,
2449 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2451 /* Set folder on header view. This function
2452 will call tny_folder_refresh_async so we
2453 pass a callback that will be called when
2454 finished. We use that callback to set the
2455 empty view if there are no messages */
2456 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2457 TNY_FOLDER (folder_store),
2459 folder_refreshed_cb,
2462 /* Restore configuration. We need to do this
2463 *after* the set_folder because the widget
2464 memory asks the header view about its
2466 modest_widget_memory_restore (modest_runtime_get_conf (),
2467 G_OBJECT(header_view),
2468 MODEST_CONF_HEADER_VIEW_KEY);
2470 /* No need to save the header view
2471 configuration for Maemo because it only
2472 saves the sorting stuff and that it's
2473 already being done by the sort
2474 dialog. Remove it when the GNOME version
2475 has the same behaviour */
2476 #ifdef MODEST_TOOLKIT_GTK
2477 if (modest_main_window_get_contents_style (main_window) ==
2478 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2479 modest_widget_memory_save (conf, G_OBJECT (header_view),
2480 MODEST_CONF_HEADER_VIEW_KEY);
2482 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2486 /* Update dimming state */
2487 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2488 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2492 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2499 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2501 online = tny_device_is_online (modest_runtime_get_device());
2504 /* already online -- the item is simply not there... */
2505 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2507 GTK_MESSAGE_WARNING,
2509 _("The %s you selected cannot be found"),
2511 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2512 gtk_dialog_run (GTK_DIALOG(dialog));
2514 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2517 _("mcen_bd_dialog_cancel"),
2518 GTK_RESPONSE_REJECT,
2519 _("mcen_bd_dialog_ok"),
2520 GTK_RESPONSE_ACCEPT,
2522 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2523 "Do you want to get online?"), item);
2524 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2525 gtk_label_new (txt), FALSE, FALSE, 0);
2526 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2529 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2530 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2531 /* TODO: Comment about why is this commented out: */
2532 /* modest_platform_connect_and_wait (); */
2535 gtk_widget_destroy (dialog);
2539 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2542 /* g_message ("%s %s", __FUNCTION__, link); */
2547 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2550 modest_platform_activate_uri (link);
2554 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2557 modest_platform_show_uri_popup (link);
2561 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2564 /* we check for low-mem; in that case, show a warning, and don't allow
2565 * viewing attachments
2567 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2570 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2574 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2575 const gchar *address,
2578 /* g_message ("%s %s", __FUNCTION__, address); */
2582 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2583 TnyMsg *saved_draft,
2586 ModestMsgEditWindow *edit_window;
2587 ModestMainWindow *win;
2589 /* FIXME. Make the header view sensitive again. This is a
2590 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2592 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2593 modest_runtime_get_window_mgr(), FALSE));
2595 GtkWidget *hdrview = modest_main_window_get_child_widget(
2596 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2597 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2600 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2602 /* Set draft is there was no error */
2603 if (!modest_mail_operation_get_error (mail_op))
2604 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2606 g_object_unref(edit_window);
2610 enough_space_for_message (ModestMsgEditWindow *edit_window,
2613 TnyAccountStore *acc_store;
2614 guint64 available_disk, expected_size;
2619 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2620 available_disk = modest_utils_get_available_space (NULL);
2621 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2622 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2627 /* Double check: memory full condition or message too big */
2628 if (available_disk < MIN_FREE_SPACE ||
2629 expected_size > available_disk) {
2631 modest_platform_information_banner (NULL, NULL,
2633 "cerm_device_memory_full"));
2638 * djcb: if we're in low-memory state, we only allow for
2639 * saving messages smaller than
2640 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2641 * should still allow for sending anything critical...
2643 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2644 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2648 * djcb: we also make sure that the attachments are smaller than the max size
2649 * this is for the case where we'd try to forward a message with attachments
2650 * bigger than our max allowed size, or sending an message from drafts which
2651 * somehow got past our checks when attaching.
2653 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2654 modest_platform_run_information_dialog (
2655 GTK_WINDOW(edit_window),
2656 dgettext("ke-recv","memr_ib_operation_disabled"),
2665 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2667 TnyTransportAccount *transport_account;
2668 ModestMailOperation *mail_operation;
2670 gchar *account_name, *from;
2671 ModestAccountMgr *account_mgr;
2672 gboolean had_error = FALSE;
2673 ModestMainWindow *win;
2675 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2677 data = modest_msg_edit_window_get_msg_data (edit_window);
2680 if (!enough_space_for_message (edit_window, data)) {
2681 modest_msg_edit_window_free_msg_data (edit_window, data);
2685 account_name = g_strdup (data->account_name);
2686 account_mgr = modest_runtime_get_account_mgr();
2688 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2690 account_name = modest_account_mgr_get_default_account (account_mgr);
2691 if (!account_name) {
2692 g_printerr ("modest: no account found\n");
2693 modest_msg_edit_window_free_msg_data (edit_window, data);
2697 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2698 account_name = g_strdup (data->account_name);
2702 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2703 (modest_runtime_get_account_store (),
2705 TNY_ACCOUNT_TYPE_TRANSPORT));
2706 if (!transport_account) {
2707 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2708 g_free (account_name);
2709 modest_msg_edit_window_free_msg_data (edit_window, data);
2712 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2714 /* Create the mail operation */
2715 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2717 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2719 modest_mail_operation_save_to_drafts (mail_operation,
2731 data->priority_flags,
2732 on_save_to_drafts_cb,
2733 g_object_ref(edit_window));
2735 #ifdef MODEST_TOOLKIT_HILDON2
2736 /* In hildon2 we always show the information banner on saving to drafts.
2737 * It will be a system information banner in this case.
2739 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2740 modest_platform_information_banner (NULL, NULL, text);
2743 /* Use the main window as the parent of the banner, if the
2744 main window does not exist it won't be shown, if the parent
2745 window exists then it's properly shown. We don't use the
2746 editor window because it could be closed (save to drafts
2747 could happen after closing the window */
2748 win = (ModestMainWindow *)
2749 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2751 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2752 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2756 modest_msg_edit_window_set_modified (edit_window, FALSE);
2760 g_free (account_name);
2761 g_object_unref (G_OBJECT (transport_account));
2762 g_object_unref (G_OBJECT (mail_operation));
2764 modest_msg_edit_window_free_msg_data (edit_window, data);
2767 * If the drafts folder is selected then make the header view
2768 * insensitive while the message is being saved to drafts
2769 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2770 * is not very clean but it avoids letting the drafts folder
2771 * in an inconsistent state: the user could edit the message
2772 * being saved and undesirable things would happen.
2773 * In the average case the user won't notice anything at
2774 * all. In the worst case (the user is editing a really big
2775 * file from Drafts) the header view will be insensitive
2776 * during the saving process (10 or 20 seconds, depending on
2777 * the message). Anyway this is just a quick workaround: once
2778 * we find a better solution it should be removed
2779 * See NB#65125 (commend #18) for details.
2781 if (!had_error && win != NULL) {
2782 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2783 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2785 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2787 if (modest_tny_folder_is_local_folder(folder)) {
2788 TnyFolderType folder_type;
2789 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2790 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2791 GtkWidget *hdrview = modest_main_window_get_child_widget(
2792 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2793 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2797 if (folder != NULL) g_object_unref(folder);
2804 /* For instance, when clicking the Send toolbar button when editing a message: */
2806 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2808 TnyTransportAccount *transport_account = NULL;
2809 gboolean had_error = FALSE;
2811 ModestAccountMgr *account_mgr;
2812 gchar *account_name;
2814 ModestMailOperation *mail_operation;
2816 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2818 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2821 data = modest_msg_edit_window_get_msg_data (edit_window);
2824 if (!enough_space_for_message (edit_window, data)) {
2825 modest_msg_edit_window_free_msg_data (edit_window, data);
2829 account_mgr = modest_runtime_get_account_mgr();
2830 account_name = g_strdup (data->account_name);
2832 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2835 account_name = modest_account_mgr_get_default_account (account_mgr);
2837 if (!account_name) {
2838 modest_msg_edit_window_free_msg_data (edit_window, data);
2839 /* Run account setup wizard */
2840 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2845 /* Get the currently-active transport account for this modest account: */
2846 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2848 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2849 (modest_runtime_get_account_store (),
2850 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2853 if (!transport_account) {
2854 modest_msg_edit_window_free_msg_data (edit_window, data);
2855 /* Run account setup wizard */
2856 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2861 /* Create the mail operation */
2862 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2863 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2864 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2866 modest_mail_operation_send_new_mail (mail_operation,
2878 data->priority_flags);
2880 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2881 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2884 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2885 const GError *error = modest_mail_operation_get_error (mail_operation);
2886 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2887 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2888 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2889 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2896 g_free (account_name);
2897 g_object_unref (G_OBJECT (transport_account));
2898 g_object_unref (G_OBJECT (mail_operation));
2900 modest_msg_edit_window_free_msg_data (edit_window, data);
2903 modest_msg_edit_window_set_sent (edit_window, TRUE);
2905 /* Save settings and close the window: */
2906 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2913 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2914 ModestMsgEditWindow *window)
2916 ModestMsgEditFormatState *format_state = NULL;
2918 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2919 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2921 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2924 format_state = modest_msg_edit_window_get_format_state (window);
2925 g_return_if_fail (format_state != NULL);
2927 format_state->bold = gtk_toggle_action_get_active (action);
2928 modest_msg_edit_window_set_format_state (window, format_state);
2929 g_free (format_state);
2934 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2935 ModestMsgEditWindow *window)
2937 ModestMsgEditFormatState *format_state = NULL;
2939 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2940 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2942 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2945 format_state = modest_msg_edit_window_get_format_state (window);
2946 g_return_if_fail (format_state != NULL);
2948 format_state->italics = gtk_toggle_action_get_active (action);
2949 modest_msg_edit_window_set_format_state (window, format_state);
2950 g_free (format_state);
2955 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2956 ModestMsgEditWindow *window)
2958 ModestMsgEditFormatState *format_state = NULL;
2960 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2961 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2963 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2966 format_state = modest_msg_edit_window_get_format_state (window);
2967 g_return_if_fail (format_state != NULL);
2969 format_state->bullet = gtk_toggle_action_get_active (action);
2970 modest_msg_edit_window_set_format_state (window, format_state);
2971 g_free (format_state);
2976 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2977 GtkRadioAction *selected,
2978 ModestMsgEditWindow *window)
2980 ModestMsgEditFormatState *format_state = NULL;
2981 GtkJustification value;
2983 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2985 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2988 value = gtk_radio_action_get_current_value (selected);
2990 format_state = modest_msg_edit_window_get_format_state (window);
2991 g_return_if_fail (format_state != NULL);
2993 format_state->justification = value;
2994 modest_msg_edit_window_set_format_state (window, format_state);
2995 g_free (format_state);
2999 modest_ui_actions_on_select_editor_color (GtkAction *action,
3000 ModestMsgEditWindow *window)
3002 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3003 g_return_if_fail (GTK_IS_ACTION (action));
3005 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3008 modest_msg_edit_window_select_color (window);
3012 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3013 ModestMsgEditWindow *window)
3015 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3016 g_return_if_fail (GTK_IS_ACTION (action));
3018 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3021 modest_msg_edit_window_select_background_color (window);
3025 modest_ui_actions_on_insert_image (GtkAction *action,
3026 ModestMsgEditWindow *window)
3028 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3029 g_return_if_fail (GTK_IS_ACTION (action));
3032 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3035 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3038 modest_msg_edit_window_insert_image (window);
3042 modest_ui_actions_on_attach_file (GtkAction *action,
3043 ModestMsgEditWindow *window)
3045 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3046 g_return_if_fail (GTK_IS_ACTION (action));
3048 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3051 modest_msg_edit_window_offer_attach_file (window);
3055 modest_ui_actions_on_remove_attachments (GtkAction *action,
3056 ModestMsgEditWindow *window)
3058 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3059 g_return_if_fail (GTK_IS_ACTION (action));
3061 modest_msg_edit_window_remove_attachments (window, NULL);
3065 #ifndef MODEST_TOOLKIT_GTK
3070 TnyFolderStore *folder;
3071 } CreateFolderHelper;
3074 show_create_folder_in_timeout (gpointer data)
3076 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3078 /* Remove the timeout ASAP, we can not wait until the dialog
3079 is shown because it could take a lot of time and so the
3080 timeout could be called twice or more times */
3081 g_source_remove (helper->handler);
3083 gdk_threads_enter ();
3084 do_create_folder (helper->win, helper->folder, helper->name);
3085 gdk_threads_leave ();
3087 g_object_unref (helper->win);
3088 g_object_unref (helper->folder);
3089 g_free (helper->name);
3090 g_slice_free (CreateFolderHelper, helper);
3097 do_create_folder_cb (ModestMailOperation *mail_op,
3098 TnyFolderStore *parent_folder,
3099 TnyFolder *new_folder,
3102 gchar *suggested_name = (gchar *) user_data;
3103 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3105 if (modest_mail_operation_get_error (mail_op)) {
3107 /* Show an error. If there was some problem writing to
3108 disk, show it, otherwise show the generic folder
3109 create error. We do it here and not in an error
3110 handler because the call to do_create_folder will
3111 stop the main loop in a gtk_dialog_run and then,
3112 the message won't be shown until that dialog is
3114 modest_ui_actions_disk_operations_error_handler (mail_op,
3115 _("mail_in_ui_folder_create_error"));
3117 /* Try again. Do *NOT* show any error because the mail
3118 operations system will do it for us because we
3119 created the mail_op with new_with_error_handler */
3120 #ifndef MODEST_TOOLKIT_GTK
3121 CreateFolderHelper *helper;
3122 helper = g_slice_new0 (CreateFolderHelper);
3123 helper->name = g_strdup (suggested_name);
3124 helper->folder = g_object_ref (parent_folder);
3125 helper->win = g_object_ref (source_win);
3127 /* Ugly but neccesary stuff. The problem is that the
3128 dialog when is shown calls a function that destroys
3129 all the temporary windows, so the banner is
3131 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3133 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3136 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3137 * FIXME: any other? */
3138 GtkWidget *folder_view;
3140 if (MODEST_IS_MAIN_WINDOW(source_win))
3142 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3143 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3146 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3148 /* Select the newly created folder. It could happen
3149 that the widget is no longer there (i.e. the window
3150 has been destroyed, so we need to check this */
3152 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3154 g_object_unref (new_folder);
3156 /* Free. Note that the first time it'll be NULL so noop */
3157 g_free (suggested_name);
3158 g_object_unref (source_win);
3162 do_create_folder (GtkWindow *parent_window,
3163 TnyFolderStore *parent_folder,
3164 const gchar *suggested_name)
3167 gchar *folder_name = NULL;
3169 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3171 (gchar *) suggested_name,
3174 if (result == GTK_RESPONSE_ACCEPT) {
3175 ModestMailOperation *mail_op;
3177 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3178 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3180 modest_mail_operation_create_folder (mail_op,
3182 (const gchar *) folder_name,
3183 do_create_folder_cb,
3185 g_object_unref (mail_op);
3190 create_folder_performer (gboolean canceled,
3192 GtkWindow *parent_window,
3193 TnyAccount *account,
3196 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3198 if (canceled || err) {
3199 /* In memory full conditions we could get this error here */
3200 check_memory_full_error ((GtkWidget *) parent_window, err);
3204 /* Run the new folder dialog */
3205 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3208 g_object_unref (parent_folder);
3212 modest_ui_actions_create_folder(GtkWidget *parent_window,
3213 GtkWidget *folder_view)
3215 TnyFolderStore *parent_folder;
3217 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3219 if (parent_folder) {
3220 /* The parent folder will be freed in the callback */
3221 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3224 create_folder_performer,
3230 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3232 GtkWidget *folder_view;
3234 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3236 folder_view = modest_main_window_get_child_widget (main_window,
3237 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3241 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3245 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3248 const GError *error = NULL;
3249 const gchar *message = NULL;
3251 /* Get error message */
3252 error = modest_mail_operation_get_error (mail_op);
3254 g_return_if_reached ();
3256 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3257 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3258 message = _CS("ckdg_ib_folder_already_exists");
3259 } else if (error->domain == TNY_ERROR_DOMAIN &&
3260 error->code == TNY_SERVICE_ERROR_STATE) {
3261 /* This means that the folder is already in use (a
3262 message is opened for example */
3263 message = _("emev_ni_internal_error");
3265 message = _("emev_ib_ui_imap_unable_to_rename");
3268 /* We don't set a parent for the dialog because the dialog
3269 will be destroyed so the banner won't appear */
3270 modest_platform_information_banner (NULL, NULL, message);
3274 TnyFolderStore *folder;
3279 on_rename_folder_cb (ModestMailOperation *mail_op,
3280 TnyFolder *new_folder,
3283 ModestFolderView *folder_view;
3285 /* If the window was closed when renaming a folder this could
3287 if (!MODEST_IS_FOLDER_VIEW (user_data))
3290 folder_view = MODEST_FOLDER_VIEW (user_data);
3291 /* Note that if the rename fails new_folder will be NULL */
3293 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3295 modest_folder_view_select_first_inbox_or_local (folder_view);
3297 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3301 on_rename_folder_performer (gboolean canceled,
3303 GtkWindow *parent_window,
3304 TnyAccount *account,
3307 ModestMailOperation *mail_op = NULL;
3308 GtkTreeSelection *sel = NULL;
3309 GtkWidget *folder_view = NULL;
3310 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3312 if (canceled || err) {
3313 /* In memory full conditions we could get this error here */
3314 check_memory_full_error ((GtkWidget *) parent_window, err);
3315 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3317 folder_view = modest_main_window_get_child_widget (
3318 MODEST_MAIN_WINDOW (parent_window),
3319 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3322 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3323 modest_ui_actions_rename_folder_error_handler,
3324 parent_window, NULL);
3326 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3329 /* Clear the headers view */
3330 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3331 gtk_tree_selection_unselect_all (sel);
3333 /* Actually rename the folder */
3334 modest_mail_operation_rename_folder (mail_op,
3335 TNY_FOLDER (data->folder),
3336 (const gchar *) (data->new_name),
3337 on_rename_folder_cb,
3339 g_object_unref (data->folder);
3340 g_object_unref (mail_op);
3343 g_free (data->new_name);
3348 modest_ui_actions_on_rename_folder (GtkAction *action,
3349 ModestMainWindow *main_window)
3351 TnyFolderStore *folder;
3352 GtkWidget *folder_view;
3353 GtkWidget *header_view;
3355 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3357 folder_view = modest_main_window_get_child_widget (main_window,
3358 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3362 header_view = modest_main_window_get_child_widget (main_window,
3363 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3368 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3373 if (TNY_IS_FOLDER (folder)) {
3376 const gchar *current_name;
3377 TnyFolderStore *parent;
3378 gboolean do_rename = TRUE;
3380 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3381 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3382 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3383 parent, current_name,
3385 g_object_unref (parent);
3387 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3390 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3391 rename_folder_data->folder = g_object_ref (folder);
3392 rename_folder_data->new_name = folder_name;
3393 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3394 folder, on_rename_folder_performer, rename_folder_data);
3397 g_object_unref (folder);
3401 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3404 GObject *win = modest_mail_operation_get_source (mail_op);
3406 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3407 _("mail_in_ui_folder_delete_error"),
3409 g_object_unref (win);
3413 TnyFolderStore *folder;
3414 gboolean move_to_trash;
3418 on_delete_folder_cb (gboolean canceled,
3420 GtkWindow *parent_window,
3421 TnyAccount *account,
3424 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3425 GtkWidget *folder_view;
3426 ModestMailOperation *mail_op;
3427 GtkTreeSelection *sel;
3429 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3430 g_object_unref (G_OBJECT (info->folder));
3435 folder_view = modest_main_window_get_child_widget (
3436 MODEST_MAIN_WINDOW (parent_window),
3437 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3439 /* Unselect the folder before deleting it to free the headers */
3440 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3441 gtk_tree_selection_unselect_all (sel);
3443 /* Create the mail operation */
3445 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3446 modest_ui_actions_delete_folder_error_handler,
3449 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3451 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3453 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3455 g_object_unref (G_OBJECT (mail_op));
3456 g_object_unref (G_OBJECT (info->folder));
3461 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3463 TnyFolderStore *folder;
3464 GtkWidget *folder_view;
3468 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3470 folder_view = modest_main_window_get_child_widget (main_window,
3471 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3475 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3477 /* Show an error if it's an account */
3478 if (!TNY_IS_FOLDER (folder)) {
3479 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3480 _("mail_in_ui_folder_delete_error"),
3482 g_object_unref (G_OBJECT (folder));
3487 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3488 tny_folder_get_name (TNY_FOLDER (folder)));
3489 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3490 (const gchar *) message);
3493 if (response == GTK_RESPONSE_OK) {
3494 DeleteFolderInfo *info;
3495 info = g_new0(DeleteFolderInfo, 1);
3496 info->folder = folder;
3497 info->move_to_trash = move_to_trash;
3498 g_object_ref (G_OBJECT (info->folder));
3499 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3500 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3502 TNY_FOLDER_STORE (account),
3503 on_delete_folder_cb, info);
3504 g_object_unref (account);
3506 g_object_unref (G_OBJECT (folder));
3510 modest_ui_actions_on_delete_folder (GtkAction *action,
3511 ModestMainWindow *main_window)
3513 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3515 delete_folder (main_window, FALSE);
3519 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3521 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3523 delete_folder (main_window, TRUE);
3527 typedef struct _PasswordDialogFields {
3528 GtkWidget *username;
3529 GtkWidget *password;
3531 } PasswordDialogFields;
3534 password_dialog_check_field (GtkEditable *editable,
3535 PasswordDialogFields *fields)
3538 gboolean any_value_empty = FALSE;
3540 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3541 if ((value == NULL) || value[0] == '\0') {
3542 any_value_empty = TRUE;
3544 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3545 if ((value == NULL) || value[0] == '\0') {
3546 any_value_empty = TRUE;
3548 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3552 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3553 const gchar* server_account_name,
3558 ModestMainWindow *main_window)
3560 g_return_if_fail(server_account_name);
3561 gboolean completed = FALSE;
3562 PasswordDialogFields *fields = NULL;
3564 /* Initalize output parameters: */
3571 #ifndef MODEST_TOOLKIT_GTK
3572 /* Maemo uses a different (awkward) button order,
3573 * It should probably just use gtk_alternative_dialog_button_order ().
3575 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3578 _("mcen_bd_dialog_ok"),
3579 GTK_RESPONSE_ACCEPT,
3580 _("mcen_bd_dialog_cancel"),
3581 GTK_RESPONSE_REJECT,
3584 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3588 GTK_RESPONSE_REJECT,
3590 GTK_RESPONSE_ACCEPT,
3592 #endif /* !MODEST_TOOLKIT_GTK */
3594 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3596 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3597 modest_runtime_get_account_mgr(), server_account_name);
3598 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3599 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3605 /* This causes a warning because the logical ID has no %s in it,
3606 * though the translation does, but there is not much we can do about that: */
3607 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3608 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3611 g_free (server_name);
3615 gchar *initial_username = modest_account_mgr_get_server_account_username (
3616 modest_runtime_get_account_mgr(), server_account_name);
3618 GtkWidget *entry_username = gtk_entry_new ();
3619 if (initial_username)
3620 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3621 /* Dim this if a connection has ever succeeded with this username,
3622 * as per the UI spec: */
3623 /* const gboolean username_known = */
3624 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3625 /* modest_runtime_get_account_mgr(), server_account_name); */
3626 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3628 /* We drop the username sensitive code and disallow changing it here
3629 * as tinymail does not support really changing the username in the callback
3631 gtk_widget_set_sensitive (entry_username, FALSE);
3633 #ifndef MODEST_TOOLKIT_GTK
3634 /* Auto-capitalization is the default, so let's turn it off: */
3635 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3637 /* Create a size group to be used by all captions.
3638 * Note that HildonCaption does not create a default size group if we do not specify one.
3639 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3640 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3642 GtkWidget *caption = hildon_caption_new (sizegroup,
3643 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3644 gtk_widget_show (entry_username);
3645 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3646 FALSE, FALSE, MODEST_MARGIN_HALF);
3647 gtk_widget_show (caption);
3649 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3651 #endif /* !MODEST_TOOLKIT_GTK */
3654 GtkWidget *entry_password = gtk_entry_new ();
3655 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3656 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3658 #ifndef MODEST_TOOLKIT_GTK
3659 /* Auto-capitalization is the default, so let's turn it off: */
3660 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3661 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3663 caption = hildon_caption_new (sizegroup,
3664 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3665 gtk_widget_show (entry_password);
3666 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3667 FALSE, FALSE, MODEST_MARGIN_HALF);
3668 gtk_widget_show (caption);
3669 g_object_unref (sizegroup);
3671 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3673 #endif /* !MODEST_TOOLKIT_GTK */
3675 if (initial_username != NULL)
3676 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3678 /* This is not in the Maemo UI spec:
3679 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3680 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3684 fields = g_slice_new0 (PasswordDialogFields);
3685 fields->username = entry_username;
3686 fields->password = entry_password;
3687 fields->dialog = dialog;
3689 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3690 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3691 password_dialog_check_field (NULL, fields);
3693 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3695 while (!completed) {
3697 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3699 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3701 /* Note that an empty field becomes the "" string */
3702 if (*username && strlen (*username) > 0) {
3703 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3704 server_account_name,
3708 const gboolean username_was_changed =
3709 (strcmp (*username, initial_username) != 0);
3710 if (username_was_changed) {
3711 g_warning ("%s: tinymail does not yet support changing the "
3712 "username in the get_password() callback.\n", __FUNCTION__);
3716 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3717 _("mcen_ib_username_pw_incorrect"));
3723 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3725 /* We do not save the password in the configuration,
3726 * because this function is only called for passwords that should
3727 * not be remembered:
3728 modest_server_account_set_password (
3729 modest_runtime_get_account_mgr(), server_account_name,
3736 /* Set parent to NULL or the banner will disappear with its parent dialog */
3737 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3748 /* This is not in the Maemo UI spec:
3749 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3755 gtk_widget_destroy (dialog);
3756 g_slice_free (PasswordDialogFields, fields);
3758 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3762 modest_ui_actions_on_cut (GtkAction *action,
3763 ModestWindow *window)
3765 GtkWidget *focused_widget;
3766 GtkClipboard *clipboard;
3768 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3769 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3770 if (GTK_IS_EDITABLE (focused_widget)) {
3771 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3772 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3773 gtk_clipboard_store (clipboard);
3774 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3775 GtkTextBuffer *buffer;
3777 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3778 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3779 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3780 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3781 gtk_clipboard_store (clipboard);
3783 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3784 TnyList *header_list = modest_header_view_get_selected_headers (
3785 MODEST_HEADER_VIEW (focused_widget));
3786 gboolean continue_download = FALSE;
3787 gint num_of_unc_msgs;
3789 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3791 if (num_of_unc_msgs) {
3792 TnyAccount *account = get_account_from_header_list (header_list);
3794 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3795 g_object_unref (account);
3799 if (num_of_unc_msgs == 0 || continue_download) {
3800 /* modest_platform_information_banner (
3801 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3802 modest_header_view_cut_selection (
3803 MODEST_HEADER_VIEW (focused_widget));
3806 g_object_unref (header_list);
3807 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3808 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3813 modest_ui_actions_on_copy (GtkAction *action,
3814 ModestWindow *window)
3816 GtkClipboard *clipboard;
3817 GtkWidget *focused_widget;
3818 gboolean copied = TRUE;
3820 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3821 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3823 if (GTK_IS_LABEL (focused_widget)) {
3825 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3826 gtk_clipboard_set_text (clipboard, selection, -1);
3828 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3829 gtk_clipboard_store (clipboard);
3830 } else if (GTK_IS_EDITABLE (focused_widget)) {
3831 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3832 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3833 gtk_clipboard_store (clipboard);
3834 } else if (GTK_IS_HTML (focused_widget)) {
3837 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3838 if ((sel == NULL) || (sel[0] == '\0')) {
3841 gtk_html_copy (GTK_HTML (focused_widget));
3842 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3843 gtk_clipboard_store (clipboard);
3845 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3846 GtkTextBuffer *buffer;
3847 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3848 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3849 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3850 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3851 gtk_clipboard_store (clipboard);
3853 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3854 TnyList *header_list = modest_header_view_get_selected_headers (
3855 MODEST_HEADER_VIEW (focused_widget));
3856 gboolean continue_download = FALSE;
3857 gint num_of_unc_msgs;
3859 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3861 if (num_of_unc_msgs) {
3862 TnyAccount *account = get_account_from_header_list (header_list);
3864 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3865 g_object_unref (account);
3869 if (num_of_unc_msgs == 0 || continue_download) {
3870 modest_platform_information_banner (
3871 NULL, NULL, _CS("mcen_ib_getting_items"));
3872 modest_header_view_copy_selection (
3873 MODEST_HEADER_VIEW (focused_widget));
3877 g_object_unref (header_list);
3879 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3880 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3883 /* Show information banner if there was a copy to clipboard */
3885 modest_platform_information_banner (
3886 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3890 modest_ui_actions_on_undo (GtkAction *action,
3891 ModestWindow *window)
3893 ModestEmailClipboard *clipboard = NULL;
3895 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3896 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3897 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3898 /* Clear clipboard source */
3899 clipboard = modest_runtime_get_email_clipboard ();
3900 modest_email_clipboard_clear (clipboard);
3903 g_return_if_reached ();
3908 modest_ui_actions_on_redo (GtkAction *action,
3909 ModestWindow *window)
3911 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3912 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3915 g_return_if_reached ();
3921 destroy_information_note (ModestMailOperation *mail_op,
3924 /* destroy information note */
3925 gtk_widget_destroy (GTK_WIDGET(user_data));
3929 destroy_folder_information_note (ModestMailOperation *mail_op,
3930 TnyFolder *new_folder,
3933 /* destroy information note */
3934 gtk_widget_destroy (GTK_WIDGET(user_data));
3939 paste_as_attachment_free (gpointer data)
3941 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3943 if (helper->banner) {
3944 gtk_widget_destroy (helper->banner);
3945 g_object_unref (helper->banner);
3951 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3956 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3957 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3962 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3967 modest_ui_actions_on_paste (GtkAction *action,
3968 ModestWindow *window)
3970 GtkWidget *focused_widget = NULL;
3971 GtkWidget *inf_note = NULL;
3972 ModestMailOperation *mail_op = NULL;
3974 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3975 if (GTK_IS_EDITABLE (focused_widget)) {
3976 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3977 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3978 ModestEmailClipboard *e_clipboard = NULL;
3979 e_clipboard = modest_runtime_get_email_clipboard ();
3980 if (modest_email_clipboard_cleared (e_clipboard)) {
3981 GtkTextBuffer *buffer;
3982 GtkClipboard *clipboard;
3984 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3985 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3986 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3987 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3988 ModestMailOperation *mail_op;
3989 TnyFolder *src_folder;
3992 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3993 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3994 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3995 _CS("ckct_nw_pasting"));
3996 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3997 mail_op = modest_mail_operation_new (G_OBJECT (window));
3998 if (helper->banner != NULL) {
3999 g_object_ref (G_OBJECT (helper->banner));
4000 gtk_widget_show (GTK_WIDGET (helper->banner));
4004 modest_mail_operation_get_msgs_full (mail_op,
4006 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4008 paste_as_attachment_free);
4011 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4012 ModestEmailClipboard *clipboard = NULL;
4013 TnyFolder *src_folder = NULL;
4014 TnyFolderStore *folder_store = NULL;
4015 TnyList *data = NULL;
4016 gboolean delete = FALSE;
4018 /* Check clipboard source */
4019 clipboard = modest_runtime_get_email_clipboard ();
4020 if (modest_email_clipboard_cleared (clipboard))
4023 /* Get elements to paste */
4024 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4026 /* Create a new mail operation */
4027 mail_op = modest_mail_operation_new (G_OBJECT(window));
4029 /* Get destination folder */
4030 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4032 /* transfer messages */
4036 /* Ask for user confirmation */
4038 modest_ui_actions_msgs_move_to_confirmation (window,
4039 TNY_FOLDER (folder_store),
4043 if (response == GTK_RESPONSE_OK) {
4044 /* Launch notification */
4045 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4046 _CS("ckct_nw_pasting"));
4047 if (inf_note != NULL) {
4048 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4049 gtk_widget_show (GTK_WIDGET(inf_note));
4052 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4053 modest_mail_operation_xfer_msgs (mail_op,
4055 TNY_FOLDER (folder_store),
4057 destroy_information_note,
4060 g_object_unref (mail_op);
4063 } else if (src_folder != NULL) {
4064 /* Launch notification */
4065 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4066 _CS("ckct_nw_pasting"));
4067 if (inf_note != NULL) {
4068 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4069 gtk_widget_show (GTK_WIDGET(inf_note));
4072 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4073 modest_mail_operation_xfer_folder (mail_op,
4077 destroy_folder_information_note,
4083 g_object_unref (data);
4084 if (src_folder != NULL)
4085 g_object_unref (src_folder);
4086 if (folder_store != NULL)
4087 g_object_unref (folder_store);
4093 modest_ui_actions_on_select_all (GtkAction *action,
4094 ModestWindow *window)
4096 GtkWidget *focused_widget;
4098 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4099 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4100 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4101 } else if (GTK_IS_LABEL (focused_widget)) {
4102 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4103 } else if (GTK_IS_EDITABLE (focused_widget)) {
4104 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4105 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4106 GtkTextBuffer *buffer;
4107 GtkTextIter start, end;
4109 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4110 gtk_text_buffer_get_start_iter (buffer, &start);
4111 gtk_text_buffer_get_end_iter (buffer, &end);
4112 gtk_text_buffer_select_range (buffer, &start, &end);
4113 } else if (GTK_IS_HTML (focused_widget)) {
4114 gtk_html_select_all (GTK_HTML (focused_widget));
4115 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4116 GtkWidget *header_view = focused_widget;
4117 GtkTreeSelection *selection = NULL;
4119 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4120 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4121 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4124 /* Disable window dimming management */
4125 modest_window_disable_dimming (MODEST_WINDOW(window));
4127 /* Select all messages */
4128 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4129 gtk_tree_selection_select_all (selection);
4131 /* Set focuse on header view */
4132 gtk_widget_grab_focus (header_view);
4134 /* Enable window dimming management */
4135 modest_window_enable_dimming (MODEST_WINDOW(window));
4136 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4137 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4143 modest_ui_actions_on_mark_as_read (GtkAction *action,
4144 ModestWindow *window)
4146 g_return_if_fail (MODEST_IS_WINDOW(window));
4148 /* Mark each header as read */
4149 do_headers_action (window, headers_action_mark_as_read, NULL);
4153 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4154 ModestWindow *window)
4156 g_return_if_fail (MODEST_IS_WINDOW(window));
4158 /* Mark each header as read */
4159 do_headers_action (window, headers_action_mark_as_unread, NULL);
4163 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4164 GtkRadioAction *selected,
4165 ModestWindow *window)
4169 value = gtk_radio_action_get_current_value (selected);
4170 if (MODEST_IS_WINDOW (window)) {
4171 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4176 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4177 GtkRadioAction *selected,
4178 ModestWindow *window)
4180 TnyHeaderFlags flags;
4181 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4183 flags = gtk_radio_action_get_current_value (selected);
4184 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4188 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4189 GtkRadioAction *selected,
4190 ModestWindow *window)
4194 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4196 file_format = gtk_radio_action_get_current_value (selected);
4197 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4202 modest_ui_actions_on_zoom_plus (GtkAction *action,
4203 ModestWindow *window)
4205 g_return_if_fail (MODEST_IS_WINDOW (window));
4207 modest_window_zoom_plus (MODEST_WINDOW (window));
4211 modest_ui_actions_on_zoom_minus (GtkAction *action,
4212 ModestWindow *window)
4214 g_return_if_fail (MODEST_IS_WINDOW (window));
4216 modest_window_zoom_minus (MODEST_WINDOW (window));
4220 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4221 ModestWindow *window)
4223 ModestWindowMgr *mgr;
4224 gboolean fullscreen, active;
4225 g_return_if_fail (MODEST_IS_WINDOW (window));
4227 mgr = modest_runtime_get_window_mgr ();
4229 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4230 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4232 if (active != fullscreen) {
4233 modest_window_mgr_set_fullscreen_mode (mgr, active);
4234 #ifndef MODEST_TOOLKIT_HILDON2
4235 gtk_window_present (GTK_WINDOW (window));
4241 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4242 ModestWindow *window)
4244 ModestWindowMgr *mgr;
4245 gboolean fullscreen;
4247 g_return_if_fail (MODEST_IS_WINDOW (window));
4249 mgr = modest_runtime_get_window_mgr ();
4250 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4251 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4253 #ifndef MODEST_TOOLKIT_HILDON2
4254 gtk_window_present (GTK_WINDOW (window));
4259 * Used by modest_ui_actions_on_details to call do_headers_action
4262 headers_action_show_details (TnyHeader *header,
4263 ModestWindow *window,
4270 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
4273 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) window);
4274 gtk_widget_show_all (dialog);
4276 g_signal_connect_swapped (dialog, "response",
4277 G_CALLBACK (gtk_widget_destroy),
4282 * Show the folder details in a ModestDetailsDialog widget
4285 show_folder_details (TnyFolder *folder,
4291 dialog = modest_details_dialog_new_with_folder (window, folder);
4294 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4295 gtk_widget_show_all (dialog);
4296 gtk_dialog_run (GTK_DIALOG (dialog));
4298 gtk_widget_destroy (dialog);
4302 * Show the header details in a ModestDetailsDialog widget
4305 modest_ui_actions_on_details (GtkAction *action,
4308 TnyList * headers_list;
4312 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4315 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4318 g_object_unref (msg);
4320 headers_list = get_selected_headers (win);
4324 iter = tny_list_create_iterator (headers_list);
4326 header = TNY_HEADER (tny_iterator_get_current (iter));
4328 headers_action_show_details (header, win, NULL);
4329 g_object_unref (header);
4332 g_object_unref (iter);
4333 g_object_unref (headers_list);
4335 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4336 GtkWidget *folder_view, *header_view;
4338 /* Check which widget has the focus */
4339 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4340 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4341 if (gtk_widget_is_focus (folder_view)) {
4342 TnyFolderStore *folder_store
4343 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4344 if (!folder_store) {
4345 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4348 /* Show only when it's a folder */
4349 /* This function should not be called for account items,
4350 * because we dim the menu item for them. */
4351 if (TNY_IS_FOLDER (folder_store)) {
4352 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
4355 g_object_unref (folder_store);
4358 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4359 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4360 /* Show details of each header */
4361 do_headers_action (win, headers_action_show_details, header_view);
4367 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4368 ModestMsgEditWindow *window)
4370 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4372 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4376 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4377 ModestMsgEditWindow *window)
4379 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4381 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4385 modest_ui_actions_toggle_folders_view (GtkAction *action,
4386 ModestMainWindow *main_window)
4388 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4390 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4391 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4393 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4397 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4398 ModestWindow *window)
4400 gboolean active, fullscreen = FALSE;
4401 ModestWindowMgr *mgr;
4403 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4405 /* Check if we want to toggle the toolbar vuew in fullscreen
4407 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4408 "ViewShowToolbarFullScreen")) {
4412 /* Toggle toolbar */
4413 mgr = modest_runtime_get_window_mgr ();
4414 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4418 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4419 ModestMsgEditWindow *window)
4421 modest_msg_edit_window_select_font (window);
4426 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4427 const gchar *display_name,
4430 /* don't update the display name if it was already set;
4431 * updating the display name apparently is expensive */
4432 const gchar* old_name = gtk_window_get_title (window);
4434 if (display_name == NULL)
4437 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4438 return; /* don't do anything */
4440 /* This is usually used to change the title of the main window, which
4441 * is the one that holds the folder view. Note that this change can
4442 * happen even when the widget doesn't have the focus. */
4443 gtk_window_set_title (window, display_name);
4448 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4450 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4451 modest_msg_edit_window_select_contacts (window);
4455 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4457 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4458 modest_msg_edit_window_check_names (window, FALSE);
4462 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4464 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4465 GTK_WIDGET (user_data));
4469 * This function is used to track changes in the selection of the
4470 * folder view that is inside the "move to" dialog to enable/disable
4471 * the OK button because we do not want the user to select a disallowed
4472 * destination for a folder.
4473 * The user also not desired to be able to use NEW button on items where
4474 * folder creation is not possibel.
4477 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4478 TnyFolderStore *folder_store,
4482 GtkWidget *dialog = NULL;
4483 GtkWidget *ok_button = NULL, *new_button = NULL;
4484 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4485 gboolean moving_folder = FALSE;
4486 gboolean is_local_account = TRUE;
4487 GtkWidget *folder_view = NULL;
4488 ModestTnyFolderRules rules;
4490 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4495 /* Get the OK button */
4496 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4500 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4501 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4503 /* check if folder_store is an remote account */
4504 if (TNY_IS_ACCOUNT (folder_store)) {
4505 TnyAccount *local_account = NULL;
4506 TnyAccount *mmc_account = NULL;
4507 ModestTnyAccountStore *account_store = NULL;
4509 account_store = modest_runtime_get_account_store ();
4510 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4511 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4513 if ((gpointer) local_account != (gpointer) folder_store &&
4514 (gpointer) mmc_account != (gpointer) folder_store) {
4515 ModestProtocolType proto;
4516 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4517 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4518 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4520 is_local_account = FALSE;
4521 /* New button should be dimmed on remote
4523 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4525 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4527 g_object_unref (local_account);
4528 g_object_unref (mmc_account);
4531 /* Check the target folder rules */
4532 if (TNY_IS_FOLDER (folder_store)) {
4533 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4534 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4535 ok_sensitive = FALSE;
4536 new_sensitive = FALSE;
4541 /* Check if we're moving a folder */
4542 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4543 /* Get the widgets */
4544 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4545 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4546 if (gtk_widget_is_focus (folder_view))
4547 moving_folder = TRUE;
4550 if (moving_folder) {
4551 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4553 /* Get the folder to move */
4554 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4556 /* Check that we're not moving to the same folder */
4557 if (TNY_IS_FOLDER (moved_folder)) {
4558 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4559 if (parent == folder_store)
4560 ok_sensitive = FALSE;
4561 g_object_unref (parent);
4564 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4565 /* Do not allow to move to an account unless it's the
4566 local folders account */
4567 if (!is_local_account)
4568 ok_sensitive = FALSE;
4571 if (ok_sensitive && (moved_folder == folder_store)) {
4572 /* Do not allow to move to itself */
4573 ok_sensitive = FALSE;
4575 g_object_unref (moved_folder);
4577 TnyFolder *src_folder = NULL;
4579 /* Moving a message */
4580 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4582 TnyHeader *header = NULL;
4583 header = modest_msg_view_window_get_header
4584 (MODEST_MSG_VIEW_WINDOW (user_data));
4585 if (!TNY_IS_HEADER(header))
4586 g_warning ("%s: could not get source header", __FUNCTION__);
4588 src_folder = tny_header_get_folder (header);
4591 g_object_unref (header);
4594 TNY_FOLDER (modest_folder_view_get_selected
4595 (MODEST_FOLDER_VIEW (folder_view)));
4598 if (TNY_IS_FOLDER(src_folder)) {
4599 /* Do not allow to move the msg to the same folder */
4600 /* Do not allow to move the msg to an account */
4601 if ((gpointer) src_folder == (gpointer) folder_store ||
4602 TNY_IS_ACCOUNT (folder_store))
4603 ok_sensitive = FALSE;
4604 g_object_unref (src_folder);
4606 g_warning ("%s: could not get source folder", __FUNCTION__);
4610 /* Set sensitivity of the OK button */
4611 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4612 /* Set sensitivity of the NEW button */
4613 gtk_widget_set_sensitive (new_button, new_sensitive);
4617 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4620 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4622 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4623 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4627 create_move_to_dialog (GtkWindow *win,
4628 GtkWidget *folder_view,
4629 GtkWidget **tree_view)
4631 GtkWidget *dialog, *scroll;
4632 GtkWidget *new_button, *ok_button;
4634 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4636 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4639 #ifndef MODEST_TOOLKIT_GTK
4640 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4641 /* We do this manually so GTK+ does not associate a response ID for
4643 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4644 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4645 gtk_widget_show (new_button);
4646 #ifndef MODEST_TOOLKIT_HILDON2
4647 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4650 /* We do this manually so GTK+ does not associate a response ID for
4652 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4653 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4654 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4655 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4656 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4657 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4658 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4660 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4661 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4663 /* Create scrolled window */
4664 scroll = gtk_scrolled_window_new (NULL, NULL);
4665 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4666 GTK_POLICY_AUTOMATIC,
4667 GTK_POLICY_AUTOMATIC);
4669 #ifdef MODEST_TOOLKIT_GTK
4670 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4673 /* Create folder view */
4674 *tree_view = modest_platform_create_folder_view (NULL);
4676 /* Track changes in the selection to
4677 * disable the OK button whenever "Move to" is not possible
4678 * disbale NEW button whenever New is not possible */
4679 g_signal_connect (*tree_view,
4680 "folder_selection_changed",
4681 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4684 /* Listen to clicks on New button */
4685 g_signal_connect (G_OBJECT (new_button),
4687 G_CALLBACK(create_move_to_dialog_on_new_folder),
4690 /* It could happen that we're trying to move a message from a
4691 window (msg window for example) after the main window was
4692 closed, so we can not just get the model of the folder
4694 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4695 const gchar *visible_id = NULL;
4697 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4698 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4699 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4700 MODEST_FOLDER_VIEW(*tree_view));
4703 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4705 /* Show the same account than the one that is shown in the main window */
4706 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4709 const gchar *active_account_name = NULL;
4710 ModestAccountMgr *mgr = NULL;
4711 ModestAccountSettings *settings = NULL;
4712 ModestServerAccountSettings *store_settings = NULL;
4714 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4715 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4716 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4717 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4719 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4720 mgr = modest_runtime_get_account_mgr ();
4721 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4724 const gchar *store_account_name;
4725 store_settings = modest_account_settings_get_store_settings (settings);
4726 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4728 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4729 store_account_name);
4730 g_object_unref (store_settings);
4731 g_object_unref (settings);
4735 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4736 * get_folder_view_from_move_to_dialog
4737 * (see above) later (needed for focus handling)
4739 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4742 /* Hide special folders */
4743 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4745 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4747 /* Add scroll to dialog */
4748 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4749 scroll, TRUE, TRUE, 0);
4751 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4752 #ifndef MODEST_TOOLKIT_GTK
4753 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4755 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4764 * Shows a confirmation dialog to the user when we're moving messages
4765 * from a remote server to the local storage. Returns the dialog
4766 * response. If it's other kind of movement then it always returns
4769 * This one is used by the next functions:
4770 * modest_ui_actions_on_paste - commented out
4771 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4774 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4775 TnyFolder *dest_folder,
4779 gint response = GTK_RESPONSE_OK;
4780 TnyAccount *account = NULL;
4781 TnyFolder *src_folder = NULL;
4782 TnyIterator *iter = NULL;
4783 TnyHeader *header = NULL;
4785 /* return with OK if the destination is a remote folder */
4786 if (modest_tny_folder_is_remote_folder (dest_folder))
4787 return GTK_RESPONSE_OK;
4789 /* Get source folder */
4790 iter = tny_list_create_iterator (headers);
4791 header = TNY_HEADER (tny_iterator_get_current (iter));
4793 src_folder = tny_header_get_folder (header);
4794 g_object_unref (header);
4796 g_object_unref (iter);
4798 /* if no src_folder, message may be an attahcment */
4799 if (src_folder == NULL)
4800 return GTK_RESPONSE_CANCEL;
4802 /* If the source is a local or MMC folder */
4803 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4804 g_object_unref (src_folder);
4805 return GTK_RESPONSE_OK;
4808 /* Get the account */
4809 account = tny_folder_get_account (src_folder);
4811 /* now if offline we ask the user */
4812 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4813 response = GTK_RESPONSE_OK;
4815 response = GTK_RESPONSE_CANCEL;
4818 g_object_unref (src_folder);
4819 g_object_unref (account);
4825 move_to_helper_destroyer (gpointer user_data)
4827 MoveToHelper *helper = (MoveToHelper *) user_data;
4829 /* Close the "Pasting" information banner */
4830 if (helper->banner) {
4831 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4832 g_object_unref (helper->banner);
4834 if (helper->reference != NULL)
4835 gtk_tree_row_reference_free (helper->reference);
4840 move_to_cb (ModestMailOperation *mail_op,
4843 MoveToHelper *helper = (MoveToHelper *) user_data;
4845 /* Note that the operation could have failed, in that case do
4847 if (modest_mail_operation_get_status (mail_op) ==
4848 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4850 GObject *object = modest_mail_operation_get_source (mail_op);
4851 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4852 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4854 if (!modest_msg_view_window_select_next_message (self) &&
4855 !modest_msg_view_window_select_previous_message (self)) {
4856 /* No more messages to view, so close this window */
4857 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4859 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4860 GtkWidget *header_view;
4862 GtkTreeSelection *sel;
4864 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4865 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4866 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4867 path = gtk_tree_row_reference_get_path (helper->reference);
4868 /* We need to unselect the previous one
4869 because we could be copying instead of
4871 gtk_tree_selection_unselect_all (sel);
4872 gtk_tree_selection_select_path (sel, path);
4873 gtk_tree_path_free (path);
4875 g_object_unref (object);
4877 /* Destroy the helper */
4878 move_to_helper_destroyer (helper);
4882 folder_move_to_cb (ModestMailOperation *mail_op,
4883 TnyFolder *new_folder,
4886 GtkWidget *folder_view;
4889 object = modest_mail_operation_get_source (mail_op);
4890 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4891 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4892 g_object_ref (folder_view);
4893 g_object_unref (object);
4894 move_to_cb (mail_op, user_data);
4895 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4896 g_object_unref (folder_view);
4900 msgs_move_to_cb (ModestMailOperation *mail_op,
4903 move_to_cb (mail_op, user_data);
4907 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4910 ModestWindow *main_window = NULL;
4912 /* Disable next automatic folder selection */
4913 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4914 FALSE); /* don't create */
4916 GObject *win = NULL;
4917 GtkWidget *folder_view = NULL;
4919 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4920 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4921 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4923 if (user_data && TNY_IS_FOLDER (user_data)) {
4924 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4925 TNY_FOLDER (user_data), FALSE);
4928 /* Show notification dialog only if the main window exists */
4929 win = modest_mail_operation_get_source (mail_op);
4930 modest_platform_run_information_dialog ((GtkWindow *) win,
4931 _("mail_in_ui_folder_move_target_error"),
4934 g_object_unref (win);
4939 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4948 gint pending_purges = 0;
4949 gboolean some_purged = FALSE;
4950 ModestWindow *win = MODEST_WINDOW (user_data);
4951 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4953 /* If there was any error */
4954 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4955 modest_window_mgr_unregister_header (mgr, header);
4959 /* Once the message has been retrieved for purging, we check if
4960 * it's all ok for purging */
4962 parts = tny_simple_list_new ();
4963 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4964 iter = tny_list_create_iterator (parts);
4966 while (!tny_iterator_is_done (iter)) {
4968 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4969 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4970 if (tny_mime_part_is_purged (part))
4977 g_object_unref (part);
4979 tny_iterator_next (iter);
4981 g_object_unref (iter);
4984 if (pending_purges>0) {
4986 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4988 if (response == GTK_RESPONSE_OK) {
4991 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_ib_removing_attachment"));
4992 iter = tny_list_create_iterator (parts);
4993 while (!tny_iterator_is_done (iter)) {
4996 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4997 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4998 tny_mime_part_set_purged (part);
5001 g_object_unref (part);
5003 tny_iterator_next (iter);
5005 g_object_unref (iter);
5007 tny_msg_rewrite_cache (msg);
5009 gtk_widget_destroy (info);
5013 modest_window_mgr_unregister_header (mgr, header);
5015 g_object_unref (parts);
5019 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5020 ModestMainWindow *win)
5022 GtkWidget *header_view;
5023 TnyList *header_list;
5025 TnyHeaderFlags flags;
5026 ModestWindow *msg_view_window = NULL;
5029 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5031 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5032 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5034 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5036 g_warning ("%s: no header selected", __FUNCTION__);
5040 if (tny_list_get_length (header_list) == 1) {
5041 TnyIterator *iter = tny_list_create_iterator (header_list);
5042 header = TNY_HEADER (tny_iterator_get_current (iter));
5043 g_object_unref (iter);
5047 if (!header || !TNY_IS_HEADER(header)) {
5048 g_warning ("%s: header is not valid", __FUNCTION__);
5052 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5053 header, &msg_view_window);
5054 flags = tny_header_get_flags (header);
5055 if (!(flags & TNY_HEADER_FLAG_CACHED))
5058 if (msg_view_window != NULL)
5059 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5061 /* do nothing; uid was registered before, so window is probably on it's way */
5062 g_warning ("debug: header %p has already been registered", header);
5065 ModestMailOperation *mail_op = NULL;
5066 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5067 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5068 modest_ui_actions_disk_operations_error_handler,
5070 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5071 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5073 g_object_unref (mail_op);
5076 g_object_unref (header);
5078 g_object_unref (header_list);
5082 * Checks if we need a connection to do the transfer and if the user
5083 * wants to connect to complete it
5086 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5087 TnyFolderStore *src_folder,
5089 TnyFolder *dst_folder,
5090 gboolean delete_originals,
5091 gboolean *need_connection,
5094 TnyAccount *src_account;
5095 gint uncached_msgs = 0;
5097 uncached_msgs = header_list_count_uncached_msgs (headers);
5099 /* We don't need any further check if
5101 * 1- the source folder is local OR
5102 * 2- the device is already online
5104 if (!modest_tny_folder_store_is_remote (src_folder) ||
5105 tny_device_is_online (modest_runtime_get_device())) {
5106 *need_connection = FALSE;
5111 /* We must ask for a connection when
5113 * - the message(s) is not already cached OR
5114 * - the message(s) is cached but the leave_on_server setting
5115 * is FALSE (because we need to sync the source folder to
5116 * delete the message from the server (for IMAP we could do it
5117 * offline, it'll take place the next time we get a
5120 src_account = get_account_from_folder_store (src_folder);
5121 if (uncached_msgs > 0) {
5125 *need_connection = TRUE;
5126 num_headers = tny_list_get_length (headers);
5127 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5129 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5130 GTK_RESPONSE_CANCEL) {
5136 /* The transfer is possible and the user wants to */
5139 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5140 const gchar *account_name;
5141 gboolean leave_on_server;
5143 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5144 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5147 if (leave_on_server == TRUE) {
5148 *need_connection = FALSE;
5150 *need_connection = TRUE;
5153 *need_connection = FALSE;
5158 g_object_unref (src_account);
5162 xfer_messages_error_handler (ModestMailOperation *mail_op,
5165 ModestWindow *main_window = NULL;
5167 /* Disable next automatic folder selection */
5168 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5169 FALSE); /* don't create */
5171 GObject *win = modest_mail_operation_get_source (mail_op);
5172 modest_platform_run_information_dialog ((GtkWindow *) win,
5173 _("mail_in_ui_folder_move_target_error"),
5176 g_object_unref (win);
5178 move_to_helper_destroyer (user_data);
5182 TnyFolderStore *dst_folder;
5187 * Utility function that transfer messages from both the main window
5188 * and the msg view window when using the "Move to" dialog
5191 xfer_messages_performer (gboolean canceled,
5193 GtkWindow *parent_window,
5194 TnyAccount *account,
5197 ModestWindow *win = MODEST_WINDOW (parent_window);
5198 TnyAccount *dst_account = NULL;
5199 gboolean dst_forbids_message_add = FALSE;
5200 XferMsgsHelper *helper;
5201 MoveToHelper *movehelper;
5202 ModestMailOperation *mail_op;
5204 helper = (XferMsgsHelper *) user_data;
5206 if (canceled || err) {
5207 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5208 /* Show the proper error message */
5209 modest_ui_actions_on_account_connection_error (parent_window, account);
5214 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5216 /* tinymail will return NULL for local folders it seems */
5217 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5218 modest_tny_account_get_protocol_type (dst_account),
5219 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5220 g_object_unref (dst_account);
5222 if (dst_forbids_message_add) {
5223 modest_platform_information_banner (GTK_WIDGET (win),
5225 ngettext("mail_in_ui_folder_move_target_error",
5226 "mail_in_ui_folder_move_targets_error",
5227 tny_list_get_length (helper->headers)));
5231 movehelper = g_new0 (MoveToHelper, 1);
5232 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5233 _CS("ckct_nw_pasting"));
5234 if (movehelper->banner != NULL) {
5235 g_object_ref (movehelper->banner);
5236 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5239 if (MODEST_IS_MAIN_WINDOW (win)) {
5240 GtkWidget *header_view =
5241 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5242 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5243 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5246 /* Perform the mail operation */
5247 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5248 xfer_messages_error_handler,
5250 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5253 modest_mail_operation_xfer_msgs (mail_op,
5255 TNY_FOLDER (helper->dst_folder),
5260 g_object_unref (G_OBJECT (mail_op));
5262 g_object_unref (helper->dst_folder);
5263 g_object_unref (helper->headers);
5264 g_slice_free (XferMsgsHelper, helper);
5268 TnyFolder *src_folder;
5269 TnyFolderStore *dst_folder;
5270 gboolean delete_original;
5271 GtkWidget *folder_view;
5275 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5276 TnyAccount *account, gpointer user_data)
5278 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5279 GtkTreeSelection *sel;
5280 ModestMailOperation *mail_op = NULL;
5282 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5283 g_object_unref (G_OBJECT (info->src_folder));
5284 g_object_unref (G_OBJECT (info->dst_folder));
5289 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5290 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5291 _CS("ckct_nw_pasting"));
5292 if (helper->banner != NULL) {
5293 g_object_ref (helper->banner);
5294 gtk_widget_show (GTK_WIDGET(helper->banner));
5296 /* Clean folder on header view before moving it */
5297 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5298 gtk_tree_selection_unselect_all (sel);
5300 /* Let gtk events run. We need that the folder
5301 view frees its reference to the source
5302 folder *before* issuing the mail operation
5303 so we need the signal handler of selection
5304 changed to happen before the mail
5306 while (gtk_events_pending ())
5307 gtk_main_iteration (); */
5310 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5311 modest_ui_actions_move_folder_error_handler,
5312 info->src_folder, NULL);
5313 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5316 /* Select *after* the changes */
5317 /* TODO: this function hangs UI after transfer */
5318 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5319 /* TNY_FOLDER (src_folder), TRUE); */
5321 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5322 TNY_FOLDER (info->dst_folder), TRUE);
5323 modest_mail_operation_xfer_folder (mail_op,
5324 TNY_FOLDER (info->src_folder),
5326 info->delete_original,
5329 g_object_unref (G_OBJECT (info->src_folder));
5331 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5334 /* Unref mail operation */
5335 g_object_unref (G_OBJECT (mail_op));
5336 g_object_unref (G_OBJECT (info->dst_folder));
5341 get_account_from_folder_store (TnyFolderStore *folder_store)
5343 if (TNY_IS_ACCOUNT (folder_store))
5344 return g_object_ref (folder_store);
5346 return tny_folder_get_account (TNY_FOLDER (folder_store));
5350 * UI handler for the "Move to" action when invoked from the
5354 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5355 GtkWidget *folder_view,
5356 TnyFolderStore *dst_folder,
5357 ModestMainWindow *win)
5359 ModestHeaderView *header_view = NULL;
5360 TnyFolderStore *src_folder = NULL;
5362 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5364 /* Get the source folder */
5365 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5367 /* Get header view */
5368 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5370 /* Get folder or messages to transfer */
5371 if (gtk_widget_is_focus (folder_view)) {
5372 gboolean do_xfer = TRUE;
5374 /* Allow only to transfer folders to the local root folder */
5375 if (TNY_IS_ACCOUNT (dst_folder) &&
5376 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5377 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5379 } else if (!TNY_IS_FOLDER (src_folder)) {
5380 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5385 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5386 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5388 info->src_folder = g_object_ref (src_folder);
5389 info->dst_folder = g_object_ref (dst_folder);
5390 info->delete_original = TRUE;
5391 info->folder_view = folder_view;
5393 connect_info->callback = on_move_folder_cb;
5394 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5395 connect_info->data = info;
5397 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5398 TNY_FOLDER_STORE (src_folder),
5401 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5404 headers = modest_header_view_get_selected_headers(header_view);
5406 /* Transfer the messages */
5407 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5408 headers, TNY_FOLDER (dst_folder));
5410 g_object_unref (headers);
5414 g_object_unref (src_folder);
5419 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5420 TnyFolder *src_folder,
5422 TnyFolder *dst_folder)
5424 gboolean need_connection = TRUE;
5425 gboolean do_xfer = TRUE;
5426 XferMsgsHelper *helper;
5428 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5429 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5430 g_return_if_fail (TNY_IS_LIST (headers));
5432 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5433 headers, TNY_FOLDER (dst_folder),
5434 TRUE, &need_connection,
5437 /* If we don't want to transfer just return */
5441 /* Create the helper */
5442 helper = g_slice_new (XferMsgsHelper);
5443 helper->dst_folder = g_object_ref (dst_folder);
5444 helper->headers = g_object_ref (headers);
5446 if (need_connection) {
5447 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5448 connect_info->callback = xfer_messages_performer;
5449 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5450 connect_info->data = helper;
5452 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5453 TNY_FOLDER_STORE (src_folder),
5456 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5457 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5458 src_account, helper);
5459 g_object_unref (src_account);
5464 * UI handler for the "Move to" action when invoked from the
5465 * ModestMsgViewWindow
5468 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5469 TnyFolderStore *dst_folder,
5470 ModestMsgViewWindow *win)
5472 TnyList *headers = NULL;
5473 TnyHeader *header = NULL;
5474 TnyFolder *src_folder = NULL;
5476 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5478 /* Create header list */
5479 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5480 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5481 headers = tny_simple_list_new ();
5482 tny_list_append (headers, G_OBJECT (header));
5484 /* Transfer the messages */
5485 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5486 TNY_FOLDER (dst_folder));
5489 g_object_unref (src_folder);
5490 g_object_unref (header);
5491 g_object_unref (headers);
5495 modest_ui_actions_on_move_to (GtkAction *action,
5498 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5500 TnyFolderStore *dst_folder = NULL;
5501 ModestMainWindow *main_window;
5503 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5504 MODEST_IS_MSG_VIEW_WINDOW (win));
5506 /* Get the main window if exists */
5507 if (MODEST_IS_MAIN_WINDOW (win))
5508 main_window = MODEST_MAIN_WINDOW (win);
5511 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5512 FALSE)); /* don't create */
5514 /* Get the folder view widget if exists */
5516 folder_view = modest_main_window_get_child_widget (main_window,
5517 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5521 /* Create and run the dialog */
5522 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5523 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5524 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5525 result = gtk_dialog_run (GTK_DIALOG(dialog));
5526 g_object_ref (tree_view);
5527 gtk_widget_destroy (dialog);
5529 if (result != GTK_RESPONSE_ACCEPT)
5532 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5533 /* Do window specific stuff */
5534 if (MODEST_IS_MAIN_WINDOW (win)) {
5535 modest_ui_actions_on_main_window_move_to (action,
5538 MODEST_MAIN_WINDOW (win));
5540 modest_ui_actions_on_msg_view_window_move_to (action,
5542 MODEST_MSG_VIEW_WINDOW (win));
5546 g_object_unref (dst_folder);
5550 * Calls #HeadersFunc for each header already selected in the main
5551 * window or the message currently being shown in the msg view window
5554 do_headers_action (ModestWindow *win,
5558 TnyList *headers_list = NULL;
5559 TnyIterator *iter = NULL;
5560 TnyHeader *header = NULL;
5561 TnyFolder *folder = NULL;
5564 headers_list = get_selected_headers (win);
5568 /* Get the folder */
5569 iter = tny_list_create_iterator (headers_list);
5570 header = TNY_HEADER (tny_iterator_get_current (iter));
5572 folder = tny_header_get_folder (header);
5573 g_object_unref (header);
5576 /* Call the function for each header */
5577 while (!tny_iterator_is_done (iter)) {
5578 header = TNY_HEADER (tny_iterator_get_current (iter));
5579 func (header, win, user_data);
5580 g_object_unref (header);
5581 tny_iterator_next (iter);
5584 /* Trick: do a poke status in order to speed up the signaling
5586 tny_folder_poke_status (folder);
5589 g_object_unref (folder);
5590 g_object_unref (iter);
5591 g_object_unref (headers_list);
5595 modest_ui_actions_view_attachment (GtkAction *action,
5596 ModestWindow *window)
5598 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5599 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5601 /* not supported window for this action */
5602 g_return_if_reached ();
5607 modest_ui_actions_save_attachments (GtkAction *action,
5608 ModestWindow *window)
5610 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5612 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5615 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5617 /* not supported window for this action */
5618 g_return_if_reached ();
5623 modest_ui_actions_remove_attachments (GtkAction *action,
5624 ModestWindow *window)
5626 if (MODEST_IS_MAIN_WINDOW (window)) {
5627 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5628 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5629 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5631 /* not supported window for this action */
5632 g_return_if_reached ();
5637 modest_ui_actions_on_settings (GtkAction *action,
5642 dialog = modest_platform_get_global_settings_dialog ();
5643 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5644 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5645 gtk_widget_show_all (dialog);
5647 gtk_dialog_run (GTK_DIALOG (dialog));
5649 gtk_widget_destroy (dialog);
5653 modest_ui_actions_on_help (GtkAction *action,
5656 const gchar *help_id;
5658 g_return_if_fail (win && GTK_IS_WINDOW(win));
5660 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5663 modest_platform_show_help (GTK_WINDOW (win), help_id);
5667 modest_ui_actions_on_csm_help (GtkAction *action,
5670 const gchar* help_id = NULL;
5671 GtkWidget *folder_view;
5672 TnyFolderStore *folder_store;
5674 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5676 /* Get selected folder */
5677 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5678 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5679 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5681 /* Switch help_id */
5682 if (folder_store && TNY_IS_FOLDER (folder_store))
5683 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5686 g_object_unref (folder_store);
5689 modest_platform_show_help (GTK_WINDOW (win), help_id);
5691 modest_ui_actions_on_help (action, win);
5695 retrieve_contents_cb (ModestMailOperation *mail_op,
5702 /* We only need this callback to show an error in case of
5703 memory low condition */
5704 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5708 retrieve_msg_contents_performer (gboolean canceled,
5710 GtkWindow *parent_window,
5711 TnyAccount *account,
5714 ModestMailOperation *mail_op;
5715 TnyList *headers = TNY_LIST (user_data);
5717 if (err || canceled) {
5718 check_memory_full_error ((GtkWidget *) parent_window, err);
5722 /* Create mail operation */
5723 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5724 modest_ui_actions_disk_operations_error_handler,
5726 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5727 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5730 g_object_unref (mail_op);
5732 g_object_unref (headers);
5733 g_object_unref (account);
5737 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5738 ModestWindow *window)
5740 TnyList *headers = NULL;
5741 TnyAccount *account = NULL;
5742 TnyIterator *iter = NULL;
5743 TnyHeader *header = NULL;
5744 TnyFolder *folder = NULL;
5747 headers = get_selected_headers (window);
5751 /* Pick the account */
5752 iter = tny_list_create_iterator (headers);
5753 header = TNY_HEADER (tny_iterator_get_current (iter));
5754 folder = tny_header_get_folder (header);
5755 account = tny_folder_get_account (folder);
5756 g_object_unref (folder);
5757 g_object_unref (header);
5758 g_object_unref (iter);
5760 /* Connect and perform the message retrieval */
5761 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5762 g_object_ref (account),
5763 retrieve_msg_contents_performer,
5764 g_object_ref (headers));
5767 g_object_unref (account);
5768 g_object_unref (headers);
5772 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5774 g_return_if_fail (MODEST_IS_WINDOW (window));
5777 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5781 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5783 g_return_if_fail (MODEST_IS_WINDOW (window));
5786 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5790 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5791 ModestWindow *window)
5793 g_return_if_fail (MODEST_IS_WINDOW (window));
5796 modest_ui_actions_check_menu_dimming_rules (window);
5800 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5801 ModestWindow *window)
5803 g_return_if_fail (MODEST_IS_WINDOW (window));
5806 modest_ui_actions_check_menu_dimming_rules (window);
5810 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5811 ModestWindow *window)
5813 g_return_if_fail (MODEST_IS_WINDOW (window));
5816 modest_ui_actions_check_menu_dimming_rules (window);
5820 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5821 ModestWindow *window)
5823 g_return_if_fail (MODEST_IS_WINDOW (window));
5826 modest_ui_actions_check_menu_dimming_rules (window);
5830 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5831 ModestWindow *window)
5833 g_return_if_fail (MODEST_IS_WINDOW (window));
5836 modest_ui_actions_check_menu_dimming_rules (window);
5840 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5841 ModestWindow *window)
5843 g_return_if_fail (MODEST_IS_WINDOW (window));
5846 modest_ui_actions_check_menu_dimming_rules (window);
5850 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5851 ModestWindow *window)
5853 g_return_if_fail (MODEST_IS_WINDOW (window));
5856 modest_ui_actions_check_menu_dimming_rules (window);
5860 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5861 ModestWindow *window)
5863 g_return_if_fail (MODEST_IS_WINDOW (window));
5866 modest_ui_actions_check_menu_dimming_rules (window);
5870 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5871 ModestWindow *window)
5873 g_return_if_fail (MODEST_IS_WINDOW (window));
5876 modest_ui_actions_check_menu_dimming_rules (window);
5880 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5882 g_return_if_fail (MODEST_IS_WINDOW (window));
5884 /* we check for low-mem; in that case, show a warning, and don't allow
5887 if (modest_platform_check_memory_low (window, TRUE))
5890 modest_platform_show_search_messages (GTK_WINDOW (window));
5894 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5896 g_return_if_fail (MODEST_IS_WINDOW (win));
5899 /* we check for low-mem; in that case, show a warning, and don't allow
5900 * for the addressbook
5902 if (modest_platform_check_memory_low (win, TRUE))
5906 modest_platform_show_addressbook (GTK_WINDOW (win));
5911 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5912 ModestWindow *window)
5914 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5916 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5920 on_send_receive_finished (ModestMailOperation *mail_op,
5923 GtkWidget *header_view, *folder_view;
5924 TnyFolderStore *folder_store;
5925 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5927 /* Set send/receive operation finished */
5928 modest_main_window_notify_send_receive_completed (main_win);
5930 /* Don't refresh the current folder if there were any errors */
5931 if (modest_mail_operation_get_status (mail_op) !=
5932 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5935 /* Refresh the current folder if we're viewing a window. We do
5936 this because the user won't be able to see the new mails in
5937 the selected folder after a Send&Receive because it only
5938 performs a poke_status, i.e, only the number of read/unread
5939 messages is updated, but the new headers are not
5941 folder_view = modest_main_window_get_child_widget (main_win,
5942 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5946 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5948 /* Do not need to refresh INBOX again because the
5949 update_account does it always automatically */
5950 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5951 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5952 ModestMailOperation *refresh_op;
5954 header_view = modest_main_window_get_child_widget (main_win,
5955 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5957 /* We do not need to set the contents style
5958 because it hasn't changed. We also do not
5959 need to save the widget status. Just force
5961 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5962 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5963 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5964 folder_refreshed_cb, main_win);
5965 g_object_unref (refresh_op);
5969 g_object_unref (folder_store);
5974 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5980 const gchar* server_name = NULL;
5981 TnyTransportAccount *server_account;
5982 gchar *message = NULL;
5984 /* Don't show anything if the user cancelled something or the
5985 * send receive request is not interactive. Authentication
5986 * errors are managed by the account store so no need to show
5987 * a dialog here again */
5988 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5989 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5990 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5994 /* Get the server name: */
5996 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5998 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6000 g_return_if_reached ();
6002 /* Show the appropriate message text for the GError: */
6003 switch (err->code) {
6004 case TNY_SERVICE_ERROR_CONNECT:
6005 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6007 case TNY_SERVICE_ERROR_SEND:
6008 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6010 case TNY_SERVICE_ERROR_UNAVAILABLE:
6011 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6014 g_warning ("%s: unexpected ERROR %d",
6015 __FUNCTION__, err->code);
6016 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6020 modest_platform_run_information_dialog (NULL, message, FALSE);
6022 g_object_unref (server_account);
6026 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6031 ModestMainWindow *main_window = NULL;
6032 ModestWindowMgr *mgr = NULL;
6033 GtkWidget *folder_view = NULL, *header_view = NULL;
6034 TnyFolderStore *selected_folder = NULL;
6035 TnyFolderType folder_type;
6037 mgr = modest_runtime_get_window_mgr ();
6038 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6039 FALSE));/* don't create */
6043 /* Check if selected folder is OUTBOX */
6044 folder_view = modest_main_window_get_child_widget (main_window,
6045 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6046 header_view = modest_main_window_get_child_widget (main_window,
6047 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6049 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6050 if (!TNY_IS_FOLDER (selected_folder))
6053 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6054 #if GTK_CHECK_VERSION(2, 8, 0)
6055 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6056 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6057 GtkTreeViewColumn *tree_column;
6059 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6060 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6062 gtk_tree_view_column_queue_resize (tree_column);
6065 gtk_widget_queue_draw (header_view);
6068 /* Rerun dimming rules, because the message could become deletable for example */
6069 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6070 MODEST_DIMMING_RULES_TOOLBAR);
6071 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6072 MODEST_DIMMING_RULES_MENU);
6076 if (selected_folder != NULL)
6077 g_object_unref (selected_folder);
6081 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6082 TnyAccount *account)
6084 ModestProtocolType protocol_type;
6085 ModestProtocol *protocol;
6086 gchar *error_note = NULL;
6088 protocol_type = modest_tny_account_get_protocol_type (account);
6089 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6092 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6093 if (error_note == NULL) {
6094 g_warning ("%s: This should not be reached", __FUNCTION__);
6096 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6097 g_free (error_note);
6102 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6106 TnyFolderStore *folder = NULL;
6107 TnyAccount *account = NULL;
6108 ModestProtocolType proto;
6109 ModestProtocol *protocol;
6110 TnyHeader *header = NULL;
6112 if (MODEST_IS_MAIN_WINDOW (win)) {
6113 GtkWidget *header_view;
6114 TnyList* headers = NULL;
6116 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6117 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6118 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6119 if (!headers || tny_list_get_length (headers) == 0) {
6121 g_object_unref (headers);
6124 iter = tny_list_create_iterator (headers);
6125 header = TNY_HEADER (tny_iterator_get_current (iter));
6126 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6127 g_object_unref (iter);
6128 g_object_unref (headers);
6129 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6130 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6131 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6134 /* Get the account type */
6135 account = tny_folder_get_account (TNY_FOLDER (folder));
6136 proto = modest_tny_account_get_protocol_type (account);
6137 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6140 subject = tny_header_dup_subject (header);
6141 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6144 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6148 g_object_unref (account);
6149 g_object_unref (folder);
6150 g_object_unref (header);