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-protocol-info.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-camel-folder.h>
50 #include <tny-camel-imap-folder.h>
51 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_PLATFORM_MAEMO
54 #include "maemo/modest-osso-state-saving.h"
55 #include "maemo/modest-hildon-includes.h"
56 #include "maemo/modest-connection-specific-smtp-window.h"
57 #endif /* MODEST_PLATFORM_MAEMO */
58 #include <modest-utils.h>
60 #include "widgets/modest-ui-constants.h"
61 #include <widgets/modest-main-window.h>
62 #include <widgets/modest-msg-view-window.h>
63 #include <widgets/modest-account-view-window.h>
64 #include <widgets/modest-details-dialog.h>
65 #include <widgets/modest-attachments-view.h>
66 #include "widgets/modest-folder-view.h"
67 #include "widgets/modest-global-settings-dialog.h"
68 #include "modest-account-mgr-helpers.h"
69 #include "modest-mail-operation.h"
70 #include "modest-text-utils.h"
72 #ifdef MODEST_HAVE_EASYSETUP
73 #include "easysetup/modest-easysetup-wizard.h"
74 #endif /* MODEST_HAVE_EASYSETUP */
76 #include <modest-widget-memory.h>
77 #include <tny-error.h>
78 #include <tny-simple-list.h>
79 #include <tny-msg-view.h>
80 #include <tny-device.h>
81 #include <tny-merge-folder.h>
83 #include <gtkhtml/gtkhtml.h>
85 typedef struct _GetMsgAsyncHelper {
87 ModestMailOperation *mail_op;
94 typedef enum _ReplyForwardAction {
100 typedef struct _ReplyForwardHelper {
101 guint reply_forward_type;
102 ReplyForwardAction action;
104 GtkWidget *parent_window;
105 } ReplyForwardHelper;
107 typedef struct _MoveToHelper {
108 GtkTreeRowReference *reference;
112 typedef struct _PasteAsAttachmentHelper {
113 ModestMsgEditWindow *window;
115 } PasteAsAttachmentHelper;
119 * The do_headers_action uses this kind of functions to perform some
120 * action to each member of a list of headers
122 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
124 static void do_headers_action (ModestWindow *win,
128 static void open_msg_cb (ModestMailOperation *mail_op,
135 static void reply_forward_cb (ModestMailOperation *mail_op,
142 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
144 static void folder_refreshed_cb (ModestMailOperation *mail_op,
148 static void on_send_receive_finished (ModestMailOperation *mail_op,
151 static gint header_list_count_uncached_msgs (TnyList *header_list);
153 static gboolean connect_to_get_msg (ModestWindow *win,
154 gint num_of_uncached_msgs,
155 TnyAccount *account);
157 static gboolean remote_folder_is_pop (TnyFolderStore *folder);
159 static void do_create_folder (GtkWindow *window,
160 TnyFolderStore *parent_folder,
161 const gchar *suggested_name);
163 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
165 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
167 static void transfer_messages_helper (GtkWindow *win,
168 TnyFolder *src_folder,
170 TnyFolder *dst_folder);
173 * This function checks whether a TnyFolderStore is a pop account
176 remote_folder_is_pop (TnyFolderStore *folder)
178 const gchar *proto = NULL;
179 TnyAccount *account = NULL;
181 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
183 account = get_account_from_folder_store (folder);
184 proto = tny_account_get_proto (account);
185 g_object_unref (account);
187 return (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
190 /* FIXME: this should be merged with the similar code in modest-account-view-window */
191 /* Show the account creation wizard dialog.
192 * returns: TRUE if an account was created. FALSE if the user cancelled.
195 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
197 gboolean result = FALSE;
198 GtkWindow *dialog, *wizard;
199 gint dialog_response;
201 /* Show the easy-setup wizard: */
202 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
204 /* old wizard is active already;
206 gtk_window_present (GTK_WINDOW(dialog));
211 /* there is no such wizard yet */
212 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
213 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
215 /* always present a main window in the background
216 * we do it here, so we cannot end up with two wizards (as this
217 * function might be called in modest_window_mgr_get_main_window as well */
219 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
220 TRUE); /* create if not existent */
222 /* make sure the mainwindow is visible */
223 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
224 gtk_widget_show_all (GTK_WIDGET(win));
225 gtk_window_present (GTK_WINDOW(win));
227 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
228 gtk_widget_destroy (GTK_WIDGET (wizard));
229 if (gtk_events_pending ())
230 gtk_main_iteration ();
232 if (dialog_response == GTK_RESPONSE_CANCEL) {
235 /* Check whether an account was created: */
236 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
243 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
246 const gchar *authors[] = {
247 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
250 about = gtk_about_dialog_new ();
251 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
252 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
253 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
254 _("Copyright (c) 2006, Nokia Corporation\n"
255 "All rights reserved."));
256 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
257 _("a modest e-mail client\n\n"
258 "design and implementation: Dirk-Jan C. Binnema\n"
259 "contributions from the fine people at KC and Ig\n"
260 "uses the tinymail email framework written by Philip van Hoof"));
261 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
262 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
263 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
264 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
266 gtk_dialog_run (GTK_DIALOG (about));
267 gtk_widget_destroy(about);
271 * Gets the list of currently selected messages. If the win is the
272 * main window, then it returns a newly allocated list of the headers
273 * selected in the header view. If win is the msg view window, then
274 * the value returned is a list with just a single header.
276 * The caller of this funcion must free the list.
279 get_selected_headers (ModestWindow *win)
281 if (MODEST_IS_MAIN_WINDOW(win)) {
282 GtkWidget *header_view;
284 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
285 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
286 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
288 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
289 /* for MsgViewWindows, we simply return a list with one element */
291 TnyList *list = NULL;
293 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
294 if (header != NULL) {
295 list = tny_simple_list_new ();
296 tny_list_prepend (list, G_OBJECT(header));
297 g_object_unref (G_OBJECT(header));
306 static GtkTreeRowReference *
307 get_next_after_selected_headers (ModestHeaderView *header_view)
309 GtkTreeSelection *sel;
310 GList *selected_rows, *node;
312 GtkTreeRowReference *result;
315 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
316 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
317 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
319 if (selected_rows == NULL)
322 node = g_list_last (selected_rows);
323 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
324 gtk_tree_path_next (path);
326 result = gtk_tree_row_reference_new (model, path);
328 gtk_tree_path_free (path);
329 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
330 g_list_free (selected_rows);
336 headers_action_mark_as_read (TnyHeader *header,
340 TnyHeaderFlags flags;
342 g_return_if_fail (TNY_IS_HEADER(header));
344 flags = tny_header_get_flags (header);
345 if (flags & TNY_HEADER_FLAG_SEEN) return;
346 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
350 headers_action_mark_as_unread (TnyHeader *header,
354 TnyHeaderFlags flags;
356 g_return_if_fail (TNY_IS_HEADER(header));
358 flags = tny_header_get_flags (header);
359 if (flags & TNY_HEADER_FLAG_SEEN) {
360 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
364 /** After deleing a message that is currently visible in a window,
365 * show the next message from the list, or close the window if there are no more messages.
368 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
370 /* Close msg view window or select next */
371 if (!modest_msg_view_window_select_next_message (win) &&
372 !modest_msg_view_window_select_previous_message (win)) {
374 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
380 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
382 TnyList *header_list = NULL;
383 TnyIterator *iter = NULL;
384 TnyHeader *header = NULL;
385 gchar *message = NULL;
388 ModestWindowMgr *mgr;
389 GtkWidget *header_view = NULL;
391 g_return_if_fail (MODEST_IS_WINDOW(win));
393 /* Check first if the header view has the focus */
394 if (MODEST_IS_MAIN_WINDOW (win)) {
396 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
397 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
398 if (!gtk_widget_is_focus (header_view))
402 /* Get the headers, either from the header view (if win is the main window),
403 * or from the message view window: */
404 header_list = get_selected_headers (win);
405 if (!header_list) return;
407 /* Check if any of the headers are already opened, or in the process of being opened */
408 if (MODEST_IS_MAIN_WINDOW (win)) {
409 gint opened_headers = 0;
411 iter = tny_list_create_iterator (header_list);
412 mgr = modest_runtime_get_window_mgr ();
413 while (!tny_iterator_is_done (iter)) {
414 header = TNY_HEADER (tny_iterator_get_current (iter));
416 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
418 g_object_unref (header);
420 tny_iterator_next (iter);
422 g_object_unref (iter);
424 if (opened_headers > 0) {
427 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
430 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
433 g_object_unref (header_list);
439 if (tny_list_get_length(header_list) == 1) {
440 iter = tny_list_create_iterator (header_list);
441 header = TNY_HEADER (tny_iterator_get_current (iter));
443 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
444 g_object_unref (header);
447 g_object_unref (iter);
449 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
450 tny_list_get_length(header_list)), desc);
452 /* Confirmation dialog */
453 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
457 if (response == GTK_RESPONSE_OK) {
458 ModestWindow *main_window = NULL;
459 ModestWindowMgr *mgr = NULL;
460 GtkTreeModel *model = NULL;
461 GtkTreeSelection *sel = NULL;
462 GList *sel_list = NULL, *tmp = NULL;
463 GtkTreeRowReference *next_row_reference = NULL;
464 GtkTreeRowReference *prev_row_reference = NULL;
465 GtkTreePath *next_path = NULL;
466 GtkTreePath *prev_path = NULL;
467 ModestMailOperation *mail_op = NULL;
469 /* Find last selected row */
470 if (MODEST_IS_MAIN_WINDOW (win)) {
471 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
472 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
473 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
474 for (tmp=sel_list; tmp; tmp=tmp->next) {
475 if (tmp->next == NULL) {
476 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
477 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
479 gtk_tree_path_prev (prev_path);
480 gtk_tree_path_next (next_path);
482 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
483 next_row_reference = gtk_tree_row_reference_new (model, next_path);
488 /* Disable window dimming management */
489 modest_window_disable_dimming (MODEST_WINDOW(win));
491 /* Remove each header. If it's a view window header_view == NULL */
492 mail_op = modest_mail_operation_new ((GObject *) win);
493 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
495 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
496 g_object_unref (mail_op);
498 /* Enable window dimming management */
500 gtk_tree_selection_unselect_all (sel);
502 modest_window_enable_dimming (MODEST_WINDOW(win));
504 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
505 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
507 /* Get main window */
508 mgr = modest_runtime_get_window_mgr ();
509 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
511 /* Move cursor to next row */
514 /* Select next or previous row */
515 if (gtk_tree_row_reference_valid (next_row_reference)) {
516 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
517 gtk_tree_selection_select_path (sel, next_path);
519 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
520 gtk_tree_selection_select_path (sel, prev_path);
524 if (next_row_reference != NULL)
525 gtk_tree_row_reference_free (next_row_reference);
526 if (next_path != NULL)
527 gtk_tree_path_free (next_path);
528 if (prev_row_reference != NULL)
529 gtk_tree_row_reference_free (prev_row_reference);
530 if (prev_path != NULL)
531 gtk_tree_path_free (prev_path);
534 /* Update toolbar dimming state */
536 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
539 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
540 g_list_free (sel_list);
546 g_object_unref (header_list);
552 /* delete either message or folder, based on where we are */
554 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
556 g_return_if_fail (MODEST_IS_WINDOW(win));
558 /* Check first if the header view has the focus */
559 if (MODEST_IS_MAIN_WINDOW (win)) {
561 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
562 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
563 if (gtk_widget_is_focus (w)) {
564 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
568 modest_ui_actions_on_delete_message (action, win);
572 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
574 ModestWindowMgr *mgr = NULL;
576 #ifdef MODEST_PLATFORM_MAEMO
577 modest_osso_save_state();
578 #endif /* MODEST_PLATFORM_MAEMO */
580 g_debug ("closing down, clearing %d item(s) from operation queue",
581 modest_mail_operation_queue_num_elements
582 (modest_runtime_get_mail_operation_queue()));
584 /* cancel all outstanding operations */
585 modest_mail_operation_queue_cancel_all
586 (modest_runtime_get_mail_operation_queue());
588 g_debug ("queue has been cleared");
591 /* Check if there are opened editing windows */
592 mgr = modest_runtime_get_window_mgr ();
593 modest_window_mgr_close_all_windows (mgr);
595 /* note: when modest-tny-account-store is finalized,
596 it will automatically set all network connections
599 /* gtk_main_quit (); */
603 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
607 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
609 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
610 /* gtk_widget_destroy (GTK_WIDGET (win)); */
611 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
612 /* gboolean ret_value; */
613 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
614 /* } else if (MODEST_IS_WINDOW (win)) { */
615 /* gtk_widget_destroy (GTK_WIDGET (win)); */
617 /* g_return_if_reached (); */
622 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
624 GtkClipboard *clipboard = NULL;
625 gchar *selection = NULL;
627 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
628 selection = gtk_clipboard_wait_for_text (clipboard);
630 /* Question: why is the clipboard being used here?
631 * It doesn't really make a lot of sense. */
635 modest_address_book_add_address (selection);
641 modest_ui_actions_on_accounts (GtkAction *action,
644 /* This is currently only implemented for Maemo */
645 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
646 if (!modest_ui_actions_run_account_setup_wizard (win))
647 g_debug ("%s: wizard was already running", __FUNCTION__);
651 /* Show the list of accounts */
652 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
653 gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
655 /* The accounts dialog must be modal */
656 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
657 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
661 #ifdef MODEST_PLATFORM_MAEMO
663 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
665 /* Save any changes. */
666 modest_connection_specific_smtp_window_save_server_accounts (
667 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
668 gtk_widget_destroy (GTK_WIDGET (window));
674 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
676 /* This is currently only implemented for Maemo,
677 * because it requires an API (libconic) to detect different connection
680 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
682 /* Create the window if necessary: */
683 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
684 modest_connection_specific_smtp_window_fill_with_connections (
685 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
686 modest_runtime_get_account_mgr());
688 /* Show the window: */
689 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
690 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
691 gtk_widget_show (specific_window);
693 /* Save changes when the window is hidden: */
694 g_signal_connect (specific_window, "hide",
695 G_CALLBACK (on_smtp_servers_window_hide), win);
696 #endif /* MODEST_PLATFORM_MAEMO */
700 modest_ui_actions_compose_msg(ModestWindow *win,
703 const gchar *bcc_str,
704 const gchar *subject_str,
705 const gchar *body_str,
708 gchar *account_name = NULL;
710 TnyAccount *account = NULL;
711 TnyFolder *folder = NULL;
712 gchar *from_str = NULL, *signature = NULL, *body = NULL;
713 gboolean use_signature = FALSE;
714 ModestWindow *msg_win = NULL;
715 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
716 ModestTnyAccountStore *store = modest_runtime_get_account_store();
718 account_name = modest_account_mgr_get_default_account(mgr);
720 g_printerr ("modest: no account found\n");
723 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
725 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
728 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
730 g_printerr ("modest: failed to find Drafts folder\n");
733 from_str = modest_account_mgr_get_from_string (mgr, account_name);
735 g_printerr ("modest: failed get from string for '%s'\n", account_name);
739 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
740 if (body_str != NULL) {
741 body = use_signature ? g_strconcat(body_str, "\n", signature, NULL) : g_strdup(body_str);
743 body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup("");
746 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL);
748 g_printerr ("modest: failed to create new msg\n");
752 /* Create and register edit window */
753 /* This is destroyed by TODO. */
754 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
755 while (attachments) {
756 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
758 attachments = g_slist_next(attachments);
760 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
761 gtk_widget_show_all (GTK_WIDGET (msg_win));
767 g_free (account_name);
768 if (account) g_object_unref (G_OBJECT(account));
769 if (folder) g_object_unref (G_OBJECT(folder));
770 if (msg_win) g_object_unref (G_OBJECT(msg_win));
771 if (msg) g_object_unref (G_OBJECT(msg));
775 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
777 /* if there are no accounts yet, just show the wizard */
778 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
779 if (!modest_ui_actions_run_account_setup_wizard (win))
782 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL);
787 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
791 ModestMailOperationStatus status;
793 /* If there is no message or the operation was not successful */
794 status = modest_mail_operation_get_status (mail_op);
795 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
797 /* Remove the header from the preregistered uids */
798 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
808 open_msg_cb (ModestMailOperation *mail_op,
815 ModestWindowMgr *mgr = NULL;
816 ModestWindow *parent_win = NULL;
817 ModestWindow *win = NULL;
818 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
819 gchar *account = NULL;
821 gboolean open_in_editor = FALSE;
823 /* Do nothing if there was any problem with the mail
824 operation. The error will be shown by the error_handler of
825 the mail operation */
826 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
829 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
830 folder = tny_header_get_folder (header);
832 /* Mark header as read */
833 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
835 /* Gets folder type (OUTBOX headers will be opened in edit window */
836 if (modest_tny_folder_is_local_folder (folder)) {
837 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
838 if (folder_type == TNY_FOLDER_TYPE_INVALID)
839 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
843 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
844 TnyTransportAccount *traccount = NULL;
845 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
846 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
848 ModestTnySendQueue *send_queue = NULL;
849 ModestTnySendQueueStatus status;
851 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
852 TNY_ACCOUNT(traccount)));
853 send_queue = modest_runtime_get_send_queue(traccount);
854 msg_id = modest_tny_send_queue_get_msg_id (header);
855 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
856 /* Only open messages in outbox with the editor if they are in Failed state */
857 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
858 open_in_editor = TRUE;
861 g_object_unref(traccount);
863 g_warning("Cannot get transport account for message in outbox!!");
865 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
866 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
871 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
873 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
875 if (open_in_editor) {
876 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
877 const gchar *from_header = NULL;
879 from_header = tny_header_get_from (header);
881 /* we cannot edit without a valid account... */
882 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
883 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
888 GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
890 for (node = accounts; node != NULL; node = g_slist_next (node)) {
891 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
893 if (from && (strcmp (from_header, from) == 0)) {
895 account = g_strdup (node->data);
901 g_slist_foreach (accounts, (GFunc) g_free, NULL);
902 g_slist_free (accounts);
905 win = modest_msg_edit_window_new (msg, account, TRUE);
909 modest_platform_information_banner_with_timeout
910 (NULL, NULL, _("mail_ib_opening_draft_message"), 1200);
913 gchar *uid = modest_tny_folder_get_header_unique_id (header);
915 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
916 GtkWidget *header_view;
917 GtkTreeSelection *sel;
918 GList *sel_list = NULL;
921 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
922 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
924 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
925 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
927 if (sel_list != NULL) {
928 GtkTreeRowReference *row_reference;
930 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
931 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
932 g_list_free (sel_list);
934 win = modest_msg_view_window_new_with_header_model (
935 msg, account, (const gchar*) uid,
936 model, row_reference);
937 gtk_tree_row_reference_free (row_reference);
939 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
942 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
947 /* Register and show new window */
949 mgr = modest_runtime_get_window_mgr ();
950 modest_window_mgr_register_window (mgr, win);
951 g_object_unref (win);
952 gtk_widget_show_all (GTK_WIDGET(win));
955 /* Update toolbar dimming state */
956 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
957 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
963 g_object_unref (parent_win);
964 g_object_unref (folder);
968 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
974 win = modest_mail_operation_get_source (mail_op);
975 error = modest_mail_operation_get_error (mail_op);
978 if (error->code == TNY_SYSTEM_ERROR_MEMORY ||
979 error->code == TNY_IO_ERROR_WRITE ||
980 error->code == TNY_IO_ERROR_READ) {
981 ModestMailOperationStatus st = modest_mail_operation_get_status (mail_op);
982 /* If the mail op has been cancelled then it's not an error: don't show any message */
983 if (st != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
984 modest_platform_information_banner ((GtkWidget *) win,
985 NULL, dgettext("ke-recv",
986 "cerm_device_memory_full"));
988 } else if (user_data) {
989 modest_platform_information_banner ((GtkWidget *) win,
994 g_object_unref (win);
998 * Returns the account a list of headers belongs to. It returns a
999 * *new* reference so don't forget to unref it
1002 get_account_from_header_list (TnyList *headers)
1004 TnyAccount *account = NULL;
1006 if (tny_list_get_length (headers) > 0) {
1007 TnyIterator *iter = tny_list_create_iterator (headers);
1008 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1009 TnyFolder *folder = tny_header_get_folder (header);
1010 account = tny_folder_get_account (folder);
1011 g_object_unref (folder);
1012 g_object_unref (header);
1013 g_object_unref (iter);
1019 foreach_unregister_headers (gpointer data,
1022 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1023 TnyHeader *header = TNY_HEADER (data);
1025 modest_window_mgr_unregister_header (mgr, header);
1029 open_msgs_performer(gboolean canceled,
1031 GtkWindow *parent_window,
1032 TnyAccount *account,
1035 ModestMailOperation *mail_op = NULL;
1036 const gchar *proto_name;
1038 ModestTransportStoreProtocol proto;
1039 TnyList *not_opened_headers;
1040 TnyConnectionStatus status;
1042 not_opened_headers = TNY_LIST (user_data);
1044 status = tny_account_get_connection_status (account);
1045 if (err || canceled) {
1046 /* Unregister the already registered headers */
1047 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1048 modest_runtime_get_window_mgr ());
1052 /* Get the error message depending on the protocol */
1053 proto_name = tny_account_get_proto (account);
1054 if (proto_name != NULL) {
1055 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1057 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1060 /* Create the error messages */
1061 if (tny_list_get_length (not_opened_headers) == 1) {
1062 if (proto == MODEST_PROTOCOL_STORE_POP) {
1063 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1064 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1065 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1066 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1067 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1068 tny_header_get_subject (header));
1069 g_object_unref (header);
1070 g_object_unref (iter);
1072 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1075 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1078 /* Create the mail operation */
1080 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1081 modest_ui_actions_get_msgs_full_error_handler,
1083 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1086 modest_mail_operation_get_msgs_full (mail_op,
1095 g_object_unref (mail_op);
1096 g_object_unref (not_opened_headers);
1097 g_object_unref (account);
1101 * This function is used by both modest_ui_actions_on_open and
1102 * modest_ui_actions_on_header_activated. This way we always do the
1103 * same when trying to open messages.
1106 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1108 ModestWindowMgr *mgr = NULL;
1109 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1110 TnyList *not_opened_headers = NULL;
1111 TnyHeaderFlags flags = 0;
1112 TnyAccount *account;
1113 gint uncached_msgs = 0;
1115 g_return_if_fail (headers != NULL);
1117 /* Check that only one message is selected for opening */
1118 if (tny_list_get_length (headers) != 1) {
1119 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1120 _("mcen_ib_select_one_message"));
1124 mgr = modest_runtime_get_window_mgr ();
1125 iter = tny_list_create_iterator (headers);
1127 /* Get the account */
1128 account = get_account_from_header_list (headers);
1130 /* Look if we already have a message view for each header. If
1131 true, then remove the header from the list of headers to
1133 not_opened_headers = tny_simple_list_new ();
1134 while (!tny_iterator_is_done (iter)) {
1136 ModestWindow *window = NULL;
1137 TnyHeader *header = NULL;
1138 gboolean found = FALSE;
1140 header = TNY_HEADER (tny_iterator_get_current (iter));
1142 flags = tny_header_get_flags (header);
1145 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1147 /* Do not open again the message and present the
1148 window to the user */
1151 gtk_window_present (GTK_WINDOW (window));
1153 /* the header has been registered already, we don't do
1154 * anything but wait for the window to come up*/
1155 g_debug ("header %p already registered, waiting for window", header);
1157 tny_list_append (not_opened_headers, G_OBJECT (header));
1161 g_object_unref (header);
1163 tny_iterator_next (iter);
1165 g_object_unref (iter);
1168 /* Open each message */
1169 if (tny_list_get_length (not_opened_headers) == 0)
1172 /* If some messages would have to be downloaded, ask the user to
1173 * make a connection. It's generally easier to do this here (in the mainloop)
1174 * than later in a thread:
1176 if (tny_list_get_length (not_opened_headers) > 0) {
1177 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1179 if (uncached_msgs > 0) {
1180 /* Allways download if we are online. */
1181 if (!tny_device_is_online (modest_runtime_get_device ())) {
1184 /* If ask for user permission to download the messages */
1185 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1186 ngettext("mcen_nc_get_msg",
1190 /* End if the user does not want to continue */
1191 if (response == GTK_RESPONSE_CANCEL)
1197 /* Register the headers before actually creating the windows: */
1198 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1199 while (!tny_iterator_is_done (iter_not_opened)) {
1200 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1202 modest_window_mgr_register_header (mgr, header, NULL);
1203 g_object_unref (header);
1205 tny_iterator_next (iter_not_opened);
1207 g_object_unref (iter_not_opened);
1208 iter_not_opened = NULL;
1210 /* Connect to the account and perform */
1211 if (uncached_msgs > 0) {
1212 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1213 open_msgs_performer, g_object_ref (not_opened_headers));
1215 /* Call directly the performer, do not need to connect */
1216 open_msgs_performer (FALSE, NULL, (GtkWindow *) win, g_object_ref (account),
1217 g_object_ref (not_opened_headers));
1222 g_object_unref (account);
1223 if (not_opened_headers)
1224 g_object_unref (not_opened_headers);
1228 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1233 headers = get_selected_headers (win);
1238 open_msgs_from_headers (headers, win);
1240 g_object_unref(headers);
1245 free_reply_forward_helper (gpointer data)
1247 ReplyForwardHelper *helper;
1249 helper = (ReplyForwardHelper *) data;
1250 g_free (helper->account_name);
1251 g_slice_free (ReplyForwardHelper, helper);
1255 reply_forward_cb (ModestMailOperation *mail_op,
1263 ReplyForwardHelper *rf_helper;
1264 ModestWindow *msg_win = NULL;
1265 ModestEditType edit_type;
1267 TnyAccount *account = NULL;
1268 ModestWindowMgr *mgr = NULL;
1269 gchar *signature = NULL;
1270 gboolean use_signature;
1272 /* If there was any error. The mail operation could be NULL,
1273 this means that we already have the message downloaded and
1274 that we didn't do a mail operation to retrieve it */
1275 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1278 g_return_if_fail (user_data != NULL);
1279 rf_helper = (ReplyForwardHelper *) user_data;
1281 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1282 rf_helper->account_name);
1283 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1284 rf_helper->account_name,
1287 /* Create reply mail */
1288 switch (rf_helper->action) {
1291 modest_tny_msg_create_reply_msg (msg, header, from,
1292 (use_signature) ? signature : NULL,
1293 rf_helper->reply_forward_type,
1294 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1296 case ACTION_REPLY_TO_ALL:
1298 modest_tny_msg_create_reply_msg (msg, header, from,
1299 (use_signature) ? signature : NULL,
1300 rf_helper->reply_forward_type,
1301 MODEST_TNY_MSG_REPLY_MODE_ALL);
1302 edit_type = MODEST_EDIT_TYPE_REPLY;
1304 case ACTION_FORWARD:
1306 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1307 rf_helper->reply_forward_type);
1308 edit_type = MODEST_EDIT_TYPE_FORWARD;
1311 g_return_if_reached ();
1318 g_printerr ("modest: failed to create message\n");
1322 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1323 rf_helper->account_name,
1324 TNY_ACCOUNT_TYPE_STORE);
1326 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1330 /* Create and register the windows */
1331 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1332 mgr = modest_runtime_get_window_mgr ();
1333 modest_window_mgr_register_window (mgr, msg_win);
1335 if (rf_helper->parent_window != NULL) {
1336 gdouble parent_zoom;
1338 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1339 modest_window_set_zoom (msg_win, parent_zoom);
1342 /* Show edit window */
1343 gtk_widget_show_all (GTK_WIDGET (msg_win));
1347 g_object_unref (msg_win);
1349 g_object_unref (G_OBJECT (new_msg));
1351 g_object_unref (G_OBJECT (account));
1352 /* g_object_unref (msg); */
1353 free_reply_forward_helper (rf_helper);
1356 /* Checks a list of headers. If any of them are not currently
1357 * downloaded (CACHED) then returns TRUE else returns FALSE.
1360 header_list_count_uncached_msgs (TnyList *header_list)
1363 gint uncached_messages = 0;
1365 iter = tny_list_create_iterator (header_list);
1366 while (!tny_iterator_is_done (iter)) {
1369 header = TNY_HEADER (tny_iterator_get_current (iter));
1371 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1372 uncached_messages ++;
1373 g_object_unref (header);
1376 tny_iterator_next (iter);
1378 g_object_unref (iter);
1380 return uncached_messages;
1383 /* Returns FALSE if the user does not want to download the
1384 * messages. Returns TRUE if the user allowed the download.
1387 connect_to_get_msg (ModestWindow *win,
1388 gint num_of_uncached_msgs,
1389 TnyAccount *account)
1391 GtkResponseType response;
1393 /* Allways download if we are online. */
1394 if (tny_device_is_online (modest_runtime_get_device ()))
1397 /* If offline, then ask for user permission to download the messages */
1398 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1399 ngettext("mcen_nc_get_msg",
1401 num_of_uncached_msgs));
1403 if (response == GTK_RESPONSE_CANCEL)
1406 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1410 * Common code for the reply and forward actions
1413 reply_forward (ReplyForwardAction action, ModestWindow *win)
1415 ModestMailOperation *mail_op = NULL;
1416 TnyList *header_list = NULL;
1417 ReplyForwardHelper *rf_helper = NULL;
1418 guint reply_forward_type;
1419 gboolean continue_download = TRUE;
1420 gboolean do_retrieve = TRUE;
1422 g_return_if_fail (MODEST_IS_WINDOW(win));
1424 /* we need an account when editing */
1425 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1426 if (!modest_ui_actions_run_account_setup_wizard (win))
1430 header_list = get_selected_headers (win);
1434 reply_forward_type =
1435 modest_conf_get_int (modest_runtime_get_conf (),
1436 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1439 /* check if we need to download msg before asking about it */
1440 do_retrieve = (action == ACTION_FORWARD) ||
1441 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1444 gint num_of_unc_msgs;
1446 /* check that the messages have been previously downloaded */
1447 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1448 /* If there are any uncached message ask the user
1449 * whether he/she wants to download them. */
1450 if (num_of_unc_msgs) {
1451 TnyAccount *account = get_account_from_header_list (header_list);
1452 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1453 g_object_unref (account);
1457 if (!continue_download) {
1458 g_object_unref (header_list);
1462 /* We assume that we can only select messages of the
1463 same folder and that we reply all of them from the
1464 same account. In fact the interface currently only
1465 allows single selection */
1468 rf_helper = g_slice_new0 (ReplyForwardHelper);
1469 rf_helper->reply_forward_type = reply_forward_type;
1470 rf_helper->action = action;
1471 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1473 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1474 rf_helper->parent_window = GTK_WIDGET (win);
1475 if (!rf_helper->account_name)
1476 rf_helper->account_name =
1477 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1479 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1482 /* Get header and message. Do not free them here, the
1483 reply_forward_cb must do it */
1484 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1485 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1486 if (!msg || !header) {
1488 g_object_unref (msg);
1489 g_printerr ("modest: no message found\n");
1492 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1495 g_object_unref (header);
1500 /* Only reply/forward to one message */
1501 iter = tny_list_create_iterator (header_list);
1502 header = TNY_HEADER (tny_iterator_get_current (iter));
1503 g_object_unref (iter);
1506 /* Retrieve messages */
1509 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1510 modest_ui_actions_get_msgs_full_error_handler,
1512 modest_mail_operation_queue_add (
1513 modest_runtime_get_mail_operation_queue (), mail_op);
1515 modest_mail_operation_get_msg (mail_op,
1520 g_object_unref(mail_op);
1522 /* we put a ref here to prevent double unref as the reply
1523 * forward callback unrefs the header at its end */
1524 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1528 g_object_unref (header);
1534 g_object_unref (header_list);
1538 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1540 g_return_if_fail (MODEST_IS_WINDOW(win));
1542 reply_forward (ACTION_REPLY, win);
1546 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1548 g_return_if_fail (MODEST_IS_WINDOW(win));
1550 reply_forward (ACTION_FORWARD, win);
1554 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1556 g_return_if_fail (MODEST_IS_WINDOW(win));
1558 reply_forward (ACTION_REPLY_TO_ALL, win);
1562 modest_ui_actions_on_next (GtkAction *action,
1563 ModestWindow *window)
1565 if (MODEST_IS_MAIN_WINDOW (window)) {
1566 GtkWidget *header_view;
1568 header_view = modest_main_window_get_child_widget (
1569 MODEST_MAIN_WINDOW(window),
1570 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1574 modest_header_view_select_next (
1575 MODEST_HEADER_VIEW(header_view));
1576 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1577 modest_msg_view_window_select_next_message (
1578 MODEST_MSG_VIEW_WINDOW (window));
1580 g_return_if_reached ();
1585 modest_ui_actions_on_prev (GtkAction *action,
1586 ModestWindow *window)
1588 g_return_if_fail (MODEST_IS_WINDOW(window));
1590 if (MODEST_IS_MAIN_WINDOW (window)) {
1591 GtkWidget *header_view;
1592 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1593 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1597 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1598 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1599 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1601 g_return_if_reached ();
1606 modest_ui_actions_on_sort (GtkAction *action,
1607 ModestWindow *window)
1609 g_return_if_fail (MODEST_IS_WINDOW(window));
1611 if (MODEST_IS_MAIN_WINDOW (window)) {
1612 GtkWidget *header_view;
1613 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1614 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1616 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1621 /* Show sorting dialog */
1622 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1627 new_messages_arrived (ModestMailOperation *self,
1628 TnyList *new_headers,
1632 gboolean show_visual_notifications;
1634 source = modest_mail_operation_get_source (self);
1635 show_visual_notifications = (source) ? FALSE : TRUE;
1637 g_object_unref (source);
1639 /* Notify new messages have been downloaded. If the
1640 send&receive was invoked by the user then do not show any
1641 visual notification, only play a sound and activate the LED
1642 (for the Maemo version) */
1643 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1644 modest_platform_on_new_headers_received (new_headers,
1645 show_visual_notifications);
1650 retrieve_all_messages_cb (GObject *source,
1652 guint retrieve_limit)
1658 window = GTK_WINDOW (source);
1659 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1660 num_msgs, retrieve_limit);
1662 /* Ask the user if they want to retrieve all the messages */
1664 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1665 _("mcen_bd_get_all"),
1666 _("mcen_bd_newest_only"));
1667 /* Free and return */
1669 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1673 TnyAccount *account;
1675 gchar *account_name;
1679 do_send_receive_performer (gboolean canceled,
1681 GtkWindow *parent_window,
1682 TnyAccount *account,
1685 ModestMailOperation *mail_op;
1686 SendReceiveInfo *info;
1688 info = (SendReceiveInfo *) user_data;
1690 if (err || canceled) {
1694 /* Set send/receive operation in progress */
1695 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
1696 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
1699 mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
1700 modest_ui_actions_send_receive_error_handler,
1703 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
1704 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1705 G_CALLBACK (on_send_receive_finished),
1708 /* Send & receive. */
1709 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1710 modest_mail_operation_update_account (mail_op, info->account_name, (info->win) ? FALSE : TRUE,
1711 (info->win) ? retrieve_all_messages_cb : NULL,
1712 new_messages_arrived, info->win);
1713 g_object_unref (G_OBJECT (mail_op));
1717 if (info->account_name)
1718 g_free (info->account_name);
1720 g_object_unref (info->win);
1722 g_object_unref (info->account);
1723 g_slice_free (SendReceiveInfo, info);
1727 * This function performs the send & receive required actions. The
1728 * window is used to create the mail operation. Typically it should
1729 * always be the main window, but we pass it as argument in order to
1733 modest_ui_actions_do_send_receive (const gchar *account_name,
1734 gboolean force_connection,
1737 gchar *acc_name = NULL;
1738 SendReceiveInfo *info;
1739 ModestTnyAccountStore *acc_store;
1741 /* If no account name was provided then get the current account, and if
1742 there is no current account then pick the default one: */
1743 if (!account_name) {
1745 acc_name = g_strdup (modest_window_get_active_account (win));
1747 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1749 g_printerr ("modest: cannot get default account\n");
1753 acc_name = g_strdup (account_name);
1756 acc_store = modest_runtime_get_account_store ();
1758 /* Create the info for the connect and perform */
1759 info = g_slice_new (SendReceiveInfo);
1760 info->account_name = acc_name;
1761 info->win = (win) ? g_object_ref (win) : NULL;
1762 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
1763 TNY_ACCOUNT_TYPE_STORE);
1765 /* Invoke the connect and perform */
1766 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
1767 force_connection, info->account,
1768 do_send_receive_performer, info);
1773 modest_ui_actions_do_cancel_send (const gchar *account_name,
1776 TnyTransportAccount *transport_account;
1777 TnySendQueue *send_queue = NULL;
1778 GError *error = NULL;
1780 /* Get transport account */
1782 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1783 (modest_runtime_get_account_store(),
1785 TNY_ACCOUNT_TYPE_TRANSPORT));
1786 if (!transport_account) {
1787 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1792 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1793 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1794 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1795 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1796 "modest: could not find send queue for account\n");
1798 /* Cancel the current send */
1799 tny_account_cancel (TNY_ACCOUNT (transport_account));
1801 /* Suspend all pending messages */
1802 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
1806 if (transport_account != NULL)
1807 g_object_unref (G_OBJECT (transport_account));
1811 modest_ui_actions_cancel_send_all (ModestWindow *win)
1813 GSList *account_names, *iter;
1815 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1818 iter = account_names;
1820 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1821 iter = g_slist_next (iter);
1824 modest_account_mgr_free_account_names (account_names);
1825 account_names = NULL;
1829 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1832 /* Check if accounts exist */
1833 gboolean accounts_exist =
1834 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1836 /* If not, allow the user to create an account before trying to send/receive. */
1837 if (!accounts_exist)
1838 modest_ui_actions_on_accounts (NULL, win);
1840 /* Cancel all sending operaitons */
1841 modest_ui_actions_cancel_send_all (win);
1845 * Refreshes all accounts. This function will be used by automatic
1849 modest_ui_actions_do_send_receive_all (ModestWindow *win,
1850 gboolean force_connection)
1852 GSList *account_names, *iter;
1854 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1857 iter = account_names;
1859 modest_ui_actions_do_send_receive ((const char*) iter->data, force_connection, win);
1860 iter = g_slist_next (iter);
1863 modest_account_mgr_free_account_names (account_names);
1864 account_names = NULL;
1868 * Handler of the click on Send&Receive button in the main toolbar
1871 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1873 /* Check if accounts exist */
1874 gboolean accounts_exist;
1877 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1879 /* If not, allow the user to create an account before trying to send/receive. */
1880 if (!accounts_exist)
1881 modest_ui_actions_on_accounts (NULL, win);
1883 /* Refresh the current folder. The if is always TRUE it's just an extra check */
1884 if (MODEST_IS_MAIN_WINDOW (win)) {
1885 GtkWidget *folder_view;
1886 TnyFolderStore *folder_store;
1889 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1890 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1894 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1897 g_object_unref (folder_store);
1900 /* Refresh the active account. Force the connection if needed */
1901 modest_ui_actions_do_send_receive (NULL, TRUE, win);
1906 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1909 GtkWidget *header_view;
1911 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1913 header_view = modest_main_window_get_child_widget (main_window,
1914 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1918 conf = modest_runtime_get_conf ();
1920 /* what is saved/restored is depending on the style; thus; we save with
1921 * old style, then update the style, and restore for this new style
1923 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1925 if (modest_header_view_get_style
1926 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1927 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1928 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1930 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1931 MODEST_HEADER_VIEW_STYLE_DETAILS);
1933 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1934 MODEST_CONF_HEADER_VIEW_KEY);
1939 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1941 ModestMainWindow *main_window)
1943 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1944 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1946 /* in the case the folder is empty, show the empty folder message and focus
1948 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1949 if (modest_header_view_is_empty (header_view)) {
1950 TnyFolder *folder = modest_header_view_get_folder (header_view);
1951 GtkWidget *folder_view =
1952 modest_main_window_get_child_widget (main_window,
1953 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1955 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1956 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1960 /* If no header has been selected then exit */
1965 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1966 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1968 /* Update toolbar dimming state */
1969 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1973 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1975 ModestMainWindow *main_window)
1979 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1984 if (modest_header_view_count_selected_headers (header_view) > 1) {
1985 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1990 /* headers = tny_simple_list_new (); */
1991 /* tny_list_prepend (headers, G_OBJECT (header)); */
1992 headers = modest_header_view_get_selected_headers (header_view);
1994 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
1996 g_object_unref (headers);
2000 set_active_account_from_tny_account (TnyAccount *account,
2001 ModestWindow *window)
2003 const gchar *server_acc_name = tny_account_get_id (account);
2005 /* We need the TnyAccount provided by the
2006 account store because that is the one that
2007 knows the name of the Modest account */
2008 TnyAccount *modest_server_account = modest_server_account =
2009 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2010 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2012 if (!modest_server_account) {
2013 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2017 /* Update active account, but only if it's not a pseudo-account */
2018 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2019 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2020 const gchar *modest_acc_name =
2021 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2022 if (modest_acc_name)
2023 modest_window_set_active_account (window, modest_acc_name);
2026 g_object_unref (modest_server_account);
2031 folder_refreshed_cb (ModestMailOperation *mail_op,
2035 ModestMainWindow *win = NULL;
2036 GtkWidget *header_view;
2038 g_return_if_fail (TNY_IS_FOLDER (folder));
2040 win = MODEST_MAIN_WINDOW (user_data);
2042 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2045 TnyFolder *current_folder;
2047 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2048 if (current_folder != NULL && folder != current_folder) {
2049 g_object_unref (current_folder);
2051 } else if (current_folder)
2052 g_object_unref (current_folder);
2055 /* Check if folder is empty and set headers view contents style */
2056 if (tny_folder_get_all_count (folder) == 0)
2057 modest_main_window_set_contents_style (win,
2058 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2062 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2063 TnyFolderStore *folder_store,
2065 ModestMainWindow *main_window)
2068 GtkWidget *header_view;
2070 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2072 header_view = modest_main_window_get_child_widget(main_window,
2073 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2077 conf = modest_runtime_get_conf ();
2079 if (TNY_IS_ACCOUNT (folder_store)) {
2081 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2083 /* Show account details */
2084 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2087 if (TNY_IS_FOLDER (folder_store) && selected) {
2089 /* Update the active account */
2090 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2092 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2093 g_object_unref (account);
2097 /* Set the header style by default, it could
2098 be changed later by the refresh callback to
2100 modest_main_window_set_contents_style (main_window,
2101 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2103 /* Set folder on header view. This function
2104 will call tny_folder_refresh_async so we
2105 pass a callback that will be called when
2106 finished. We use that callback to set the
2107 empty view if there are no messages */
2108 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2109 TNY_FOLDER (folder_store),
2110 folder_refreshed_cb,
2113 /* Restore configuration. We need to do this
2114 *after* the set_folder because the widget
2115 memory asks the header view about its
2117 modest_widget_memory_restore (modest_runtime_get_conf (),
2118 G_OBJECT(header_view),
2119 MODEST_CONF_HEADER_VIEW_KEY);
2121 /* Update the active account */
2122 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2123 /* Save only if we're seeing headers */
2124 if (modest_main_window_get_contents_style (main_window) ==
2125 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2126 modest_widget_memory_save (conf, G_OBJECT (header_view),
2127 MODEST_CONF_HEADER_VIEW_KEY);
2128 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2132 /* Update toolbar dimming state */
2133 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2137 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2144 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2146 online = tny_device_is_online (modest_runtime_get_device());
2149 /* already online -- the item is simply not there... */
2150 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2152 GTK_MESSAGE_WARNING,
2154 _("The %s you selected cannot be found"),
2156 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2157 gtk_dialog_run (GTK_DIALOG(dialog));
2159 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2162 _("mcen_bd_dialog_cancel"),
2163 GTK_RESPONSE_REJECT,
2164 _("mcen_bd_dialog_ok"),
2165 GTK_RESPONSE_ACCEPT,
2167 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2168 "Do you want to get online?"), item);
2169 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2170 gtk_label_new (txt), FALSE, FALSE, 0);
2171 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2174 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2175 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2176 /* TODO: Comment about why is this commented out: */
2177 /* modest_platform_connect_and_wait (); */
2180 gtk_widget_destroy (dialog);
2184 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2187 /* g_message ("%s %s", __FUNCTION__, link); */
2192 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2195 modest_platform_activate_uri (link);
2199 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2202 modest_platform_show_uri_popup (link);
2206 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2209 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2213 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2214 const gchar *address,
2217 /* g_message ("%s %s", __FUNCTION__, address); */
2221 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2222 TnyMsg *saved_draft,
2225 ModestMsgEditWindow *edit_window;
2226 ModestMainWindow *win;
2228 /* FIXME. Make the header view sensitive again. This is a
2229 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2231 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2232 modest_runtime_get_window_mgr(), FALSE));
2234 GtkWidget *hdrview = modest_main_window_get_child_widget(
2235 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2236 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2239 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2241 /* It might not be a good idea to do nothing if there was an error,
2242 * so let's at least show a generic error banner. */
2243 /* TODO error while saving attachment, show "Saving draft failed" banner */
2244 if (modest_mail_operation_get_error (mail_op) != NULL) {
2245 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_op))->message);
2246 modest_platform_information_banner (NULL, NULL, _("mail_ib_file_operation_failed"));
2248 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2250 g_object_unref(edit_window);
2254 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2256 TnyTransportAccount *transport_account;
2257 ModestMailOperation *mail_operation;
2259 gchar *account_name, *from;
2260 ModestAccountMgr *account_mgr;
2261 /* char *info_text; */
2262 gboolean had_error = FALSE;
2263 guint64 available_disk, expected_size;
2267 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2269 data = modest_msg_edit_window_get_msg_data (edit_window);
2272 available_disk = modest_folder_available_space (NULL);
2273 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2274 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2279 if ((available_disk != -1) && expected_size > available_disk) {
2280 modest_msg_edit_window_free_msg_data (edit_window, data);
2282 modest_platform_information_banner (NULL, NULL, dgettext("ke-recv", "cerm_device_memory_full"));
2286 account_name = g_strdup (data->account_name);
2287 account_mgr = modest_runtime_get_account_mgr();
2289 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2291 account_name = modest_account_mgr_get_default_account (account_mgr);
2292 if (!account_name) {
2293 g_printerr ("modest: no account found\n");
2294 modest_msg_edit_window_free_msg_data (edit_window, data);
2298 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2299 account_name = g_strdup (data->account_name);
2303 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2304 (modest_runtime_get_account_store(),
2306 TNY_ACCOUNT_TYPE_TRANSPORT));
2307 if (!transport_account) {
2308 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2309 g_free (account_name);
2310 modest_msg_edit_window_free_msg_data (edit_window, data);
2313 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2315 /* Create the mail operation */
2316 mail_operation = modest_mail_operation_new (NULL);
2317 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2319 modest_mail_operation_save_to_drafts (mail_operation,
2331 data->priority_flags,
2332 on_save_to_drafts_cb,
2333 g_object_ref(edit_window));
2335 /* info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts")); */
2336 modest_platform_information_banner (NULL, NULL, _CS("sfil_ib_saving"));
2337 modest_msg_edit_window_reset_modified (edit_window);
2341 g_free (account_name);
2342 g_object_unref (G_OBJECT (transport_account));
2343 g_object_unref (G_OBJECT (mail_operation));
2345 modest_msg_edit_window_free_msg_data (edit_window, data);
2348 * If the drafts folder is selected then make the header view
2349 * insensitive while the message is being saved to drafts
2350 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2351 * is not very clean but it avoids letting the drafts folder
2352 * in an inconsistent state: the user could edit the message
2353 * being saved and undesirable things would happen.
2354 * In the average case the user won't notice anything at
2355 * all. In the worst case (the user is editing a really big
2356 * file from Drafts) the header view will be insensitive
2357 * during the saving process (10 or 20 seconds, depending on
2358 * the message). Anyway this is just a quick workaround: once
2359 * we find a better solution it should be removed
2360 * See NB#65125 (commend #18) for details.
2362 ModestMainWindow *win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2363 modest_runtime_get_window_mgr(), FALSE));
2364 if (!had_error && win != NULL) {
2365 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2366 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2368 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2370 if (modest_tny_folder_is_local_folder(folder)) {
2371 TnyFolderType folder_type;
2372 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2373 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2374 GtkWidget *hdrview = modest_main_window_get_child_widget(
2375 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2376 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2380 if (folder != NULL) g_object_unref(folder);
2387 /* For instance, when clicking the Send toolbar button when editing a message: */
2389 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2391 TnyTransportAccount *transport_account = NULL;
2392 gboolean had_error = FALSE;
2393 guint64 available_disk, expected_size;
2397 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2399 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2402 /* FIXME: Code added just for testing. The final version will
2403 use the send queue provided by tinymail and some
2405 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2408 available_disk = modest_folder_available_space (NULL);
2409 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2410 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2415 if ((available_disk != -1) && expected_size > available_disk) {
2416 modest_msg_edit_window_free_msg_data (edit_window, data);
2418 modest_platform_information_banner (NULL, NULL, dgettext("ke-recv", "cerm_device_memory_full"));
2422 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2423 gchar *account_name = g_strdup (data->account_name);
2425 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2428 account_name = modest_account_mgr_get_default_account (account_mgr);
2430 if (!account_name) {
2431 modest_msg_edit_window_free_msg_data (edit_window, data);
2432 /* Run account setup wizard */
2433 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2438 /* Get the currently-active transport account for this modest account: */
2439 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2440 transport_account = TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2441 (modest_runtime_get_account_store(),
2442 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2445 if (!transport_account) {
2446 modest_msg_edit_window_free_msg_data (edit_window, data);
2447 /* Run account setup wizard */
2448 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2452 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2454 /* Create the mail operation */
2455 ModestMailOperation *mail_operation = modest_mail_operation_new (NULL);
2456 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2458 modest_mail_operation_send_new_mail (mail_operation,
2470 data->priority_flags);
2472 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2473 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2476 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2477 const GError *error = modest_mail_operation_get_error (mail_operation);
2478 if (error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2479 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2480 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2487 g_free (account_name);
2488 g_object_unref (G_OBJECT (transport_account));
2489 g_object_unref (G_OBJECT (mail_operation));
2491 modest_msg_edit_window_free_msg_data (edit_window, data);
2494 modest_msg_edit_window_set_sent (edit_window, TRUE);
2496 /* Save settings and close the window: */
2497 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2504 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2505 ModestMsgEditWindow *window)
2507 ModestMsgEditFormatState *format_state = NULL;
2509 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2510 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2512 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2515 format_state = modest_msg_edit_window_get_format_state (window);
2516 g_return_if_fail (format_state != NULL);
2518 format_state->bold = gtk_toggle_action_get_active (action);
2519 modest_msg_edit_window_set_format_state (window, format_state);
2520 g_free (format_state);
2525 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2526 ModestMsgEditWindow *window)
2528 ModestMsgEditFormatState *format_state = NULL;
2530 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2531 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2533 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2536 format_state = modest_msg_edit_window_get_format_state (window);
2537 g_return_if_fail (format_state != NULL);
2539 format_state->italics = gtk_toggle_action_get_active (action);
2540 modest_msg_edit_window_set_format_state (window, format_state);
2541 g_free (format_state);
2546 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2547 ModestMsgEditWindow *window)
2549 ModestMsgEditFormatState *format_state = NULL;
2551 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2552 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2554 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2557 format_state = modest_msg_edit_window_get_format_state (window);
2558 g_return_if_fail (format_state != NULL);
2560 format_state->bullet = gtk_toggle_action_get_active (action);
2561 modest_msg_edit_window_set_format_state (window, format_state);
2562 g_free (format_state);
2567 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2568 GtkRadioAction *selected,
2569 ModestMsgEditWindow *window)
2571 ModestMsgEditFormatState *format_state = NULL;
2572 GtkJustification value;
2574 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2576 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2579 value = gtk_radio_action_get_current_value (selected);
2581 format_state = modest_msg_edit_window_get_format_state (window);
2582 g_return_if_fail (format_state != NULL);
2584 format_state->justification = value;
2585 modest_msg_edit_window_set_format_state (window, format_state);
2586 g_free (format_state);
2590 modest_ui_actions_on_select_editor_color (GtkAction *action,
2591 ModestMsgEditWindow *window)
2593 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2594 g_return_if_fail (GTK_IS_ACTION (action));
2596 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2599 modest_msg_edit_window_select_color (window);
2603 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2604 ModestMsgEditWindow *window)
2606 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2607 g_return_if_fail (GTK_IS_ACTION (action));
2609 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2612 modest_msg_edit_window_select_background_color (window);
2616 modest_ui_actions_on_insert_image (GtkAction *action,
2617 ModestMsgEditWindow *window)
2619 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2620 g_return_if_fail (GTK_IS_ACTION (action));
2622 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2625 modest_msg_edit_window_insert_image (window);
2629 modest_ui_actions_on_attach_file (GtkAction *action,
2630 ModestMsgEditWindow *window)
2632 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2633 g_return_if_fail (GTK_IS_ACTION (action));
2635 modest_msg_edit_window_offer_attach_file (window);
2639 modest_ui_actions_on_remove_attachments (GtkAction *action,
2640 ModestMsgEditWindow *window)
2642 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2643 g_return_if_fail (GTK_IS_ACTION (action));
2645 modest_msg_edit_window_remove_attachments (window, NULL);
2649 do_create_folder_cb (ModestMailOperation *mail_op,
2650 TnyFolderStore *parent_folder,
2651 TnyFolder *new_folder,
2654 gchar *suggested_name = (gchar *) user_data;
2655 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
2657 if (modest_mail_operation_get_error (mail_op)) {
2659 modest_platform_information_banner (GTK_WIDGET (source_win), NULL,
2660 _("mail_in_ui_folder_create_error"));
2663 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
2665 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
2666 * FIXME: any other? */
2667 GtkWidget *folder_view;
2669 if (MODEST_IS_MAIN_WINDOW(source_win))
2671 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
2672 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2675 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
2677 /* Select the newly created folder */
2678 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
2680 g_object_unref (new_folder);
2682 /* Free. Note that the first time it'll be NULL so noop */
2683 g_free (suggested_name);
2684 g_object_unref (source_win);
2688 do_create_folder (GtkWindow *parent_window,
2689 TnyFolderStore *parent_folder,
2690 const gchar *suggested_name)
2693 gchar *folder_name = NULL;
2695 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2697 (gchar *) suggested_name,
2700 if (result == GTK_RESPONSE_ACCEPT) {
2701 ModestMailOperation *mail_op;
2703 mail_op = modest_mail_operation_new (G_OBJECT(parent_window));
2705 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2707 modest_mail_operation_create_folder (mail_op,
2709 (const gchar *) folder_name,
2710 do_create_folder_cb,
2712 g_object_unref (mail_op);
2717 create_folder_performer (gboolean canceled,
2719 GtkWindow *parent_window,
2720 TnyAccount *account,
2723 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
2725 if (canceled || err) {
2729 /* Run the new folder dialog */
2730 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
2733 g_object_unref (parent_folder);
2737 modest_ui_actions_create_folder(GtkWidget *parent_window,
2738 GtkWidget *folder_view)
2740 TnyFolderStore *parent_folder;
2742 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2744 if (parent_folder) {
2745 /* The parent folder will be freed in the callback */
2746 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
2749 create_folder_performer,
2755 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2757 GtkWidget *folder_view;
2759 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2761 folder_view = modest_main_window_get_child_widget (main_window,
2762 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2766 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2770 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2773 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2774 const GError *error = NULL;
2775 const gchar *message = NULL;
2777 /* Get error message */
2778 error = modest_mail_operation_get_error (mail_op);
2780 g_return_if_reached ();
2782 switch (error->code) {
2783 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2784 message = _CS("ckdg_ib_folder_already_exists");
2787 g_warning ("%s: BUG: unexpected error:[%d]: %s", __FUNCTION__,
2788 error->code, error->message);
2792 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2796 TnyFolderStore *folder;
2801 on_rename_folder_cb (ModestMailOperation *mail_op,
2802 TnyFolder *new_folder,
2806 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (user_data),
2811 on_rename_folder_performer (gboolean canceled,
2813 GtkWindow *parent_window,
2814 TnyAccount *account,
2817 ModestMailOperation *mail_op = NULL;
2818 GtkTreeSelection *sel = NULL;
2819 GtkWidget *folder_view = NULL;
2820 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
2822 if (!canceled && (err == NULL) && MODEST_IS_MAIN_WINDOW(parent_window)) {
2824 folder_view = modest_main_window_get_child_widget (
2825 MODEST_MAIN_WINDOW (parent_window),
2826 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2829 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2830 modest_ui_actions_rename_folder_error_handler,
2831 parent_window, NULL);
2833 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2836 /* Clear the headers view */
2837 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2838 gtk_tree_selection_unselect_all (sel);
2840 /* Actually rename the folder */
2841 modest_mail_operation_rename_folder (mail_op,
2842 TNY_FOLDER (data->folder),
2843 (const gchar *) (data->new_name),
2844 on_rename_folder_cb,
2848 g_object_unref (mail_op);
2849 g_free (data->new_name);
2854 modest_ui_actions_on_rename_folder (GtkAction *action,
2855 ModestMainWindow *main_window)
2857 TnyFolderStore *folder;
2858 GtkWidget *folder_view;
2859 GtkWidget *header_view;
2861 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2863 folder_view = modest_main_window_get_child_widget (main_window,
2864 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2868 header_view = modest_main_window_get_child_widget (main_window,
2869 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2874 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2879 if (TNY_IS_FOLDER (folder)) {
2882 const gchar *current_name;
2883 TnyFolderStore *parent;
2884 gboolean do_rename = TRUE;
2886 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2887 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2888 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2889 parent, current_name,
2891 g_object_unref (parent);
2893 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2896 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
2897 rename_folder_data->folder = folder;
2898 rename_folder_data->new_name = folder_name;
2899 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
2900 folder, on_rename_folder_performer, rename_folder_data);
2903 g_object_unref (folder);
2907 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2910 GObject *win = modest_mail_operation_get_source (mail_op);
2912 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2913 _("mail_in_ui_folder_delete_error"));
2914 g_object_unref (win);
2918 TnyFolderStore *folder;
2919 gboolean move_to_trash;
2923 on_delete_folder_cb (gboolean canceled,
2925 GtkWindow *parent_window,
2926 TnyAccount *account,
2929 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
2930 GtkWidget *folder_view;
2931 ModestMailOperation *mail_op;
2932 GtkTreeSelection *sel;
2934 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
2935 g_object_unref (G_OBJECT (info->folder));
2940 folder_view = modest_main_window_get_child_widget (
2941 MODEST_MAIN_WINDOW (parent_window),
2942 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2944 /* Unselect the folder before deleting it to free the headers */
2945 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2946 gtk_tree_selection_unselect_all (sel);
2948 /* Create the mail operation */
2950 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2951 modest_ui_actions_delete_folder_error_handler,
2954 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2956 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
2958 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2960 g_object_unref (G_OBJECT (mail_op));
2961 g_object_unref (G_OBJECT (info->folder));
2966 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2968 TnyFolderStore *folder;
2969 GtkWidget *folder_view;
2973 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2975 folder_view = modest_main_window_get_child_widget (main_window,
2976 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2980 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2982 /* Show an error if it's an account */
2983 if (!TNY_IS_FOLDER (folder)) {
2984 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2985 _("mail_in_ui_folder_delete_error"));
2986 g_object_unref (G_OBJECT (folder));
2991 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2992 tny_folder_get_name (TNY_FOLDER (folder)));
2993 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2994 (const gchar *) message);
2997 if (response == GTK_RESPONSE_OK) {
2998 DeleteFolderInfo *info;
2999 info = g_new0(DeleteFolderInfo, 1);
3000 info->folder = folder;
3001 info->move_to_trash = move_to_trash;
3002 g_object_ref (G_OBJECT (info->folder));
3003 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3004 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3006 TNY_FOLDER_STORE (account),
3007 on_delete_folder_cb, info);
3008 g_object_unref (account);
3010 g_object_unref (G_OBJECT (folder));
3014 modest_ui_actions_on_delete_folder (GtkAction *action,
3015 ModestMainWindow *main_window)
3017 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3019 delete_folder (main_window, FALSE);
3023 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3025 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3027 delete_folder (main_window, TRUE);
3032 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3033 const gchar* server_account_name,
3038 ModestMainWindow *main_window)
3040 g_return_if_fail(server_account_name);
3042 /* Initalize output parameters: */
3049 #ifdef MODEST_PLATFORM_MAEMO
3050 /* Maemo uses a different (awkward) button order,
3051 * It should probably just use gtk_alternative_dialog_button_order ().
3053 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3056 _("mcen_bd_dialog_ok"),
3057 GTK_RESPONSE_ACCEPT,
3058 _("mcen_bd_dialog_cancel"),
3059 GTK_RESPONSE_REJECT,
3062 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3066 GTK_RESPONSE_REJECT,
3068 GTK_RESPONSE_ACCEPT,
3070 #endif /* MODEST_PLATFORM_MAEMO */
3072 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog));
3074 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3075 modest_runtime_get_account_mgr(), server_account_name);
3076 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3077 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3083 /* This causes a warning because the logical ID has no %s in it,
3084 * though the translation does, but there is not much we can do about that: */
3085 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3086 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3089 g_free (server_name);
3093 gchar *initial_username = modest_account_mgr_get_server_account_username (
3094 modest_runtime_get_account_mgr(), server_account_name);
3096 GtkWidget *entry_username = gtk_entry_new ();
3097 if (initial_username)
3098 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3099 /* Dim this if a connection has ever succeeded with this username,
3100 * as per the UI spec: */
3101 const gboolean username_known =
3102 modest_account_mgr_get_server_account_username_has_succeeded(
3103 modest_runtime_get_account_mgr(), server_account_name);
3104 gtk_widget_set_sensitive (entry_username, !username_known);
3106 #ifdef MODEST_PLATFORM_MAEMO
3107 /* Auto-capitalization is the default, so let's turn it off: */
3108 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3110 /* Create a size group to be used by all captions.
3111 * Note that HildonCaption does not create a default size group if we do not specify one.
3112 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3113 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3115 GtkWidget *caption = hildon_caption_new (sizegroup,
3116 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3117 gtk_widget_show (entry_username);
3118 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3119 FALSE, FALSE, MODEST_MARGIN_HALF);
3120 gtk_widget_show (caption);
3122 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3124 #endif /* MODEST_PLATFORM_MAEMO */
3127 GtkWidget *entry_password = gtk_entry_new ();
3128 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3129 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3131 #ifdef MODEST_PLATFORM_MAEMO
3132 /* Auto-capitalization is the default, so let's turn it off: */
3133 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3134 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3136 caption = hildon_caption_new (sizegroup,
3137 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3138 gtk_widget_show (entry_password);
3139 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3140 FALSE, FALSE, MODEST_MARGIN_HALF);
3141 gtk_widget_show (caption);
3142 g_object_unref (sizegroup);
3144 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3146 #endif /* MODEST_PLATFORM_MAEMO */
3148 if (initial_username != NULL)
3149 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3151 /* This is not in the Maemo UI spec:
3152 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3153 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3157 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3159 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3161 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3163 modest_account_mgr_set_server_account_username (
3164 modest_runtime_get_account_mgr(), server_account_name,
3167 const gboolean username_was_changed =
3168 (strcmp (*username, initial_username) != 0);
3169 if (username_was_changed) {
3170 g_warning ("%s: tinymail does not yet support changing the "
3171 "username in the get_password() callback.\n", __FUNCTION__);
3176 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3178 /* We do not save the password in the configuration,
3179 * because this function is only called for passwords that should
3180 * not be remembered:
3181 modest_server_account_set_password (
3182 modest_runtime_get_account_mgr(), server_account_name,
3191 modest_platform_information_banner(GTK_WIDGET (main_window), NULL, _("mail_ib_login_cancelled"));
3203 /* This is not in the Maemo UI spec:
3204 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3210 gtk_widget_destroy (dialog);
3212 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3216 modest_ui_actions_on_cut (GtkAction *action,
3217 ModestWindow *window)
3219 GtkWidget *focused_widget;
3220 GtkClipboard *clipboard;
3222 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3223 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3224 if (GTK_IS_EDITABLE (focused_widget)) {
3225 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3226 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3227 gtk_clipboard_store (clipboard);
3228 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3229 GtkTextBuffer *buffer;
3231 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3232 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3233 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3234 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3235 gtk_clipboard_store (clipboard);
3237 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3238 TnyList *header_list = modest_header_view_get_selected_headers (
3239 MODEST_HEADER_VIEW (focused_widget));
3240 gboolean continue_download = FALSE;
3241 gint num_of_unc_msgs;
3243 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3245 if (num_of_unc_msgs) {
3246 TnyAccount *account = get_account_from_header_list (header_list);
3247 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3248 g_object_unref (account);
3251 if (num_of_unc_msgs == 0 || continue_download) {
3252 /* modest_platform_information_banner (
3253 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3254 modest_header_view_cut_selection (
3255 MODEST_HEADER_VIEW (focused_widget));
3258 g_object_unref (header_list);
3259 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3260 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3265 modest_ui_actions_on_copy (GtkAction *action,
3266 ModestWindow *window)
3268 GtkClipboard *clipboard;
3269 GtkWidget *focused_widget;
3270 gboolean copied = TRUE;
3272 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3273 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3275 if (GTK_IS_LABEL (focused_widget)) {
3277 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3278 gtk_clipboard_set_text (clipboard, selection, -1);
3280 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3281 gtk_clipboard_store (clipboard);
3282 } else if (GTK_IS_EDITABLE (focused_widget)) {
3283 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3284 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3285 gtk_clipboard_store (clipboard);
3286 } else if (GTK_IS_HTML (focused_widget)) {
3287 gtk_html_copy (GTK_HTML (focused_widget));
3288 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3289 gtk_clipboard_store (clipboard);
3290 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3291 GtkTextBuffer *buffer;
3292 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3293 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3294 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3295 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3296 gtk_clipboard_store (clipboard);
3298 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3299 TnyList *header_list = modest_header_view_get_selected_headers (
3300 MODEST_HEADER_VIEW (focused_widget));
3301 gboolean continue_download = FALSE;
3302 gint num_of_unc_msgs;
3304 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3306 if (num_of_unc_msgs) {
3307 TnyAccount *account = get_account_from_header_list (header_list);
3308 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3309 g_object_unref (account);
3312 if (num_of_unc_msgs == 0 || continue_download) {
3313 modest_platform_information_banner (
3314 NULL, NULL, _CS("mcen_ib_getting_items"));
3315 modest_header_view_copy_selection (
3316 MODEST_HEADER_VIEW (focused_widget));
3320 g_object_unref (header_list);
3322 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3323 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3326 /* Show information banner if there was a copy to clipboard */
3328 modest_platform_information_banner (
3329 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3333 modest_ui_actions_on_undo (GtkAction *action,
3334 ModestWindow *window)
3336 ModestEmailClipboard *clipboard = NULL;
3338 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3339 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3340 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3341 /* Clear clipboard source */
3342 clipboard = modest_runtime_get_email_clipboard ();
3343 modest_email_clipboard_clear (clipboard);
3346 g_return_if_reached ();
3351 modest_ui_actions_on_redo (GtkAction *action,
3352 ModestWindow *window)
3354 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3355 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3358 g_return_if_reached ();
3364 destroy_information_note (ModestMailOperation *mail_op,
3367 /* destroy information note */
3368 gtk_widget_destroy (GTK_WIDGET(user_data));
3372 destroy_folder_information_note (ModestMailOperation *mail_op,
3373 TnyFolder *new_folder,
3376 /* destroy information note */
3377 gtk_widget_destroy (GTK_WIDGET(user_data));
3382 paste_as_attachment_free (gpointer data)
3384 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3386 gtk_widget_destroy (helper->banner);
3387 g_object_unref (helper->banner);
3392 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3397 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3398 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3403 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3408 modest_ui_actions_on_paste (GtkAction *action,
3409 ModestWindow *window)
3411 GtkWidget *focused_widget = NULL;
3412 GtkWidget *inf_note = NULL;
3413 ModestMailOperation *mail_op = NULL;
3415 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3416 if (GTK_IS_EDITABLE (focused_widget)) {
3417 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3418 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3419 ModestEmailClipboard *e_clipboard = NULL;
3420 e_clipboard = modest_runtime_get_email_clipboard ();
3421 if (modest_email_clipboard_cleared (e_clipboard)) {
3422 GtkTextBuffer *buffer;
3423 GtkClipboard *clipboard;
3425 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3426 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3427 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3428 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3429 ModestMailOperation *mail_op;
3430 TnyFolder *src_folder;
3433 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3434 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3435 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3436 _CS("ckct_nw_pasting"));
3437 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3438 mail_op = modest_mail_operation_new (G_OBJECT (window));
3439 if (helper->banner != NULL) {
3440 g_object_ref (G_OBJECT (helper->banner));
3441 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3442 gtk_widget_show (GTK_WIDGET (helper->banner));
3446 modest_mail_operation_get_msgs_full (mail_op,
3448 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3450 paste_as_attachment_free);
3453 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3454 ModestEmailClipboard *clipboard = NULL;
3455 TnyFolder *src_folder = NULL;
3456 TnyFolderStore *folder_store = NULL;
3457 TnyList *data = NULL;
3458 gboolean delete = FALSE;
3460 /* Check clipboard source */
3461 clipboard = modest_runtime_get_email_clipboard ();
3462 if (modest_email_clipboard_cleared (clipboard))
3465 /* Get elements to paste */
3466 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3468 /* Create a new mail operation */
3469 mail_op = modest_mail_operation_new (G_OBJECT(window));
3471 /* Get destination folder */
3472 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3474 /* transfer messages */
3478 /* Ask for user confirmation */
3480 modest_ui_actions_msgs_move_to_confirmation (window,
3481 TNY_FOLDER (folder_store),
3485 if (response == GTK_RESPONSE_OK) {
3486 /* Launch notification */
3487 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3488 _CS("ckct_nw_pasting"));
3489 if (inf_note != NULL) {
3490 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3491 gtk_widget_show (GTK_WIDGET(inf_note));
3494 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3495 modest_mail_operation_xfer_msgs (mail_op,
3497 TNY_FOLDER (folder_store),
3499 destroy_information_note,
3502 g_object_unref (mail_op);
3505 } else if (src_folder != NULL) {
3506 /* Launch notification */
3507 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3508 _CS("ckct_nw_pasting"));
3509 if (inf_note != NULL) {
3510 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3511 gtk_widget_show (GTK_WIDGET(inf_note));
3514 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3515 modest_mail_operation_xfer_folder (mail_op,
3519 destroy_folder_information_note,
3525 g_object_unref (data);
3526 if (src_folder != NULL)
3527 g_object_unref (src_folder);
3528 if (folder_store != NULL)
3529 g_object_unref (folder_store);
3535 modest_ui_actions_on_select_all (GtkAction *action,
3536 ModestWindow *window)
3538 GtkWidget *focused_widget;
3540 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3541 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3542 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3543 } else if (GTK_IS_LABEL (focused_widget)) {
3544 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3545 } else if (GTK_IS_EDITABLE (focused_widget)) {
3546 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3547 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3548 GtkTextBuffer *buffer;
3549 GtkTextIter start, end;
3551 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3552 gtk_text_buffer_get_start_iter (buffer, &start);
3553 gtk_text_buffer_get_end_iter (buffer, &end);
3554 gtk_text_buffer_select_range (buffer, &start, &end);
3555 } else if (GTK_IS_HTML (focused_widget)) {
3556 gtk_html_select_all (GTK_HTML (focused_widget));
3557 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3558 GtkWidget *header_view = focused_widget;
3559 GtkTreeSelection *selection = NULL;
3561 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3562 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3563 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3566 /* Disable window dimming management */
3567 modest_window_disable_dimming (MODEST_WINDOW(window));
3569 /* Select all messages */
3570 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3571 gtk_tree_selection_select_all (selection);
3573 /* Set focuse on header view */
3574 gtk_widget_grab_focus (header_view);
3577 /* Enable window dimming management */
3578 modest_window_enable_dimming (MODEST_WINDOW(window));
3579 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3585 modest_ui_actions_on_mark_as_read (GtkAction *action,
3586 ModestWindow *window)
3588 g_return_if_fail (MODEST_IS_WINDOW(window));
3590 /* Mark each header as read */
3591 do_headers_action (window, headers_action_mark_as_read, NULL);
3595 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3596 ModestWindow *window)
3598 g_return_if_fail (MODEST_IS_WINDOW(window));
3600 /* Mark each header as read */
3601 do_headers_action (window, headers_action_mark_as_unread, NULL);
3605 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3606 GtkRadioAction *selected,
3607 ModestWindow *window)
3611 value = gtk_radio_action_get_current_value (selected);
3612 if (MODEST_IS_WINDOW (window)) {
3613 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3618 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3619 GtkRadioAction *selected,
3620 ModestWindow *window)
3622 TnyHeaderFlags flags;
3623 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3625 flags = gtk_radio_action_get_current_value (selected);
3626 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3630 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3631 GtkRadioAction *selected,
3632 ModestWindow *window)
3636 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3638 file_format = gtk_radio_action_get_current_value (selected);
3639 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3644 modest_ui_actions_on_zoom_plus (GtkAction *action,
3645 ModestWindow *window)
3647 g_return_if_fail (MODEST_IS_WINDOW (window));
3649 modest_window_zoom_plus (MODEST_WINDOW (window));
3653 modest_ui_actions_on_zoom_minus (GtkAction *action,
3654 ModestWindow *window)
3656 g_return_if_fail (MODEST_IS_WINDOW (window));
3658 modest_window_zoom_minus (MODEST_WINDOW (window));
3662 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3663 ModestWindow *window)
3665 ModestWindowMgr *mgr;
3666 gboolean fullscreen, active;
3667 g_return_if_fail (MODEST_IS_WINDOW (window));
3669 mgr = modest_runtime_get_window_mgr ();
3671 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3672 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3674 if (active != fullscreen) {
3675 modest_window_mgr_set_fullscreen_mode (mgr, active);
3676 gtk_window_present (GTK_WINDOW (window));
3681 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3682 ModestWindow *window)
3684 ModestWindowMgr *mgr;
3685 gboolean fullscreen;
3687 g_return_if_fail (MODEST_IS_WINDOW (window));
3689 mgr = modest_runtime_get_window_mgr ();
3690 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3691 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3693 gtk_window_present (GTK_WINDOW (window));
3697 * Used by modest_ui_actions_on_details to call do_headers_action
3700 headers_action_show_details (TnyHeader *header,
3701 ModestWindow *window,
3708 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3711 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3712 gtk_widget_show_all (dialog);
3713 gtk_dialog_run (GTK_DIALOG (dialog));
3715 gtk_widget_destroy (dialog);
3719 * Show the folder details in a ModestDetailsDialog widget
3722 show_folder_details (TnyFolder *folder,
3728 dialog = modest_details_dialog_new_with_folder (window, folder);
3731 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3732 gtk_widget_show_all (dialog);
3733 gtk_dialog_run (GTK_DIALOG (dialog));
3735 gtk_widget_destroy (dialog);
3739 * Show the header details in a ModestDetailsDialog widget
3742 modest_ui_actions_on_details (GtkAction *action,
3745 TnyList * headers_list;
3749 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3752 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3755 g_object_unref (msg);
3757 headers_list = get_selected_headers (win);
3761 iter = tny_list_create_iterator (headers_list);
3763 header = TNY_HEADER (tny_iterator_get_current (iter));
3765 headers_action_show_details (header, win, NULL);
3766 g_object_unref (header);
3769 g_object_unref (iter);
3770 g_object_unref (headers_list);
3772 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3773 GtkWidget *folder_view, *header_view;
3775 /* Check which widget has the focus */
3776 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3777 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3778 if (gtk_widget_is_focus (folder_view)) {
3779 TnyFolderStore *folder_store
3780 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3781 if (!folder_store) {
3782 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3785 /* Show only when it's a folder */
3786 /* This function should not be called for account items,
3787 * because we dim the menu item for them. */
3788 if (TNY_IS_FOLDER (folder_store)) {
3789 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3792 g_object_unref (folder_store);
3795 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3796 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3797 /* Show details of each header */
3798 do_headers_action (win, headers_action_show_details, header_view);
3804 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3805 ModestMsgEditWindow *window)
3807 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3809 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3813 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3814 ModestMsgEditWindow *window)
3816 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3818 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3822 modest_ui_actions_toggle_folders_view (GtkAction *action,
3823 ModestMainWindow *main_window)
3825 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3827 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3828 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3830 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3834 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3835 ModestWindow *window)
3837 gboolean active, fullscreen = FALSE;
3838 ModestWindowMgr *mgr;
3840 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3842 /* Check if we want to toggle the toolbar vuew in fullscreen
3844 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3845 "ViewShowToolbarFullScreen")) {
3849 /* Toggle toolbar */
3850 mgr = modest_runtime_get_window_mgr ();
3851 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3855 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3856 ModestMsgEditWindow *window)
3858 modest_msg_edit_window_select_font (window);
3863 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3864 const gchar *display_name,
3867 /* don't update the display name if it was already set;
3868 * updating the display name apparently is expensive */
3869 const gchar* old_name = gtk_window_get_title (window);
3871 if (display_name == NULL)
3874 if (old_name && display_name && strcmp (old_name, display_name) == 0)
3875 return; /* don't do anything */
3877 /* This is usually used to change the title of the main window, which
3878 * is the one that holds the folder view. Note that this change can
3879 * happen even when the widget doesn't have the focus. */
3880 gtk_window_set_title (window, display_name);
3885 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3887 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3888 modest_msg_edit_window_select_contacts (window);
3892 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3894 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3895 modest_msg_edit_window_check_names (window, FALSE);
3899 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3901 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3902 GTK_WIDGET (user_data));
3906 * This function is used to track changes in the selection of the
3907 * folder view that is inside the "move to" dialog to enable/disable
3908 * the OK button because we do not want the user to select a disallowed
3909 * destination for a folder.
3910 * The user also not desired to be able to use NEW button on items where
3911 * folder creation is not possibel.
3914 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3915 TnyFolderStore *folder_store,
3919 GtkWidget *dialog = NULL;
3920 GtkWidget *ok_button = NULL, *new_button = NULL;
3921 GList *children = NULL;
3922 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3923 gboolean moving_folder = FALSE;
3924 gboolean is_local_account = TRUE;
3925 GtkWidget *folder_view = NULL;
3926 ModestTnyFolderRules rules;
3928 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
3933 /* Get the OK button */
3934 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3938 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3939 ok_button = GTK_WIDGET (children->next->next->data);
3940 new_button = GTK_WIDGET (children->next->data);
3941 g_list_free (children);
3943 /* check if folder_store is an remote account */
3944 if (TNY_IS_ACCOUNT (folder_store)) {
3945 TnyAccount *local_account = NULL;
3946 TnyAccount *mmc_account = NULL;
3947 ModestTnyAccountStore *account_store = NULL;
3949 account_store = modest_runtime_get_account_store ();
3950 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3951 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
3953 if ((gpointer) local_account != (gpointer) folder_store &&
3954 (gpointer) mmc_account != (gpointer) folder_store) {
3955 const char *proto_name = tny_account_get_proto (TNY_ACCOUNT (folder_store));
3956 ModestTransportStoreProtocol proto = MODEST_PROTOCOL_STORE_MAILDIR;
3957 if (proto_name != NULL) {
3958 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
3960 is_local_account = FALSE;
3961 /* New button should be dimmed on remote
3963 new_sensitive = (proto != MODEST_PROTOCOL_STORE_POP);
3965 g_object_unref (local_account);
3968 /* Check the target folder rules */
3969 if (TNY_IS_FOLDER (folder_store)) {
3970 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3971 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3972 ok_sensitive = FALSE;
3973 new_sensitive = FALSE;
3978 /* Check if we're moving a folder */
3979 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3980 /* Get the widgets */
3981 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3982 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3983 if (gtk_widget_is_focus (folder_view))
3984 moving_folder = TRUE;
3987 if (moving_folder) {
3988 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3990 /* Get the folder to move */
3991 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3993 /* Check that we're not moving to the same folder */
3994 if (TNY_IS_FOLDER (moved_folder)) {
3995 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3996 if (parent == folder_store)
3997 ok_sensitive = FALSE;
3998 g_object_unref (parent);
4001 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4002 /* Do not allow to move to an account unless it's the
4003 local folders account */
4004 if (!is_local_account)
4005 ok_sensitive = FALSE;
4008 if (ok_sensitive && (moved_folder == folder_store)) {
4009 /* Do not allow to move to itself */
4010 ok_sensitive = FALSE;
4012 g_object_unref (moved_folder);
4014 TnyFolder *src_folder = NULL;
4016 /* Moving a message */
4017 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4019 TnyHeader *header = NULL;
4020 header = modest_msg_view_window_get_header
4021 (MODEST_MSG_VIEW_WINDOW (user_data));
4022 if (!TNY_IS_HEADER(header))
4023 g_warning ("%s: could not get source header", __FUNCTION__);
4025 src_folder = tny_header_get_folder (header);
4028 g_object_unref (header);
4031 TNY_FOLDER (modest_folder_view_get_selected
4032 (MODEST_FOLDER_VIEW (folder_view)));
4035 if (TNY_IS_FOLDER(src_folder)) {
4036 /* Do not allow to move the msg to the same folder */
4037 /* Do not allow to move the msg to an account */
4038 if ((gpointer) src_folder == (gpointer) folder_store ||
4039 TNY_IS_ACCOUNT (folder_store))
4040 ok_sensitive = FALSE;
4041 g_object_unref (src_folder);
4043 g_warning ("%s: could not get source folder", __FUNCTION__);
4047 /* Set sensitivity of the OK button */
4048 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4049 /* Set sensitivity of the NEW button */
4050 gtk_widget_set_sensitive (new_button, new_sensitive);
4054 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4057 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4059 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4060 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4064 create_move_to_dialog (GtkWindow *win,
4065 GtkWidget *folder_view,
4066 GtkWidget **tree_view)
4068 GtkWidget *dialog, *scroll;
4069 GtkWidget *new_button;
4071 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4073 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4076 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4077 /* We do this manually so GTK+ does not associate a response ID for
4079 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4080 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4081 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4083 /* Create scrolled window */
4084 scroll = gtk_scrolled_window_new (NULL, NULL);
4085 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4086 GTK_POLICY_AUTOMATIC,
4087 GTK_POLICY_AUTOMATIC);
4089 /* Create folder view */
4090 *tree_view = modest_platform_create_folder_view (NULL);
4092 /* Track changes in the selection to
4093 * disable the OK button whenever "Move to" is not possible
4094 * disbale NEW button whenever New is not possible */
4095 g_signal_connect (*tree_view,
4096 "folder_selection_changed",
4097 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4100 /* Listen to clicks on New button */
4101 g_signal_connect (G_OBJECT (new_button),
4103 G_CALLBACK(create_move_to_dialog_on_new_folder),
4106 /* It could happen that we're trying to move a message from a
4107 window (msg window for example) after the main window was
4108 closed, so we can not just get the model of the folder
4110 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4111 const gchar *visible_id = NULL;
4113 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4114 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4115 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4116 MODEST_FOLDER_VIEW(*tree_view));
4119 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4121 /* Show the same account than the one that is shown in the main window */
4122 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4125 const gchar *active_account_name = NULL;
4126 ModestAccountMgr *mgr = NULL;
4127 ModestAccountSettings *settings = NULL;
4128 ModestServerAccountSettings *store_settings = NULL;
4130 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4131 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4132 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4133 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4135 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4136 mgr = modest_runtime_get_account_mgr ();
4137 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4140 const gchar *store_account_name;
4141 store_settings = modest_account_settings_get_store_settings (settings);
4142 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4144 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4145 store_account_name);
4146 g_object_unref (store_settings);
4147 g_object_unref (settings);
4151 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4152 * get_folder_view_from_move_to_dialog
4153 * (see above) later (needed for focus handling)
4155 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4158 /* Hide special folders */
4159 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4161 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4163 /* Add scroll to dialog */
4164 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4165 scroll, TRUE, TRUE, 0);
4167 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4168 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4174 * Returns TRUE if at least one of the headers of the list belongs to
4175 * a message that has been fully retrieved.
4177 #if 0 /* no longer in use. delete in 2007.10 */
4179 has_retrieved_msgs (TnyList *list)
4182 gboolean found = FALSE;
4184 iter = tny_list_create_iterator (list);
4185 while (!tny_iterator_is_done (iter) && !found) {
4187 TnyHeaderFlags flags = 0;
4189 header = TNY_HEADER (tny_iterator_get_current (iter));
4191 flags = tny_header_get_flags (header);
4192 if (flags & TNY_HEADER_FLAG_CACHED)
4193 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
4196 g_object_unref (header);
4200 tny_iterator_next (iter);
4202 g_object_unref (iter);
4210 * Shows a confirmation dialog to the user when we're moving messages
4211 * from a remote server to the local storage. Returns the dialog
4212 * response. If it's other kind of movement then it always returns
4215 * This one is used by the next functions:
4216 * modest_ui_actions_on_paste - commented out
4217 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4220 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4221 TnyFolder *dest_folder,
4225 gint response = GTK_RESPONSE_OK;
4226 TnyAccount *account = NULL;
4227 TnyFolder *src_folder = NULL;
4228 TnyIterator *iter = NULL;
4229 TnyHeader *header = NULL;
4231 /* return with OK if the destination is a remote folder */
4232 if (modest_tny_folder_is_remote_folder (dest_folder))
4233 return GTK_RESPONSE_OK;
4235 /* Get source folder */
4236 iter = tny_list_create_iterator (headers);
4237 header = TNY_HEADER (tny_iterator_get_current (iter));
4239 src_folder = tny_header_get_folder (header);
4240 g_object_unref (header);
4242 g_object_unref (iter);
4244 /* if no src_folder, message may be an attahcment */
4245 if (src_folder == NULL)
4246 return GTK_RESPONSE_CANCEL;
4248 /* If the source is a local or MMC folder */
4249 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4250 g_object_unref (src_folder);
4251 return GTK_RESPONSE_OK;
4254 /* Get the account */
4255 account = tny_folder_get_account (src_folder);
4257 /* now if offline we ask the user */
4258 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4259 response = GTK_RESPONSE_OK;
4261 response = GTK_RESPONSE_CANCEL;
4264 g_object_unref (src_folder);
4265 g_object_unref (account);
4271 move_to_cb (ModestMailOperation *mail_op,
4274 MoveToHelper *helper = (MoveToHelper *) user_data;
4276 /* Note that the operation could have failed, in that case do
4278 if (modest_mail_operation_get_status (mail_op) ==
4279 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4281 GObject *object = modest_mail_operation_get_source (mail_op);
4282 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4283 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4285 if (!modest_msg_view_window_select_next_message (self) &&
4286 !modest_msg_view_window_select_previous_message (self)) {
4287 /* No more messages to view, so close this window */
4288 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4290 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4291 GtkWidget *header_view;
4293 GtkTreeSelection *sel;
4295 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4296 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4297 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4298 path = gtk_tree_row_reference_get_path (helper->reference);
4299 gtk_tree_selection_select_path (sel, path);
4300 gtk_tree_path_free (path);
4302 g_object_unref (object);
4305 /* Close the "Pasting" information banner */
4306 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4307 if (helper->reference != NULL)
4308 gtk_tree_row_reference_free (helper->reference);
4313 folder_move_to_cb (ModestMailOperation *mail_op,
4314 TnyFolder *new_folder,
4317 GtkWidget *folder_view;
4320 object = modest_mail_operation_get_source (mail_op);
4321 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4322 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4323 g_object_ref (folder_view);
4324 g_object_unref (object);
4325 move_to_cb (mail_op, user_data);
4326 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4327 g_object_unref (folder_view);
4331 msgs_move_to_cb (ModestMailOperation *mail_op,
4334 move_to_cb (mail_op, user_data);
4338 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4341 ModestWindow *main_window = NULL;
4342 GObject *win = NULL;
4344 /* Disable next automatic folder selection */
4345 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4346 FALSE); /* don't create */
4348 GtkWidget *folder_view = NULL;
4350 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4351 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4352 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4354 if (user_data && TNY_IS_FOLDER (user_data)) {
4355 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4356 TNY_FOLDER (user_data), FALSE);
4360 /* Show notification dialog */
4361 win = modest_mail_operation_get_source (mail_op);
4362 modest_platform_run_information_dialog ((GtkWindow *) win, _("mail_in_ui_folder_move_target_error"));
4364 g_object_unref (win);
4368 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4371 GObject *win = modest_mail_operation_get_source (mail_op);
4372 const GError *error = modest_mail_operation_get_error (mail_op);
4374 g_return_if_fail (error != NULL);
4375 if (error->message != NULL)
4376 g_printerr ("modest: %s\n", error->message);
4378 g_printerr ("modest: unkonw error on send&receive operation");
4380 /* Show error message */
4381 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4382 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4383 /* _CS("sfil_ib_unable_to_receive")); */
4385 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4386 /* _CS("sfil_ib_unable_to_send")); */
4387 g_object_unref (win);
4391 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4400 gint pending_purges = 0;
4401 gboolean some_purged = FALSE;
4402 ModestWindow *win = MODEST_WINDOW (user_data);
4403 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4405 /* If there was any error */
4406 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4407 modest_window_mgr_unregister_header (mgr, header);
4411 /* Once the message has been retrieved for purging, we check if
4412 * it's all ok for purging */
4414 parts = tny_simple_list_new ();
4415 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4416 iter = tny_list_create_iterator (parts);
4418 while (!tny_iterator_is_done (iter)) {
4420 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4421 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4422 if (tny_mime_part_is_purged (part))
4429 g_object_unref (part);
4431 tny_iterator_next (iter);
4433 g_object_unref (iter);
4436 if (pending_purges>0) {
4438 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4440 if (response == GTK_RESPONSE_OK) {
4441 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4442 iter = tny_list_create_iterator (parts);
4443 while (!tny_iterator_is_done (iter)) {
4446 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4447 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4448 tny_mime_part_set_purged (part);
4451 g_object_unref (part);
4453 tny_iterator_next (iter);
4455 g_object_unref (iter);
4457 tny_msg_rewrite_cache (msg);
4460 /* This string no longer exists, refer to NB#75415 for more info */
4461 /* modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged")); */
4464 modest_window_mgr_unregister_header (mgr, header);
4466 g_object_unref (parts);
4470 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4471 ModestMainWindow *win)
4473 GtkWidget *header_view;
4474 TnyList *header_list;
4476 TnyHeaderFlags flags;
4477 ModestWindow *msg_view_window = NULL;
4480 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4482 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4483 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4485 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4487 g_warning ("%s: no header selected", __FUNCTION__);
4491 if (tny_list_get_length (header_list) == 1) {
4492 TnyIterator *iter = tny_list_create_iterator (header_list);
4493 header = TNY_HEADER (tny_iterator_get_current (iter));
4494 g_object_unref (iter);
4498 if (!header || !TNY_IS_HEADER(header)) {
4499 g_warning ("%s: header is not valid", __FUNCTION__);
4503 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4504 header, &msg_view_window);
4505 flags = tny_header_get_flags (header);
4506 if (!(flags & TNY_HEADER_FLAG_CACHED))
4509 if (msg_view_window != NULL)
4510 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4512 /* do nothing; uid was registered before, so window is probably on it's way */
4513 g_warning ("debug: header %p has already been registered", header);
4516 ModestMailOperation *mail_op = NULL;
4517 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
4518 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4519 modest_ui_actions_get_msgs_full_error_handler,
4521 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4522 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4524 g_object_unref (mail_op);
4527 g_object_unref (header);
4529 g_object_unref (header_list);
4533 * Checks if we need a connection to do the transfer and if the user
4534 * wants to connect to complete it
4537 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
4538 TnyFolderStore *src_folder,
4540 TnyFolder *dst_folder,
4541 gboolean delete_originals,
4542 gboolean *need_connection,
4545 TnyAccount *src_account;
4546 gint uncached_msgs = 0;
4548 uncached_msgs = header_list_count_uncached_msgs (headers);
4550 /* We don't need any further check if
4552 * 1- the source folder is local OR
4553 * 2- the device is already online
4555 if (!modest_tny_folder_store_is_remote (src_folder) ||
4556 tny_device_is_online (modest_runtime_get_device())) {
4557 *need_connection = FALSE;
4562 /* We must ask for a connection when
4564 * - the message(s) is not already cached OR
4565 * - the message(s) is cached but the leave_on_server setting
4566 * is FALSE (because we need to sync the source folder to
4567 * delete the message from the server (for IMAP we could do it
4568 * offline, it'll take place the next time we get a
4571 src_account = get_account_from_folder_store (src_folder);
4572 if (uncached_msgs > 0) {
4576 *need_connection = TRUE;
4577 num_headers = tny_list_get_length (headers);
4578 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4580 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
4581 GTK_RESPONSE_CANCEL) {
4587 /* The transfer is possible and the user wants to */
4590 if (remote_folder_is_pop (src_folder) && delete_originals) {
4591 const gchar *account_name;
4592 gboolean leave_on_server;
4594 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4595 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
4598 if (leave_on_server == TRUE) {
4599 *need_connection = FALSE;
4601 *need_connection = TRUE;
4604 *need_connection = FALSE;
4609 g_object_unref (src_account);
4614 * Utility function that transfer messages from both the main window
4615 * and the msg view window when using the "Move to" dialog
4618 xfer_messages_performer (gboolean canceled,
4620 GtkWindow *parent_window,
4621 TnyAccount *account,
4624 TnyFolderStore *dst_folder = TNY_FOLDER_STORE (user_data);
4625 ModestWindow *win = MODEST_WINDOW (parent_window);
4626 TnyList *headers = NULL;
4627 TnyAccount *dst_account = NULL;
4628 const gchar *proto_str = NULL;
4629 gboolean dst_is_pop = FALSE;
4631 if (canceled || err) {
4632 /* Show the proper error message */
4633 modest_ui_actions_on_account_connection_error (parent_window, account);
4634 g_object_unref (dst_folder);
4638 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4639 proto_str = tny_account_get_proto (dst_account);
4641 /* tinymail will return NULL for local folders it seems */
4642 dst_is_pop = proto_str &&
4643 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4644 MODEST_PROTOCOL_STORE_POP);
4646 g_object_unref (dst_account);
4648 /* Get selected headers */
4649 headers = get_selected_headers (MODEST_WINDOW (win));
4651 g_warning ("%s: no headers selected", __FUNCTION__);
4657 modest_platform_information_banner (GTK_WIDGET (win),
4659 ngettext("mail_in_ui_folder_move_target_error",
4660 "mail_in_ui_folder_move_targets_error",
4661 tny_list_get_length (headers)));
4662 g_object_unref (headers);
4666 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4667 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4668 _CS("ckct_nw_pasting"));
4669 if (helper->banner != NULL) {
4670 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4671 gtk_widget_show (GTK_WIDGET(helper->banner));
4674 if (MODEST_IS_MAIN_WINDOW (win)) {
4675 GtkWidget *header_view =
4676 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4677 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4678 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4681 ModestMailOperation *mail_op =
4682 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4683 modest_ui_actions_move_folder_error_handler,
4685 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4688 modest_mail_operation_xfer_msgs (mail_op,
4690 TNY_FOLDER (dst_folder),
4695 g_object_unref (G_OBJECT (mail_op));
4696 g_object_unref (headers);
4697 g_object_unref (dst_folder);
4701 TnyFolder *src_folder;
4702 TnyFolderStore *dst_folder;
4703 gboolean delete_original;
4704 GtkWidget *folder_view;
4708 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
4709 TnyAccount *account, gpointer user_data)
4711 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4712 GtkTreeSelection *sel;
4713 ModestMailOperation *mail_op = NULL;
4715 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
4716 g_object_unref (G_OBJECT (info->src_folder));
4717 g_object_unref (G_OBJECT (info->dst_folder));
4722 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4723 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4724 _CS("ckct_nw_pasting"));
4725 if (helper->banner != NULL) {
4726 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4727 gtk_widget_show (GTK_WIDGET(helper->banner));
4729 /* Clean folder on header view before moving it */
4730 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4731 gtk_tree_selection_unselect_all (sel);
4733 /* Let gtk events run. We need that the folder
4734 view frees its reference to the source
4735 folder *before* issuing the mail operation
4736 so we need the signal handler of selection
4737 changed to happen before the mail
4739 while (gtk_events_pending ())
4740 gtk_main_iteration (); */
4743 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4744 modest_ui_actions_move_folder_error_handler,
4745 info->src_folder, NULL);
4746 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4749 /* Select *after* the changes */
4750 /* TODO: this function hangs UI after transfer */
4751 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4752 /* TNY_FOLDER (src_folder), TRUE); */
4754 modest_mail_operation_xfer_folder (mail_op,
4755 TNY_FOLDER (info->src_folder),
4757 info->delete_original,
4761 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4762 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
4763 TNY_FOLDER (info->dst_folder), TRUE);
4766 /* Unref mail operation */
4767 g_object_unref (G_OBJECT (mail_op));
4768 g_object_unref (G_OBJECT (info->src_folder));
4769 g_object_unref (G_OBJECT (info->dst_folder));
4774 get_account_from_folder_store (TnyFolderStore *folder_store)
4776 if (TNY_IS_ACCOUNT (folder_store))
4777 return g_object_ref (folder_store);
4779 return tny_folder_get_account (TNY_FOLDER (folder_store));
4783 * UI handler for the "Move to" action when invoked from the
4787 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4788 GtkWidget *folder_view,
4789 TnyFolderStore *dst_folder,
4790 ModestMainWindow *win)
4792 ModestHeaderView *header_view = NULL;
4793 TnyFolderStore *src_folder = NULL;
4795 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4797 /* Get the source folder */
4798 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4800 /* Get header view */
4801 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4803 /* Get folder or messages to transfer */
4804 if (gtk_widget_is_focus (folder_view)) {
4805 gboolean do_xfer = TRUE;
4807 /* Allow only to transfer folders to the local root folder */
4808 if (TNY_IS_ACCOUNT (dst_folder) &&
4809 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
4810 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
4812 } else if (!TNY_IS_FOLDER (src_folder)) {
4813 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4818 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4819 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4821 info->src_folder = g_object_ref (src_folder);
4822 info->dst_folder = g_object_ref (dst_folder);
4823 info->delete_original = TRUE;
4824 info->folder_view = folder_view;
4826 connect_info->callback = on_move_folder_cb;
4827 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
4828 connect_info->data = info;
4830 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4831 TNY_FOLDER_STORE (src_folder),
4834 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4837 headers = modest_header_view_get_selected_headers(header_view);
4839 /* Transfer the messages */
4840 transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
4841 headers, TNY_FOLDER (dst_folder));
4843 g_object_unref (headers);
4847 g_object_unref (src_folder);
4852 transfer_messages_helper (GtkWindow *win,
4853 TnyFolder *src_folder,
4855 TnyFolder *dst_folder)
4857 gboolean need_connection = TRUE;
4858 gboolean do_xfer = TRUE;
4860 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
4861 headers, TNY_FOLDER (dst_folder),
4862 TRUE, &need_connection,
4865 /* If we don't want to transfer just return */
4869 if (need_connection) {
4870 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
4871 connect_info->callback = xfer_messages_performer;
4872 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4873 connect_info->data = g_object_ref (dst_folder);
4875 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
4876 TNY_FOLDER_STORE (src_folder),
4879 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
4880 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
4882 g_object_ref (dst_folder));
4883 g_object_unref (src_account);
4888 * UI handler for the "Move to" action when invoked from the
4889 * ModestMsgViewWindow
4892 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4893 TnyFolderStore *dst_folder,
4894 ModestMsgViewWindow *win)
4896 TnyList *headers = NULL;
4897 TnyHeader *header = NULL;
4898 TnyFolder *src_folder = NULL;
4900 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
4902 /* Create header list */
4903 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4904 src_folder = TNY_FOLDER (tny_header_get_folder(header));
4905 headers = tny_simple_list_new ();
4906 tny_list_append (headers, G_OBJECT (header));
4908 /* Transfer the messages */
4909 transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
4910 TNY_FOLDER (dst_folder));
4913 g_object_unref (header);
4914 g_object_unref (headers);
4918 modest_ui_actions_on_move_to (GtkAction *action,
4921 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4923 TnyFolderStore *dst_folder = NULL;
4924 ModestMainWindow *main_window;
4926 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4927 MODEST_IS_MSG_VIEW_WINDOW (win));
4929 /* Get the main window if exists */
4930 if (MODEST_IS_MAIN_WINDOW (win))
4931 main_window = MODEST_MAIN_WINDOW (win);
4934 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4935 FALSE)); /* don't create */
4937 /* Get the folder view widget if exists */
4939 folder_view = modest_main_window_get_child_widget (main_window,
4940 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4944 /* Create and run the dialog */
4945 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4946 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4947 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4948 result = gtk_dialog_run (GTK_DIALOG(dialog));
4949 g_object_ref (tree_view);
4950 gtk_widget_destroy (dialog);
4952 if (result != GTK_RESPONSE_ACCEPT)
4955 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4956 /* Do window specific stuff */
4957 if (MODEST_IS_MAIN_WINDOW (win)) {
4958 modest_ui_actions_on_main_window_move_to (action,
4961 MODEST_MAIN_WINDOW (win));
4963 modest_ui_actions_on_msg_view_window_move_to (action,
4965 MODEST_MSG_VIEW_WINDOW (win));
4969 g_object_unref (dst_folder);
4973 * Calls #HeadersFunc for each header already selected in the main
4974 * window or the message currently being shown in the msg view window
4977 do_headers_action (ModestWindow *win,
4981 TnyList *headers_list = NULL;
4982 TnyIterator *iter = NULL;
4983 TnyHeader *header = NULL;
4984 TnyFolder *folder = NULL;
4987 headers_list = get_selected_headers (win);
4991 /* Get the folder */
4992 iter = tny_list_create_iterator (headers_list);
4993 header = TNY_HEADER (tny_iterator_get_current (iter));
4995 folder = tny_header_get_folder (header);
4996 g_object_unref (header);
4999 /* Call the function for each header */
5000 while (!tny_iterator_is_done (iter)) {
5001 header = TNY_HEADER (tny_iterator_get_current (iter));
5002 func (header, win, user_data);
5003 g_object_unref (header);
5004 tny_iterator_next (iter);
5007 /* Trick: do a poke status in order to speed up the signaling
5009 tny_folder_poke_status (folder);
5012 g_object_unref (folder);
5013 g_object_unref (iter);
5014 g_object_unref (headers_list);
5018 modest_ui_actions_view_attachment (GtkAction *action,
5019 ModestWindow *window)
5021 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5022 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5024 /* not supported window for this action */
5025 g_return_if_reached ();
5030 modest_ui_actions_save_attachments (GtkAction *action,
5031 ModestWindow *window)
5033 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5034 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5036 /* not supported window for this action */
5037 g_return_if_reached ();
5042 modest_ui_actions_remove_attachments (GtkAction *action,
5043 ModestWindow *window)
5045 if (MODEST_IS_MAIN_WINDOW (window)) {
5046 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5047 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5048 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5050 /* not supported window for this action */
5051 g_return_if_reached ();
5056 modest_ui_actions_on_settings (GtkAction *action,
5061 dialog = modest_platform_get_global_settings_dialog ();
5062 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5063 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5064 gtk_widget_show_all (dialog);
5066 gtk_dialog_run (GTK_DIALOG (dialog));
5068 gtk_widget_destroy (dialog);
5072 modest_ui_actions_on_help (GtkAction *action,
5075 const gchar *help_id;
5077 g_return_if_fail (action);
5078 g_return_if_fail (win && GTK_IS_WINDOW(win));
5080 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5083 modest_platform_show_help (GTK_WINDOW (win), help_id);
5085 g_warning ("%s: no help for window %p", __FUNCTION__, win);
5089 retrieve_msg_contents_performer (gboolean canceled,
5091 GtkWindow *parent_window,
5092 TnyAccount *account,
5095 ModestMailOperation *mail_op;
5096 TnyList *headers = TNY_LIST (user_data);
5098 if (err || canceled) {
5102 /* Create mail operation */
5103 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5104 modest_ui_actions_get_msgs_full_error_handler,
5106 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5107 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
5110 g_object_unref (mail_op);
5112 g_object_unref (headers);
5113 g_object_unref (account);
5117 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5118 ModestWindow *window)
5120 TnyList *headers = NULL;
5121 TnyAccount *account = NULL;
5122 TnyIterator *iter = NULL;
5123 TnyHeader *header = NULL;
5124 TnyFolder *folder = NULL;
5127 headers = get_selected_headers (window);
5131 /* Pick the account */
5132 iter = tny_list_create_iterator (headers);
5133 header = TNY_HEADER (tny_iterator_get_current (iter));
5134 folder = tny_header_get_folder (header);
5135 account = tny_folder_get_account (folder);
5136 g_object_unref (folder);
5137 g_object_unref (header);
5138 g_object_unref (iter);
5140 /* Connect and perform the message retrieval */
5141 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5142 g_object_ref (account),
5143 retrieve_msg_contents_performer,
5144 g_object_ref (headers));
5147 g_object_unref (account);
5148 g_object_unref (headers);
5152 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5154 g_return_if_fail (MODEST_IS_WINDOW (window));
5157 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5161 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5163 g_return_if_fail (MODEST_IS_WINDOW (window));
5166 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5170 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5171 ModestWindow *window)
5173 g_return_if_fail (MODEST_IS_WINDOW (window));
5176 modest_ui_actions_check_menu_dimming_rules (window);
5180 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5181 ModestWindow *window)
5183 g_return_if_fail (MODEST_IS_WINDOW (window));
5186 modest_ui_actions_check_menu_dimming_rules (window);
5190 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5191 ModestWindow *window)
5193 g_return_if_fail (MODEST_IS_WINDOW (window));
5196 modest_ui_actions_check_menu_dimming_rules (window);
5200 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5201 ModestWindow *window)
5203 g_return_if_fail (MODEST_IS_WINDOW (window));
5206 modest_ui_actions_check_menu_dimming_rules (window);
5210 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5211 ModestWindow *window)
5213 g_return_if_fail (MODEST_IS_WINDOW (window));
5216 modest_ui_actions_check_menu_dimming_rules (window);
5220 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5221 ModestWindow *window)
5223 g_return_if_fail (MODEST_IS_WINDOW (window));
5226 modest_ui_actions_check_menu_dimming_rules (window);
5230 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5231 ModestWindow *window)
5233 g_return_if_fail (MODEST_IS_WINDOW (window));
5236 modest_ui_actions_check_menu_dimming_rules (window);
5240 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5241 ModestWindow *window)
5243 g_return_if_fail (MODEST_IS_WINDOW (window));
5246 modest_ui_actions_check_menu_dimming_rules (window);
5250 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5251 ModestWindow *window)
5253 g_return_if_fail (MODEST_IS_WINDOW (window));
5256 modest_ui_actions_check_menu_dimming_rules (window);
5260 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5262 g_return_if_fail (MODEST_IS_WINDOW (window));
5264 modest_platform_show_search_messages (GTK_WINDOW (window));
5268 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5270 g_return_if_fail (MODEST_IS_WINDOW (win));
5271 modest_platform_show_addressbook (GTK_WINDOW (win));
5276 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5277 ModestWindow *window)
5279 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5281 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5285 on_send_receive_finished (ModestMailOperation *mail_op,
5288 GtkWidget *header_view, *folder_view;
5289 TnyFolderStore *folder_store;
5290 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5292 /* Set send/receive operation finished */
5293 modest_main_window_notify_send_receive_completed (main_win);
5295 /* Don't refresh the current folder if there were any errors */
5296 if (modest_mail_operation_get_status (mail_op) !=
5297 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5300 /* Refresh the current folder if we're viewing a window. We do
5301 this because the user won't be able to see the new mails in
5302 the selected folder after a Send&Receive because it only
5303 performs a poke_status, i.e, only the number of read/unread
5304 messages is updated, but the new headers are not
5306 folder_view = modest_main_window_get_child_widget (main_win,
5307 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5311 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5313 /* Do not need to refresh INBOX again because the
5314 update_account does it always automatically */
5315 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5316 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5317 ModestMailOperation *refresh_op;
5319 header_view = modest_main_window_get_child_widget (main_win,
5320 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5322 /* We do not need to set the contents style
5323 because it hasn't changed. We also do not
5324 need to save the widget status. Just force
5326 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5327 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5328 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5329 folder_refreshed_cb, main_win);
5330 g_object_unref (refresh_op);
5334 g_object_unref (folder_store);
5339 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5345 const gchar* server_name = NULL;
5346 TnyTransportAccount *server_account;
5347 gchar *message = NULL;
5349 /* Don't show anything if the user cancelled something */
5350 if (err->code == TNY_SYSTEM_ERROR_CANCEL)
5353 /* Get the server name: */
5355 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5356 if (server_account) {
5357 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5359 g_object_unref (server_account);
5360 server_account = NULL;
5363 g_return_if_fail (server_name);
5365 /* Show the appropriate message text for the GError: */
5366 switch (err->code) {
5367 case TNY_SERVICE_ERROR_CONNECT:
5368 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5370 case TNY_SERVICE_ERROR_AUTHENTICATE:
5371 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
5373 case TNY_SERVICE_ERROR_SEND:
5374 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
5377 g_warning ("%s: unexpected ERROR %d",
5378 __FUNCTION__, err->code);
5379 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
5383 /* TODO if the username or the password where not defined we
5384 should show the Accounts Settings dialog or the Connection
5385 specific SMTP server window */
5387 modest_platform_run_information_dialog (NULL, message);
5392 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5397 ModestMainWindow *main_window = NULL;
5398 ModestWindowMgr *mgr = NULL;
5399 GtkWidget *folder_view = NULL, *header_view = NULL;
5400 TnyFolderStore *selected_folder = NULL;
5401 TnyFolderType folder_type;
5403 mgr = modest_runtime_get_window_mgr ();
5404 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
5405 FALSE));/* don't create */
5409 /* Check if selected folder is OUTBOX */
5410 folder_view = modest_main_window_get_child_widget (main_window,
5411 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5412 header_view = modest_main_window_get_child_widget (main_window,
5413 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5415 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5416 if (!TNY_IS_FOLDER (selected_folder))
5419 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5420 #if GTK_CHECK_VERSION(2, 8, 0)
5421 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
5422 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5423 GtkTreeViewColumn *tree_column;
5425 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5426 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5427 gtk_tree_view_column_queue_resize (tree_column);
5430 gtk_widget_queue_draw (header_view);
5433 /* Rerun dimming rules, because the message could become deletable for example */
5434 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
5435 MODEST_DIMMING_RULES_TOOLBAR);
5439 if (selected_folder != NULL)
5440 g_object_unref (selected_folder);
5444 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5445 TnyAccount *account)
5447 ModestTransportStoreProtocol proto;
5448 const gchar *proto_name;
5449 gchar *error_note = NULL;
5451 proto_name = tny_account_get_proto (account);
5452 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
5455 case MODEST_PROTOCOL_STORE_POP:
5456 error_note = g_strdup_printf (_("emev_ni_ui_pop3_msg_connect_error"),
5457 tny_account_get_hostname (account));
5459 case MODEST_PROTOCOL_STORE_IMAP:
5460 error_note = g_strdup_printf (_("emev_ni_ui_imap_connect_server_error"),
5461 tny_account_get_hostname (account));
5463 case MODEST_PROTOCOL_STORE_MAILDIR:
5464 case MODEST_PROTOCOL_STORE_MBOX:
5465 error_note = g_strdup (_("emev_nc_mailbox_notavailable"));
5468 g_warning ("%s: This should not be reached", __FUNCTION__);
5472 modest_platform_run_information_dialog (parent_window, error_note);
5473 g_free (error_note);
5478 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5481 TnyFolderStore *folder = NULL;
5482 TnyAccount *account = NULL;
5483 ModestTransportStoreProtocol proto;
5484 TnyHeader *header = NULL;
5486 if (MODEST_IS_MAIN_WINDOW (win)) {
5487 GtkWidget *header_view;
5488 TnyList* headers = NULL;
5490 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5491 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5492 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5493 if (!headers || tny_list_get_length (headers) == 0) {
5495 g_object_unref (headers);
5498 iter = tny_list_create_iterator (headers);
5499 header = TNY_HEADER (tny_iterator_get_current (iter));
5500 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5501 g_object_unref (iter);
5502 g_object_unref (headers);
5503 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5504 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5505 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5508 /* Get the account type */
5509 account = tny_folder_get_account (TNY_FOLDER (folder));
5510 proto = modest_protocol_info_get_transport_store_protocol (tny_account_get_proto (account));
5511 if (proto == MODEST_PROTOCOL_STORE_POP) {
5512 msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
5513 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
5514 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
5515 tny_header_get_subject (header));
5517 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5521 g_object_unref (account);
5522 g_object_unref (folder);
5523 g_object_unref (header);