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 (const TnyFolderStore *folder);
159 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
160 const TnyFolderStore *src_folder);
164 * This function checks whether a TnyFolderStore is a pop account
167 remote_folder_is_pop (const TnyFolderStore *folder)
169 const gchar *proto = NULL;
170 TnyAccount *account = NULL;
172 g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
174 if (TNY_IS_ACCOUNT (folder)) {
175 account = TNY_ACCOUNT(folder);
176 g_object_ref(account);
177 } else if (TNY_IS_FOLDER (folder)) {
178 account = tny_folder_get_account(TNY_FOLDER(folder));
181 if (!account && !TNY_IS_ACCOUNT(account)) {
182 g_warning ("%s: could not get account", __FUNCTION__);
186 proto = tny_account_get_proto(account);
187 g_object_unref (account);
190 (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
194 * This functions checks whether if a list of messages are already
195 * deleted from the server: that is, if the server is a POP account
196 * and all messages are already cached.
199 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
201 g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
202 g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
204 gboolean src_is_pop = remote_folder_is_pop (src_folder);
205 gint uncached_msgs = header_list_count_uncached_msgs (headers);
207 return (src_is_pop && !uncached_msgs);
211 /* FIXME: this should be merged with the similar code in modest-account-view-window */
212 /* Show the account creation wizard dialog.
213 * returns: TRUE if an account was created. FALSE if the user cancelled.
216 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
218 gboolean result = FALSE;
219 GtkWindow *dialog, *wizard;
220 gint dialog_response;
222 /* Show the easy-setup wizard: */
223 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
225 /* old wizard is active already;
227 gtk_window_present (GTK_WINDOW(dialog));
232 /* there is no such wizard yet */
233 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
234 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
236 /* always present a main window in the background
237 * we do it here, so we cannot end up with two wizards (as this
238 * function might be called in modest_window_mgr_get_main_window as well */
240 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
241 TRUE); /* create if not existent */
243 /* make sure the mainwindow is visible */
244 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
245 gtk_widget_show_all (GTK_WIDGET(win));
246 gtk_window_present (GTK_WINDOW(win));
248 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
249 gtk_widget_destroy (GTK_WIDGET (wizard));
250 if (gtk_events_pending ())
251 gtk_main_iteration ();
253 if (dialog_response == GTK_RESPONSE_CANCEL) {
256 /* Check whether an account was created: */
257 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
264 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
267 const gchar *authors[] = {
268 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
271 about = gtk_about_dialog_new ();
272 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
273 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
274 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
275 _("Copyright (c) 2006, Nokia Corporation\n"
276 "All rights reserved."));
277 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
278 _("a modest e-mail client\n\n"
279 "design and implementation: Dirk-Jan C. Binnema\n"
280 "contributions from the fine people at KC and Ig\n"
281 "uses the tinymail email framework written by Philip van Hoof"));
282 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
283 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
284 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
285 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
287 gtk_dialog_run (GTK_DIALOG (about));
288 gtk_widget_destroy(about);
292 * Gets the list of currently selected messages. If the win is the
293 * main window, then it returns a newly allocated list of the headers
294 * selected in the header view. If win is the msg view window, then
295 * the value returned is a list with just a single header.
297 * The caller of this funcion must free the list.
300 get_selected_headers (ModestWindow *win)
302 if (MODEST_IS_MAIN_WINDOW(win)) {
303 GtkWidget *header_view;
305 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
306 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
307 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
309 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
310 /* for MsgViewWindows, we simply return a list with one element */
312 TnyList *list = NULL;
314 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
315 if (header != NULL) {
316 list = tny_simple_list_new ();
317 tny_list_prepend (list, G_OBJECT(header));
318 g_object_unref (G_OBJECT(header));
327 static GtkTreeRowReference *
328 get_next_after_selected_headers (ModestHeaderView *header_view)
330 GtkTreeSelection *sel;
331 GList *selected_rows, *node;
333 GtkTreeRowReference *result;
336 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
337 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
338 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
340 if (selected_rows == NULL)
343 node = g_list_last (selected_rows);
344 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
345 gtk_tree_path_next (path);
347 result = gtk_tree_row_reference_new (model, path);
349 gtk_tree_path_free (path);
350 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
351 g_list_free (selected_rows);
357 headers_action_mark_as_read (TnyHeader *header,
361 TnyHeaderFlags flags;
363 g_return_if_fail (TNY_IS_HEADER(header));
365 flags = tny_header_get_flags (header);
366 if (flags & TNY_HEADER_FLAG_SEEN) return;
367 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
371 headers_action_mark_as_unread (TnyHeader *header,
375 TnyHeaderFlags flags;
377 g_return_if_fail (TNY_IS_HEADER(header));
379 flags = tny_header_get_flags (header);
380 if (flags & TNY_HEADER_FLAG_SEEN) {
381 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
385 /** After deleing a message that is currently visible in a window,
386 * show the next message from the list, or close the window if there are no more messages.
389 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
391 /* Close msg view window or select next */
392 if (modest_msg_view_window_last_message_selected (win) &&
393 modest_msg_view_window_first_message_selected (win)) {
394 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
395 } else if (!modest_msg_view_window_select_next_message (win)) {
397 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
403 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
405 TnyList *header_list = NULL;
406 TnyIterator *iter = NULL;
407 TnyHeader *header = NULL;
408 gchar *message = NULL;
411 ModestWindowMgr *mgr;
412 GtkWidget *header_view = NULL;
414 g_return_if_fail (MODEST_IS_WINDOW(win));
416 /* Check first if the header view has the focus */
417 if (MODEST_IS_MAIN_WINDOW (win)) {
419 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
420 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
421 if (!gtk_widget_is_focus (header_view))
425 /* Get the headers, either from the header view (if win is the main window),
426 * or from the message view window: */
427 header_list = get_selected_headers (win);
428 if (!header_list) return;
430 /* Check if any of the headers are already opened, or in the process of being opened */
431 if (MODEST_IS_MAIN_WINDOW (win)) {
432 gint opened_headers = 0;
434 iter = tny_list_create_iterator (header_list);
435 mgr = modest_runtime_get_window_mgr ();
436 while (!tny_iterator_is_done (iter)) {
437 header = TNY_HEADER (tny_iterator_get_current (iter));
439 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
441 g_object_unref (header);
443 tny_iterator_next (iter);
445 g_object_unref (iter);
447 if (opened_headers > 0) {
450 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
453 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
456 g_object_unref (header_list);
462 if (tny_list_get_length(header_list) == 1) {
463 iter = tny_list_create_iterator (header_list);
464 header = TNY_HEADER (tny_iterator_get_current (iter));
466 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
467 g_object_unref (header);
470 g_object_unref (iter);
472 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
473 tny_list_get_length(header_list)), desc);
475 /* Confirmation dialog */
476 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
480 if (response == GTK_RESPONSE_OK) {
481 ModestWindow *main_window = NULL;
482 ModestWindowMgr *mgr = NULL;
483 GtkTreeModel *model = NULL;
484 GtkTreeSelection *sel = NULL;
485 GList *sel_list = NULL, *tmp = NULL;
486 GtkTreeRowReference *next_row_reference = NULL;
487 GtkTreeRowReference *prev_row_reference = NULL;
488 GtkTreePath *next_path = NULL;
489 GtkTreePath *prev_path = NULL;
490 ModestMailOperation *mail_op = NULL;
492 /* Find last selected row */
493 if (MODEST_IS_MAIN_WINDOW (win)) {
494 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
495 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
496 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
497 for (tmp=sel_list; tmp; tmp=tmp->next) {
498 if (tmp->next == NULL) {
499 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
500 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
502 gtk_tree_path_prev (prev_path);
503 gtk_tree_path_next (next_path);
505 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
506 next_row_reference = gtk_tree_row_reference_new (model, next_path);
511 /* Disable window dimming management */
512 modest_window_disable_dimming (MODEST_WINDOW(win));
514 /* Remove each header. If it's a view window header_view == NULL */
515 mail_op = modest_mail_operation_new ((GObject *) win);
516 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
518 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
519 g_object_unref (mail_op);
521 /* Enable window dimming management */
523 gtk_tree_selection_unselect_all (sel);
525 modest_window_enable_dimming (MODEST_WINDOW(win));
527 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
528 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
530 /* Get main window */
531 mgr = modest_runtime_get_window_mgr ();
532 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
534 /* Move cursor to next row */
537 /* Select next or previous row */
538 if (gtk_tree_row_reference_valid (next_row_reference)) {
539 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
540 gtk_tree_selection_select_path (sel, next_path);
542 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
543 gtk_tree_selection_select_path (sel, prev_path);
547 if (next_row_reference != NULL)
548 gtk_tree_row_reference_free (next_row_reference);
549 if (next_path != NULL)
550 gtk_tree_path_free (next_path);
551 if (prev_row_reference != NULL)
552 gtk_tree_row_reference_free (prev_row_reference);
553 if (prev_path != NULL)
554 gtk_tree_path_free (prev_path);
557 /* Update toolbar dimming state */
559 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
562 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
563 g_list_free (sel_list);
569 g_object_unref (header_list);
575 /* delete either message or folder, based on where we are */
577 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
579 g_return_if_fail (MODEST_IS_WINDOW(win));
581 /* Check first if the header view has the focus */
582 if (MODEST_IS_MAIN_WINDOW (win)) {
584 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
585 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
586 if (gtk_widget_is_focus (w)) {
587 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
591 modest_ui_actions_on_delete_message (action, win);
597 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
599 ModestWindowMgr *mgr = NULL;
601 #ifdef MODEST_PLATFORM_MAEMO
602 modest_osso_save_state();
603 #endif /* MODEST_PLATFORM_MAEMO */
605 g_debug ("closing down, clearing %d item(s) from operation queue",
606 modest_mail_operation_queue_num_elements
607 (modest_runtime_get_mail_operation_queue()));
609 /* cancel all outstanding operations */
610 modest_mail_operation_queue_cancel_all
611 (modest_runtime_get_mail_operation_queue());
613 g_debug ("queue has been cleared");
616 /* Check if there are opened editing windows */
617 mgr = modest_runtime_get_window_mgr ();
618 modest_window_mgr_close_all_windows (mgr);
620 /* note: when modest-tny-account-store is finalized,
621 it will automatically set all network connections
624 /* gtk_main_quit (); */
628 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
632 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
634 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
635 /* gtk_widget_destroy (GTK_WIDGET (win)); */
636 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
637 /* gboolean ret_value; */
638 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
639 /* } else if (MODEST_IS_WINDOW (win)) { */
640 /* gtk_widget_destroy (GTK_WIDGET (win)); */
642 /* g_return_if_reached (); */
647 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
649 GtkClipboard *clipboard = NULL;
650 gchar *selection = NULL;
652 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
653 selection = gtk_clipboard_wait_for_text (clipboard);
655 /* Question: why is the clipboard being used here?
656 * It doesn't really make a lot of sense. */
660 modest_address_book_add_address (selection);
666 modest_ui_actions_on_accounts (GtkAction *action,
669 /* This is currently only implemented for Maemo */
670 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
671 if (!modest_ui_actions_run_account_setup_wizard (win))
672 g_debug ("%s: wizard was already running", __FUNCTION__);
676 /* Show the list of accounts */
677 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
678 gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
680 /* The accounts dialog must be modal */
681 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
682 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
686 #ifdef MODEST_PLATFORM_MAEMO
688 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
690 /* Save any changes. */
691 modest_connection_specific_smtp_window_save_server_accounts (
692 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
693 gtk_widget_destroy (GTK_WIDGET (window));
699 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
701 /* This is currently only implemented for Maemo,
702 * because it requires an API (libconic) to detect different connection
705 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
707 /* Create the window if necessary: */
708 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
709 modest_connection_specific_smtp_window_fill_with_connections (
710 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
711 modest_runtime_get_account_mgr());
713 /* Show the window: */
714 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
715 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
716 gtk_widget_show (specific_window);
718 /* Save changes when the window is hidden: */
719 g_signal_connect (specific_window, "hide",
720 G_CALLBACK (on_smtp_servers_window_hide), win);
721 #endif /* MODEST_PLATFORM_MAEMO */
725 modest_ui_actions_compose_msg(ModestWindow *win,
728 const gchar *bcc_str,
729 const gchar *subject_str,
730 const gchar *body_str,
733 gchar *account_name = NULL;
735 TnyAccount *account = NULL;
736 TnyFolder *folder = NULL;
737 gchar *from_str = NULL, *signature = NULL, *body = NULL;
738 gboolean use_signature = FALSE;
739 ModestWindow *msg_win = NULL;
740 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
741 ModestTnyAccountStore *store = modest_runtime_get_account_store();
743 if (win) account_name = g_strdup (modest_window_get_active_account (win));
744 if (!account_name) account_name = modest_account_mgr_get_default_account(mgr);
746 g_printerr ("modest: no account found\n");
749 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
751 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
754 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
756 g_printerr ("modest: failed to find Drafts folder\n");
759 from_str = modest_account_mgr_get_from_string (mgr, account_name);
761 g_printerr ("modest: failed get from string for '%s'\n", account_name);
765 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
766 if (body_str != NULL) {
767 body = use_signature ? g_strconcat(body_str, "\n", signature, NULL) : g_strdup(body_str);
769 body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup("");
772 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL);
774 g_printerr ("modest: failed to create new msg\n");
778 /* Create and register edit window */
779 /* This is destroyed by TODO. */
780 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
781 while (attachments) {
782 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
784 attachments = g_slist_next(attachments);
786 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
789 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
792 gtk_widget_show_all (GTK_WIDGET (msg_win));
798 g_free (account_name);
799 if (account) g_object_unref (G_OBJECT(account));
800 if (folder) g_object_unref (G_OBJECT(folder));
801 if (msg_win) g_object_unref (G_OBJECT(msg_win));
802 if (msg) g_object_unref (G_OBJECT(msg));
806 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
808 /* if there are no accounts yet, just show the wizard */
809 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
810 if (!modest_ui_actions_run_account_setup_wizard (win))
813 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL);
817 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
821 ModestMailOperationStatus status;
823 /* If there is no message or the operation was not successful */
824 status = modest_mail_operation_get_status (mail_op);
825 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
827 /* Remove the header from the preregistered uids */
828 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
838 open_msg_cb (ModestMailOperation *mail_op,
845 ModestWindowMgr *mgr = NULL;
846 ModestWindow *parent_win = NULL;
847 ModestWindow *win = NULL;
848 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
849 gchar *account = NULL;
851 gboolean open_in_editor = FALSE;
853 /* Do nothing if there was any problem with the mail
854 operation. The error will be shown by the error_handler of
855 the mail operation */
856 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
859 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
860 folder = tny_header_get_folder (header);
862 /* Mark header as read */
863 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
865 /* Gets folder type (OUTBOX headers will be opened in edit window */
866 if (modest_tny_folder_is_local_folder (folder)) {
867 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
868 if (folder_type == TNY_FOLDER_TYPE_INVALID)
869 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
873 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
874 TnyTransportAccount *traccount = NULL;
875 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
876 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
878 ModestTnySendQueue *send_queue = NULL;
879 ModestTnySendQueueStatus status;
881 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
882 TNY_ACCOUNT(traccount)));
883 send_queue = modest_runtime_get_send_queue(traccount);
884 msg_id = modest_tny_send_queue_get_msg_id (header);
885 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
886 /* Only open messages in outbox with the editor if they are in Failed state */
887 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
888 open_in_editor = TRUE;
891 g_object_unref(traccount);
893 g_warning("Cannot get transport account for message in outbox!!");
895 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
896 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
901 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
903 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
905 if (open_in_editor) {
906 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
907 const gchar *from_header = NULL;
909 from_header = tny_header_get_from (header);
911 /* we cannot edit without a valid account... */
912 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
913 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
918 GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
920 for (node = accounts; node != NULL; node = g_slist_next (node)) {
921 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
923 if (from && (strcmp (from_header, from) == 0)) {
925 account = g_strdup (node->data);
931 g_slist_foreach (accounts, (GFunc) g_free, NULL);
932 g_slist_free (accounts);
935 win = modest_msg_edit_window_new (msg, account, TRUE);
939 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
942 gchar *uid = modest_tny_folder_get_header_unique_id (header);
944 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
945 GtkWidget *header_view;
946 GtkTreeSelection *sel;
947 GList *sel_list = NULL;
950 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
951 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
953 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
954 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
956 if (sel_list != NULL) {
957 GtkTreeRowReference *row_reference;
959 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
960 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
961 g_list_free (sel_list);
963 win = modest_msg_view_window_new_with_header_model (
964 msg, account, (const gchar*) uid,
965 model, row_reference);
966 gtk_tree_row_reference_free (row_reference);
968 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
971 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
976 /* Register and show new window */
978 mgr = modest_runtime_get_window_mgr ();
979 modest_window_mgr_register_window (mgr, win);
980 g_object_unref (win);
981 gtk_widget_show_all (GTK_WIDGET(win));
984 /* Update toolbar dimming state */
985 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
986 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
992 g_object_unref (parent_win);
993 g_object_unref (folder);
997 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1000 const GError *error;
1001 GObject *win = NULL;
1002 const gchar *err_msg;
1004 win = modest_mail_operation_get_source (mail_op);
1005 error = modest_mail_operation_get_error (mail_op);
1007 /* Select error message */
1008 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT)
1009 err_msg = _("emev_ni_ui_imap_msg_size_exceed_error");
1011 err_msg = (const gchar *) user_data;
1014 modest_platform_run_information_dialog ((GtkWindow *) win, err_msg);
1017 g_object_unref (win);
1021 * Returns the account a list of headers belongs to. It returns a
1022 * *new* reference so don't forget to unref it
1025 get_account_from_header_list (TnyList *headers)
1027 TnyAccount *account = NULL;
1029 if (tny_list_get_length (headers) > 0) {
1030 TnyIterator *iter = tny_list_create_iterator (headers);
1031 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1032 TnyFolder *folder = tny_header_get_folder (header);
1033 account = tny_folder_get_account (folder);
1034 g_object_unref (folder);
1035 g_object_unref (header);
1036 g_object_unref (iter);
1042 open_msgs_performer(gboolean canceled,
1044 GtkWindow *parent_window,
1045 TnyAccount *account,
1048 ModestMailOperation *mail_op = NULL;
1049 const gchar *proto_name;
1051 ModestTransportStoreProtocol proto;
1052 TnyList *not_opened_headers;
1053 TnyConnectionStatus status;
1055 not_opened_headers = TNY_LIST (user_data);
1057 status = tny_account_get_connection_status (account);
1058 if (err || canceled) {
1059 /* TODO: Show an error ? */
1063 /* Get the error message depending on the protocol */
1064 proto_name = tny_account_get_proto (account);
1065 if (proto_name != NULL) {
1066 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1068 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1071 /* Create the error messages */
1072 if (tny_list_get_length (not_opened_headers) == 1) {
1073 if (proto == MODEST_PROTOCOL_STORE_POP) {
1074 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1075 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1076 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1077 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1078 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1079 tny_header_get_subject (header));
1080 g_object_unref (header);
1081 g_object_unref (iter);
1083 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1086 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1089 /* Create the mail operation */
1091 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1092 modest_ui_actions_get_msgs_full_error_handler,
1094 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1097 modest_mail_operation_get_msgs_full (mail_op,
1106 g_object_unref (mail_op);
1107 g_object_unref (not_opened_headers);
1108 g_object_unref (account);
1112 * This function is used by both modest_ui_actions_on_open and
1113 * modest_ui_actions_on_header_activated. This way we always do the
1114 * same when trying to open messages.
1117 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1119 ModestWindowMgr *mgr = NULL;
1120 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1121 TnyList *not_opened_headers = NULL;
1122 TnyHeaderFlags flags = 0;
1123 TnyAccount *account;
1124 gint uncached_msgs = 0;
1126 g_return_if_fail (headers != NULL);
1128 /* Check that only one message is selected for opening */
1129 if (tny_list_get_length (headers) != 1) {
1130 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1131 _("mcen_ib_select_one_message"));
1135 mgr = modest_runtime_get_window_mgr ();
1136 iter = tny_list_create_iterator (headers);
1138 /* Get the account */
1139 account = get_account_from_header_list (headers);
1141 /* Look if we already have a message view for each header. If
1142 true, then remove the header from the list of headers to
1144 not_opened_headers = tny_simple_list_new ();
1145 while (!tny_iterator_is_done (iter)) {
1147 ModestWindow *window = NULL;
1148 TnyHeader *header = NULL;
1149 gboolean found = FALSE;
1151 header = TNY_HEADER (tny_iterator_get_current (iter));
1153 flags = tny_header_get_flags (header);
1156 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1158 /* Do not open again the message and present the
1159 window to the user */
1162 gtk_window_present (GTK_WINDOW (window));
1164 /* the header has been registered already, we don't do
1165 * anything but wait for the window to come up*/
1166 g_debug ("header %p already registered, waiting for window", header);
1168 tny_list_append (not_opened_headers, G_OBJECT (header));
1172 g_object_unref (header);
1174 tny_iterator_next (iter);
1176 g_object_unref (iter);
1179 /* Open each message */
1180 if (tny_list_get_length (not_opened_headers) == 0)
1183 /* If some messages would have to be downloaded, ask the user to
1184 * make a connection. It's generally easier to do this here (in the mainloop)
1185 * than later in a thread:
1187 if (tny_list_get_length (not_opened_headers) > 0) {
1188 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1190 if (uncached_msgs > 0) {
1191 /* Allways download if we are online. */
1192 if (!tny_device_is_online (modest_runtime_get_device ())) {
1195 /* If ask for user permission to download the messages */
1196 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1197 ngettext("mcen_nc_get_msg",
1201 /* End if the user does not want to continue */
1202 if (response == GTK_RESPONSE_CANCEL)
1208 /* Register the headers before actually creating the windows: */
1209 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1210 while (!tny_iterator_is_done (iter_not_opened)) {
1211 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1213 modest_window_mgr_register_header (mgr, header, NULL);
1214 g_object_unref (header);
1216 tny_iterator_next (iter_not_opened);
1218 g_object_unref (iter_not_opened);
1219 iter_not_opened = NULL;
1221 /* Connect to the account and perform */
1222 if (uncached_msgs > 0) {
1223 modest_platform_connect_and_perform ((GtkWindow *) win, g_object_ref (account),
1224 open_msgs_performer, g_object_ref (not_opened_headers));
1226 /* Call directly the performer, do not need to connect */
1227 open_msgs_performer (FALSE, NULL, (GtkWindow *) win, g_object_ref (account),
1228 g_object_ref (not_opened_headers));
1233 g_object_unref (account);
1234 if (not_opened_headers)
1235 g_object_unref (not_opened_headers);
1239 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1244 headers = get_selected_headers (win);
1249 open_msgs_from_headers (headers, win);
1251 g_object_unref(headers);
1256 free_reply_forward_helper (gpointer data)
1258 ReplyForwardHelper *helper;
1260 helper = (ReplyForwardHelper *) data;
1261 g_free (helper->account_name);
1262 g_slice_free (ReplyForwardHelper, helper);
1266 reply_forward_cb (ModestMailOperation *mail_op,
1274 ReplyForwardHelper *rf_helper;
1275 ModestWindow *msg_win = NULL;
1276 ModestEditType edit_type;
1278 TnyAccount *account = NULL;
1279 ModestWindowMgr *mgr = NULL;
1280 gchar *signature = NULL;
1281 gboolean use_signature;
1283 /* If there was any error. The mail operation could be NULL,
1284 this means that we already have the message downloaded and
1285 that we didn't do a mail operation to retrieve it */
1286 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1289 g_return_if_fail (user_data != NULL);
1290 rf_helper = (ReplyForwardHelper *) user_data;
1292 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1293 rf_helper->account_name);
1294 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1295 rf_helper->account_name,
1298 /* Create reply mail */
1299 switch (rf_helper->action) {
1302 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1303 rf_helper->reply_forward_type,
1304 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1306 case ACTION_REPLY_TO_ALL:
1308 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1309 MODEST_TNY_MSG_REPLY_MODE_ALL);
1310 edit_type = MODEST_EDIT_TYPE_REPLY;
1312 case ACTION_FORWARD:
1314 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1315 edit_type = MODEST_EDIT_TYPE_FORWARD;
1318 g_return_if_reached ();
1325 g_printerr ("modest: failed to create message\n");
1329 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1330 rf_helper->account_name,
1331 TNY_ACCOUNT_TYPE_STORE);
1333 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1337 /* Create and register the windows */
1338 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1339 mgr = modest_runtime_get_window_mgr ();
1340 modest_window_mgr_register_window (mgr, msg_win);
1342 if (rf_helper->parent_window != NULL) {
1343 gdouble parent_zoom;
1345 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1346 modest_window_set_zoom (msg_win, parent_zoom);
1349 /* Show edit window */
1350 gtk_widget_show_all (GTK_WIDGET (msg_win));
1354 g_object_unref (msg_win);
1356 g_object_unref (G_OBJECT (new_msg));
1358 g_object_unref (G_OBJECT (account));
1359 /* g_object_unref (msg); */
1360 free_reply_forward_helper (rf_helper);
1363 /* Checks a list of headers. If any of them are not currently
1364 * downloaded (CACHED) then returns TRUE else returns FALSE.
1367 header_list_count_uncached_msgs (TnyList *header_list)
1370 gint uncached_messages = 0;
1372 iter = tny_list_create_iterator (header_list);
1373 while (!tny_iterator_is_done (iter)) {
1376 header = TNY_HEADER (tny_iterator_get_current (iter));
1378 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1379 uncached_messages ++;
1380 g_object_unref (header);
1383 tny_iterator_next (iter);
1385 g_object_unref (iter);
1387 return uncached_messages;
1390 /* Returns FALSE if the user does not want to download the
1391 * messages. Returns TRUE if the user allowed the download.
1394 connect_to_get_msg (ModestWindow *win,
1395 gint num_of_uncached_msgs,
1396 TnyAccount *account)
1398 GtkResponseType response;
1400 /* Allways download if we are online. */
1401 if (tny_device_is_online (modest_runtime_get_device ()))
1404 /* If offline, then ask for user permission to download the messages */
1405 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1406 ngettext("mcen_nc_get_msg",
1408 num_of_uncached_msgs));
1410 if (response == GTK_RESPONSE_CANCEL)
1413 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1417 * Common code for the reply and forward actions
1420 reply_forward (ReplyForwardAction action, ModestWindow *win)
1422 ModestMailOperation *mail_op = NULL;
1423 TnyList *header_list = NULL;
1424 ReplyForwardHelper *rf_helper = NULL;
1425 guint reply_forward_type;
1426 gboolean continue_download = TRUE;
1427 gboolean do_retrieve = TRUE;
1429 g_return_if_fail (MODEST_IS_WINDOW(win));
1431 /* we need an account when editing */
1432 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1433 if (!modest_ui_actions_run_account_setup_wizard (win))
1437 header_list = get_selected_headers (win);
1441 reply_forward_type =
1442 modest_conf_get_int (modest_runtime_get_conf (),
1443 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1446 /* check if we need to download msg before asking about it */
1447 do_retrieve = (action == ACTION_FORWARD) ||
1448 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1451 gint num_of_unc_msgs;
1453 /* check that the messages have been previously downloaded */
1454 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1455 /* If there are any uncached message ask the user
1456 * whether he/she wants to download them. */
1457 if (num_of_unc_msgs) {
1458 TnyAccount *account = get_account_from_header_list (header_list);
1459 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1460 g_object_unref (account);
1464 if (!continue_download) {
1465 g_object_unref (header_list);
1469 /* We assume that we can only select messages of the
1470 same folder and that we reply all of them from the
1471 same account. In fact the interface currently only
1472 allows single selection */
1475 rf_helper = g_slice_new0 (ReplyForwardHelper);
1476 rf_helper->reply_forward_type = reply_forward_type;
1477 rf_helper->action = action;
1478 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1480 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1481 rf_helper->parent_window = GTK_WIDGET (win);
1482 if (!rf_helper->account_name)
1483 rf_helper->account_name =
1484 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1486 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1489 /* Get header and message. Do not free them here, the
1490 reply_forward_cb must do it */
1491 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1492 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1493 if (!msg || !header) {
1495 g_object_unref (msg);
1496 g_printerr ("modest: no message found\n");
1499 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1502 g_object_unref (header);
1507 /* Only reply/forward to one message */
1508 iter = tny_list_create_iterator (header_list);
1509 header = TNY_HEADER (tny_iterator_get_current (iter));
1510 g_object_unref (iter);
1513 /* Retrieve messages */
1516 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1517 modest_ui_actions_get_msgs_full_error_handler,
1519 modest_mail_operation_queue_add (
1520 modest_runtime_get_mail_operation_queue (), mail_op);
1522 modest_mail_operation_get_msg (mail_op,
1527 g_object_unref(mail_op);
1529 /* we put a ref here to prevent double unref as the reply
1530 * forward callback unrefs the header at its end */
1531 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1535 g_object_unref (header);
1541 g_object_unref (header_list);
1545 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1547 g_return_if_fail (MODEST_IS_WINDOW(win));
1549 reply_forward (ACTION_REPLY, win);
1553 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1555 g_return_if_fail (MODEST_IS_WINDOW(win));
1557 reply_forward (ACTION_FORWARD, win);
1561 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1563 g_return_if_fail (MODEST_IS_WINDOW(win));
1565 reply_forward (ACTION_REPLY_TO_ALL, win);
1569 modest_ui_actions_on_next (GtkAction *action,
1570 ModestWindow *window)
1572 if (MODEST_IS_MAIN_WINDOW (window)) {
1573 GtkWidget *header_view;
1575 header_view = modest_main_window_get_child_widget (
1576 MODEST_MAIN_WINDOW(window),
1577 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1581 modest_header_view_select_next (
1582 MODEST_HEADER_VIEW(header_view));
1583 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1584 modest_msg_view_window_select_next_message (
1585 MODEST_MSG_VIEW_WINDOW (window));
1587 g_return_if_reached ();
1592 modest_ui_actions_on_prev (GtkAction *action,
1593 ModestWindow *window)
1595 g_return_if_fail (MODEST_IS_WINDOW(window));
1597 if (MODEST_IS_MAIN_WINDOW (window)) {
1598 GtkWidget *header_view;
1599 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1600 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1604 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1605 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1606 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1608 g_return_if_reached ();
1613 modest_ui_actions_on_sort (GtkAction *action,
1614 ModestWindow *window)
1616 g_return_if_fail (MODEST_IS_WINDOW(window));
1618 if (MODEST_IS_MAIN_WINDOW (window)) {
1619 GtkWidget *header_view;
1620 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1621 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1623 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1628 /* Show sorting dialog */
1629 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1634 new_messages_arrived (ModestMailOperation *self,
1635 TnyList *new_headers,
1640 source = modest_mail_operation_get_source (self);
1642 /* Notify new messages have been downloaded. Do not notify if
1643 the send&receive was invoked by the user, i.e, if the mail
1644 operation has a source (the main window) */
1645 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0) && !source)
1646 modest_platform_on_new_headers_received (new_headers);
1649 g_object_unref (source);
1653 retrieve_all_messages_cb (GObject *source,
1655 guint retrieve_limit)
1661 window = GTK_WINDOW (source);
1662 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1663 num_msgs, retrieve_limit);
1665 /* Ask the user if they want to retrieve all the messages */
1667 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1668 _("mcen_bd_get_all"),
1669 _("mcen_bd_newest_only"));
1670 /* Free and return */
1672 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1676 TnyAccount *account;
1678 gchar *account_name;
1682 do_send_receive_performer (gboolean canceled,
1684 GtkWindow *parent_window,
1685 TnyAccount *account,
1688 ModestMailOperation *mail_op;
1689 SendReceiveInfo *info;
1691 info = (SendReceiveInfo *) user_data;
1693 if (err || canceled) {
1698 /* Set send/receive operation in progress */
1699 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
1700 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
1703 mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
1704 modest_ui_actions_send_receive_error_handler,
1707 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
1708 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1709 G_CALLBACK (on_send_receive_finished),
1712 /* Send & receive. */
1713 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1714 modest_mail_operation_update_account (mail_op, info->account_name, (info->win) ? FALSE : TRUE,
1715 (info->win) ? retrieve_all_messages_cb : NULL,
1716 new_messages_arrived, info->win);
1717 g_object_unref (G_OBJECT (mail_op));
1721 if (info->account_name)
1722 g_free (info->account_name);
1724 g_object_unref (info->win);
1726 g_object_unref (info->account);
1727 g_slice_free (SendReceiveInfo, info);
1731 * This function performs the send & receive required actions. The
1732 * window is used to create the mail operation. Typically it should
1733 * always be the main window, but we pass it as argument in order to
1737 modest_ui_actions_do_send_receive (const gchar *account_name,
1740 gchar *acc_name = NULL;
1741 SendReceiveInfo *info;
1742 ModestTnyAccountStore *acc_store;
1744 /* If no account name was provided then get the current account, and if
1745 there is no current account then pick the default one: */
1746 if (!account_name) {
1748 acc_name = g_strdup (modest_window_get_active_account (win));
1750 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1752 g_printerr ("modest: cannot get default account\n");
1756 acc_name = g_strdup (account_name);
1759 acc_store = modest_runtime_get_account_store ();
1761 /* Create the info for the connect and perform */
1762 info = g_slice_new (SendReceiveInfo);
1763 info->account_name = acc_name;
1764 info->win = (win) ? g_object_ref (win) : NULL;
1765 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
1766 TNY_ACCOUNT_TYPE_STORE);
1768 /* Invoke the connect and perform */
1769 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL, info->account,
1770 do_send_receive_performer, info);
1775 modest_ui_actions_do_cancel_send (const gchar *account_name,
1778 TnyTransportAccount *transport_account;
1779 TnySendQueue *send_queue = NULL;
1780 GError *error = NULL;
1782 /* Get transport account */
1784 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1785 (modest_runtime_get_account_store(),
1787 TNY_ACCOUNT_TYPE_TRANSPORT));
1788 if (!transport_account) {
1789 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1794 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1795 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1796 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1797 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1798 "modest: could not find send queue for account\n");
1800 /* Keeep messages in outbox folder */
1801 tny_send_queue_cancel (send_queue, FALSE, &error);
1805 if (transport_account != NULL)
1806 g_object_unref (G_OBJECT (transport_account));
1810 modest_ui_actions_cancel_send_all (ModestWindow *win)
1812 GSList *account_names, *iter;
1814 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1817 iter = account_names;
1819 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1820 iter = g_slist_next (iter);
1823 modest_account_mgr_free_account_names (account_names);
1824 account_names = NULL;
1828 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1831 /* Check if accounts exist */
1832 gboolean accounts_exist =
1833 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1835 /* If not, allow the user to create an account before trying to send/receive. */
1836 if (!accounts_exist)
1837 modest_ui_actions_on_accounts (NULL, win);
1839 /* Cancel all sending operaitons */
1840 modest_ui_actions_cancel_send_all (win);
1844 * Refreshes all accounts. This function will be used by automatic
1848 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1850 GSList *account_names, *iter;
1852 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1855 iter = account_names;
1857 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1858 iter = g_slist_next (iter);
1861 modest_account_mgr_free_account_names (account_names);
1862 account_names = NULL;
1866 * Handler of the click on Send&Receive button in the main toolbar
1869 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1871 /* Check if accounts exist */
1872 gboolean accounts_exist;
1875 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1877 /* If not, allow the user to create an account before trying to send/receive. */
1878 if (!accounts_exist)
1879 modest_ui_actions_on_accounts (NULL, win);
1881 /* Refresh the current folder. The if is always TRUE it's just an extra check */
1882 if (MODEST_IS_MAIN_WINDOW (win)) {
1883 GtkWidget *header_view, *folder_view;
1884 TnyFolderStore *folder_store;
1887 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1888 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1892 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1894 /* No need to refresh the INBOX the send_receive will do it for us */
1895 if (folder_store && TNY_IS_FOLDER (folder_store) &&
1896 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
1898 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1899 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1904 g_object_unref (folder_store);
1907 /* Refresh the active account */
1908 modest_ui_actions_do_send_receive (NULL, win);
1913 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1916 GtkWidget *header_view;
1918 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1920 header_view = modest_main_window_get_child_widget (main_window,
1921 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1925 conf = modest_runtime_get_conf ();
1927 /* what is saved/restored is depending on the style; thus; we save with
1928 * old style, then update the style, and restore for this new style
1930 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1932 if (modest_header_view_get_style
1933 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1934 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1935 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1937 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1938 MODEST_HEADER_VIEW_STYLE_DETAILS);
1940 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1941 MODEST_CONF_HEADER_VIEW_KEY);
1946 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1948 ModestMainWindow *main_window)
1950 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1951 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1953 /* in the case the folder is empty, show the empty folder message and focus
1955 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1956 if (modest_header_view_is_empty (header_view)) {
1957 TnyFolder *folder = modest_header_view_get_folder (header_view);
1958 GtkWidget *folder_view =
1959 modest_main_window_get_child_widget (main_window,
1960 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1962 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1963 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1967 /* If no header has been selected then exit */
1972 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1973 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1975 /* Update toolbar dimming state */
1976 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1980 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1982 ModestMainWindow *main_window)
1986 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1991 if (modest_header_view_count_selected_headers (header_view) > 1) {
1992 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1997 /* headers = tny_simple_list_new (); */
1998 /* tny_list_prepend (headers, G_OBJECT (header)); */
1999 headers = modest_header_view_get_selected_headers (header_view);
2001 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2003 g_object_unref (headers);
2007 set_active_account_from_tny_account (TnyAccount *account,
2008 ModestWindow *window)
2010 const gchar *server_acc_name = tny_account_get_id (account);
2012 /* We need the TnyAccount provided by the
2013 account store because that is the one that
2014 knows the name of the Modest account */
2015 TnyAccount *modest_server_account = modest_server_account =
2016 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2017 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2019 if (!modest_server_account) {
2020 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2024 /* Update active account, but only if it's not a pseudo-account */
2025 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2026 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2027 const gchar *modest_acc_name =
2028 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2029 if (modest_acc_name)
2030 modest_window_set_active_account (window, modest_acc_name);
2033 g_object_unref (modest_server_account);
2038 folder_refreshed_cb (ModestMailOperation *mail_op,
2042 ModestMainWindow *win = NULL;
2043 GtkWidget *header_view;
2044 gboolean folder_empty = FALSE;
2045 gboolean all_marked_as_deleted = FALSE;
2047 g_return_if_fail (TNY_IS_FOLDER (folder));
2049 win = MODEST_MAIN_WINDOW (user_data);
2051 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2054 TnyFolder *current_folder;
2056 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2057 if (current_folder != NULL && folder != current_folder) {
2058 g_object_unref (current_folder);
2061 g_object_unref (current_folder);
2064 /* Check if folder is empty and set headers view contents style */
2065 folder_empty = (tny_folder_get_all_count (folder) == 0);
2066 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
2067 if (folder_empty || all_marked_as_deleted)
2068 modest_main_window_set_contents_style (win,
2069 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2073 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2074 TnyFolderStore *folder_store,
2076 ModestMainWindow *main_window)
2079 GtkWidget *header_view;
2081 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2083 header_view = modest_main_window_get_child_widget(main_window,
2084 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2088 conf = modest_runtime_get_conf ();
2090 if (TNY_IS_ACCOUNT (folder_store)) {
2092 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2094 /* Show account details */
2095 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2098 if (TNY_IS_FOLDER (folder_store) && selected) {
2100 /* Update the active account */
2101 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2103 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2104 g_object_unref (account);
2108 /* Set the header style by default, it could
2109 be changed later by the refresh callback to
2111 modest_main_window_set_contents_style (main_window,
2112 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2114 /* Set folder on header view. This function
2115 will call tny_folder_refresh_async so we
2116 pass a callback that will be called when
2117 finished. We use that callback to set the
2118 empty view if there are no messages */
2119 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2120 TNY_FOLDER (folder_store),
2121 folder_refreshed_cb,
2124 /* Restore configuration. We need to do this
2125 *after* the set_folder because the widget
2126 memory asks the header view about its
2128 modest_widget_memory_restore (modest_runtime_get_conf (),
2129 G_OBJECT(header_view),
2130 MODEST_CONF_HEADER_VIEW_KEY);
2132 /* Update the active account */
2133 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2134 /* Save only if we're seeing headers */
2135 if (modest_main_window_get_contents_style (main_window) ==
2136 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2137 modest_widget_memory_save (conf, G_OBJECT (header_view),
2138 MODEST_CONF_HEADER_VIEW_KEY);
2139 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2143 /* Update toolbar dimming state */
2144 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2148 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2155 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2157 online = tny_device_is_online (modest_runtime_get_device());
2160 /* already online -- the item is simply not there... */
2161 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2163 GTK_MESSAGE_WARNING,
2165 _("The %s you selected cannot be found"),
2167 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2168 gtk_dialog_run (GTK_DIALOG(dialog));
2170 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2173 _("mcen_bd_dialog_cancel"),
2174 GTK_RESPONSE_REJECT,
2175 _("mcen_bd_dialog_ok"),
2176 GTK_RESPONSE_ACCEPT,
2178 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2179 "Do you want to get online?"), item);
2180 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2181 gtk_label_new (txt), FALSE, FALSE, 0);
2182 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2185 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2186 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2187 /* TODO: Comment about why is this commented out: */
2188 /* modest_platform_connect_and_wait (); */
2191 gtk_widget_destroy (dialog);
2195 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2198 /* g_message ("%s %s", __FUNCTION__, link); */
2203 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2206 modest_platform_activate_uri (link);
2210 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2213 modest_platform_show_uri_popup (link);
2217 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2220 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2224 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2225 const gchar *address,
2228 /* g_message ("%s %s", __FUNCTION__, address); */
2232 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2233 TnyMsg *saved_draft,
2236 ModestMsgEditWindow *edit_window;
2237 ModestMainWindow *win;
2239 /* FIXME. Make the header view sensitive again. This is a
2240 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2242 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2243 modest_runtime_get_window_mgr(), FALSE));
2245 GtkWidget *hdrview = modest_main_window_get_child_widget(
2246 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2247 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2250 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2252 /* If there was any error do nothing */
2253 if (modest_mail_operation_get_error (mail_op) != NULL)
2256 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2260 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2262 TnyTransportAccount *transport_account;
2263 ModestMailOperation *mail_operation;
2265 gchar *account_name, *from;
2266 ModestAccountMgr *account_mgr;
2269 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2271 data = modest_msg_edit_window_get_msg_data (edit_window);
2273 account_name = g_strdup (data->account_name);
2274 account_mgr = modest_runtime_get_account_mgr();
2276 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2278 account_name = modest_account_mgr_get_default_account (account_mgr);
2279 if (!account_name) {
2280 g_printerr ("modest: no account found\n");
2281 modest_msg_edit_window_free_msg_data (edit_window, data);
2285 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2286 account_name = g_strdup (data->account_name);
2290 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2291 (modest_runtime_get_account_store(),
2293 TNY_ACCOUNT_TYPE_TRANSPORT));
2294 if (!transport_account) {
2295 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2296 g_free (account_name);
2297 modest_msg_edit_window_free_msg_data (edit_window, data);
2300 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2302 /* Create the mail operation */
2303 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2304 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2306 modest_mail_operation_save_to_drafts (mail_operation,
2318 data->priority_flags,
2319 on_save_to_drafts_cb,
2321 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2322 modest_platform_information_banner (NULL, NULL, info_text);
2327 g_free (account_name);
2328 g_object_unref (G_OBJECT (transport_account));
2329 g_object_unref (G_OBJECT (mail_operation));
2331 modest_msg_edit_window_free_msg_data (edit_window, data);
2332 modest_msg_edit_window_reset_modified (edit_window);
2335 * If the drafts folder is selected then make the header view
2336 * insensitive while the message is being saved to drafts
2337 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2338 * is not very clean but it avoids letting the drafts folder
2339 * in an inconsistent state: the user could edit the message
2340 * being saved and undesirable things would happen.
2341 * In the average case the user won't notice anything at
2342 * all. In the worst case (the user is editing a really big
2343 * file from Drafts) the header view will be insensitive
2344 * during the saving process (10 or 20 seconds, depending on
2345 * the message). Anyway this is just a quick workaround: once
2346 * we find a better solution it should be removed
2347 * See NB#65125 (commend #18) for details.
2349 ModestMainWindow *win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2350 modest_runtime_get_window_mgr(), FALSE));
2352 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2353 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2355 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2357 if (modest_tny_folder_is_local_folder(folder)) {
2358 TnyFolderType folder_type;
2359 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2360 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2361 GtkWidget *hdrview = modest_main_window_get_child_widget(
2362 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2363 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2367 if (folder != NULL) g_object_unref(folder);
2372 /* For instance, when clicking the Send toolbar button when editing a message: */
2374 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2376 TnyTransportAccount *transport_account = NULL;
2378 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2380 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2383 /* FIXME: Code added just for testing. The final version will
2384 use the send queue provided by tinymail and some
2386 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2388 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2389 gchar *account_name = g_strdup (data->account_name);
2391 g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2394 account_name = modest_account_mgr_get_default_account (account_mgr);
2396 if (!account_name) {
2397 modest_msg_edit_window_free_msg_data (edit_window, data);
2398 /* Run account setup wizard */
2399 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2403 /* Get the currently-active transport account for this modest account: */
2404 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2405 transport_account = TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2406 (modest_runtime_get_account_store(),
2407 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2410 if (!transport_account) {
2411 /* Run account setup wizard */
2412 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2416 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2418 /* Create the mail operation */
2419 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2420 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2422 modest_mail_operation_send_new_mail (mail_operation,
2434 data->priority_flags);
2436 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2437 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2442 g_free (account_name);
2443 g_object_unref (G_OBJECT (transport_account));
2444 g_object_unref (G_OBJECT (mail_operation));
2446 modest_msg_edit_window_free_msg_data (edit_window, data);
2447 modest_msg_edit_window_set_sent (edit_window, TRUE);
2449 /* Save settings and close the window: */
2450 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2454 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2455 ModestMsgEditWindow *window)
2457 ModestMsgEditFormatState *format_state = NULL;
2459 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2460 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2462 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2465 format_state = modest_msg_edit_window_get_format_state (window);
2466 g_return_if_fail (format_state != NULL);
2468 format_state->bold = gtk_toggle_action_get_active (action);
2469 modest_msg_edit_window_set_format_state (window, format_state);
2470 g_free (format_state);
2475 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2476 ModestMsgEditWindow *window)
2478 ModestMsgEditFormatState *format_state = NULL;
2480 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2481 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2483 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2486 format_state = modest_msg_edit_window_get_format_state (window);
2487 g_return_if_fail (format_state != NULL);
2489 format_state->italics = gtk_toggle_action_get_active (action);
2490 modest_msg_edit_window_set_format_state (window, format_state);
2491 g_free (format_state);
2496 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2497 ModestMsgEditWindow *window)
2499 ModestMsgEditFormatState *format_state = NULL;
2501 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2502 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2504 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2507 format_state = modest_msg_edit_window_get_format_state (window);
2508 g_return_if_fail (format_state != NULL);
2510 format_state->bullet = gtk_toggle_action_get_active (action);
2511 modest_msg_edit_window_set_format_state (window, format_state);
2512 g_free (format_state);
2517 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2518 GtkRadioAction *selected,
2519 ModestMsgEditWindow *window)
2521 ModestMsgEditFormatState *format_state = NULL;
2522 GtkJustification value;
2524 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2526 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2529 value = gtk_radio_action_get_current_value (selected);
2531 format_state = modest_msg_edit_window_get_format_state (window);
2532 g_return_if_fail (format_state != NULL);
2534 format_state->justification = value;
2535 modest_msg_edit_window_set_format_state (window, format_state);
2536 g_free (format_state);
2540 modest_ui_actions_on_select_editor_color (GtkAction *action,
2541 ModestMsgEditWindow *window)
2543 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2544 g_return_if_fail (GTK_IS_ACTION (action));
2546 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2549 modest_msg_edit_window_select_color (window);
2553 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2554 ModestMsgEditWindow *window)
2556 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2557 g_return_if_fail (GTK_IS_ACTION (action));
2559 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2562 modest_msg_edit_window_select_background_color (window);
2566 modest_ui_actions_on_insert_image (GtkAction *action,
2567 ModestMsgEditWindow *window)
2569 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2570 g_return_if_fail (GTK_IS_ACTION (action));
2572 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2575 modest_msg_edit_window_insert_image (window);
2579 modest_ui_actions_on_attach_file (GtkAction *action,
2580 ModestMsgEditWindow *window)
2582 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2583 g_return_if_fail (GTK_IS_ACTION (action));
2585 modest_msg_edit_window_offer_attach_file (window);
2589 modest_ui_actions_on_remove_attachments (GtkAction *action,
2590 ModestMsgEditWindow *window)
2592 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2593 g_return_if_fail (GTK_IS_ACTION (action));
2595 modest_msg_edit_window_remove_attachments (window, NULL);
2599 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2602 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2603 const GError *error = modest_mail_operation_get_error (mail_op);
2606 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2607 _("mail_in_ui_folder_create_error"));
2612 modest_ui_actions_create_folder(GtkWidget *parent_window,
2613 GtkWidget *folder_view)
2615 TnyFolderStore *parent_folder;
2617 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2619 if (parent_folder) {
2620 gboolean finished = FALSE;
2622 gchar *folder_name = NULL, *suggested_name = NULL;
2623 const gchar *proto_str = NULL;
2624 TnyAccount *account;
2626 if (TNY_IS_ACCOUNT (parent_folder))
2627 account = g_object_ref (parent_folder);
2629 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2630 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2632 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2633 MODEST_PROTOCOL_STORE_POP) {
2635 modest_platform_information_banner (NULL, NULL, _("mail_in_ui_folder_create_error"));
2637 g_object_unref (account);
2639 /* Run the new folder dialog */
2641 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2646 g_free (suggested_name);
2647 suggested_name = NULL;
2649 if (result == GTK_RESPONSE_ACCEPT) {
2650 ModestMailOperation *mail_op;
2651 TnyFolder *new_folder = NULL;
2653 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2654 modest_ui_actions_new_folder_error_handler,
2655 parent_window, NULL);
2657 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2659 new_folder = modest_mail_operation_create_folder (mail_op,
2661 (const gchar *) folder_name);
2663 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2666 g_object_unref (new_folder);
2669 g_object_unref (mail_op);
2674 suggested_name = folder_name;
2678 g_object_unref (parent_folder);
2683 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2685 GtkWidget *folder_view;
2687 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2689 folder_view = modest_main_window_get_child_widget (main_window,
2690 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2694 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2698 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2701 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2702 const GError *error = NULL;
2703 const gchar *message = NULL;
2705 /* Get error message */
2706 error = modest_mail_operation_get_error (mail_op);
2708 g_return_if_reached ();
2710 switch (error->code) {
2711 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2712 message = _CS("ckdg_ib_folder_already_exists");
2715 g_warning ("%s: BUG: unexpected error:[%d]: %s", __FUNCTION__,
2716 error->code, error->message);
2720 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2724 TnyFolderStore *folder;
2729 on_rename_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
2730 TnyAccount *account, gpointer user_data)
2732 ModestMailOperation *mail_op = NULL;
2733 GtkTreeSelection *sel = NULL;
2734 GtkWidget *folder_view = NULL;
2735 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
2737 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
2739 folder_view = modest_main_window_get_child_widget (
2740 MODEST_MAIN_WINDOW (parent_window),
2741 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2744 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2745 modest_ui_actions_rename_folder_error_handler,
2746 parent_window, NULL);
2748 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2751 /* Clear the headers view */
2752 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2753 gtk_tree_selection_unselect_all (sel);
2755 /* Select *after* the changes */
2756 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2757 TNY_FOLDER(data->folder), TRUE);
2759 /* Actually rename the folder */
2760 modest_mail_operation_rename_folder (mail_op,
2761 TNY_FOLDER (data->folder),
2762 (const gchar *) (data->new_name));
2764 /* TODO folder view filter refilter */
2766 GtkTreeModel *tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view));
2767 if (GTK_IS_TREE_MODEL_FILTER (tree_model))
2768 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (tree_model)); */
2771 g_object_unref (mail_op);
2772 g_free (data->new_name);
2777 modest_ui_actions_on_rename_folder (GtkAction *action,
2778 ModestMainWindow *main_window)
2780 TnyFolderStore *folder;
2781 GtkWidget *folder_view;
2782 GtkWidget *header_view;
2784 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2786 folder_view = modest_main_window_get_child_widget (main_window,
2787 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2791 header_view = modest_main_window_get_child_widget (main_window,
2792 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2797 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2802 if (TNY_IS_FOLDER (folder)) {
2805 const gchar *current_name;
2806 TnyFolderStore *parent;
2807 gboolean do_rename = TRUE;
2809 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2810 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2811 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2812 parent, current_name,
2814 g_object_unref (parent);
2816 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2819 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
2820 rename_folder_data->folder = folder;
2821 rename_folder_data->new_name = folder_name;
2822 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window),
2823 folder, on_rename_folder_cb, rename_folder_data);
2826 g_object_unref (folder);
2830 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2833 GObject *win = modest_mail_operation_get_source (mail_op);
2835 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2836 _("mail_in_ui_folder_delete_error"));
2837 g_object_unref (win);
2841 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2843 TnyFolderStore *folder;
2844 GtkWidget *folder_view;
2847 gboolean do_delete = TRUE;
2849 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2851 folder_view = modest_main_window_get_child_widget (main_window,
2852 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2856 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2858 /* Show an error if it's an account */
2859 if (!TNY_IS_FOLDER (folder)) {
2860 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2861 _("mail_in_ui_folder_delete_error"));
2862 g_object_unref (G_OBJECT (folder));
2867 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2868 tny_folder_get_name (TNY_FOLDER (folder)));
2869 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2870 (const gchar *) message);
2873 if (response != GTK_RESPONSE_OK) {
2875 } else if (modest_tny_folder_store_is_remote(folder) &&
2876 !tny_device_is_online (modest_runtime_get_device())) {
2877 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2878 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2879 g_object_unref(account);
2883 ModestMailOperation *mail_op;
2884 GtkTreeSelection *sel;
2886 /* Unselect the folder before deleting it to free the headers */
2887 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2888 gtk_tree_selection_unselect_all (sel);
2890 /* Create the mail operation */
2892 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2893 modest_ui_actions_delete_folder_error_handler,
2896 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2898 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2899 g_object_unref (G_OBJECT (mail_op));
2902 g_object_unref (G_OBJECT (folder));
2908 modest_ui_actions_on_delete_folder (GtkAction *action,
2909 ModestMainWindow *main_window)
2911 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2913 if (delete_folder (main_window, FALSE)) {
2914 GtkWidget *folder_view;
2916 folder_view = modest_main_window_get_child_widget (main_window,
2917 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2918 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2923 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2925 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2927 delete_folder (main_window, TRUE);
2932 show_error (GtkWidget *parent_widget, const gchar* text)
2934 modest_platform_information_banner(parent_widget, NULL, text);
2937 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2939 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2946 gtk_dialog_run (dialog);
2947 gtk_widget_destroy (GTK_WIDGET (dialog));
2952 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2953 const gchar* server_account_name,
2958 ModestMainWindow *main_window)
2960 g_return_if_fail(server_account_name);
2962 /* Initalize output parameters: */
2969 #ifdef MODEST_PLATFORM_MAEMO
2970 /* Maemo uses a different (awkward) button order,
2971 * It should probably just use gtk_alternative_dialog_button_order ().
2973 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2976 _("mcen_bd_dialog_ok"),
2977 GTK_RESPONSE_ACCEPT,
2978 _("mcen_bd_dialog_cancel"),
2979 GTK_RESPONSE_REJECT,
2982 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2986 GTK_RESPONSE_REJECT,
2988 GTK_RESPONSE_ACCEPT,
2990 #endif /* MODEST_PLATFORM_MAEMO */
2992 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog));
2994 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2995 modest_runtime_get_account_mgr(), server_account_name);
2996 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2997 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3003 /* This causes a warning because the logical ID has no %s in it,
3004 * though the translation does, but there is not much we can do about that: */
3005 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3006 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3009 g_free (server_name);
3013 gchar *initial_username = modest_account_mgr_get_server_account_username (
3014 modest_runtime_get_account_mgr(), server_account_name);
3016 GtkWidget *entry_username = gtk_entry_new ();
3017 if (initial_username)
3018 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3019 /* Dim this if a connection has ever succeeded with this username,
3020 * as per the UI spec: */
3021 const gboolean username_known =
3022 modest_account_mgr_get_server_account_username_has_succeeded(
3023 modest_runtime_get_account_mgr(), server_account_name);
3024 gtk_widget_set_sensitive (entry_username, !username_known);
3026 #ifdef MODEST_PLATFORM_MAEMO
3027 /* Auto-capitalization is the default, so let's turn it off: */
3028 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3030 /* Create a size group to be used by all captions.
3031 * Note that HildonCaption does not create a default size group if we do not specify one.
3032 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3033 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3035 GtkWidget *caption = hildon_caption_new (sizegroup,
3036 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3037 gtk_widget_show (entry_username);
3038 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3039 FALSE, FALSE, MODEST_MARGIN_HALF);
3040 gtk_widget_show (caption);
3042 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3044 #endif /* MODEST_PLATFORM_MAEMO */
3047 GtkWidget *entry_password = gtk_entry_new ();
3048 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3049 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3051 #ifdef MODEST_PLATFORM_MAEMO
3052 /* Auto-capitalization is the default, so let's turn it off: */
3053 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3054 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3056 caption = hildon_caption_new (sizegroup,
3057 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3058 gtk_widget_show (entry_password);
3059 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3060 FALSE, FALSE, MODEST_MARGIN_HALF);
3061 gtk_widget_show (caption);
3062 g_object_unref (sizegroup);
3064 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3066 #endif /* MODEST_PLATFORM_MAEMO */
3068 if (initial_username != NULL)
3069 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3071 /* This is not in the Maemo UI spec:
3072 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3073 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3077 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3079 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3081 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3083 modest_account_mgr_set_server_account_username (
3084 modest_runtime_get_account_mgr(), server_account_name,
3087 const gboolean username_was_changed =
3088 (strcmp (*username, initial_username) != 0);
3089 if (username_was_changed) {
3090 g_warning ("%s: tinymail does not yet support changing the "
3091 "username in the get_password() callback.\n", __FUNCTION__);
3096 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3098 /* We do not save the password in the configuration,
3099 * because this function is only called for passwords that should
3100 * not be remembered:
3101 modest_server_account_set_password (
3102 modest_runtime_get_account_mgr(), server_account_name,
3111 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
3123 /* This is not in the Maemo UI spec:
3124 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3130 gtk_widget_destroy (dialog);
3132 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3136 modest_ui_actions_on_cut (GtkAction *action,
3137 ModestWindow *window)
3139 GtkWidget *focused_widget;
3140 GtkClipboard *clipboard;
3142 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3143 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3144 if (GTK_IS_EDITABLE (focused_widget)) {
3145 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3146 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3147 gtk_clipboard_store (clipboard);
3148 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3149 GtkTextBuffer *buffer;
3151 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3152 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3153 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3154 gtk_clipboard_store (clipboard);
3155 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3156 TnyList *header_list = modest_header_view_get_selected_headers (
3157 MODEST_HEADER_VIEW (focused_widget));
3158 gboolean continue_download = FALSE;
3159 gint num_of_unc_msgs;
3161 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3163 if (num_of_unc_msgs) {
3164 TnyAccount *account = get_account_from_header_list (header_list);
3165 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3166 g_object_unref (account);
3169 if (num_of_unc_msgs == 0 || continue_download) {
3170 /* modest_platform_information_banner (
3171 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3172 modest_header_view_cut_selection (
3173 MODEST_HEADER_VIEW (focused_widget));
3176 g_object_unref (header_list);
3177 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3178 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3183 modest_ui_actions_on_copy (GtkAction *action,
3184 ModestWindow *window)
3186 GtkClipboard *clipboard;
3187 GtkWidget *focused_widget;
3188 gboolean copied = TRUE;
3190 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3191 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3193 if (GTK_IS_LABEL (focused_widget)) {
3194 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3195 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3196 gtk_clipboard_store (clipboard);
3197 } else if (GTK_IS_EDITABLE (focused_widget)) {
3198 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3199 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3200 gtk_clipboard_store (clipboard);
3201 } else if (GTK_IS_HTML (focused_widget)) {
3202 gtk_html_copy (GTK_HTML (focused_widget));
3203 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3204 gtk_clipboard_store (clipboard);
3205 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3206 GtkTextBuffer *buffer;
3207 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3208 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3209 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3210 gtk_clipboard_store (clipboard);
3211 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3212 TnyList *header_list = modest_header_view_get_selected_headers (
3213 MODEST_HEADER_VIEW (focused_widget));
3214 gboolean continue_download = FALSE;
3215 gint num_of_unc_msgs;
3217 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3219 if (num_of_unc_msgs) {
3220 TnyAccount *account = get_account_from_header_list (header_list);
3221 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3222 g_object_unref (account);
3225 if (num_of_unc_msgs == 0 || continue_download) {
3226 modest_platform_information_banner (
3227 NULL, NULL, _CS("mcen_ib_getting_items"));
3228 modest_header_view_copy_selection (
3229 MODEST_HEADER_VIEW (focused_widget));
3233 g_object_unref (header_list);
3235 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3236 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3239 /* Show information banner if there was a copy to clipboard */
3241 modest_platform_information_banner (
3242 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3246 modest_ui_actions_on_undo (GtkAction *action,
3247 ModestWindow *window)
3249 ModestEmailClipboard *clipboard = NULL;
3251 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3252 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3253 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3254 /* Clear clipboard source */
3255 clipboard = modest_runtime_get_email_clipboard ();
3256 modest_email_clipboard_clear (clipboard);
3259 g_return_if_reached ();
3264 modest_ui_actions_on_redo (GtkAction *action,
3265 ModestWindow *window)
3267 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3268 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3271 g_return_if_reached ();
3277 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3279 /* destroy information note */
3280 gtk_widget_destroy (GTK_WIDGET(user_data));
3285 paste_as_attachment_free (gpointer data)
3287 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3289 gtk_widget_destroy (helper->banner);
3290 g_object_unref (helper->banner);
3295 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3300 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3301 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3306 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3311 modest_ui_actions_on_paste (GtkAction *action,
3312 ModestWindow *window)
3314 GtkWidget *focused_widget = NULL;
3315 GtkWidget *inf_note = NULL;
3316 ModestMailOperation *mail_op = NULL;
3318 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3319 if (GTK_IS_EDITABLE (focused_widget)) {
3320 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3321 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3322 ModestEmailClipboard *e_clipboard = NULL;
3323 e_clipboard = modest_runtime_get_email_clipboard ();
3324 if (modest_email_clipboard_cleared (e_clipboard)) {
3325 GtkTextBuffer *buffer;
3326 GtkClipboard *clipboard;
3328 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3329 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3330 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3331 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3332 ModestMailOperation *mail_op;
3333 TnyFolder *src_folder;
3336 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3337 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3338 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3339 _CS("ckct_nw_pasting"));
3340 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3341 mail_op = modest_mail_operation_new (G_OBJECT (window));
3342 if (helper->banner != NULL) {
3343 g_object_ref (G_OBJECT (helper->banner));
3344 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3345 gtk_widget_show (GTK_WIDGET (helper->banner));
3349 modest_mail_operation_get_msgs_full (mail_op,
3351 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3353 paste_as_attachment_free);
3356 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3357 ModestEmailClipboard *clipboard = NULL;
3358 TnyFolder *src_folder = NULL;
3359 TnyFolderStore *folder_store = NULL;
3360 TnyList *data = NULL;
3361 gboolean delete = FALSE;
3363 /* Check clipboard source */
3364 clipboard = modest_runtime_get_email_clipboard ();
3365 if (modest_email_clipboard_cleared (clipboard))
3368 /* Get elements to paste */
3369 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3371 /* Create a new mail operation */
3372 mail_op = modest_mail_operation_new (G_OBJECT(window));
3374 /* Get destination folder */
3375 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3377 /* transfer messages */
3381 /* Ask for user confirmation */
3383 modest_ui_actions_msgs_move_to_confirmation (window,
3384 TNY_FOLDER (folder_store),
3388 if (response == GTK_RESPONSE_OK) {
3389 /* Launch notification */
3390 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3391 _CS("ckct_nw_pasting"));
3392 if (inf_note != NULL) {
3393 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3394 gtk_widget_show (GTK_WIDGET(inf_note));
3397 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3398 modest_mail_operation_xfer_msgs (mail_op,
3400 TNY_FOLDER (folder_store),
3402 destroy_information_note,
3405 g_object_unref (mail_op);
3408 } else if (src_folder != NULL) {
3409 /* Launch notification */
3410 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3411 _CS("ckct_nw_pasting"));
3412 if (inf_note != NULL) {
3413 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3414 gtk_widget_show (GTK_WIDGET(inf_note));
3417 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3418 modest_mail_operation_xfer_folder (mail_op,
3422 destroy_information_note,
3428 g_object_unref (data);
3429 if (src_folder != NULL)
3430 g_object_unref (src_folder);
3431 if (folder_store != NULL)
3432 g_object_unref (folder_store);
3438 modest_ui_actions_on_select_all (GtkAction *action,
3439 ModestWindow *window)
3441 GtkWidget *focused_widget;
3443 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3444 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3445 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3446 } else if (GTK_IS_LABEL (focused_widget)) {
3447 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3448 } else if (GTK_IS_EDITABLE (focused_widget)) {
3449 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3450 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3451 GtkTextBuffer *buffer;
3452 GtkTextIter start, end;
3454 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3455 gtk_text_buffer_get_start_iter (buffer, &start);
3456 gtk_text_buffer_get_end_iter (buffer, &end);
3457 gtk_text_buffer_select_range (buffer, &start, &end);
3458 } else if (GTK_IS_HTML (focused_widget)) {
3459 gtk_html_select_all (GTK_HTML (focused_widget));
3460 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3461 GtkWidget *header_view = focused_widget;
3462 GtkTreeSelection *selection = NULL;
3464 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3465 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3466 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3469 /* Disable window dimming management */
3470 modest_window_disable_dimming (MODEST_WINDOW(window));
3472 /* Select all messages */
3473 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3474 gtk_tree_selection_select_all (selection);
3476 /* Set focuse on header view */
3477 gtk_widget_grab_focus (header_view);
3480 /* Enable window dimming management */
3481 modest_window_enable_dimming (MODEST_WINDOW(window));
3482 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3488 modest_ui_actions_on_mark_as_read (GtkAction *action,
3489 ModestWindow *window)
3491 g_return_if_fail (MODEST_IS_WINDOW(window));
3493 /* Mark each header as read */
3494 do_headers_action (window, headers_action_mark_as_read, NULL);
3498 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3499 ModestWindow *window)
3501 g_return_if_fail (MODEST_IS_WINDOW(window));
3503 /* Mark each header as read */
3504 do_headers_action (window, headers_action_mark_as_unread, NULL);
3508 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3509 GtkRadioAction *selected,
3510 ModestWindow *window)
3514 value = gtk_radio_action_get_current_value (selected);
3515 if (MODEST_IS_WINDOW (window)) {
3516 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3521 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3522 GtkRadioAction *selected,
3523 ModestWindow *window)
3525 TnyHeaderFlags flags;
3526 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3528 flags = gtk_radio_action_get_current_value (selected);
3529 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3533 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3534 GtkRadioAction *selected,
3535 ModestWindow *window)
3539 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3541 file_format = gtk_radio_action_get_current_value (selected);
3542 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3547 modest_ui_actions_on_zoom_plus (GtkAction *action,
3548 ModestWindow *window)
3550 g_return_if_fail (MODEST_IS_WINDOW (window));
3552 modest_window_zoom_plus (MODEST_WINDOW (window));
3556 modest_ui_actions_on_zoom_minus (GtkAction *action,
3557 ModestWindow *window)
3559 g_return_if_fail (MODEST_IS_WINDOW (window));
3561 modest_window_zoom_minus (MODEST_WINDOW (window));
3565 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3566 ModestWindow *window)
3568 ModestWindowMgr *mgr;
3569 gboolean fullscreen, active;
3570 g_return_if_fail (MODEST_IS_WINDOW (window));
3572 mgr = modest_runtime_get_window_mgr ();
3574 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3575 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3577 if (active != fullscreen) {
3578 modest_window_mgr_set_fullscreen_mode (mgr, active);
3579 gtk_window_present (GTK_WINDOW (window));
3584 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3585 ModestWindow *window)
3587 ModestWindowMgr *mgr;
3588 gboolean fullscreen;
3590 g_return_if_fail (MODEST_IS_WINDOW (window));
3592 mgr = modest_runtime_get_window_mgr ();
3593 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3594 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3596 gtk_window_present (GTK_WINDOW (window));
3600 * Used by modest_ui_actions_on_details to call do_headers_action
3603 headers_action_show_details (TnyHeader *header,
3604 ModestWindow *window,
3611 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3614 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3615 gtk_widget_show_all (dialog);
3616 gtk_dialog_run (GTK_DIALOG (dialog));
3618 gtk_widget_destroy (dialog);
3622 * Show the folder details in a ModestDetailsDialog widget
3625 show_folder_details (TnyFolder *folder,
3631 dialog = modest_details_dialog_new_with_folder (window, folder);
3634 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3635 gtk_widget_show_all (dialog);
3636 gtk_dialog_run (GTK_DIALOG (dialog));
3638 gtk_widget_destroy (dialog);
3642 * Show the header details in a ModestDetailsDialog widget
3645 modest_ui_actions_on_details (GtkAction *action,
3648 TnyList * headers_list;
3652 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3655 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3658 g_object_unref (msg);
3660 headers_list = get_selected_headers (win);
3664 iter = tny_list_create_iterator (headers_list);
3666 header = TNY_HEADER (tny_iterator_get_current (iter));
3668 headers_action_show_details (header, win, NULL);
3669 g_object_unref (header);
3672 g_object_unref (iter);
3673 g_object_unref (headers_list);
3675 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3676 GtkWidget *folder_view, *header_view;
3678 /* Check which widget has the focus */
3679 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3680 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3681 if (gtk_widget_is_focus (folder_view)) {
3682 TnyFolderStore *folder_store
3683 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3684 if (!folder_store) {
3685 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3688 /* Show only when it's a folder */
3689 /* This function should not be called for account items,
3690 * because we dim the menu item for them. */
3691 if (TNY_IS_FOLDER (folder_store)) {
3692 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3695 g_object_unref (folder_store);
3698 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3699 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3700 /* Show details of each header */
3701 do_headers_action (win, headers_action_show_details, header_view);
3707 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3708 ModestMsgEditWindow *window)
3710 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3712 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3716 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3717 ModestMsgEditWindow *window)
3719 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3721 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3725 modest_ui_actions_toggle_folders_view (GtkAction *action,
3726 ModestMainWindow *main_window)
3728 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3730 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3731 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3733 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3737 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3738 ModestWindow *window)
3740 gboolean active, fullscreen = FALSE;
3741 ModestWindowMgr *mgr;
3743 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3745 /* Check if we want to toggle the toolbar vuew in fullscreen
3747 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3748 "ViewShowToolbarFullScreen")) {
3752 /* Toggle toolbar */
3753 mgr = modest_runtime_get_window_mgr ();
3754 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3758 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3759 ModestMsgEditWindow *window)
3761 modest_msg_edit_window_select_font (window);
3765 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3766 const gchar *display_name,
3769 /* This is usually used to change the title of the main window, which
3770 * is the one that holds the folder view. Note that this change can
3771 * happen even when the widget doesn't have the focus. */
3773 gtk_window_set_title (window, display_name);
3775 gtk_window_set_title (window, " ");
3779 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3781 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3782 modest_msg_edit_window_select_contacts (window);
3786 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3788 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3789 modest_msg_edit_window_check_names (window, FALSE);
3793 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3795 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3796 GTK_WIDGET (user_data));
3800 * This function is used to track changes in the selection of the
3801 * folder view that is inside the "move to" dialog to enable/disable
3802 * the OK button because we do not want the user to select a disallowed
3803 * destination for a folder.
3804 * The user also not desired to be able to use NEW button on items where
3805 * folder creation is not possibel.
3808 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3809 TnyFolderStore *folder_store,
3813 GtkWidget *dialog = NULL;
3814 GtkWidget *ok_button = NULL, *new_button = NULL;
3815 GList *children = NULL;
3816 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3817 gboolean moving_folder = FALSE;
3818 gboolean is_local_account = TRUE;
3819 GtkWidget *folder_view = NULL;
3820 ModestTnyFolderRules rules;
3825 /* Get the OK button */
3826 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3830 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3831 ok_button = GTK_WIDGET (children->next->next->data);
3832 new_button = GTK_WIDGET (children->next->data);
3833 g_list_free (children);
3835 /* check if folder_store is an remote account */
3836 if (TNY_IS_ACCOUNT (folder_store)) {
3837 TnyAccount *local_account = NULL;
3838 TnyAccount *mmc_account = NULL;
3839 ModestTnyAccountStore *account_store = NULL;
3841 account_store = modest_runtime_get_account_store ();
3842 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3843 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
3845 if ((gpointer) local_account != (gpointer) folder_store &&
3846 (gpointer) mmc_account != (gpointer) folder_store) {
3847 is_local_account = FALSE;
3848 /* New button should be dimmed on remote
3850 new_sensitive = FALSE;
3852 g_object_unref (local_account);
3855 /* Check the target folder rules */
3856 if (TNY_IS_FOLDER (folder_store)) {
3857 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3858 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3859 ok_sensitive = FALSE;
3860 new_sensitive = FALSE;
3865 /* Check if we're moving a folder */
3866 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3867 /* Get the widgets */
3868 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3869 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3870 if (gtk_widget_is_focus (folder_view))
3871 moving_folder = TRUE;
3874 if (moving_folder) {
3875 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3877 /* Get the folder to move */
3878 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3880 /* Check that we're not moving to the same folder */
3881 if (TNY_IS_FOLDER (moved_folder)) {
3882 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3883 if (parent == folder_store)
3884 ok_sensitive = FALSE;
3885 g_object_unref (parent);
3888 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3889 /* Do not allow to move to an account unless it's the
3890 local folders account */
3891 if (!is_local_account)
3892 ok_sensitive = FALSE;
3895 if (ok_sensitive && (moved_folder == folder_store)) {
3896 /* Do not allow to move to itself */
3897 ok_sensitive = FALSE;
3899 g_object_unref (moved_folder);
3901 TnyHeader *header = NULL;
3902 TnyFolder *src_folder = NULL;
3904 /* Moving a message */
3905 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3906 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3907 src_folder = tny_header_get_folder (header);
3908 g_object_unref (header);
3911 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3914 /* Do not allow to move the msg to the same folder */
3915 /* Do not allow to move the msg to an account */
3916 if ((gpointer) src_folder == (gpointer) folder_store ||
3917 TNY_IS_ACCOUNT (folder_store))
3918 ok_sensitive = FALSE;
3919 g_object_unref (src_folder);
3923 /* Set sensitivity of the OK button */
3924 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3925 /* Set sensitivity of the NEW button */
3926 gtk_widget_set_sensitive (new_button, new_sensitive);
3930 create_move_to_dialog (GtkWindow *win,
3931 GtkWidget *folder_view,
3932 GtkWidget **tree_view)
3934 GtkWidget *dialog, *scroll;
3935 GtkWidget *new_button;
3937 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3939 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3942 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3943 /* We do this manually so GTK+ does not associate a response ID for
3945 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3946 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3947 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3949 /* Create scrolled window */
3950 scroll = gtk_scrolled_window_new (NULL, NULL);
3951 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3952 GTK_POLICY_AUTOMATIC,
3953 GTK_POLICY_AUTOMATIC);
3955 /* Create folder view */
3956 *tree_view = modest_platform_create_folder_view (NULL);
3958 /* Track changes in the selection to
3959 * disable the OK button whenever "Move to" is not possible
3960 * disbale NEW button whenever New is not possible */
3961 g_signal_connect (*tree_view,
3962 "folder_selection_changed",
3963 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3966 /* Listen to clicks on New button */
3967 g_signal_connect (G_OBJECT (new_button),
3969 G_CALLBACK(create_move_to_dialog_on_new_folder),
3972 /* It could happen that we're trying to move a message from a
3973 window (msg window for example) after the main window was
3974 closed, so we can not just get the model of the folder
3976 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3977 const gchar *visible_id = NULL;
3979 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
3980 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
3981 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3982 MODEST_FOLDER_VIEW(*tree_view));
3985 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3987 /* Show the same account than the one that is shown in the main window */
3988 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3991 const gchar *active_account_name = NULL;
3992 ModestAccountMgr *mgr = NULL;
3993 ModestAccountSettings *settings = NULL;
3994 ModestServerAccountSettings *store_settings = NULL;
3996 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
3997 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
3998 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3999 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4001 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4002 mgr = modest_runtime_get_account_mgr ();
4003 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4006 const gchar *store_account_name;
4007 store_settings = modest_account_settings_get_store_settings (settings);
4008 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4010 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4011 store_account_name);
4012 g_object_unref (store_settings);
4013 g_object_unref (settings);
4017 /* Hide special folders */
4018 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4020 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4022 /* Add scroll to dialog */
4023 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4024 scroll, TRUE, TRUE, 0);
4026 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4027 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4033 * Returns TRUE if at least one of the headers of the list belongs to
4034 * a message that has been fully retrieved.
4036 #if 0 /* no longer in use. delete in 2007.10 */
4038 has_retrieved_msgs (TnyList *list)
4041 gboolean found = FALSE;
4043 iter = tny_list_create_iterator (list);
4044 while (!tny_iterator_is_done (iter) && !found) {
4046 TnyHeaderFlags flags = 0;
4048 header = TNY_HEADER (tny_iterator_get_current (iter));
4050 flags = tny_header_get_flags (header);
4051 if (flags & TNY_HEADER_FLAG_CACHED)
4052 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
4055 g_object_unref (header);
4059 tny_iterator_next (iter);
4061 g_object_unref (iter);
4069 * Shows a confirmation dialog to the user when we're moving messages
4070 * from a remote server to the local storage. Returns the dialog
4071 * response. If it's other kind of movement then it always returns
4074 * This one is used by the next functions:
4075 * modest_ui_actions_on_paste - commented out
4076 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4079 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4080 TnyFolder *dest_folder,
4084 gint response = GTK_RESPONSE_OK;
4085 TnyAccount *account = NULL;
4086 TnyFolder *src_folder = NULL;
4087 TnyIterator *iter = NULL;
4088 TnyHeader *header = NULL;
4090 /* return with OK if the destination is a remote folder */
4091 if (modest_tny_folder_is_remote_folder (dest_folder))
4092 return GTK_RESPONSE_OK;
4094 /* Get source folder */
4095 iter = tny_list_create_iterator (headers);
4096 header = TNY_HEADER (tny_iterator_get_current (iter));
4098 src_folder = tny_header_get_folder (header);
4099 g_object_unref (header);
4101 g_object_unref (iter);
4103 /* if no src_folder, message may be an attahcment */
4104 if (src_folder == NULL)
4105 return GTK_RESPONSE_CANCEL;
4107 /* If the source is a local or MMC folder */
4108 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4109 g_object_unref (src_folder);
4110 return GTK_RESPONSE_OK;
4113 /* Get the account */
4114 account = tny_folder_get_account (src_folder);
4116 /* now if offline we ask the user */
4117 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4118 response = GTK_RESPONSE_OK;
4120 response = GTK_RESPONSE_CANCEL;
4123 g_object_unref (src_folder);
4124 g_object_unref (account);
4132 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
4134 MoveToHelper *helper = (MoveToHelper *) user_data;
4136 /* Note that the operation could have failed, in that case do
4138 if (modest_mail_operation_get_status (mail_op) ==
4139 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4141 GObject *object = modest_mail_operation_get_source (mail_op);
4142 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4143 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4145 if (!modest_msg_view_window_select_next_message (self))
4146 if (!modest_msg_view_window_select_previous_message (self))
4147 /* No more messages to view, so close this window */
4148 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4149 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4150 GtkWidget *header_view;
4152 GtkTreeSelection *sel;
4154 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4155 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4156 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4157 path = gtk_tree_row_reference_get_path (helper->reference);
4158 gtk_tree_selection_select_path (sel, path);
4159 gtk_tree_path_free (path);
4161 g_object_unref (object);
4164 /* Close the "Pasting" information banner */
4165 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4166 if (helper->reference != NULL)
4167 gtk_tree_row_reference_free (helper->reference);
4172 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4175 ModestWindow *main_window = NULL;
4176 GObject *win = NULL;
4177 const GError *error = NULL;
4178 const gchar *message = NULL;
4180 /* Get error message */
4181 error = modest_mail_operation_get_error (mail_op);
4182 if (error != NULL && error->message != NULL) {
4183 message = error->message;
4185 message = _("mail_in_ui_folder_move_target_error");
4188 /* Disable next automatic folder selection */
4189 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4190 FALSE); /* don't create */
4192 GtkWidget *folder_view = NULL;
4194 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4195 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4196 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4198 if (user_data && TNY_IS_FOLDER (user_data)) {
4199 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4200 TNY_FOLDER (user_data), FALSE);
4204 /* Show notification dialog */
4205 win = modest_mail_operation_get_source (mail_op);
4206 modest_platform_run_information_dialog ((GtkWindow *) win, message);
4208 g_object_unref (win);
4212 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4215 GObject *win = modest_mail_operation_get_source (mail_op);
4216 const GError *error = modest_mail_operation_get_error (mail_op);
4218 g_return_if_fail (error != NULL);
4219 if (error->message != NULL)
4220 g_printerr ("modest: %s\n", error->message);
4222 g_printerr ("modest: unkonw error on send&receive operation");
4224 /* Show error message */
4225 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4226 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4227 /* _CS("sfil_ib_unable_to_receive")); */
4229 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4230 /* _CS("sfil_ib_unable_to_send")); */
4231 g_object_unref (win);
4235 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4244 gint pending_purges = 0;
4245 gboolean some_purged = FALSE;
4246 ModestWindow *win = MODEST_WINDOW (user_data);
4247 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4249 /* If there was any error */
4250 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4251 modest_window_mgr_unregister_header (mgr, header);
4255 /* Once the message has been retrieved for purging, we check if
4256 * it's all ok for purging */
4258 parts = tny_simple_list_new ();
4259 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4260 iter = tny_list_create_iterator (parts);
4262 while (!tny_iterator_is_done (iter)) {
4264 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4265 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4266 if (tny_mime_part_is_purged (part))
4273 g_object_unref (part);
4275 tny_iterator_next (iter);
4277 g_object_unref (iter);
4280 if (pending_purges>0) {
4282 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4284 if (response == GTK_RESPONSE_OK) {
4285 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4286 iter = tny_list_create_iterator (parts);
4287 while (!tny_iterator_is_done (iter)) {
4290 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4291 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4292 tny_mime_part_set_purged (part);
4295 g_object_unref (part);
4297 tny_iterator_next (iter);
4300 tny_msg_rewrite_cache (msg);
4303 /* This string no longer exists, refer to NB#75415 for more info */
4304 /* modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged")); */
4306 g_object_unref (iter);
4308 modest_window_mgr_unregister_header (mgr, header);
4310 g_object_unref (parts);
4314 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4315 ModestMainWindow *win)
4317 GtkWidget *header_view;
4318 TnyList *header_list;
4321 TnyHeaderFlags flags;
4322 ModestWindow *msg_view_window = NULL;
4325 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4327 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4328 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4330 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4332 g_warning ("%s: no header selected", __FUNCTION__);
4336 if (tny_list_get_length (header_list) == 1) {
4337 iter = tny_list_create_iterator (header_list);
4338 header = TNY_HEADER (tny_iterator_get_current (iter));
4339 g_object_unref (iter);
4343 if (!header || !TNY_IS_HEADER(header)) {
4344 g_warning ("%s: header is not valid", __FUNCTION__);
4348 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4349 header, &msg_view_window);
4350 flags = tny_header_get_flags (header);
4351 if (!(flags & TNY_HEADER_FLAG_CACHED))
4354 if (msg_view_window != NULL)
4355 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4357 /* do nothing; uid was registered before, so window is probably on it's way */
4358 g_warning ("debug: header %p has already been registered", header);
4361 ModestMailOperation *mail_op = NULL;
4362 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
4363 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4364 modest_ui_actions_get_msgs_full_error_handler,
4366 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4367 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4369 g_object_unref (mail_op);
4372 g_object_unref (header);
4374 g_object_unref (header_list);
4378 * Utility function that transfer messages from both the main window
4379 * and the msg view window when using the "Move to" dialog
4382 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4385 TnyList *headers = NULL;
4386 TnyAccount *dst_account = NULL;
4387 const gchar *proto_str = NULL;
4388 gboolean dst_is_pop = FALSE;
4390 if (!TNY_IS_FOLDER (dst_folder)) {
4391 modest_platform_information_banner (GTK_WIDGET (win),
4393 _CS("ckdg_ib_unable_to_move_to_current_location"));
4397 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4398 proto_str = tny_account_get_proto (dst_account);
4400 /* tinymail will return NULL for local folders it seems */
4401 dst_is_pop = proto_str &&
4402 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4403 MODEST_PROTOCOL_STORE_POP);
4405 g_object_unref (dst_account);
4407 /* Get selected headers */
4408 headers = get_selected_headers (MODEST_WINDOW (win));
4410 g_warning ("%s: no headers selected", __FUNCTION__);
4416 modest_platform_information_banner (GTK_WIDGET (win),
4418 ngettext("mail_in_ui_folder_move_target_error",
4419 "mail_in_ui_folder_move_targets_error",
4420 tny_list_get_length (headers)));
4421 g_object_unref (headers);
4425 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4426 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4427 _CS("ckct_nw_pasting"));
4428 if (helper->banner != NULL) {
4429 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4430 gtk_widget_show (GTK_WIDGET(helper->banner));
4433 if (MODEST_IS_MAIN_WINDOW (win)) {
4434 GtkWidget *header_view =
4435 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4436 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4437 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4440 ModestMailOperation *mail_op =
4441 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4442 modest_ui_actions_move_folder_error_handler,
4444 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4447 modest_mail_operation_xfer_msgs (mail_op,
4449 TNY_FOLDER (dst_folder),
4454 g_object_unref (G_OBJECT (mail_op));
4455 g_object_unref (headers);
4459 * UI handler for the "Move to" action when invoked from the
4463 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4464 GtkWidget *folder_view,
4465 TnyFolderStore *dst_folder,
4466 ModestMainWindow *win)
4468 ModestHeaderView *header_view = NULL;
4469 ModestMailOperation *mail_op = NULL;
4470 TnyFolderStore *src_folder;
4471 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4473 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4475 /* Get the source folder */
4476 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4478 /* Get header view */
4479 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4481 /* Get folder or messages to transfer */
4482 if (gtk_widget_is_focus (folder_view)) {
4483 GtkTreeSelection *sel;
4484 gboolean do_xfer = TRUE;
4486 /* Allow only to transfer folders to the local root folder */
4487 if (TNY_IS_ACCOUNT (dst_folder) &&
4488 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4490 } else if (!TNY_IS_FOLDER (src_folder)) {
4491 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4493 } else if (!online && modest_tny_folder_store_is_remote(src_folder)) {
4494 guint num_headers = tny_folder_get_all_count(TNY_FOLDER (src_folder));
4495 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (src_folder));
4496 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4498 g_object_unref (account);
4502 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4503 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4504 _CS("ckct_nw_pasting"));
4505 if (helper->banner != NULL) {
4506 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4507 gtk_widget_show (GTK_WIDGET(helper->banner));
4509 /* Clean folder on header view before moving it */
4510 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4511 gtk_tree_selection_unselect_all (sel);
4513 /* Let gtk events run. We need that the folder
4514 view frees its reference to the source
4515 folder *before* issuing the mail operation
4516 so we need the signal handler of selection
4517 changed to happen before the mail
4519 while (gtk_events_pending ())
4520 gtk_main_iteration ();
4523 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4524 modest_ui_actions_move_folder_error_handler,
4526 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4529 /* Select *after* the changes */
4530 /* TODO: this function hangs UI after transfer */
4531 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4532 /* TNY_FOLDER (src_folder), TRUE); */
4534 modest_mail_operation_xfer_folder (mail_op,
4535 TNY_FOLDER (src_folder),
4540 /* Unref mail operation */
4541 g_object_unref (G_OBJECT (mail_op));
4543 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4544 gboolean do_xfer = TRUE;
4545 /* Ask for confirmation if the source folder is remote and we're not connected */
4546 if (!online && modest_tny_folder_store_is_remote(src_folder)) {
4547 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4548 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4549 guint num_headers = tny_list_get_length(headers);
4550 TnyAccount *account = get_account_from_header_list (headers);
4551 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4553 g_object_unref (account);
4555 g_object_unref(headers);
4557 if (do_xfer) /* Transfer messages */
4558 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4562 g_object_unref (src_folder);
4567 * UI handler for the "Move to" action when invoked from the
4568 * ModestMsgViewWindow
4571 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4572 TnyFolderStore *dst_folder,
4573 ModestMsgViewWindow *win)
4575 TnyHeader *header = NULL;
4576 TnyFolder *src_folder = NULL;
4577 TnyAccount *account = NULL;
4578 gboolean do_xfer = FALSE;
4580 /* Create header list */
4581 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4582 src_folder = TNY_FOLDER (tny_header_get_folder(header));
4583 g_object_unref (header);
4585 account = tny_folder_get_account (src_folder);
4586 if (!modest_tny_folder_store_is_remote(TNY_FOLDER_STORE(src_folder))) {
4587 /* Transfer if the source folder is local */
4589 } else if (remote_folder_is_pop(TNY_FOLDER_STORE(src_folder))) {
4590 /* Transfer if the source folder is POP (as it means
4591 * that the message is already downloaded) */
4593 } else if (connect_to_get_msg(MODEST_WINDOW(win), 1, account)) {
4594 /* Transfer after asking confirmation */
4599 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4601 g_object_unref (account);
4602 g_object_unref (src_folder);
4606 modest_ui_actions_on_move_to (GtkAction *action,
4609 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4611 TnyFolderStore *dst_folder = NULL;
4612 ModestMainWindow *main_window;
4614 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4615 MODEST_IS_MSG_VIEW_WINDOW (win));
4617 /* Get the main window if exists */
4618 if (MODEST_IS_MAIN_WINDOW (win))
4619 main_window = MODEST_MAIN_WINDOW (win);
4622 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4623 FALSE)); /* don't create */
4625 /* Get the folder view widget if exists */
4627 folder_view = modest_main_window_get_child_widget (main_window,
4628 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4632 /* Create and run the dialog */
4633 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4634 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4635 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4636 result = gtk_dialog_run (GTK_DIALOG(dialog));
4637 g_object_ref (tree_view);
4638 gtk_widget_destroy (dialog);
4640 if (result != GTK_RESPONSE_ACCEPT)
4643 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4644 /* Do window specific stuff */
4645 if (MODEST_IS_MAIN_WINDOW (win)) {
4646 modest_ui_actions_on_main_window_move_to (action,
4649 MODEST_MAIN_WINDOW (win));
4651 modest_ui_actions_on_msg_view_window_move_to (action,
4653 MODEST_MSG_VIEW_WINDOW (win));
4657 g_object_unref (dst_folder);
4661 * Calls #HeadersFunc for each header already selected in the main
4662 * window or the message currently being shown in the msg view window
4665 do_headers_action (ModestWindow *win,
4669 TnyList *headers_list = NULL;
4670 TnyIterator *iter = NULL;
4671 TnyHeader *header = NULL;
4672 TnyFolder *folder = NULL;
4675 headers_list = get_selected_headers (win);
4679 /* Get the folder */
4680 iter = tny_list_create_iterator (headers_list);
4681 header = TNY_HEADER (tny_iterator_get_current (iter));
4683 folder = tny_header_get_folder (header);
4684 g_object_unref (header);
4687 /* Call the function for each header */
4688 while (!tny_iterator_is_done (iter)) {
4689 header = TNY_HEADER (tny_iterator_get_current (iter));
4690 func (header, win, user_data);
4691 g_object_unref (header);
4692 tny_iterator_next (iter);
4695 /* Trick: do a poke status in order to speed up the signaling
4697 tny_folder_poke_status (folder);
4700 g_object_unref (folder);
4701 g_object_unref (iter);
4702 g_object_unref (headers_list);
4706 modest_ui_actions_view_attachment (GtkAction *action,
4707 ModestWindow *window)
4709 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4710 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4712 /* not supported window for this action */
4713 g_return_if_reached ();
4718 modest_ui_actions_save_attachments (GtkAction *action,
4719 ModestWindow *window)
4721 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4722 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4724 /* not supported window for this action */
4725 g_return_if_reached ();
4730 modest_ui_actions_remove_attachments (GtkAction *action,
4731 ModestWindow *window)
4733 if (MODEST_IS_MAIN_WINDOW (window)) {
4734 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4735 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4736 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4738 /* not supported window for this action */
4739 g_return_if_reached ();
4744 modest_ui_actions_on_settings (GtkAction *action,
4749 dialog = modest_platform_get_global_settings_dialog ();
4750 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4751 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4752 gtk_widget_show_all (dialog);
4754 gtk_dialog_run (GTK_DIALOG (dialog));
4756 gtk_widget_destroy (dialog);
4760 modest_ui_actions_on_help (GtkAction *action,
4763 const gchar *help_id;
4765 g_return_if_fail (action);
4766 g_return_if_fail (win && GTK_IS_WINDOW(win));
4768 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
4771 modest_platform_show_help (GTK_WINDOW (win), help_id);
4773 g_warning ("%s: no help for window %p", __FUNCTION__, win);
4777 retrieve_msg_contents_performer (gboolean canceled,
4779 GtkWindow *parent_window,
4780 TnyAccount *account,
4783 ModestMailOperation *mail_op;
4784 TnyList *headers = TNY_LIST (user_data);
4786 if (err || canceled) {
4787 /* Show an error ? */
4791 /* Create mail operation */
4792 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
4793 modest_ui_actions_get_msgs_full_error_handler,
4795 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4796 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4799 g_object_unref (mail_op);
4801 g_object_unref (headers);
4802 g_object_unref (account);
4806 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4807 ModestWindow *window)
4809 TnyList *headers = NULL;
4810 TnyAccount *account = NULL;
4811 TnyIterator *iter = NULL;
4812 TnyHeader *header = NULL;
4813 TnyFolder *folder = NULL;
4816 headers = get_selected_headers (window);
4820 /* Pick the account */
4821 iter = tny_list_create_iterator (headers);
4822 header = TNY_HEADER (tny_iterator_get_current (iter));
4823 folder = tny_header_get_folder (header);
4824 account = tny_folder_get_account (folder);
4825 g_object_unref (folder);
4826 g_object_unref (header);
4827 g_object_unref (iter);
4829 /* Connect and perform the message retrieval */
4830 modest_platform_connect_and_perform ((GtkWindow *) window,
4831 g_object_ref (account),
4832 retrieve_msg_contents_performer,
4833 g_object_ref (headers));
4836 g_object_unref (account);
4837 g_object_unref (headers);
4841 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4842 ModestWindow *window)
4844 g_return_if_fail (MODEST_IS_WINDOW (window));
4847 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4851 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4852 ModestWindow *window)
4854 g_return_if_fail (MODEST_IS_WINDOW (window));
4857 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4861 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4862 ModestWindow *window)
4864 g_return_if_fail (MODEST_IS_WINDOW (window));
4867 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4871 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4872 ModestWindow *window)
4874 g_return_if_fail (MODEST_IS_WINDOW (window));
4877 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4881 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4882 ModestWindow *window)
4884 g_return_if_fail (MODEST_IS_WINDOW (window));
4887 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4891 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4892 ModestWindow *window)
4894 g_return_if_fail (MODEST_IS_WINDOW (window));
4897 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4901 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4902 ModestWindow *window)
4904 g_return_if_fail (MODEST_IS_WINDOW (window));
4907 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4911 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4912 ModestWindow *window)
4914 g_return_if_fail (MODEST_IS_WINDOW (window));
4917 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4921 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4922 ModestWindow *window)
4924 g_return_if_fail (MODEST_IS_WINDOW (window));
4927 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4931 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4933 g_return_if_fail (MODEST_IS_WINDOW (window));
4936 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4940 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4942 g_return_if_fail (MODEST_IS_WINDOW (window));
4944 modest_platform_show_search_messages (GTK_WINDOW (window));
4948 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4950 g_return_if_fail (MODEST_IS_WINDOW (win));
4951 modest_platform_show_addressbook (GTK_WINDOW (win));
4956 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4957 ModestWindow *window)
4959 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4961 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4965 on_send_receive_finished (ModestMailOperation *mail_op,
4968 GtkWidget *header_view, *folder_view;
4969 TnyFolderStore *folder_store;
4970 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
4972 /* Set send/receive operation finished */
4973 modest_main_window_notify_send_receive_completed (main_win);
4975 /* Don't refresh the current folder if there were any errors */
4976 if (modest_mail_operation_get_status (mail_op) !=
4977 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4980 /* Refresh the current folder if we're viewing a window. We do
4981 this because the user won't be able to see the new mails in
4982 the selected folder after a Send&Receive because it only
4983 performs a poke_status, i.e, only the number of read/unread
4984 messages is updated, but the new headers are not
4986 folder_view = modest_main_window_get_child_widget (main_win,
4987 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4991 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4993 /* Do not need to refresh INBOX again because the
4994 update_account does it always automatically */
4995 if (folder_store && TNY_IS_FOLDER (folder_store) &&
4996 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
4997 ModestMailOperation *refresh_op;
4999 header_view = modest_main_window_get_child_widget (main_win,
5000 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5002 /* We do not need to set the contents style
5003 because it hasn't changed. We also do not
5004 need to save the widget status. Just force
5006 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5007 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5008 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5009 folder_refreshed_cb, main_win);
5010 g_object_unref (refresh_op);
5014 g_object_unref (folder_store);
5019 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5025 const gchar* server_name = NULL;
5026 TnyTransportAccount *server_account;
5027 gchar *message = NULL;
5029 /* Don't show anything if the user cancelled something */
5030 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
5033 /* Get the server name: */
5035 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5036 if (server_account) {
5037 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5039 g_object_unref (server_account);
5040 server_account = NULL;
5043 g_return_if_fail (server_name);
5045 /* Show the appropriate message text for the GError: */
5046 switch (err->code) {
5047 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
5048 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5050 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
5051 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5053 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
5054 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
5056 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
5057 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
5060 g_return_if_reached ();
5063 /* TODO if the username or the password where not defined we
5064 should show the Accounts Settings dialog or the Connection
5065 specific SMTP server window */
5067 modest_platform_run_information_dialog (NULL, message);
5072 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5077 ModestMainWindow *main_window = NULL;
5078 ModestWindowMgr *mgr = NULL;
5079 GtkWidget *folder_view = NULL, *header_view = NULL;
5080 TnyFolderStore *selected_folder = NULL;
5081 TnyFolderType folder_type;
5083 mgr = modest_runtime_get_window_mgr ();
5084 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
5085 FALSE));/* don't create */
5089 /* Check if selected folder is OUTBOX */
5090 folder_view = modest_main_window_get_child_widget (main_window,
5091 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5092 header_view = modest_main_window_get_child_widget (main_window,
5093 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5095 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5096 if (!TNY_IS_FOLDER (selected_folder))
5099 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5100 #if GTK_CHECK_VERSION(2, 8, 0)
5101 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
5102 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5103 GtkTreeViewColumn *tree_column;
5105 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5106 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5107 gtk_tree_view_column_queue_resize (tree_column);
5110 gtk_widget_queue_draw (header_view);
5115 if (selected_folder != NULL)
5116 g_object_unref (selected_folder);
5120 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5121 TnyAccount *account)
5123 ModestTransportStoreProtocol proto;
5124 const gchar *proto_name;
5125 gchar *error_note = NULL;
5127 proto_name = tny_account_get_proto (account);
5128 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
5131 case MODEST_PROTOCOL_STORE_POP:
5132 error_note = g_strdup_printf (_("emev_ni_ui_pop3_msg_connect_error"),
5133 tny_account_get_hostname (account));
5135 case MODEST_PROTOCOL_STORE_IMAP:
5136 error_note = g_strdup_printf (_("emev_ni_ui_imap_connect_server_error"),
5137 tny_account_get_hostname (account));
5139 case MODEST_PROTOCOL_STORE_MAILDIR:
5140 case MODEST_PROTOCOL_STORE_MBOX:
5141 error_note = g_strdup (_("emev_nc_mailbox_notavailable"));
5144 g_warning ("%s: This should not be reached", __FUNCTION__);
5148 modest_platform_run_information_dialog (parent_window, error_note);
5149 g_free (error_note);