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"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
49 #ifdef MODEST_PLATFORM_MAEMO
50 #include "maemo/modest-osso-state-saving.h"
51 #endif /* MODEST_PLATFORM_MAEMO */
53 #include "widgets/modest-ui-constants.h"
54 #include <widgets/modest-main-window.h>
55 #include <widgets/modest-msg-view-window.h>
56 #include <widgets/modest-account-view-window.h>
57 #include <widgets/modest-details-dialog.h>
58 #include <widgets/modest-attachments-view.h>
59 #include "widgets/modest-folder-view.h"
60 #include "widgets/modest-global-settings-dialog.h"
61 #include "modest-connection-specific-smtp-window.h"
62 #include "modest-account-mgr-helpers.h"
63 #include "modest-mail-operation.h"
64 #include "modest-text-utils.h"
66 #ifdef MODEST_HAVE_EASYSETUP
67 #include "easysetup/modest-easysetup-wizard.h"
68 #endif /* MODEST_HAVE_EASYSETUP */
70 #include <modest-widget-memory.h>
71 #include <tny-error.h>
72 #include <tny-simple-list.h>
73 #include <tny-msg-view.h>
74 #include <tny-device.h>
75 #include <tny-merge-folder.h>
77 #include <gtkhtml/gtkhtml.h>
79 typedef struct _GetMsgAsyncHelper {
81 ModestMailOperation *mail_op;
88 typedef enum _ReplyForwardAction {
94 typedef struct _ReplyForwardHelper {
95 guint reply_forward_type;
96 ReplyForwardAction action;
98 GtkWidget *parent_window;
103 * The do_headers_action uses this kind of functions to perform some
104 * action to each member of a list of headers
106 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
109 do_headers_action (ModestWindow *win,
114 static void open_msg_cb (ModestMailOperation *mail_op,
119 static void reply_forward_cb (ModestMailOperation *mail_op,
124 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
127 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
128 ModestMailOperationState *state,
134 run_account_setup_wizard (ModestWindow *win)
136 ModestEasysetupWizardDialog *wizard;
138 g_return_if_fail (MODEST_IS_WINDOW(win));
140 wizard = modest_easysetup_wizard_dialog_new ();
141 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
142 gtk_dialog_run (GTK_DIALOG (wizard));
143 gtk_widget_destroy (GTK_WIDGET (wizard));
148 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
151 const gchar *authors[] = {
152 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
155 about = gtk_about_dialog_new ();
156 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
157 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
158 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
159 _("Copyright (c) 2006, Nokia Corporation\n"
160 "All rights reserved."));
161 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
162 _("a modest e-mail client\n\n"
163 "design and implementation: Dirk-Jan C. Binnema\n"
164 "contributions from the fine people at KC and Ig\n"
165 "uses the tinymail email framework written by Philip van Hoof"));
166 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
167 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
169 gtk_dialog_run (GTK_DIALOG (about));
170 gtk_widget_destroy(about);
174 * Gets the list of currently selected messages. If the win is the
175 * main window, then it returns a newly allocated list of the headers
176 * selected in the header view. If win is the msg view window, then
177 * the value returned is a list with just a single header.
179 * The caller of this funcion must free the list.
182 get_selected_headers (ModestWindow *win)
184 if (MODEST_IS_MAIN_WINDOW(win)) {
185 GtkWidget *header_view;
187 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
188 MODEST_WIDGET_TYPE_HEADER_VIEW);
189 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
191 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
192 /* for MsgViewWindows, we simply return a list with one element */
194 TnyList *list = NULL;
196 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
197 if (header != NULL) {
198 list = tny_simple_list_new ();
199 tny_list_prepend (list, G_OBJECT(header));
200 g_object_unref (G_OBJECT(header));
210 headers_action_mark_as_read (TnyHeader *header,
214 TnyHeaderFlags flags;
216 g_return_if_fail (TNY_IS_HEADER(header));
218 flags = tny_header_get_flags (header);
219 if (flags & TNY_HEADER_FLAG_SEEN) return;
220 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
224 headers_action_mark_as_unread (TnyHeader *header,
228 TnyHeaderFlags flags;
230 g_return_if_fail (TNY_IS_HEADER(header));
232 flags = tny_header_get_flags (header);
233 if (flags & TNY_HEADER_FLAG_SEEN) {
234 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
240 headers_action_delete (TnyHeader *header,
244 ModestMailOperation *mail_op = NULL;
246 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
247 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
250 /* Always delete. TODO: Move to trash still not supported */
251 modest_mail_operation_remove_msg (mail_op, header, FALSE);
252 g_object_unref (G_OBJECT (mail_op));
256 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
258 TnyList *header_list = NULL;
259 TnyIterator *iter = NULL;
260 TnyHeader *header = NULL;
261 gchar *message = NULL;
265 ModestWindowMgr *mgr;
266 GtkWidget *header_view;
268 g_return_if_fail (MODEST_IS_WINDOW(win));
270 /* Check first if the header view has the focus */
271 if (MODEST_IS_MAIN_WINDOW (win)) {
272 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
273 MODEST_WIDGET_TYPE_HEADER_VIEW);
274 if (!gtk_widget_is_focus (header_view))
278 header_list = get_selected_headers (win);
279 if (!header_list) return;
281 /* Check if any of the headers is already opened, or in the process of being opened */
282 iter = tny_list_create_iterator (header_list);
284 mgr = modest_runtime_get_window_mgr ();
285 while (!tny_iterator_is_done (iter) && !found) {
286 header = TNY_HEADER (tny_iterator_get_current (iter));
287 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
288 g_object_unref (header);
289 tny_iterator_next (iter);
291 g_object_unref (iter);
296 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
297 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
299 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
303 g_object_unref (header_list);
308 if (tny_list_get_length(header_list) == 1) {
309 iter = tny_list_create_iterator (header_list);
310 header = TNY_HEADER (tny_iterator_get_current (iter));
311 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
312 g_object_unref (header);
313 g_object_unref (iter);
315 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
316 tny_list_get_length(header_list)), desc);
318 /* Confirmation dialog */
319 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
323 if (response == GTK_RESPONSE_OK) {
324 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
326 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
330 /* Remove each header */
331 do_headers_action (win, headers_action_delete, NULL);
333 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
334 gtk_widget_destroy (GTK_WIDGET(win));
338 /* Update toolbar dimming state */
339 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
344 g_object_unref (header_list);
349 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
351 #ifdef MODEST_PLATFORM_MAEMO
352 modest_osso_save_state();
353 #endif /* MODEST_PLATFORM_MAEMO */
355 /* FIXME: we need to cancel all actions/threads here,
362 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
365 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
367 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
368 /* gtk_widget_destroy (GTK_WIDGET (win)); */
369 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
370 /* gboolean ret_value; */
371 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
372 /* } else if (MODEST_IS_WINDOW (win)) { */
373 /* gtk_widget_destroy (GTK_WIDGET (win)); */
375 /* g_return_if_reached (); */
380 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
382 GtkClipboard *clipboard = NULL;
383 gchar *selection = NULL;
385 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
386 selection = gtk_clipboard_wait_for_text (clipboard);
388 /* Question: why is the clipboard being used here?
389 * It doesn't really make a lot of sense. */
393 modest_address_book_add_address (selection);
399 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
401 /* This is currently only implemented for Maemo */
402 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
403 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
404 run_account_setup_wizard (win);
407 /* Show the list of accounts: */
408 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
409 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
410 gtk_dialog_run (account_win);
411 gtk_widget_destroy (GTK_WIDGET(account_win));
414 GtkWidget *dialog, *label;
416 /* Create the widgets */
418 dialog = gtk_dialog_new_with_buttons ("Message",
420 GTK_DIALOG_DESTROY_WITH_PARENT,
424 label = gtk_label_new ("Hello World!");
426 /* Ensure that the dialog box is destroyed when the user responds. */
428 g_signal_connect_swapped (dialog, "response",
429 G_CALLBACK (gtk_widget_destroy),
432 /* Add the label, and show everything we've added to the dialog. */
434 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
436 gtk_widget_show_all (dialog);
437 #endif /* MODEST_PLATFORM_MAEMO */
441 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
443 ModestWindow *main_window = MODEST_WINDOW (user_data);
445 /* Save any changes. */
446 modest_connection_specific_smtp_window_save_server_accounts (
447 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
448 modest_window_get_active_account (main_window));
449 gtk_widget_destroy (GTK_WIDGET (window));
455 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
457 /* This is currently only implemented for Maemo,
458 * because it requires an API (libconic) to detect different connection
461 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
463 /* Create the window if necessary: */
464 const gchar *active_account_name = modest_window_get_active_account (win);
466 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
467 * or show the default account?
468 * If we show the default account then the account name should be shown in
469 * the window when we show it. */
470 if (!active_account_name) {
471 g_warning ("%s: No account is active.", __FUNCTION__);
475 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
476 modest_connection_specific_smtp_window_fill_with_connections (
477 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
478 modest_runtime_get_account_mgr(),
479 active_account_name);
481 /* Show the window: */
482 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
483 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
484 gtk_widget_show (specific_window);
486 /* Save changes when the window is hidden: */
487 g_signal_connect (specific_window, "hide",
488 G_CALLBACK (on_smtp_servers_window_hide), win);
489 #endif /* MODEST_PLATFORM_MAEMO */
493 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
495 ModestWindow *msg_win = NULL;
497 TnyFolder *folder = NULL;
498 gchar *account_name = NULL;
499 gchar *from_str = NULL;
500 /* GError *err = NULL; */
501 TnyAccount *account = NULL;
502 ModestWindowMgr *mgr;
503 gchar *signature = NULL, *blank_and_signature = NULL;
505 /* if there are no accounts yet, just show the wizard */
506 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
507 run_account_setup_wizard (win);
511 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
513 account_name = g_strdup (modest_window_get_active_account (win));
515 g_printerr ("modest: no account found\n");
519 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
521 TNY_ACCOUNT_TYPE_STORE);
523 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
527 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
529 g_printerr ("modest: failed get from string for '%s'\n", account_name);
533 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
534 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
535 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
536 MODEST_ACCOUNT_SIGNATURE, FALSE);
537 blank_and_signature = g_strconcat ("\n", signature, NULL);
540 blank_and_signature = g_strdup ("");
543 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
545 g_printerr ("modest: failed to create new msg\n");
549 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
551 g_printerr ("modest: failed to find Drafts folder\n");
556 /* Create and register edit window */
557 /* This is destroyed by TOOD. */
558 msg_win = modest_msg_edit_window_new (msg, account_name);
559 mgr = modest_runtime_get_window_mgr ();
560 modest_window_mgr_register_window (mgr, msg_win);
563 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
565 gtk_widget_show_all (GTK_WIDGET (msg_win));
568 g_free (account_name);
570 g_free (blank_and_signature);
572 g_object_unref (msg_win);
574 g_object_unref (G_OBJECT(account));
576 g_object_unref (G_OBJECT(msg));
578 g_object_unref (G_OBJECT(folder));
582 open_msg_cb (ModestMailOperation *mail_op,
587 ModestWindowMgr *mgr = NULL;
588 ModestWindow *parent_win = NULL;
589 ModestWindow *win = NULL;
590 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
591 gchar *account = NULL;
594 /* TODO: Show an error? (review the specs) */
598 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
599 folder = tny_header_get_folder (header);
601 /* Mark header as read */
602 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
605 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
607 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
609 /* Gets folder type (OUTBOX headers will be opened in edit window */
610 if (modest_tny_folder_is_local_folder (folder))
611 folder_type = modest_tny_folder_get_local_folder_type (folder);
613 /* If the header is in the drafts folder then open the editor,
614 else the message view window */
615 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
616 /* we cannot edit without a valid account... */
617 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
618 run_account_setup_wizard(parent_win);
621 win = modest_msg_edit_window_new (msg, account);
623 gchar *uid = modest_tny_folder_get_header_unique_id (header);
625 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
626 GtkWidget *header_view;
627 GtkTreeSelection *sel;
628 GList *sel_list = NULL;
631 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
632 MODEST_WIDGET_TYPE_HEADER_VIEW);
634 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
635 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
637 if (sel_list != NULL) {
638 GtkTreeRowReference *row_reference;
640 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
641 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
642 g_list_free (sel_list);
644 win = modest_msg_view_window_new_with_header_model (msg,
649 gtk_tree_row_reference_free (row_reference);
651 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
654 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
659 /* Register and show new window */
661 mgr = modest_runtime_get_window_mgr ();
662 modest_window_mgr_register_window (mgr, win);
663 g_object_unref (win);
664 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
665 gtk_widget_show_all (GTK_WIDGET(win));
668 /* Update toolbar dimming state */
669 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
670 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
676 g_object_unref (parent_win);
677 /* g_object_unref (msg); */
678 g_object_unref (folder);
682 * This function is the error handler of the
683 * modest_mail_operation_get_msgs_full operation
686 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
691 error = modest_mail_operation_get_error (mail_op);
692 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
693 GObject *win = modest_mail_operation_get_source (mail_op);
695 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
697 g_object_unref (win);
702 * This function is used by both modest_ui_actions_on_open and
703 * modest_ui_actions_on_header_activated. This way we always do the
704 * same when trying to open messages.
707 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
709 ModestWindowMgr *mgr = NULL;
710 TnyIterator *iter = NULL;
711 ModestMailOperation *mail_op1 = NULL;
712 ModestMailOperation *mail_op2 = NULL;
713 TnyList *not_opened_headers = NULL;
714 TnyList *not_opened_cached_headers = NULL;
715 TnyHeaderFlags flags;
717 /* Look if we already have a message view for each header. If
718 true, then remove the header from the list of headers to
720 mgr = modest_runtime_get_window_mgr ();
721 iter = tny_list_create_iterator (headers);
722 not_opened_headers = tny_simple_list_new ();
723 not_opened_cached_headers = tny_simple_list_new ();
724 while (!tny_iterator_is_done (iter)) {
726 ModestWindow *window;
730 header = TNY_HEADER (tny_iterator_get_current (iter));
731 flags = tny_header_get_flags (header);
734 found = modest_window_mgr_find_registered_header (mgr, header, &window);
736 /* Do not open again the message and present the
737 window to the user */
740 gtk_window_present (GTK_WINDOW (window));
742 /* the header has been registered already, we don't do
743 * anything but wait for the window to come up*/
744 g_warning ("debug: header %p already registered, waiting for window",
747 /* register the header before actually creating the window */
748 modest_window_mgr_register_header (mgr, header);
750 if (!(flags & TNY_HEADER_FLAG_CACHED))
751 tny_list_append (not_opened_headers, G_OBJECT (header));
752 /* Check if msg has already been retreived */
754 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
756 g_object_unref (header);
757 tny_iterator_next (iter);
760 /* Open each uncached message */
761 if (tny_list_get_length (not_opened_headers) > 0) {
762 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
764 modest_ui_actions_get_msgs_full_error_handler,
766 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
767 if (tny_list_get_length (not_opened_headers) > 1) {
768 modest_mail_operation_get_msgs_full (mail_op1,
774 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
775 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
776 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
777 g_object_unref (header);
778 g_object_unref (iter);
782 /* Open each cached message */
783 if (tny_list_get_length (not_opened_cached_headers) > 0) {
784 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
786 modest_ui_actions_get_msgs_full_error_handler,
788 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
789 if (tny_list_get_length (not_opened_cached_headers) > 1) {
790 modest_mail_operation_get_msgs_full (mail_op2,
796 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
797 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
798 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
799 g_object_unref (header);
800 g_object_unref (iter);
805 if (not_opened_headers != NULL)
806 g_object_unref (not_opened_headers);
807 if (not_opened_cached_headers != NULL)
808 g_object_unref (not_opened_cached_headers);
810 g_object_unref (iter);
811 if (mail_op1 != NULL)
812 g_object_unref (mail_op1);
813 if (mail_op2 != NULL)
814 g_object_unref (mail_op2);
818 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
823 headers = get_selected_headers (win);
828 _modest_ui_actions_open (headers, win);
830 g_object_unref(headers);
835 free_reply_forward_helper (gpointer data)
837 ReplyForwardHelper *helper;
839 helper = (ReplyForwardHelper *) data;
840 g_free (helper->account_name);
841 g_slice_free (ReplyForwardHelper, helper);
845 reply_forward_cb (ModestMailOperation *mail_op,
851 ReplyForwardHelper *rf_helper;
852 ModestWindow *msg_win = NULL;
853 ModestEditType edit_type;
855 TnyAccount *account = NULL;
856 ModestWindowMgr *mgr = NULL;
857 gchar *signature = NULL;
859 g_return_if_fail (user_data != NULL);
860 rf_helper = (ReplyForwardHelper *) user_data;
862 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
863 rf_helper->account_name);
864 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
865 rf_helper->account_name,
866 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
867 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
868 rf_helper->account_name,
869 MODEST_ACCOUNT_SIGNATURE, FALSE);
872 /* Create reply mail */
873 switch (rf_helper->action) {
876 modest_tny_msg_create_reply_msg (msg, from, signature,
877 rf_helper->reply_forward_type,
878 MODEST_TNY_MSG_REPLY_MODE_SENDER);
880 case ACTION_REPLY_TO_ALL:
882 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
883 MODEST_TNY_MSG_REPLY_MODE_ALL);
884 edit_type = MODEST_EDIT_TYPE_REPLY;
888 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
889 edit_type = MODEST_EDIT_TYPE_FORWARD;
892 g_return_if_reached ();
899 g_printerr ("modest: failed to create message\n");
903 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
904 rf_helper->account_name,
905 TNY_ACCOUNT_TYPE_STORE);
907 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
911 /* Create and register the windows */
912 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
913 mgr = modest_runtime_get_window_mgr ();
914 modest_window_mgr_register_window (mgr, msg_win);
916 if (rf_helper->parent_window != NULL) {
919 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
920 modest_window_set_zoom (msg_win, parent_zoom);
923 /* Show edit window */
924 gtk_widget_show_all (GTK_WIDGET (msg_win));
928 g_object_unref (msg_win);
930 g_object_unref (G_OBJECT (new_msg));
932 g_object_unref (G_OBJECT (account));
933 /* g_object_unref (msg); */
934 g_object_unref (header);
938 * Checks a list of headers. If any of them are not currently
939 * downloaded (CACHED) then it asks the user for permission to
942 * Returns FALSE if the user does not want to download the
943 * messages. Returns TRUE if the user allowed the download or if all
944 * of them are currently downloaded
947 download_uncached_messages (TnyList *header_list, GtkWindow *win)
951 gint uncached_messages = 0;
953 iter = tny_list_create_iterator (header_list);
954 while (!tny_iterator_is_done (iter)) {
956 TnyHeaderFlags flags;
958 header = TNY_HEADER (tny_iterator_get_current (iter));
959 flags = tny_header_get_flags (header);
960 /* TODO: is this the right flag?, it seems that some
961 headers that have been previously downloaded do not
963 if (! (flags & TNY_HEADER_FLAG_CACHED))
964 uncached_messages ++;
965 g_object_unref (header);
966 tny_iterator_next (iter);
968 g_object_unref (iter);
970 /* Ask for user permission to download the messages */
972 if (uncached_messages > 0) {
973 GtkResponseType response;
975 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
976 ngettext("mcen_nc_get_msg",
979 if (response == GTK_RESPONSE_CANCEL)
987 * Common code for the reply and forward actions
990 reply_forward (ReplyForwardAction action, ModestWindow *win)
992 ModestMailOperation *mail_op = NULL;
993 TnyList *header_list = NULL;
994 ReplyForwardHelper *rf_helper = NULL;
995 guint reply_forward_type;
996 gboolean continue_download;
998 g_return_if_fail (MODEST_IS_WINDOW(win));
1000 /* we need an account when editing */
1001 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1002 run_account_setup_wizard (win);
1006 header_list = get_selected_headers (win);
1010 /* Check that the messages have been previously downloaded */
1011 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1012 if (!continue_download) {
1013 g_object_unref (header_list);
1017 reply_forward_type =
1018 modest_conf_get_int (modest_runtime_get_conf (),
1019 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1021 /* We assume that we can only select messages of the
1022 same folder and that we reply all of them from the
1023 same account. In fact the interface currently only
1024 allows single selection */
1027 rf_helper = g_slice_new0 (ReplyForwardHelper);
1028 rf_helper->reply_forward_type = reply_forward_type;
1029 rf_helper->action = action;
1030 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1031 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1032 rf_helper->parent_window = GTK_WIDGET (win);
1033 if (!rf_helper->account_name)
1034 rf_helper->account_name =
1035 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1037 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1040 /* Get header and message. Do not free them here, the
1041 reply_forward_cb must do it */
1042 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1043 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1044 if (!msg || !header) {
1046 g_object_unref (msg);
1048 g_object_unref (header);
1049 g_printerr ("modest: no message found\n");
1052 reply_forward_cb (NULL, header, msg, rf_helper);
1054 /* Retrieve messages */
1055 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1057 modest_ui_actions_get_msgs_full_error_handler,
1059 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1060 modest_mail_operation_get_msgs_full (mail_op,
1064 free_reply_forward_helper);
1067 g_object_unref(mail_op);
1071 g_object_unref (header_list);
1075 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1077 g_return_if_fail (MODEST_IS_WINDOW(win));
1079 reply_forward (ACTION_REPLY, win);
1083 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1085 g_return_if_fail (MODEST_IS_WINDOW(win));
1087 reply_forward (ACTION_FORWARD, win);
1091 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1093 g_return_if_fail (MODEST_IS_WINDOW(win));
1095 reply_forward (ACTION_REPLY_TO_ALL, win);
1099 modest_ui_actions_on_next (GtkAction *action,
1100 ModestWindow *window)
1102 if (MODEST_IS_MAIN_WINDOW (window)) {
1103 GtkWidget *header_view;
1105 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1106 MODEST_WIDGET_TYPE_HEADER_VIEW);
1110 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1111 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1112 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1114 g_return_if_reached ();
1119 modest_ui_actions_on_prev (GtkAction *action,
1120 ModestWindow *window)
1122 g_return_if_fail (MODEST_IS_WINDOW(window));
1124 if (MODEST_IS_MAIN_WINDOW (window)) {
1125 GtkWidget *header_view;
1126 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1127 MODEST_WIDGET_TYPE_HEADER_VIEW);
1131 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1132 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1133 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1135 g_return_if_reached ();
1140 modest_ui_actions_on_sort (GtkAction *action,
1141 ModestWindow *window)
1143 g_return_if_fail (MODEST_IS_WINDOW(window));
1145 if (MODEST_IS_MAIN_WINDOW (window)) {
1146 GtkWidget *header_view;
1147 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1148 MODEST_WIDGET_TYPE_HEADER_VIEW);
1152 /* Show sorting dialog */
1153 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1158 new_messages_arrived (ModestMailOperation *self,
1162 if (new_messages == 0)
1165 modest_platform_on_new_msg ();
1169 * This function performs the send & receive required actions. The
1170 * window is used to create the mail operation. Typically it should
1171 * always be the main window, but we pass it as argument in order to
1175 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1177 gchar *acc_name = NULL;
1178 ModestMailOperation *mail_op;
1180 /* If no account name was provided then get the current account, and if
1181 there is no current account then pick the default one: */
1182 if (!account_name) {
1183 acc_name = g_strdup (modest_window_get_active_account(win));
1185 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1187 g_printerr ("modest: cannot get default account\n");
1191 acc_name = g_strdup (account_name);
1194 /* Set send/receive operation in progress */
1195 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1197 /* mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win)); */
1198 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
1200 modest_ui_actions_send_receive_error_handler,
1203 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1204 G_CALLBACK (_on_send_receive_progress_changed),
1207 /* Send & receive. */
1208 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1209 /* Receive and then send. The operation is tagged initially as
1210 a receive operation because the account update performs a
1211 receive and then a send. The operation changes its type
1212 internally, so the progress objects will receive the proper
1213 progress information */
1214 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1215 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1216 g_object_unref (G_OBJECT (mail_op));
1223 * Refreshes all accounts. This function will be used by automatic
1227 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1229 GSList *account_names, *iter;
1231 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1234 iter = account_names;
1236 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1237 iter = g_slist_next (iter);
1240 modest_account_mgr_free_account_names (account_names);
1241 account_names = NULL;
1245 * Handler of the click on Send&Receive button in the main toolbar
1248 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1250 /* Check if accounts exist */
1251 gboolean accounts_exist =
1252 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1254 /* If not, allow the user to create an account before trying to send/receive. */
1255 if (!accounts_exist)
1256 modest_ui_actions_on_accounts (NULL, win);
1258 /* Refresh the active account */
1259 modest_ui_actions_do_send_receive (NULL, win);
1264 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1267 GtkWidget *header_view;
1269 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1271 header_view = modest_main_window_get_child_widget (main_window,
1272 MODEST_WIDGET_TYPE_HEADER_VIEW);
1276 conf = modest_runtime_get_conf ();
1278 /* what is saved/restored is depending on the style; thus; we save with
1279 * old style, then update the style, and restore for this new style
1281 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1283 if (modest_header_view_get_style
1284 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1285 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1286 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1288 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1289 MODEST_HEADER_VIEW_STYLE_DETAILS);
1291 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1292 MODEST_CONF_HEADER_VIEW_KEY);
1297 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1299 ModestMainWindow *main_window)
1301 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1302 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1304 /* If no header has been selected then exit */
1309 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1310 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1312 /* Update Main window title */
1313 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1314 const gchar *subject = tny_header_get_subject (header);
1315 if (subject && strlen(subject) > 0)
1316 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1318 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1321 /* Update toolbar dimming state */
1322 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1326 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1328 ModestMainWindow *main_window)
1332 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1337 headers = tny_simple_list_new ();
1338 tny_list_prepend (headers, G_OBJECT (header));
1340 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1342 g_object_unref (headers);
1346 set_active_account_from_tny_account (TnyAccount *account,
1347 ModestWindow *window)
1349 const gchar *server_acc_name = tny_account_get_id (account);
1351 /* We need the TnyAccount provided by the
1352 account store because that is the one that
1353 knows the name of the Modest account */
1354 TnyAccount *modest_server_account = modest_server_account =
1355 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1356 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1359 const gchar *modest_acc_name =
1360 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1361 modest_window_set_active_account (window, modest_acc_name);
1362 g_object_unref (modest_server_account);
1367 folder_refreshed_cb (const GObject *obj,
1371 ModestMainWindow *win = NULL;
1372 GtkWidget *header_view;
1374 g_return_if_fail (TNY_IS_FOLDER (folder));
1376 win = MODEST_MAIN_WINDOW (user_data);
1378 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1380 /* Check if folder is empty and set headers view contents style */
1381 if (tny_folder_get_all_count (folder) == 0) {
1382 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1383 modest_main_window_set_contents_style (win,
1384 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1386 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1391 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1392 TnyFolderStore *folder_store,
1394 ModestMainWindow *main_window)
1397 GtkWidget *header_view;
1399 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1401 header_view = modest_main_window_get_child_widget(main_window,
1402 MODEST_WIDGET_TYPE_HEADER_VIEW);
1406 conf = modest_runtime_get_conf ();
1408 if (TNY_IS_ACCOUNT (folder_store)) {
1410 /* Update active account */
1411 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1412 /* Show account details */
1413 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1416 if (TNY_IS_FOLDER (folder_store) && selected) {
1418 /* Update the active account */
1419 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1421 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1422 g_object_unref (account);
1426 /* Set the header style by default, it could
1427 be changed later by the refresh callback to
1429 modest_main_window_set_contents_style (main_window,
1430 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1432 /* Set folder on header view. This function
1433 will call tny_folder_refresh_async so we
1434 pass a callback that will be called when
1435 finished. We use that callback to set the
1436 empty view if there are no messages */
1437 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1438 TNY_FOLDER (folder_store),
1439 folder_refreshed_cb,
1442 /* Restore configuration. We need to do this
1443 *after* the set_folder because the widget
1444 memory asks the header view about its
1446 modest_widget_memory_restore (modest_runtime_get_conf (),
1447 G_OBJECT(header_view),
1448 MODEST_CONF_HEADER_VIEW_KEY);
1450 /* Update the active account */
1451 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1452 /* Save only if we're seeing headers */
1453 if (modest_main_window_get_contents_style (main_window) ==
1454 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1455 modest_widget_memory_save (conf, G_OBJECT (header_view),
1456 MODEST_CONF_HEADER_VIEW_KEY);
1457 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1461 /* Update toolbar dimming state */
1462 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1466 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1473 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1475 online = tny_device_is_online (modest_runtime_get_device());
1478 /* already online -- the item is simply not there... */
1479 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1481 GTK_MESSAGE_WARNING,
1483 _("The %s you selected cannot be found"),
1485 gtk_dialog_run (GTK_DIALOG(dialog));
1487 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1491 GTK_RESPONSE_REJECT,
1493 GTK_RESPONSE_ACCEPT,
1495 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1496 "Do you want to get online?"), item);
1497 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1498 gtk_label_new (txt), FALSE, FALSE, 0);
1499 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1502 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1503 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1504 // modest_platform_connect_and_wait ();
1507 gtk_widget_destroy (dialog);
1511 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1514 /* g_message ("%s %s", __FUNCTION__, link); */
1519 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1522 modest_platform_activate_uri (link);
1526 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1529 modest_platform_show_uri_popup (link);
1533 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1536 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1540 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1541 const gchar *address,
1544 /* g_message ("%s %s", __FUNCTION__, address); */
1548 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1550 TnyTransportAccount *transport_account;
1551 ModestMailOperation *mail_operation;
1553 gchar *account_name, *from;
1554 ModestAccountMgr *account_mgr;
1555 gchar *info_text = NULL;
1557 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1559 data = modest_msg_edit_window_get_msg_data (edit_window);
1561 account_mgr = modest_runtime_get_account_mgr();
1562 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1564 account_name = modest_account_mgr_get_default_account (account_mgr);
1565 if (!account_name) {
1566 g_printerr ("modest: no account found\n");
1567 modest_msg_edit_window_free_msg_data (edit_window, data);
1571 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1572 account_name = g_strdup (data->account_name);
1576 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1577 (modest_runtime_get_account_store(),
1579 TNY_ACCOUNT_TYPE_TRANSPORT));
1580 if (!transport_account) {
1581 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1582 g_free (account_name);
1583 modest_msg_edit_window_free_msg_data (edit_window, data);
1586 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1588 /* Create the mail operation */
1589 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1590 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1592 modest_mail_operation_save_to_drafts (mail_operation,
1603 data->priority_flags);
1606 g_free (account_name);
1607 g_object_unref (G_OBJECT (transport_account));
1608 g_object_unref (G_OBJECT (mail_operation));
1610 modest_msg_edit_window_free_msg_data (edit_window, data);
1612 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1613 modest_platform_information_banner (NULL, NULL, info_text);
1617 /* For instance, when clicking the Send toolbar button when editing a message: */
1619 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1621 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1623 if (!modest_msg_edit_window_check_names (edit_window))
1626 /* FIXME: Code added just for testing. The final version will
1627 use the send queue provided by tinymail and some
1629 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1630 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1632 account_name = modest_account_mgr_get_default_account (account_mgr);
1634 if (!account_name) {
1635 g_printerr ("modest: no account found\n");
1639 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1641 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1642 account_name = g_strdup (data->account_name);
1645 /* Get the currently-active transport account for this modest account: */
1646 TnyTransportAccount *transport_account =
1647 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1648 (modest_runtime_get_account_store(),
1650 if (!transport_account) {
1651 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1652 g_free (account_name);
1653 modest_msg_edit_window_free_msg_data (edit_window, data);
1657 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1659 /* mail content checks and dialogs */
1660 if (data->subject == NULL || data->subject[0] == '\0') {
1661 GtkResponseType response;
1662 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1663 _("mcen_nc_subject_is_empty_send"));
1664 if (response == GTK_RESPONSE_CANCEL) {
1665 g_free (account_name);
1670 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1671 GtkResponseType response;
1672 gchar *note_message;
1673 gchar *note_subject = data->subject;
1674 if (note_subject == NULL || note_subject[0] == '\0')
1675 note_subject = _("mail_va_no_subject");
1676 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1677 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1679 g_free (note_message);
1680 if (response == GTK_RESPONSE_CANCEL) {
1681 g_free (account_name);
1686 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1688 /* Create the mail operation */
1689 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1690 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1692 modest_mail_operation_send_new_mail (mail_operation,
1703 data->priority_flags);
1707 g_free (account_name);
1708 g_object_unref (G_OBJECT (transport_account));
1709 g_object_unref (G_OBJECT (mail_operation));
1711 modest_msg_edit_window_free_msg_data (edit_window, data);
1712 modest_msg_edit_window_set_sent (edit_window, TRUE);
1714 /* Save settings and close the window: */
1715 gtk_widget_destroy (GTK_WIDGET (edit_window));
1719 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1720 ModestMsgEditWindow *window)
1722 ModestMsgEditFormatState *format_state = NULL;
1724 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1725 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1727 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1730 format_state = modest_msg_edit_window_get_format_state (window);
1731 g_return_if_fail (format_state != NULL);
1733 format_state->bold = gtk_toggle_action_get_active (action);
1734 modest_msg_edit_window_set_format_state (window, format_state);
1735 g_free (format_state);
1740 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1741 ModestMsgEditWindow *window)
1743 ModestMsgEditFormatState *format_state = NULL;
1745 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1746 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1748 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1751 format_state = modest_msg_edit_window_get_format_state (window);
1752 g_return_if_fail (format_state != NULL);
1754 format_state->italics = gtk_toggle_action_get_active (action);
1755 modest_msg_edit_window_set_format_state (window, format_state);
1756 g_free (format_state);
1761 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1762 ModestMsgEditWindow *window)
1764 ModestMsgEditFormatState *format_state = NULL;
1766 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1767 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1769 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1772 format_state = modest_msg_edit_window_get_format_state (window);
1773 g_return_if_fail (format_state != NULL);
1775 format_state->bullet = gtk_toggle_action_get_active (action);
1776 modest_msg_edit_window_set_format_state (window, format_state);
1777 g_free (format_state);
1782 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1783 GtkRadioAction *selected,
1784 ModestMsgEditWindow *window)
1786 ModestMsgEditFormatState *format_state = NULL;
1787 GtkJustification value;
1789 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1791 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1794 value = gtk_radio_action_get_current_value (selected);
1796 format_state = modest_msg_edit_window_get_format_state (window);
1797 g_return_if_fail (format_state != NULL);
1799 format_state->justification = value;
1800 modest_msg_edit_window_set_format_state (window, format_state);
1801 g_free (format_state);
1805 modest_ui_actions_on_select_editor_color (GtkAction *action,
1806 ModestMsgEditWindow *window)
1808 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1809 g_return_if_fail (GTK_IS_ACTION (action));
1811 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1814 modest_msg_edit_window_select_color (window);
1818 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1819 ModestMsgEditWindow *window)
1821 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1822 g_return_if_fail (GTK_IS_ACTION (action));
1824 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1827 modest_msg_edit_window_select_background_color (window);
1831 modest_ui_actions_on_insert_image (GtkAction *action,
1832 ModestMsgEditWindow *window)
1834 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1835 g_return_if_fail (GTK_IS_ACTION (action));
1837 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1840 modest_msg_edit_window_insert_image (window);
1844 modest_ui_actions_on_attach_file (GtkAction *action,
1845 ModestMsgEditWindow *window)
1847 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1848 g_return_if_fail (GTK_IS_ACTION (action));
1850 modest_msg_edit_window_attach_file (window);
1854 modest_ui_actions_on_remove_attachments (GtkAction *action,
1855 ModestMsgEditWindow *window)
1857 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1858 g_return_if_fail (GTK_IS_ACTION (action));
1860 modest_msg_edit_window_remove_attachments (window, NULL);
1864 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1866 TnyFolderStore *parent_folder;
1867 GtkWidget *folder_view;
1869 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1871 folder_view = modest_main_window_get_child_widget (main_window,
1872 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1876 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1878 if (parent_folder) {
1879 gboolean finished = FALSE;
1881 gchar *folder_name = NULL, *suggested_name = NULL;
1883 /* Run the new folder dialog */
1885 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1890 if (result == GTK_RESPONSE_REJECT) {
1893 ModestMailOperation *mail_op;
1894 TnyFolder *new_folder = NULL;
1896 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1897 G_OBJECT(main_window));
1898 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1900 new_folder = modest_mail_operation_create_folder (mail_op,
1902 (const gchar *) folder_name);
1904 g_object_unref (new_folder);
1907 g_object_unref (mail_op);
1909 g_free (folder_name);
1913 g_object_unref (parent_folder);
1918 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1921 GObject *win = modest_mail_operation_get_source (mail_op);
1923 /* TODO: what should we do in case of this error ? */
1924 g_warning ("Invalid folder name");
1926 g_object_unref (win);
1930 modest_ui_actions_on_rename_folder (GtkAction *action,
1931 ModestMainWindow *main_window)
1933 TnyFolderStore *folder;
1934 GtkWidget *folder_view;
1935 GtkWidget *header_view;
1937 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1939 folder_view = modest_main_window_get_child_widget (main_window,
1940 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1944 header_view = modest_main_window_get_child_widget (main_window,
1945 MODEST_WIDGET_TYPE_HEADER_VIEW);
1950 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1952 if (folder && TNY_IS_FOLDER (folder)) {
1955 const gchar *current_name;
1957 current_name = tny_folder_get_name (TNY_FOLDER (folder));
1958 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
1959 current_name, &folder_name);
1961 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
1962 ModestMailOperation *mail_op;
1965 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
1966 G_OBJECT(main_window),
1967 modest_ui_actions_rename_folder_error_handler,
1971 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1974 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
1976 modest_mail_operation_rename_folder (mail_op,
1977 TNY_FOLDER (folder),
1978 (const gchar *) folder_name);
1980 g_object_unref (mail_op);
1981 g_free (folder_name);
1983 g_object_unref (folder);
1988 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1991 GObject *win = modest_mail_operation_get_source (mail_op);
1993 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1994 _("mail_in_ui_folder_delete_error"));
1995 g_object_unref (win);
1999 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2001 TnyFolderStore *folder;
2002 GtkWidget *folder_view;
2006 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2008 folder_view = modest_main_window_get_child_widget (main_window,
2009 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2013 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2015 /* Show an error if it's an account */
2016 if (!TNY_IS_FOLDER (folder)) {
2017 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2018 _("mail_in_ui_folder_delete_error"));
2023 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2024 tny_folder_get_name (TNY_FOLDER (folder)));
2025 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2026 (const gchar *) message);
2029 if (response == GTK_RESPONSE_OK) {
2030 ModestMailOperation *mail_op =
2031 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2032 G_OBJECT(main_window),
2033 modest_ui_actions_delete_folder_error_handler,
2036 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2038 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2039 g_object_unref (G_OBJECT (mail_op));
2042 g_object_unref (G_OBJECT (folder));
2046 modest_ui_actions_on_delete_folder (GtkAction *action,
2047 ModestMainWindow *main_window)
2049 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2051 delete_folder (main_window, FALSE);
2055 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2057 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2059 delete_folder (main_window, TRUE);
2063 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2064 const gchar* server_account_name,
2069 ModestMainWindow *main_window)
2071 g_return_if_fail(server_account_name);
2072 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2074 /* Initalize output parameters: */
2081 #ifdef MODEST_PLATFORM_MAEMO
2082 /* Maemo uses a different (awkward) button order,
2083 * It should probably just use gtk_alternative_dialog_button_order ().
2085 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2089 GTK_RESPONSE_ACCEPT,
2091 GTK_RESPONSE_REJECT,
2094 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2098 GTK_RESPONSE_REJECT,
2100 GTK_RESPONSE_ACCEPT,
2102 #endif /* MODEST_PLATFORM_MAEMO */
2104 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2106 gchar *server_name = modest_server_account_get_hostname (
2107 modest_runtime_get_account_mgr(), server_account_name);
2108 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2109 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2114 /* This causes a warning because the logical ID has no %s in it,
2115 * though the translation does, but there is not much we can do about that: */
2116 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2117 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2120 g_free (server_name);
2124 gchar *initial_username = modest_server_account_get_username (
2125 modest_runtime_get_account_mgr(), server_account_name);
2127 GtkWidget *entry_username = gtk_entry_new ();
2128 if (initial_username)
2129 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2130 /* Dim this if a connection has ever succeeded with this username,
2131 * as per the UI spec: */
2132 const gboolean username_known =
2133 modest_server_account_get_username_has_succeeded(
2134 modest_runtime_get_account_mgr(), server_account_name);
2135 gtk_widget_set_sensitive (entry_username, !username_known);
2137 #ifdef MODEST_PLATFORM_MAEMO
2138 /* Auto-capitalization is the default, so let's turn it off: */
2139 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2141 /* Create a size group to be used by all captions.
2142 * Note that HildonCaption does not create a default size group if we do not specify one.
2143 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2144 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2146 GtkWidget *caption = hildon_caption_new (sizegroup,
2147 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2148 gtk_widget_show (entry_username);
2149 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2150 FALSE, FALSE, MODEST_MARGIN_HALF);
2151 gtk_widget_show (caption);
2153 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2155 #endif /* MODEST_PLATFORM_MAEMO */
2158 GtkWidget *entry_password = gtk_entry_new ();
2159 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2160 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2162 #ifdef MODEST_PLATFORM_MAEMO
2163 /* Auto-capitalization is the default, so let's turn it off: */
2164 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2165 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2167 caption = hildon_caption_new (sizegroup,
2168 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2169 gtk_widget_show (entry_password);
2170 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2171 FALSE, FALSE, MODEST_MARGIN_HALF);
2172 gtk_widget_show (caption);
2173 g_object_unref (sizegroup);
2175 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2177 #endif /* MODEST_PLATFORM_MAEMO */
2179 /* This is not in the Maemo UI spec:
2180 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2181 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2185 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2187 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2189 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2191 modest_server_account_set_username (
2192 modest_runtime_get_account_mgr(), server_account_name,
2195 const gboolean username_was_changed =
2196 (strcmp (*username, initial_username) != 0);
2197 if (username_was_changed) {
2198 g_warning ("%s: tinymail does not yet support changing the "
2199 "username in the get_password() callback.\n", __FUNCTION__);
2204 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2206 /* We do not save the password in the configuration,
2207 * because this function is only called for passwords that should
2208 * not be remembered:
2209 modest_server_account_set_password (
2210 modest_runtime_get_account_mgr(), server_account_name,
2229 /* This is not in the Maemo UI spec:
2230 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2236 gtk_widget_destroy (dialog);
2238 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2242 modest_ui_actions_on_cut (GtkAction *action,
2243 ModestWindow *window)
2245 GtkWidget *focused_widget;
2247 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2248 if (GTK_IS_EDITABLE (focused_widget)) {
2249 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2250 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2251 GtkTextBuffer *buffer;
2252 GtkClipboard *clipboard;
2254 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2255 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2256 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2257 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2258 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2259 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2260 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2265 modest_ui_actions_on_copy (GtkAction *action,
2266 ModestWindow *window)
2268 GtkClipboard *clipboard;
2269 GtkWidget *focused_widget;
2271 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2272 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2274 if (GTK_IS_LABEL (focused_widget)) {
2275 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2276 } else if (GTK_IS_EDITABLE (focused_widget)) {
2277 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2278 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2279 GtkTextBuffer *buffer;
2280 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2281 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2282 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2283 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2284 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2285 TnyIterator *iter = tny_list_create_iterator (header_list);
2286 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2287 TnyFolder *folder = tny_header_get_folder (header);
2288 TnyAccount *account = tny_folder_get_account (folder);
2289 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2290 /* If it's POP then ask */
2291 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2292 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2293 g_object_unref (account);
2294 g_object_unref (folder);
2295 g_object_unref (header);
2296 g_object_unref (iter);
2298 /* Check that the messages have been previously downloaded */
2299 gboolean continue_download = TRUE;
2301 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2302 if (continue_download)
2303 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2304 g_object_unref (header_list);
2305 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2306 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2309 /* Show information banner */
2310 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2315 modest_ui_actions_on_undo (GtkAction *action,
2316 ModestWindow *window)
2318 ModestEmailClipboard *clipboard = NULL;
2320 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2321 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2322 } if (MODEST_IS_MAIN_WINDOW (window)) {
2323 /* Clear clipboard source */
2324 clipboard = modest_runtime_get_email_clipboard ();
2325 modest_email_clipboard_clear (clipboard);
2328 g_return_if_reached ();
2333 modest_ui_actions_on_paste (GtkAction *action,
2334 ModestWindow *window)
2336 GtkWidget *focused_widget;
2337 ModestMailOperation *mail_op = NULL;
2339 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2340 if (GTK_IS_EDITABLE (focused_widget)) {
2341 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2342 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2343 GtkTextBuffer *buffer;
2344 GtkClipboard *clipboard;
2346 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2347 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2348 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2349 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2350 ModestEmailClipboard *clipboard = NULL;
2351 TnyFolder *src_folder = NULL;
2352 TnyFolderStore *folder_store = NULL;
2353 TnyList *data = NULL;
2354 gboolean delete = FALSE;
2356 /* Check clipboard source */
2357 clipboard = modest_runtime_get_email_clipboard ();
2358 if (modest_email_clipboard_cleared (clipboard))
2361 /* Get elements to paste */
2362 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2364 /* Create a new mail operation */
2365 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2366 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2369 /* Get destination folder */
2370 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2372 /* transfer messages */
2374 modest_mail_operation_xfer_msgs (mail_op,
2376 TNY_FOLDER (folder_store),
2381 } else if (src_folder != NULL) {
2382 modest_mail_operation_xfer_folder (mail_op,
2390 g_object_unref (data);
2391 if (src_folder != NULL)
2392 g_object_unref (src_folder);
2393 if (folder_store != NULL)
2394 g_object_unref (folder_store);
2399 modest_ui_actions_on_select_all (GtkAction *action,
2400 ModestWindow *window)
2402 GtkWidget *focused_widget;
2404 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2405 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2406 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2407 } else if (GTK_IS_LABEL (focused_widget)) {
2408 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2409 } else if (GTK_IS_EDITABLE (focused_widget)) {
2410 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2411 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2412 GtkTextBuffer *buffer;
2413 GtkTextIter start, end;
2415 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2416 gtk_text_buffer_get_start_iter (buffer, &start);
2417 gtk_text_buffer_get_end_iter (buffer, &end);
2418 gtk_text_buffer_select_range (buffer, &start, &end);
2419 } else if (GTK_IS_HTML (focused_widget)) {
2420 gtk_html_select_all (GTK_HTML (focused_widget));
2421 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2422 GtkWidget *header_view = focused_widget;
2423 GtkTreeSelection *selection = NULL;
2425 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2426 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2427 MODEST_WIDGET_TYPE_HEADER_VIEW);
2429 /* Select all messages */
2430 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2431 gtk_tree_selection_select_all (selection);
2433 /* Set focuse on header view */
2434 gtk_widget_grab_focus (header_view);
2440 modest_ui_actions_on_mark_as_read (GtkAction *action,
2441 ModestWindow *window)
2443 g_return_if_fail (MODEST_IS_WINDOW(window));
2445 /* Mark each header as read */
2446 do_headers_action (window, headers_action_mark_as_read, NULL);
2450 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2451 ModestWindow *window)
2453 g_return_if_fail (MODEST_IS_WINDOW(window));
2455 /* Mark each header as read */
2456 do_headers_action (window, headers_action_mark_as_unread, NULL);
2460 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2461 GtkRadioAction *selected,
2462 ModestWindow *window)
2466 value = gtk_radio_action_get_current_value (selected);
2467 if (MODEST_IS_WINDOW (window)) {
2468 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2472 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2473 GtkRadioAction *selected,
2474 ModestWindow *window)
2476 TnyHeaderFlags flags;
2477 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2479 flags = gtk_radio_action_get_current_value (selected);
2480 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2483 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2484 GtkRadioAction *selected,
2485 ModestWindow *window)
2489 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2491 file_format = gtk_radio_action_get_current_value (selected);
2492 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2497 modest_ui_actions_on_zoom_plus (GtkAction *action,
2498 ModestWindow *window)
2500 g_return_if_fail (MODEST_IS_WINDOW (window));
2502 modest_window_zoom_plus (MODEST_WINDOW (window));
2506 modest_ui_actions_on_zoom_minus (GtkAction *action,
2507 ModestWindow *window)
2509 g_return_if_fail (MODEST_IS_WINDOW (window));
2511 modest_window_zoom_minus (MODEST_WINDOW (window));
2515 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2516 ModestWindow *window)
2518 ModestWindowMgr *mgr;
2519 gboolean fullscreen, active;
2520 g_return_if_fail (MODEST_IS_WINDOW (window));
2522 mgr = modest_runtime_get_window_mgr ();
2524 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2525 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2527 if (active != fullscreen) {
2528 modest_window_mgr_set_fullscreen_mode (mgr, active);
2529 gtk_window_present (GTK_WINDOW (window));
2534 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2535 ModestWindow *window)
2537 ModestWindowMgr *mgr;
2538 gboolean fullscreen;
2540 g_return_if_fail (MODEST_IS_WINDOW (window));
2542 mgr = modest_runtime_get_window_mgr ();
2543 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2544 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2546 gtk_window_present (GTK_WINDOW (window));
2550 * Used by modest_ui_actions_on_details to call do_headers_action
2553 headers_action_show_details (TnyHeader *header,
2554 ModestWindow *window,
2561 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2564 gtk_widget_show_all (dialog);
2565 gtk_dialog_run (GTK_DIALOG (dialog));
2567 gtk_widget_destroy (dialog);
2571 * Show the folder details in a ModestDetailsDialog widget
2574 show_folder_details (TnyFolder *folder,
2580 dialog = modest_details_dialog_new_with_folder (window, folder);
2583 gtk_widget_show_all (dialog);
2584 gtk_dialog_run (GTK_DIALOG (dialog));
2586 gtk_widget_destroy (dialog);
2590 * Show the header details in a ModestDetailsDialog widget
2593 modest_ui_actions_on_details (GtkAction *action,
2596 TnyList * headers_list;
2600 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2603 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2606 g_object_unref (msg);
2608 headers_list = get_selected_headers (win);
2612 iter = tny_list_create_iterator (headers_list);
2614 header = TNY_HEADER (tny_iterator_get_current (iter));
2615 headers_action_show_details (header, win, NULL);
2616 g_object_unref (header);
2618 g_object_unref (iter);
2619 g_object_unref (headers_list);
2621 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2622 GtkWidget *folder_view, *header_view;
2624 /* Check which widget has the focus */
2625 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2626 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2627 if (gtk_widget_is_focus (folder_view)) {
2628 TnyFolderStore *folder_store
2629 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2630 if (!folder_store) {
2631 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2634 /* Show only when it's a folder */
2635 /* This function should not be called for account items,
2636 * because we dim the menu item for them. */
2637 if (TNY_IS_FOLDER (folder_store)) {
2638 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2641 g_object_unref (folder_store);
2644 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2645 MODEST_WIDGET_TYPE_HEADER_VIEW);
2646 /* Show details of each header */
2647 do_headers_action (win, headers_action_show_details, header_view);
2653 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2654 ModestMsgEditWindow *window)
2656 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2658 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2662 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2663 ModestMsgEditWindow *window)
2665 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2667 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2671 modest_ui_actions_toggle_folders_view (GtkAction *action,
2672 ModestMainWindow *main_window)
2676 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2678 conf = modest_runtime_get_conf ();
2680 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2681 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2683 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2687 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2688 ModestWindow *window)
2690 gboolean active, fullscreen = FALSE;
2691 ModestWindowMgr *mgr;
2693 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2695 /* Check if we want to toggle the toolbar vuew in fullscreen
2697 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2698 "ViewShowToolbarFullScreen")) {
2702 /* Toggle toolbar */
2703 mgr = modest_runtime_get_window_mgr ();
2704 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2708 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2709 ModestMsgEditWindow *window)
2711 modest_msg_edit_window_select_font (window);
2715 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2716 const gchar *display_name,
2719 /* Do not change the application name if the widget has not
2720 the focus. This callback could be called even if the folder
2721 view has not the focus, because the handled signal could be
2722 emitted when the folder view is redrawn */
2723 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2725 gtk_window_set_title (window, display_name);
2727 gtk_window_set_title (window, " ");
2732 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2734 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2735 modest_msg_edit_window_select_contacts (window);
2739 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2741 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2742 modest_msg_edit_window_check_names (window);
2747 create_move_to_dialog (ModestWindow *win,
2748 GtkWidget *folder_view,
2749 GtkWidget **tree_view)
2751 GtkWidget *dialog, *scroll;
2753 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2755 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2757 GTK_RESPONSE_ACCEPT,
2759 GTK_RESPONSE_REJECT,
2762 /* Create scrolled window */
2763 scroll = gtk_scrolled_window_new (NULL, NULL);
2764 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2765 GTK_POLICY_AUTOMATIC,
2766 GTK_POLICY_AUTOMATIC);
2768 /* Create folder view */
2769 *tree_view = modest_platform_create_folder_view (NULL);
2771 /* It could happen that we're trying to move a message from a
2772 window (msg window for example) after the main window was
2773 closed, so we can not just get the model of the folder
2775 if (MODEST_IS_FOLDER_VIEW (folder_view))
2776 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2777 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2779 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2780 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2782 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2784 /* Add scroll to dialog */
2785 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2786 scroll, FALSE, FALSE, 0);
2788 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2790 /* Select INBOX or local account */
2791 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2797 * Returns TRUE if at least one of the headers of the list belongs to
2798 * a message that has been fully retrieved.
2801 has_retrieved_msgs (TnyList *list)
2804 gboolean found = FALSE;
2806 iter = tny_list_create_iterator (list);
2807 while (tny_iterator_is_done (iter) && !found) {
2809 TnyHeaderFlags flags;
2811 header = TNY_HEADER (tny_iterator_get_current (iter));
2812 flags = tny_header_get_flags (header);
2813 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2817 tny_iterator_next (iter);
2819 g_object_unref (iter);
2825 * Shows a confirmation dialog to the user when we're moving messages
2826 * from a remote server to the local storage. Returns the dialog
2827 * response. If it's other kind of movement the it always returns
2831 msgs_move_to_confirmation (GtkWindow *win,
2832 TnyFolder *dest_folder,
2835 gint response = GTK_RESPONSE_OK;
2837 /* If the destination is a local folder */
2838 if (modest_tny_folder_is_local_folder (dest_folder)) {
2839 TnyFolder *src_folder;
2843 /* Get source folder */
2844 iter = tny_list_create_iterator (headers);
2845 header = TNY_HEADER (tny_iterator_get_current (iter));
2846 src_folder = tny_header_get_folder (header);
2847 g_object_unref (header);
2848 g_object_unref (iter);
2850 /* if no src_folder, message may be an attahcment */
2851 if (src_folder == NULL)
2852 return GTK_RESPONSE_CANCEL;
2854 /* If the source is a remote folder */
2855 if (!modest_tny_folder_is_local_folder (src_folder)) {
2856 const gchar *message;
2858 if (has_retrieved_msgs (headers))
2859 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2860 tny_list_get_length (headers));
2862 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2863 tny_list_get_length (headers));
2865 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2866 (const gchar *) message);
2868 g_object_unref (src_folder);
2875 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2877 ModestMsgViewWindow *self = NULL;
2878 gboolean last, first;
2880 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2881 self = MODEST_MSG_VIEW_WINDOW (object);
2883 last = modest_msg_view_window_last_message_selected (self);
2884 first = modest_msg_view_window_first_message_selected (self);
2886 /* No more messages to view, so close this window */
2887 /* gboolean ret_value; */
2888 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2889 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
2891 modest_msg_view_window_select_previous_message (self);
2893 modest_msg_view_window_select_next_message (self);
2897 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2900 GObject *win = modest_mail_operation_get_source (mail_op);
2902 /* TODO: show error message */
2903 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2904 _("mail_in_ui_folder_move_target_error"));
2905 g_object_unref (win);
2909 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
2912 GObject *win = modest_mail_operation_get_source (mail_op);
2913 const GError *error = modest_mail_operation_get_error (mail_op);
2915 g_return_if_fail (error != NULL);
2916 if (error->message != NULL)
2917 g_printerr ("modest: %s\n", error->message);
2919 g_printerr ("modest: unkonw error on sedn&receive operation");
2921 /* Show error message */
2922 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2923 _CS("sfil_ib_unable_to_send"));
2924 /* g_object_unref (win); */
2928 open_msg_for_purge_cb (ModestMailOperation *mail_op,
2935 gint pending_purges = 0;
2936 gboolean some_purged = FALSE;
2937 ModestWindow *win = MODEST_WINDOW (user_data);
2941 /* Once the message has been retrieved for purging, we check if
2942 * it's all ok for purging */
2944 parts = tny_simple_list_new ();
2945 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
2946 iter = tny_list_create_iterator (parts);
2948 while (!tny_iterator_is_done (iter)) {
2950 part = TNY_MIME_PART (tny_iterator_get_current (iter));
2951 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
2952 if (tny_mime_part_is_purged (part))
2957 tny_iterator_next (iter);
2960 if (pending_purges>0) {
2962 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
2964 if (response == GTK_RESPONSE_OK) {
2965 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
2966 tny_iterator_first (iter);
2967 while (!tny_iterator_is_done (iter)) {
2970 part = TNY_MIME_PART (tny_iterator_get_current (iter));
2971 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
2972 tny_mime_part_set_purged (part);
2973 tny_iterator_next (iter);
2976 tny_msg_rewrite_cache (msg);
2979 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
2982 /* remove attachments */
2983 tny_iterator_first (iter);
2984 while (!tny_iterator_is_done (iter)) {
2987 part = TNY_MIME_PART (tny_iterator_get_current (iter));
2988 g_object_unref (part);
2989 tny_iterator_next (iter);
2992 g_object_unref (iter);
2993 g_object_unref (parts);
2997 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
2998 ModestMainWindow *win)
3000 GtkWidget *header_view;
3001 TnyList *header_list;
3004 TnyHeaderFlags flags;
3005 ModestWindow *msg_view_window = NULL;
3008 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3010 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3011 MODEST_WIDGET_TYPE_HEADER_VIEW);
3013 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3015 if (tny_list_get_length (header_list) == 1) {
3016 iter = tny_list_create_iterator (header_list);
3017 header = TNY_HEADER (tny_iterator_get_current (iter));
3018 g_object_unref (iter);
3023 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3024 header, &msg_view_window);
3025 flags = tny_header_get_flags (header);
3026 if (!(flags & TNY_HEADER_FLAG_CACHED))
3029 if (msg_view_window != NULL)
3030 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3032 /* do nothing; uid was registered before, so window is probably on it's way */
3033 g_warning ("debug: header %p has already been registered", header);
3036 ModestMailOperation *mail_op = NULL;
3037 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3038 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
3040 modest_ui_actions_get_msgs_full_error_handler,
3042 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3043 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3045 g_object_unref (mail_op);
3048 g_object_unref (header);
3050 g_object_unref (header_list);
3054 * UI handler for the "Move to" action when invoked from the
3058 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3059 ModestMainWindow *win)
3061 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3062 GtkWidget *header_view = NULL;
3064 TnyFolderStore *folder_store = NULL;
3065 ModestMailOperation *mail_op = NULL;
3067 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3069 /* Get the folder view */
3070 folder_view = modest_main_window_get_child_widget (win,
3071 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3073 /* Get header view */
3074 header_view = modest_main_window_get_child_widget (win,
3075 MODEST_WIDGET_TYPE_HEADER_VIEW);
3077 /* Create and run the dialog */
3078 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3079 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3080 result = gtk_dialog_run (GTK_DIALOG(dialog));
3081 g_object_ref (tree_view);
3083 /* We do this to save an indentation level ;-) */
3084 if (result != GTK_RESPONSE_ACCEPT)
3087 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3089 if (TNY_IS_ACCOUNT (folder_store) &&
3090 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3093 /* Get folder or messages to transfer */
3094 if (gtk_widget_is_focus (folder_view)) {
3095 TnyFolderStore *src_folder;
3096 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3098 /* Clean folder on header view before moving it */
3099 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3101 if (TNY_IS_FOLDER (src_folder)) {
3103 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3105 modest_ui_actions_move_folder_error_handler,
3107 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3109 modest_mail_operation_xfer_folder (mail_op,
3110 TNY_FOLDER (src_folder),
3113 /* Unref mail operation */
3114 g_object_unref (G_OBJECT (mail_op));
3118 g_object_unref (G_OBJECT (src_folder));
3120 if (gtk_widget_is_focus (header_view)) {
3124 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3126 /* Ask for user confirmation */
3127 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3128 TNY_FOLDER (folder_store),
3131 /* Transfer messages */
3132 if (response == GTK_RESPONSE_OK) {
3133 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3134 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3137 modest_mail_operation_xfer_msgs (mail_op,
3139 TNY_FOLDER (folder_store),
3144 g_object_unref (G_OBJECT (mail_op));
3146 g_object_unref (headers);
3150 if (folder_store != NULL)
3151 g_object_unref (folder_store);
3152 gtk_widget_destroy (dialog);
3157 * UI handler for the "Move to" action when invoked from the
3158 * ModestMsgViewWindow
3161 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3162 ModestMsgViewWindow *win)
3164 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3166 ModestMainWindow *main_window;
3170 /* Get the folder view */
3171 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3173 folder_view = modest_main_window_get_child_widget (main_window,
3174 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3178 /* Create and run the dialog */
3179 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3180 result = gtk_dialog_run (GTK_DIALOG(dialog));
3181 g_object_ref (tree_view);
3183 if (result == GTK_RESPONSE_ACCEPT) {
3184 TnyFolderStore *folder_store;
3187 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3189 /* Create header list */
3190 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3192 headers = tny_simple_list_new ();
3193 tny_list_prepend (headers, G_OBJECT (header));
3194 g_object_unref (header);
3196 /* Ask user for confirmation. MSG-NOT404 */
3197 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3198 TNY_FOLDER (folder_store),
3201 /* Transfer current msg */
3202 if (response == GTK_RESPONSE_OK) {
3203 ModestMailOperation *mail_op;
3205 /* Create mail op */
3206 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3207 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3210 /* Transfer messages */
3211 modest_mail_operation_xfer_msgs (mail_op,
3213 TNY_FOLDER (folder_store),
3215 transfer_msgs_from_viewer_cb,
3217 g_object_unref (G_OBJECT (mail_op));
3219 g_object_unref (headers);
3220 g_object_unref (folder_store);
3222 gtk_widget_destroy (dialog);
3226 modest_ui_actions_on_move_to (GtkAction *action,
3229 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3230 MODEST_IS_MSG_VIEW_WINDOW (win));
3232 if (MODEST_IS_MAIN_WINDOW (win))
3233 modest_ui_actions_on_main_window_move_to (action,
3234 MODEST_MAIN_WINDOW (win));
3236 modest_ui_actions_on_msg_view_window_move_to (action,
3237 MODEST_MSG_VIEW_WINDOW (win));
3241 * Calls #HeadersFunc for each header already selected in the main
3242 * window or the message currently being shown in the msg view window
3245 do_headers_action (ModestWindow *win,
3249 TnyList *headers_list;
3255 headers_list = get_selected_headers (win);
3259 /* Get the folder */
3260 iter = tny_list_create_iterator (headers_list);
3261 header = TNY_HEADER (tny_iterator_get_current (iter));
3262 folder = tny_header_get_folder (header);
3263 g_object_unref (header);
3265 /* Call the function for each header */
3266 while (!tny_iterator_is_done (iter)) {
3267 header = TNY_HEADER (tny_iterator_get_current (iter));
3268 func (header, win, user_data);
3269 g_object_unref (header);
3270 tny_iterator_next (iter);
3273 /* Trick: do a poke status in order to speed up the signaling
3275 tny_folder_poke_status (folder);
3278 g_object_unref (folder);
3279 g_object_unref (iter);
3280 g_object_unref (headers_list);
3284 modest_ui_actions_view_attachment (GtkAction *action,
3285 ModestWindow *window)
3287 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3288 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3290 /* not supported window for this action */
3291 g_return_if_reached ();
3296 modest_ui_actions_save_attachments (GtkAction *action,
3297 ModestWindow *window)
3299 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3300 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3302 /* not supported window for this action */
3303 g_return_if_reached ();
3308 modest_ui_actions_remove_attachments (GtkAction *action,
3309 ModestWindow *window)
3311 if (MODEST_IS_MAIN_WINDOW (window)) {
3312 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3313 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3314 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3316 /* not supported window for this action */
3317 g_return_if_reached ();
3322 modest_ui_actions_on_settings (GtkAction *action,
3327 dialog = modest_platform_get_global_settings_dialog ();
3328 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3329 gtk_widget_show_all (dialog);
3331 gtk_dialog_run (GTK_DIALOG (dialog));
3333 gtk_widget_destroy (dialog);
3337 modest_ui_actions_on_help (GtkAction *action,
3340 const gchar *help_id = NULL;
3342 if (MODEST_IS_MAIN_WINDOW (win)) {
3343 const gchar *action_name;
3344 action_name = gtk_action_get_name (action);
3346 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3347 !strcmp (action_name, "HeaderViewCSMHelp")) {
3348 GtkWidget *folder_view;
3349 TnyFolderStore *folder_store;
3350 /* Get selected folder */
3351 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3352 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3353 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3355 /* Switch help_id */
3356 if (TNY_IS_FOLDER (folder_store)) {
3357 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3358 case TNY_FOLDER_TYPE_NORMAL:
3359 help_id = "applications_email_userfolder";
3361 case TNY_FOLDER_TYPE_INBOX:
3362 help_id = "applications_email_inbox";
3364 case TNY_FOLDER_TYPE_OUTBOX:
3365 help_id = "applications_email_outbox";
3367 case TNY_FOLDER_TYPE_SENT:
3368 help_id = "applications_email_sent";
3370 case TNY_FOLDER_TYPE_DRAFTS:
3371 help_id = "applications_email_drafts";
3373 case TNY_FOLDER_TYPE_ARCHIVE:
3374 help_id = "applications_email_archive";
3380 g_object_unref (folder_store);
3382 help_id = "applications_email_mainview";
3384 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3385 help_id = "applications_email_viewer";
3386 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3387 help_id = "applications_email_editor";
3389 modest_platform_show_help (GTK_WINDOW (win), help_id);
3393 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3394 ModestWindow *window)
3396 ModestMailOperation *mail_op;
3400 headers = get_selected_headers (window);
3404 /* Create mail operation */
3405 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3407 modest_ui_actions_get_msgs_full_error_handler,
3409 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3410 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3413 g_object_unref (headers);
3414 g_object_unref (mail_op);
3418 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3419 ModestWindow *window)
3421 g_return_if_fail (MODEST_IS_WINDOW (window));
3424 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3428 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3429 ModestWindow *window)
3431 g_return_if_fail (MODEST_IS_WINDOW (window));
3434 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3438 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3439 ModestWindow *window)
3441 g_return_if_fail (MODEST_IS_WINDOW (window));
3444 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3448 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3449 ModestWindow *window)
3451 g_return_if_fail (MODEST_IS_WINDOW (window));
3454 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3458 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3459 ModestWindow *window)
3461 g_return_if_fail (MODEST_IS_WINDOW (window));
3464 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3468 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3469 ModestWindow *window)
3471 g_return_if_fail (MODEST_IS_WINDOW (window));
3474 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3478 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3479 ModestWindow *window)
3481 g_return_if_fail (MODEST_IS_WINDOW (window));
3484 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3488 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3489 ModestWindow *window)
3491 g_return_if_fail (MODEST_IS_WINDOW (window));
3494 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3498 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3500 g_return_if_fail (MODEST_IS_WINDOW (window));
3503 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3507 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3509 g_return_if_fail (MODEST_IS_WINDOW (window));
3511 modest_platform_show_search_messages (GTK_WINDOW (window));
3515 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3517 g_return_if_fail (MODEST_IS_WINDOW (win));
3518 modest_platform_show_addressbook (GTK_WINDOW (win));
3523 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3524 ModestWindow *window)
3526 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3528 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3532 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3533 ModestMailOperationState *state,
3536 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3538 /* Set send/receive operation finished */
3539 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3540 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));