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;
245 GtkTreeModel *model = NULL;
247 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
248 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
251 /* Always delete. TODO: Move to trash still not supported */
252 modest_mail_operation_remove_msg (mail_op, header, FALSE);
253 g_object_unref (G_OBJECT (mail_op));
255 /* refilter treemodel to hide marked-as-deleted rows */
256 if (MODEST_IS_HEADER_VIEW (user_data)) {
257 model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
258 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
263 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
265 TnyList *header_list = NULL;
266 TnyIterator *iter = NULL;
267 TnyHeader *header = NULL;
268 gchar *message = NULL;
272 ModestWindowMgr *mgr;
273 GtkWidget *header_view;
275 g_return_if_fail (MODEST_IS_WINDOW(win));
276 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
277 MODEST_WIDGET_TYPE_HEADER_VIEW);
279 /* Check first if the header view has the focus */
280 if (MODEST_IS_MAIN_WINDOW (win)) {
281 if (!gtk_widget_is_focus (header_view))
285 header_list = get_selected_headers (win);
286 if (!header_list) return;
288 /* Check if any of the headers is already opened, or in the process of being opened */
289 iter = tny_list_create_iterator (header_list);
291 mgr = modest_runtime_get_window_mgr ();
292 while (!tny_iterator_is_done (iter) && !found) {
293 header = TNY_HEADER (tny_iterator_get_current (iter));
294 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
295 g_object_unref (header);
296 tny_iterator_next (iter);
298 g_object_unref (iter);
303 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
304 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
306 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
310 g_object_unref (header_list);
315 if (tny_list_get_length(header_list) == 1) {
316 iter = tny_list_create_iterator (header_list);
317 header = TNY_HEADER (tny_iterator_get_current (iter));
318 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
319 g_object_unref (header);
320 g_object_unref (iter);
322 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
323 tny_list_get_length(header_list)), desc);
325 /* Confirmation dialog */
326 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
330 if (response == GTK_RESPONSE_OK) {
331 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
333 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
337 /* Remove each header */
338 do_headers_action (win, headers_action_delete, header_view);
340 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
341 gtk_widget_destroy (GTK_WIDGET(win));
345 /* Update toolbar dimming state */
346 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
351 g_object_unref (header_list);
356 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
358 #ifdef MODEST_PLATFORM_MAEMO
359 modest_osso_save_state();
360 #endif /* MODEST_PLATFORM_MAEMO */
362 g_debug ("closing down, clearing %d item(s) from operation queue",
363 modest_mail_operation_queue_num_elements
364 (modest_runtime_get_mail_operation_queue()));
366 /* cancel all outstanding operations */
367 modest_mail_operation_queue_cancel_all
368 (modest_runtime_get_mail_operation_queue());
370 g_debug ("queue has been cleared");
372 /* note: when modest-tny-account-store is finalized,
373 it will automatically set all network connections
380 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
383 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
385 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
386 /* gtk_widget_destroy (GTK_WIDGET (win)); */
387 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
388 /* gboolean ret_value; */
389 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
390 /* } else if (MODEST_IS_WINDOW (win)) { */
391 /* gtk_widget_destroy (GTK_WIDGET (win)); */
393 /* g_return_if_reached (); */
398 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
400 GtkClipboard *clipboard = NULL;
401 gchar *selection = NULL;
403 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
404 selection = gtk_clipboard_wait_for_text (clipboard);
406 /* Question: why is the clipboard being used here?
407 * It doesn't really make a lot of sense. */
411 modest_address_book_add_address (selection);
417 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
419 /* This is currently only implemented for Maemo */
420 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
421 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
422 run_account_setup_wizard (win);
425 /* Show the list of accounts: */
426 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
427 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
428 gtk_dialog_run (account_win);
429 gtk_widget_destroy (GTK_WIDGET(account_win));
432 GtkWidget *dialog, *label;
434 /* Create the widgets */
436 dialog = gtk_dialog_new_with_buttons ("Message",
438 GTK_DIALOG_DESTROY_WITH_PARENT,
442 label = gtk_label_new ("Hello World!");
444 /* Ensure that the dialog box is destroyed when the user responds. */
446 g_signal_connect_swapped (dialog, "response",
447 G_CALLBACK (gtk_widget_destroy),
450 /* Add the label, and show everything we've added to the dialog. */
452 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
454 gtk_widget_show_all (dialog);
455 #endif /* MODEST_PLATFORM_MAEMO */
459 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
461 ModestWindow *main_window = MODEST_WINDOW (user_data);
463 /* Save any changes. */
464 modest_connection_specific_smtp_window_save_server_accounts (
465 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
466 modest_window_get_active_account (main_window));
467 gtk_widget_destroy (GTK_WIDGET (window));
473 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
475 /* This is currently only implemented for Maemo,
476 * because it requires an API (libconic) to detect different connection
479 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
481 /* Create the window if necessary: */
482 const gchar *active_account_name = modest_window_get_active_account (win);
484 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
485 * or show the default account?
486 * If we show the default account then the account name should be shown in
487 * the window when we show it. */
488 if (!active_account_name) {
489 g_warning ("%s: No account is active.", __FUNCTION__);
493 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
494 modest_connection_specific_smtp_window_fill_with_connections (
495 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
496 modest_runtime_get_account_mgr(),
497 active_account_name);
499 /* Show the window: */
500 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
501 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
502 gtk_widget_show (specific_window);
504 /* Save changes when the window is hidden: */
505 g_signal_connect (specific_window, "hide",
506 G_CALLBACK (on_smtp_servers_window_hide), win);
507 #endif /* MODEST_PLATFORM_MAEMO */
511 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
513 ModestWindow *msg_win = NULL;
515 TnyFolder *folder = NULL;
516 gchar *account_name = NULL;
517 gchar *from_str = NULL;
518 /* GError *err = NULL; */
519 TnyAccount *account = NULL;
520 ModestWindowMgr *mgr;
521 gchar *signature = NULL, *blank_and_signature = NULL;
523 /* if there are no accounts yet, just show the wizard */
524 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
525 run_account_setup_wizard (win);
529 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
531 account_name = g_strdup (modest_window_get_active_account (win));
533 g_printerr ("modest: no account found\n");
537 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
539 TNY_ACCOUNT_TYPE_STORE);
541 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
545 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
547 g_printerr ("modest: failed get from string for '%s'\n", account_name);
551 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
552 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
553 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
554 MODEST_ACCOUNT_SIGNATURE, FALSE);
555 blank_and_signature = g_strconcat ("\n", signature, NULL);
558 blank_and_signature = g_strdup ("");
561 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
563 g_printerr ("modest: failed to create new msg\n");
567 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
569 g_printerr ("modest: failed to find Drafts folder\n");
574 /* Create and register edit window */
575 /* This is destroyed by TOOD. */
576 msg_win = modest_msg_edit_window_new (msg, account_name);
577 mgr = modest_runtime_get_window_mgr ();
578 modest_window_mgr_register_window (mgr, msg_win);
581 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
583 gtk_widget_show_all (GTK_WIDGET (msg_win));
586 g_free (account_name);
588 g_free (blank_and_signature);
590 g_object_unref (msg_win);
592 g_object_unref (G_OBJECT(account));
594 g_object_unref (G_OBJECT(msg));
596 g_object_unref (G_OBJECT(folder));
600 open_msg_cb (ModestMailOperation *mail_op,
605 ModestWindowMgr *mgr = NULL;
606 ModestWindow *parent_win = NULL;
607 ModestWindow *win = NULL;
608 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
609 gchar *account = NULL;
612 /* TODO: Show an error? (review the specs) */
616 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
617 folder = tny_header_get_folder (header);
619 /* Mark header as read */
620 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
623 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
625 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
627 /* Gets folder type (OUTBOX headers will be opened in edit window */
628 if (modest_tny_folder_is_local_folder (folder))
629 folder_type = modest_tny_folder_get_local_folder_type (folder);
631 /* If the header is in the drafts folder then open the editor,
632 else the message view window */
633 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
634 /* we cannot edit without a valid account... */
635 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
636 run_account_setup_wizard(parent_win);
639 win = modest_msg_edit_window_new (msg, account);
641 gchar *uid = modest_tny_folder_get_header_unique_id (header);
643 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
644 GtkWidget *header_view;
645 GtkTreeSelection *sel;
646 GList *sel_list = NULL;
649 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
650 MODEST_WIDGET_TYPE_HEADER_VIEW);
652 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
653 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
655 if (sel_list != NULL) {
656 GtkTreeRowReference *row_reference;
658 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
659 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
660 g_list_free (sel_list);
662 win = modest_msg_view_window_new_with_header_model (msg,
667 gtk_tree_row_reference_free (row_reference);
669 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
672 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
677 /* Register and show new window */
679 mgr = modest_runtime_get_window_mgr ();
680 modest_window_mgr_register_window (mgr, win);
681 g_object_unref (win);
682 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
683 gtk_widget_show_all (GTK_WIDGET(win));
686 /* Update toolbar dimming state */
687 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
688 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
694 g_object_unref (parent_win);
695 /* g_object_unref (msg); */
696 g_object_unref (folder);
700 * This function is the error handler of the
701 * modest_mail_operation_get_msgs_full operation
704 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
709 error = modest_mail_operation_get_error (mail_op);
710 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
711 GObject *win = modest_mail_operation_get_source (mail_op);
713 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
715 g_object_unref (win);
720 * This function is used by both modest_ui_actions_on_open and
721 * modest_ui_actions_on_header_activated. This way we always do the
722 * same when trying to open messages.
725 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
727 ModestWindowMgr *mgr = NULL;
728 TnyIterator *iter = NULL;
729 ModestMailOperation *mail_op1 = NULL;
730 ModestMailOperation *mail_op2 = NULL;
731 TnyList *not_opened_headers = NULL;
732 TnyList *not_opened_cached_headers = NULL;
733 TnyHeaderFlags flags;
735 /* Look if we already have a message view for each header. If
736 true, then remove the header from the list of headers to
738 mgr = modest_runtime_get_window_mgr ();
739 iter = tny_list_create_iterator (headers);
740 not_opened_headers = tny_simple_list_new ();
741 not_opened_cached_headers = tny_simple_list_new ();
742 while (!tny_iterator_is_done (iter)) {
744 ModestWindow *window;
748 header = TNY_HEADER (tny_iterator_get_current (iter));
749 flags = tny_header_get_flags (header);
752 found = modest_window_mgr_find_registered_header (mgr, header, &window);
754 /* Do not open again the message and present the
755 window to the user */
758 gtk_window_present (GTK_WINDOW (window));
760 /* the header has been registered already, we don't do
761 * anything but wait for the window to come up*/
762 g_warning ("debug: header %p already registered, waiting for window",
765 /* register the header before actually creating the window */
766 modest_window_mgr_register_header (mgr, header);
768 if (!(flags & TNY_HEADER_FLAG_CACHED))
769 tny_list_append (not_opened_headers, G_OBJECT (header));
770 /* Check if msg has already been retreived */
772 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
774 g_object_unref (header);
775 tny_iterator_next (iter);
778 /* Open each uncached message */
779 if (tny_list_get_length (not_opened_headers) > 0) {
780 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
782 modest_ui_actions_get_msgs_full_error_handler,
784 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
785 if (tny_list_get_length (not_opened_headers) > 1) {
786 modest_mail_operation_get_msgs_full (mail_op1,
792 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
793 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
794 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
795 g_object_unref (header);
796 g_object_unref (iter);
800 /* Open each cached message */
801 if (tny_list_get_length (not_opened_cached_headers) > 0) {
802 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
804 modest_ui_actions_get_msgs_full_error_handler,
806 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
807 if (tny_list_get_length (not_opened_cached_headers) > 1) {
808 modest_mail_operation_get_msgs_full (mail_op2,
814 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
815 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
816 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
817 g_object_unref (header);
818 g_object_unref (iter);
823 if (not_opened_headers != NULL)
824 g_object_unref (not_opened_headers);
825 if (not_opened_cached_headers != NULL)
826 g_object_unref (not_opened_cached_headers);
828 g_object_unref (iter);
829 if (mail_op1 != NULL)
830 g_object_unref (mail_op1);
831 if (mail_op2 != NULL)
832 g_object_unref (mail_op2);
836 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
841 headers = get_selected_headers (win);
846 _modest_ui_actions_open (headers, win);
848 g_object_unref(headers);
853 free_reply_forward_helper (gpointer data)
855 ReplyForwardHelper *helper;
857 helper = (ReplyForwardHelper *) data;
858 g_free (helper->account_name);
859 g_slice_free (ReplyForwardHelper, helper);
863 reply_forward_cb (ModestMailOperation *mail_op,
869 ReplyForwardHelper *rf_helper;
870 ModestWindow *msg_win = NULL;
871 ModestEditType edit_type;
873 TnyAccount *account = NULL;
874 ModestWindowMgr *mgr = NULL;
875 gchar *signature = NULL;
877 g_return_if_fail (user_data != NULL);
878 rf_helper = (ReplyForwardHelper *) user_data;
880 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
881 rf_helper->account_name);
882 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
883 rf_helper->account_name,
884 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
885 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
886 rf_helper->account_name,
887 MODEST_ACCOUNT_SIGNATURE, FALSE);
890 /* Create reply mail */
891 switch (rf_helper->action) {
894 modest_tny_msg_create_reply_msg (msg, from, signature,
895 rf_helper->reply_forward_type,
896 MODEST_TNY_MSG_REPLY_MODE_SENDER);
898 case ACTION_REPLY_TO_ALL:
900 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
901 MODEST_TNY_MSG_REPLY_MODE_ALL);
902 edit_type = MODEST_EDIT_TYPE_REPLY;
906 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
907 edit_type = MODEST_EDIT_TYPE_FORWARD;
910 g_return_if_reached ();
917 g_printerr ("modest: failed to create message\n");
921 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
922 rf_helper->account_name,
923 TNY_ACCOUNT_TYPE_STORE);
925 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
929 /* Create and register the windows */
930 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
931 mgr = modest_runtime_get_window_mgr ();
932 modest_window_mgr_register_window (mgr, msg_win);
934 if (rf_helper->parent_window != NULL) {
937 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
938 modest_window_set_zoom (msg_win, parent_zoom);
941 /* Show edit window */
942 gtk_widget_show_all (GTK_WIDGET (msg_win));
946 g_object_unref (msg_win);
948 g_object_unref (G_OBJECT (new_msg));
950 g_object_unref (G_OBJECT (account));
951 /* g_object_unref (msg); */
952 g_object_unref (header);
953 free_reply_forward_helper (rf_helper);
957 * Checks a list of headers. If any of them are not currently
958 * downloaded (CACHED) then it asks the user for permission to
961 * Returns FALSE if the user does not want to download the
962 * messages. Returns TRUE if the user allowed the download or if all
963 * of them are currently downloaded
966 download_uncached_messages (TnyList *header_list, GtkWindow *win)
970 gint uncached_messages = 0;
972 iter = tny_list_create_iterator (header_list);
973 while (!tny_iterator_is_done (iter)) {
975 TnyHeaderFlags flags;
977 header = TNY_HEADER (tny_iterator_get_current (iter));
978 flags = tny_header_get_flags (header);
979 /* TODO: is this the right flag?, it seems that some
980 headers that have been previously downloaded do not
982 if (! (flags & TNY_HEADER_FLAG_CACHED))
983 uncached_messages ++;
984 g_object_unref (header);
985 tny_iterator_next (iter);
987 g_object_unref (iter);
989 /* Ask for user permission to download the messages */
991 if (uncached_messages > 0) {
992 GtkResponseType response;
994 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
995 ngettext("mcen_nc_get_msg",
998 if (response == GTK_RESPONSE_CANCEL)
1006 * Common code for the reply and forward actions
1009 reply_forward (ReplyForwardAction action, ModestWindow *win)
1011 ModestMailOperation *mail_op = NULL;
1012 TnyList *header_list = NULL;
1013 ReplyForwardHelper *rf_helper = NULL;
1014 guint reply_forward_type;
1015 gboolean continue_download;
1017 g_return_if_fail (MODEST_IS_WINDOW(win));
1019 /* we need an account when editing */
1020 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1021 run_account_setup_wizard (win);
1025 header_list = get_selected_headers (win);
1029 /* Check that the messages have been previously downloaded */
1030 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1031 if (!continue_download) {
1032 g_object_unref (header_list);
1036 reply_forward_type =
1037 modest_conf_get_int (modest_runtime_get_conf (),
1038 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1040 /* We assume that we can only select messages of the
1041 same folder and that we reply all of them from the
1042 same account. In fact the interface currently only
1043 allows single selection */
1046 rf_helper = g_slice_new0 (ReplyForwardHelper);
1047 rf_helper->reply_forward_type = reply_forward_type;
1048 rf_helper->action = action;
1049 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1050 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1051 rf_helper->parent_window = GTK_WIDGET (win);
1052 if (!rf_helper->account_name)
1053 rf_helper->account_name =
1054 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1056 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1059 /* Get header and message. Do not free them here, the
1060 reply_forward_cb must do it */
1061 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1062 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1063 if (!msg || !header) {
1065 g_object_unref (msg);
1067 g_object_unref (header);
1068 g_printerr ("modest: no message found\n");
1071 reply_forward_cb (NULL, header, msg, rf_helper);
1076 /* Retrieve messages */
1077 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1079 modest_ui_actions_get_msgs_full_error_handler,
1081 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1083 /* Only reply/forward to one message */
1084 iter = tny_list_create_iterator (header_list);
1085 header = TNY_HEADER (tny_iterator_get_current (iter));
1086 g_object_unref (iter);
1088 modest_mail_operation_get_msg (mail_op,
1093 /* modest_mail_operation_get_msgs_full (mail_op, */
1095 /* reply_forward_cb, */
1097 /* free_reply_forward_helper); */
1100 g_object_unref(mail_op);
1104 g_object_unref (header_list);
1108 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1110 g_return_if_fail (MODEST_IS_WINDOW(win));
1112 reply_forward (ACTION_REPLY, win);
1116 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1118 g_return_if_fail (MODEST_IS_WINDOW(win));
1120 reply_forward (ACTION_FORWARD, win);
1124 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1126 g_return_if_fail (MODEST_IS_WINDOW(win));
1128 reply_forward (ACTION_REPLY_TO_ALL, win);
1132 modest_ui_actions_on_next (GtkAction *action,
1133 ModestWindow *window)
1135 if (MODEST_IS_MAIN_WINDOW (window)) {
1136 GtkWidget *header_view;
1138 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1139 MODEST_WIDGET_TYPE_HEADER_VIEW);
1143 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1144 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1145 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1147 g_return_if_reached ();
1152 modest_ui_actions_on_prev (GtkAction *action,
1153 ModestWindow *window)
1155 g_return_if_fail (MODEST_IS_WINDOW(window));
1157 if (MODEST_IS_MAIN_WINDOW (window)) {
1158 GtkWidget *header_view;
1159 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1160 MODEST_WIDGET_TYPE_HEADER_VIEW);
1164 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1165 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1166 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1168 g_return_if_reached ();
1173 modest_ui_actions_on_sort (GtkAction *action,
1174 ModestWindow *window)
1176 g_return_if_fail (MODEST_IS_WINDOW(window));
1178 if (MODEST_IS_MAIN_WINDOW (window)) {
1179 GtkWidget *header_view;
1180 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1181 MODEST_WIDGET_TYPE_HEADER_VIEW);
1185 /* Show sorting dialog */
1186 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1191 new_messages_arrived (ModestMailOperation *self,
1195 if (new_messages == 0)
1198 modest_platform_on_new_msg ();
1202 * This function performs the send & receive required actions. The
1203 * window is used to create the mail operation. Typically it should
1204 * always be the main window, but we pass it as argument in order to
1208 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1210 gchar *acc_name = NULL;
1211 ModestMailOperation *mail_op;
1213 /* If no account name was provided then get the current account, and if
1214 there is no current account then pick the default one: */
1215 if (!account_name) {
1216 acc_name = g_strdup (modest_window_get_active_account(win));
1218 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1220 g_printerr ("modest: cannot get default account\n");
1224 acc_name = g_strdup (account_name);
1227 /* Set send/receive operation in progress */
1228 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1230 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1232 modest_ui_actions_send_receive_error_handler,
1235 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1236 G_CALLBACK (_on_send_receive_progress_changed),
1239 /* Send & receive. */
1240 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1241 /* Receive and then send. The operation is tagged initially as
1242 a receive operation because the account update performs a
1243 receive and then a send. The operation changes its type
1244 internally, so the progress objects will receive the proper
1245 progress information */
1246 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1247 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1248 g_object_unref (G_OBJECT (mail_op));
1255 * Refreshes all accounts. This function will be used by automatic
1259 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1261 GSList *account_names, *iter;
1263 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1266 iter = account_names;
1268 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1269 iter = g_slist_next (iter);
1272 modest_account_mgr_free_account_names (account_names);
1273 account_names = NULL;
1277 * Handler of the click on Send&Receive button in the main toolbar
1280 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1282 /* Check if accounts exist */
1283 gboolean accounts_exist =
1284 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1286 /* If not, allow the user to create an account before trying to send/receive. */
1287 if (!accounts_exist)
1288 modest_ui_actions_on_accounts (NULL, win);
1290 /* Refresh the active account */
1291 modest_ui_actions_do_send_receive (NULL, win);
1296 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1299 GtkWidget *header_view;
1301 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1303 header_view = modest_main_window_get_child_widget (main_window,
1304 MODEST_WIDGET_TYPE_HEADER_VIEW);
1308 conf = modest_runtime_get_conf ();
1310 /* what is saved/restored is depending on the style; thus; we save with
1311 * old style, then update the style, and restore for this new style
1313 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1315 if (modest_header_view_get_style
1316 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1317 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1318 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1320 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1321 MODEST_HEADER_VIEW_STYLE_DETAILS);
1323 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1324 MODEST_CONF_HEADER_VIEW_KEY);
1329 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1331 ModestMainWindow *main_window)
1333 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1334 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1336 /* If no header has been selected then exit */
1341 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1342 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1344 /* Update Main window title */
1345 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1346 const gchar *subject = tny_header_get_subject (header);
1347 if (subject && strlen(subject) > 0)
1348 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1350 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1353 /* Update toolbar dimming state */
1354 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1358 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1360 ModestMainWindow *main_window)
1364 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1369 headers = tny_simple_list_new ();
1370 tny_list_prepend (headers, G_OBJECT (header));
1372 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1374 g_object_unref (headers);
1378 set_active_account_from_tny_account (TnyAccount *account,
1379 ModestWindow *window)
1381 const gchar *server_acc_name = tny_account_get_id (account);
1383 /* We need the TnyAccount provided by the
1384 account store because that is the one that
1385 knows the name of the Modest account */
1386 TnyAccount *modest_server_account = modest_server_account =
1387 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1388 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1391 const gchar *modest_acc_name =
1392 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1393 modest_window_set_active_account (window, modest_acc_name);
1394 g_object_unref (modest_server_account);
1399 folder_refreshed_cb (const GObject *obj,
1403 ModestMainWindow *win = NULL;
1404 GtkWidget *header_view;
1406 g_return_if_fail (TNY_IS_FOLDER (folder));
1408 win = MODEST_MAIN_WINDOW (user_data);
1410 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1412 /* Check if folder is empty and set headers view contents style */
1413 if (tny_folder_get_all_count (folder) == 0) {
1414 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1415 modest_main_window_set_contents_style (win,
1416 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1418 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1423 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1424 TnyFolderStore *folder_store,
1426 ModestMainWindow *main_window)
1429 GtkWidget *header_view;
1431 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1433 header_view = modest_main_window_get_child_widget(main_window,
1434 MODEST_WIDGET_TYPE_HEADER_VIEW);
1438 conf = modest_runtime_get_conf ();
1440 if (TNY_IS_ACCOUNT (folder_store)) {
1442 /* Update active account */
1443 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1444 /* Show account details */
1445 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1448 if (TNY_IS_FOLDER (folder_store) && selected) {
1450 /* Update the active account */
1451 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1453 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1454 g_object_unref (account);
1458 /* Set the header style by default, it could
1459 be changed later by the refresh callback to
1461 modest_main_window_set_contents_style (main_window,
1462 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1464 /* Set folder on header view. This function
1465 will call tny_folder_refresh_async so we
1466 pass a callback that will be called when
1467 finished. We use that callback to set the
1468 empty view if there are no messages */
1469 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1470 TNY_FOLDER (folder_store),
1471 folder_refreshed_cb,
1474 /* Restore configuration. We need to do this
1475 *after* the set_folder because the widget
1476 memory asks the header view about its
1478 modest_widget_memory_restore (modest_runtime_get_conf (),
1479 G_OBJECT(header_view),
1480 MODEST_CONF_HEADER_VIEW_KEY);
1482 /* Update the active account */
1483 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1484 /* Save only if we're seeing headers */
1485 if (modest_main_window_get_contents_style (main_window) ==
1486 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1487 modest_widget_memory_save (conf, G_OBJECT (header_view),
1488 MODEST_CONF_HEADER_VIEW_KEY);
1489 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1493 /* Update toolbar dimming state */
1494 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1498 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1505 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1507 online = tny_device_is_online (modest_runtime_get_device());
1510 /* already online -- the item is simply not there... */
1511 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1513 GTK_MESSAGE_WARNING,
1515 _("The %s you selected cannot be found"),
1517 gtk_dialog_run (GTK_DIALOG(dialog));
1519 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1523 GTK_RESPONSE_REJECT,
1525 GTK_RESPONSE_ACCEPT,
1527 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1528 "Do you want to get online?"), item);
1529 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1530 gtk_label_new (txt), FALSE, FALSE, 0);
1531 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1534 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1535 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1536 // modest_platform_connect_and_wait ();
1539 gtk_widget_destroy (dialog);
1543 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1546 /* g_message ("%s %s", __FUNCTION__, link); */
1551 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1554 modest_platform_activate_uri (link);
1558 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1561 modest_platform_show_uri_popup (link);
1565 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1568 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1572 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1573 const gchar *address,
1576 /* g_message ("%s %s", __FUNCTION__, address); */
1580 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1582 TnyTransportAccount *transport_account;
1583 ModestMailOperation *mail_operation;
1585 gchar *account_name, *from;
1586 ModestAccountMgr *account_mgr;
1587 gchar *info_text = NULL;
1589 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1591 data = modest_msg_edit_window_get_msg_data (edit_window);
1593 account_mgr = modest_runtime_get_account_mgr();
1594 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1596 account_name = modest_account_mgr_get_default_account (account_mgr);
1597 if (!account_name) {
1598 g_printerr ("modest: no account found\n");
1599 modest_msg_edit_window_free_msg_data (edit_window, data);
1603 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1604 account_name = g_strdup (data->account_name);
1608 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1609 (modest_runtime_get_account_store(),
1611 TNY_ACCOUNT_TYPE_TRANSPORT));
1612 if (!transport_account) {
1613 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1614 g_free (account_name);
1615 modest_msg_edit_window_free_msg_data (edit_window, data);
1618 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1620 /* Create the mail operation */
1621 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1622 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1624 modest_mail_operation_save_to_drafts (mail_operation,
1635 data->priority_flags);
1638 g_free (account_name);
1639 g_object_unref (G_OBJECT (transport_account));
1640 g_object_unref (G_OBJECT (mail_operation));
1642 modest_msg_edit_window_free_msg_data (edit_window, data);
1644 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1645 modest_platform_information_banner (NULL, NULL, info_text);
1649 /* For instance, when clicking the Send toolbar button when editing a message: */
1651 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1653 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1655 if (!modest_msg_edit_window_check_names (edit_window))
1658 /* FIXME: Code added just for testing. The final version will
1659 use the send queue provided by tinymail and some
1661 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1662 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1664 account_name = modest_account_mgr_get_default_account (account_mgr);
1666 if (!account_name) {
1667 g_printerr ("modest: no account found\n");
1671 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1673 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1674 account_name = g_strdup (data->account_name);
1677 /* Get the currently-active transport account for this modest account: */
1678 TnyTransportAccount *transport_account =
1679 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1680 (modest_runtime_get_account_store(),
1682 if (!transport_account) {
1683 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1684 g_free (account_name);
1685 modest_msg_edit_window_free_msg_data (edit_window, data);
1689 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1691 /* mail content checks and dialogs */
1692 if (data->subject == NULL || data->subject[0] == '\0') {
1693 GtkResponseType response;
1694 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1695 _("mcen_nc_subject_is_empty_send"));
1696 if (response == GTK_RESPONSE_CANCEL) {
1697 g_free (account_name);
1702 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1703 GtkResponseType response;
1704 gchar *note_message;
1705 gchar *note_subject = data->subject;
1706 if (note_subject == NULL || note_subject[0] == '\0')
1707 note_subject = _("mail_va_no_subject");
1708 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1709 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1711 g_free (note_message);
1712 if (response == GTK_RESPONSE_CANCEL) {
1713 g_free (account_name);
1718 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1720 /* Create the mail operation */
1721 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1722 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1724 modest_mail_operation_send_new_mail (mail_operation,
1735 data->priority_flags);
1739 g_free (account_name);
1740 g_object_unref (G_OBJECT (transport_account));
1741 g_object_unref (G_OBJECT (mail_operation));
1743 modest_msg_edit_window_free_msg_data (edit_window, data);
1744 modest_msg_edit_window_set_sent (edit_window, TRUE);
1746 /* Save settings and close the window: */
1747 gtk_widget_destroy (GTK_WIDGET (edit_window));
1751 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1752 ModestMsgEditWindow *window)
1754 ModestMsgEditFormatState *format_state = NULL;
1756 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1757 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1759 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1762 format_state = modest_msg_edit_window_get_format_state (window);
1763 g_return_if_fail (format_state != NULL);
1765 format_state->bold = gtk_toggle_action_get_active (action);
1766 modest_msg_edit_window_set_format_state (window, format_state);
1767 g_free (format_state);
1772 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1773 ModestMsgEditWindow *window)
1775 ModestMsgEditFormatState *format_state = NULL;
1777 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1778 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1780 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1783 format_state = modest_msg_edit_window_get_format_state (window);
1784 g_return_if_fail (format_state != NULL);
1786 format_state->italics = gtk_toggle_action_get_active (action);
1787 modest_msg_edit_window_set_format_state (window, format_state);
1788 g_free (format_state);
1793 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1794 ModestMsgEditWindow *window)
1796 ModestMsgEditFormatState *format_state = NULL;
1798 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1799 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1801 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1804 format_state = modest_msg_edit_window_get_format_state (window);
1805 g_return_if_fail (format_state != NULL);
1807 format_state->bullet = gtk_toggle_action_get_active (action);
1808 modest_msg_edit_window_set_format_state (window, format_state);
1809 g_free (format_state);
1814 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1815 GtkRadioAction *selected,
1816 ModestMsgEditWindow *window)
1818 ModestMsgEditFormatState *format_state = NULL;
1819 GtkJustification value;
1821 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1823 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1826 value = gtk_radio_action_get_current_value (selected);
1828 format_state = modest_msg_edit_window_get_format_state (window);
1829 g_return_if_fail (format_state != NULL);
1831 format_state->justification = value;
1832 modest_msg_edit_window_set_format_state (window, format_state);
1833 g_free (format_state);
1837 modest_ui_actions_on_select_editor_color (GtkAction *action,
1838 ModestMsgEditWindow *window)
1840 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1841 g_return_if_fail (GTK_IS_ACTION (action));
1843 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1846 modest_msg_edit_window_select_color (window);
1850 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1851 ModestMsgEditWindow *window)
1853 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1854 g_return_if_fail (GTK_IS_ACTION (action));
1856 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1859 modest_msg_edit_window_select_background_color (window);
1863 modest_ui_actions_on_insert_image (GtkAction *action,
1864 ModestMsgEditWindow *window)
1866 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1867 g_return_if_fail (GTK_IS_ACTION (action));
1869 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1872 modest_msg_edit_window_insert_image (window);
1876 modest_ui_actions_on_attach_file (GtkAction *action,
1877 ModestMsgEditWindow *window)
1879 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1880 g_return_if_fail (GTK_IS_ACTION (action));
1882 modest_msg_edit_window_attach_file (window);
1886 modest_ui_actions_on_remove_attachments (GtkAction *action,
1887 ModestMsgEditWindow *window)
1889 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1890 g_return_if_fail (GTK_IS_ACTION (action));
1892 modest_msg_edit_window_remove_attachments (window, NULL);
1896 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1898 TnyFolderStore *parent_folder;
1899 GtkWidget *folder_view;
1901 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1903 folder_view = modest_main_window_get_child_widget (main_window,
1904 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1908 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1910 if (parent_folder) {
1911 gboolean finished = FALSE;
1913 gchar *folder_name = NULL, *suggested_name = NULL;
1915 /* Run the new folder dialog */
1917 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1922 if (result == GTK_RESPONSE_REJECT) {
1925 ModestMailOperation *mail_op;
1926 TnyFolder *new_folder = NULL;
1928 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1929 G_OBJECT(main_window));
1930 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1932 new_folder = modest_mail_operation_create_folder (mail_op,
1934 (const gchar *) folder_name);
1936 g_object_unref (new_folder);
1939 g_object_unref (mail_op);
1941 g_free (folder_name);
1945 g_object_unref (parent_folder);
1950 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1953 GObject *win = modest_mail_operation_get_source (mail_op);
1954 const GError *error = NULL;
1955 const gchar *message = NULL;
1957 /* Get error message */
1958 error = modest_mail_operation_get_error (mail_op);
1959 if (error != NULL && error->message != NULL) {
1960 message = error->message;
1962 message = _("!!! FIXME: Unable to rename");
1965 /* Show notification dialog */
1966 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
1967 g_object_unref (win);
1971 modest_ui_actions_on_rename_folder (GtkAction *action,
1972 ModestMainWindow *main_window)
1974 TnyFolderStore *folder;
1975 GtkWidget *folder_view;
1976 GtkWidget *header_view;
1978 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1980 folder_view = modest_main_window_get_child_widget (main_window,
1981 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1985 header_view = modest_main_window_get_child_widget (main_window,
1986 MODEST_WIDGET_TYPE_HEADER_VIEW);
1991 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1993 if (folder && TNY_IS_FOLDER (folder)) {
1996 const gchar *current_name;
1998 current_name = tny_folder_get_name (TNY_FOLDER (folder));
1999 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2000 current_name, &folder_name);
2002 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2003 ModestMailOperation *mail_op;
2006 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2007 G_OBJECT(main_window),
2008 modest_ui_actions_rename_folder_error_handler,
2012 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2015 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2017 modest_mail_operation_rename_folder (mail_op,
2018 TNY_FOLDER (folder),
2019 (const gchar *) folder_name);
2021 g_object_unref (mail_op);
2022 g_free (folder_name);
2024 g_object_unref (folder);
2029 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2032 GObject *win = modest_mail_operation_get_source (mail_op);
2034 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2035 _("mail_in_ui_folder_delete_error"));
2036 g_object_unref (win);
2040 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2042 TnyFolderStore *folder;
2043 GtkWidget *folder_view;
2047 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2049 folder_view = modest_main_window_get_child_widget (main_window,
2050 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2054 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2056 /* Show an error if it's an account */
2057 if (!TNY_IS_FOLDER (folder)) {
2058 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2059 _("mail_in_ui_folder_delete_error"));
2064 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2065 tny_folder_get_name (TNY_FOLDER (folder)));
2066 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2067 (const gchar *) message);
2070 if (response == GTK_RESPONSE_OK) {
2071 ModestMailOperation *mail_op =
2072 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2073 G_OBJECT(main_window),
2074 modest_ui_actions_delete_folder_error_handler,
2077 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2079 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2080 g_object_unref (G_OBJECT (mail_op));
2083 g_object_unref (G_OBJECT (folder));
2087 modest_ui_actions_on_delete_folder (GtkAction *action,
2088 ModestMainWindow *main_window)
2090 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2092 delete_folder (main_window, FALSE);
2096 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2098 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2100 delete_folder (main_window, TRUE);
2104 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2105 const gchar* server_account_name,
2110 ModestMainWindow *main_window)
2112 g_return_if_fail(server_account_name);
2113 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2115 /* Initalize output parameters: */
2122 #ifdef MODEST_PLATFORM_MAEMO
2123 /* Maemo uses a different (awkward) button order,
2124 * It should probably just use gtk_alternative_dialog_button_order ().
2126 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2130 GTK_RESPONSE_ACCEPT,
2132 GTK_RESPONSE_REJECT,
2135 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2139 GTK_RESPONSE_REJECT,
2141 GTK_RESPONSE_ACCEPT,
2143 #endif /* MODEST_PLATFORM_MAEMO */
2145 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2147 gchar *server_name = modest_server_account_get_hostname (
2148 modest_runtime_get_account_mgr(), server_account_name);
2149 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2150 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2155 /* This causes a warning because the logical ID has no %s in it,
2156 * though the translation does, but there is not much we can do about that: */
2157 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2158 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2161 g_free (server_name);
2165 gchar *initial_username = modest_server_account_get_username (
2166 modest_runtime_get_account_mgr(), server_account_name);
2168 GtkWidget *entry_username = gtk_entry_new ();
2169 if (initial_username)
2170 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2171 /* Dim this if a connection has ever succeeded with this username,
2172 * as per the UI spec: */
2173 const gboolean username_known =
2174 modest_server_account_get_username_has_succeeded(
2175 modest_runtime_get_account_mgr(), server_account_name);
2176 gtk_widget_set_sensitive (entry_username, !username_known);
2178 #ifdef MODEST_PLATFORM_MAEMO
2179 /* Auto-capitalization is the default, so let's turn it off: */
2180 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2182 /* Create a size group to be used by all captions.
2183 * Note that HildonCaption does not create a default size group if we do not specify one.
2184 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2185 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2187 GtkWidget *caption = hildon_caption_new (sizegroup,
2188 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2189 gtk_widget_show (entry_username);
2190 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2191 FALSE, FALSE, MODEST_MARGIN_HALF);
2192 gtk_widget_show (caption);
2194 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2196 #endif /* MODEST_PLATFORM_MAEMO */
2199 GtkWidget *entry_password = gtk_entry_new ();
2200 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2201 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2203 #ifdef MODEST_PLATFORM_MAEMO
2204 /* Auto-capitalization is the default, so let's turn it off: */
2205 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2206 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2208 caption = hildon_caption_new (sizegroup,
2209 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2210 gtk_widget_show (entry_password);
2211 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2212 FALSE, FALSE, MODEST_MARGIN_HALF);
2213 gtk_widget_show (caption);
2214 g_object_unref (sizegroup);
2216 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2218 #endif /* MODEST_PLATFORM_MAEMO */
2220 /* This is not in the Maemo UI spec:
2221 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2222 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2226 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2228 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2230 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2232 modest_server_account_set_username (
2233 modest_runtime_get_account_mgr(), server_account_name,
2236 const gboolean username_was_changed =
2237 (strcmp (*username, initial_username) != 0);
2238 if (username_was_changed) {
2239 g_warning ("%s: tinymail does not yet support changing the "
2240 "username in the get_password() callback.\n", __FUNCTION__);
2245 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2247 /* We do not save the password in the configuration,
2248 * because this function is only called for passwords that should
2249 * not be remembered:
2250 modest_server_account_set_password (
2251 modest_runtime_get_account_mgr(), server_account_name,
2270 /* This is not in the Maemo UI spec:
2271 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2277 gtk_widget_destroy (dialog);
2279 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2283 modest_ui_actions_on_cut (GtkAction *action,
2284 ModestWindow *window)
2286 GtkWidget *focused_widget;
2288 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2289 if (GTK_IS_EDITABLE (focused_widget)) {
2290 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2291 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2292 GtkTextBuffer *buffer;
2293 GtkClipboard *clipboard;
2295 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2296 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2297 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2298 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2299 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2300 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2301 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2306 modest_ui_actions_on_copy (GtkAction *action,
2307 ModestWindow *window)
2309 GtkClipboard *clipboard;
2310 GtkWidget *focused_widget;
2312 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2313 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2315 if (GTK_IS_LABEL (focused_widget)) {
2316 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2317 } else if (GTK_IS_EDITABLE (focused_widget)) {
2318 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2319 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2320 GtkTextBuffer *buffer;
2321 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2322 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2323 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2324 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2325 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2326 TnyIterator *iter = tny_list_create_iterator (header_list);
2327 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2328 TnyFolder *folder = tny_header_get_folder (header);
2329 TnyAccount *account = tny_folder_get_account (folder);
2330 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2331 /* If it's POP then ask */
2332 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2333 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2334 g_object_unref (account);
2335 g_object_unref (folder);
2336 g_object_unref (header);
2337 g_object_unref (iter);
2339 /* Check that the messages have been previously downloaded */
2340 gboolean continue_download = TRUE;
2342 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2343 if (continue_download)
2344 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2345 g_object_unref (header_list);
2346 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2347 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2350 /* Show information banner */
2351 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2356 modest_ui_actions_on_undo (GtkAction *action,
2357 ModestWindow *window)
2359 ModestEmailClipboard *clipboard = NULL;
2361 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2362 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2363 } if (MODEST_IS_MAIN_WINDOW (window)) {
2364 /* Clear clipboard source */
2365 clipboard = modest_runtime_get_email_clipboard ();
2366 modest_email_clipboard_clear (clipboard);
2369 g_return_if_reached ();
2374 modest_ui_actions_on_paste (GtkAction *action,
2375 ModestWindow *window)
2377 GtkWidget *focused_widget;
2378 ModestMailOperation *mail_op = NULL;
2380 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2381 if (GTK_IS_EDITABLE (focused_widget)) {
2382 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2383 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2384 GtkTextBuffer *buffer;
2385 GtkClipboard *clipboard;
2387 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2388 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2389 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2390 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2391 ModestEmailClipboard *clipboard = NULL;
2392 TnyFolder *src_folder = NULL;
2393 TnyFolderStore *folder_store = NULL;
2394 TnyList *data = NULL;
2395 gboolean delete = FALSE;
2397 /* Check clipboard source */
2398 clipboard = modest_runtime_get_email_clipboard ();
2399 if (modest_email_clipboard_cleared (clipboard))
2402 /* Get elements to paste */
2403 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2405 /* Create a new mail operation */
2406 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2407 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2410 /* Get destination folder */
2411 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2413 /* transfer messages */
2415 modest_mail_operation_xfer_msgs (mail_op,
2417 TNY_FOLDER (folder_store),
2422 } else if (src_folder != NULL) {
2423 modest_mail_operation_xfer_folder (mail_op,
2431 g_object_unref (data);
2432 if (src_folder != NULL)
2433 g_object_unref (src_folder);
2434 if (folder_store != NULL)
2435 g_object_unref (folder_store);
2440 modest_ui_actions_on_select_all (GtkAction *action,
2441 ModestWindow *window)
2443 GtkWidget *focused_widget;
2445 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2446 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2447 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2448 } else if (GTK_IS_LABEL (focused_widget)) {
2449 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2450 } else if (GTK_IS_EDITABLE (focused_widget)) {
2451 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2452 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2453 GtkTextBuffer *buffer;
2454 GtkTextIter start, end;
2456 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2457 gtk_text_buffer_get_start_iter (buffer, &start);
2458 gtk_text_buffer_get_end_iter (buffer, &end);
2459 gtk_text_buffer_select_range (buffer, &start, &end);
2460 } else if (GTK_IS_HTML (focused_widget)) {
2461 gtk_html_select_all (GTK_HTML (focused_widget));
2462 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2463 GtkWidget *header_view = focused_widget;
2464 GtkTreeSelection *selection = NULL;
2466 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2467 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2468 MODEST_WIDGET_TYPE_HEADER_VIEW);
2470 /* Select all messages */
2471 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2472 gtk_tree_selection_select_all (selection);
2474 /* Set focuse on header view */
2475 gtk_widget_grab_focus (header_view);
2481 modest_ui_actions_on_mark_as_read (GtkAction *action,
2482 ModestWindow *window)
2484 g_return_if_fail (MODEST_IS_WINDOW(window));
2486 /* Mark each header as read */
2487 do_headers_action (window, headers_action_mark_as_read, NULL);
2491 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2492 ModestWindow *window)
2494 g_return_if_fail (MODEST_IS_WINDOW(window));
2496 /* Mark each header as read */
2497 do_headers_action (window, headers_action_mark_as_unread, NULL);
2501 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2502 GtkRadioAction *selected,
2503 ModestWindow *window)
2507 value = gtk_radio_action_get_current_value (selected);
2508 if (MODEST_IS_WINDOW (window)) {
2509 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2513 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2514 GtkRadioAction *selected,
2515 ModestWindow *window)
2517 TnyHeaderFlags flags;
2518 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2520 flags = gtk_radio_action_get_current_value (selected);
2521 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2524 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2525 GtkRadioAction *selected,
2526 ModestWindow *window)
2530 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2532 file_format = gtk_radio_action_get_current_value (selected);
2533 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2538 modest_ui_actions_on_zoom_plus (GtkAction *action,
2539 ModestWindow *window)
2541 g_return_if_fail (MODEST_IS_WINDOW (window));
2543 modest_window_zoom_plus (MODEST_WINDOW (window));
2547 modest_ui_actions_on_zoom_minus (GtkAction *action,
2548 ModestWindow *window)
2550 g_return_if_fail (MODEST_IS_WINDOW (window));
2552 modest_window_zoom_minus (MODEST_WINDOW (window));
2556 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2557 ModestWindow *window)
2559 ModestWindowMgr *mgr;
2560 gboolean fullscreen, active;
2561 g_return_if_fail (MODEST_IS_WINDOW (window));
2563 mgr = modest_runtime_get_window_mgr ();
2565 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2566 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2568 if (active != fullscreen) {
2569 modest_window_mgr_set_fullscreen_mode (mgr, active);
2570 gtk_window_present (GTK_WINDOW (window));
2575 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2576 ModestWindow *window)
2578 ModestWindowMgr *mgr;
2579 gboolean fullscreen;
2581 g_return_if_fail (MODEST_IS_WINDOW (window));
2583 mgr = modest_runtime_get_window_mgr ();
2584 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2585 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2587 gtk_window_present (GTK_WINDOW (window));
2591 * Used by modest_ui_actions_on_details to call do_headers_action
2594 headers_action_show_details (TnyHeader *header,
2595 ModestWindow *window,
2602 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2605 gtk_widget_show_all (dialog);
2606 gtk_dialog_run (GTK_DIALOG (dialog));
2608 gtk_widget_destroy (dialog);
2612 * Show the folder details in a ModestDetailsDialog widget
2615 show_folder_details (TnyFolder *folder,
2621 dialog = modest_details_dialog_new_with_folder (window, folder);
2624 gtk_widget_show_all (dialog);
2625 gtk_dialog_run (GTK_DIALOG (dialog));
2627 gtk_widget_destroy (dialog);
2631 * Show the header details in a ModestDetailsDialog widget
2634 modest_ui_actions_on_details (GtkAction *action,
2637 TnyList * headers_list;
2641 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2644 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2647 g_object_unref (msg);
2649 headers_list = get_selected_headers (win);
2653 iter = tny_list_create_iterator (headers_list);
2655 header = TNY_HEADER (tny_iterator_get_current (iter));
2656 headers_action_show_details (header, win, NULL);
2657 g_object_unref (header);
2659 g_object_unref (iter);
2660 g_object_unref (headers_list);
2662 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2663 GtkWidget *folder_view, *header_view;
2665 /* Check which widget has the focus */
2666 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2667 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2668 if (gtk_widget_is_focus (folder_view)) {
2669 TnyFolderStore *folder_store
2670 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2671 if (!folder_store) {
2672 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2675 /* Show only when it's a folder */
2676 /* This function should not be called for account items,
2677 * because we dim the menu item for them. */
2678 if (TNY_IS_FOLDER (folder_store)) {
2679 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2682 g_object_unref (folder_store);
2685 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2686 MODEST_WIDGET_TYPE_HEADER_VIEW);
2687 /* Show details of each header */
2688 do_headers_action (win, headers_action_show_details, header_view);
2694 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2695 ModestMsgEditWindow *window)
2697 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2699 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2703 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2704 ModestMsgEditWindow *window)
2706 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2708 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2712 modest_ui_actions_toggle_folders_view (GtkAction *action,
2713 ModestMainWindow *main_window)
2717 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2719 conf = modest_runtime_get_conf ();
2721 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2722 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2724 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2728 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2729 ModestWindow *window)
2731 gboolean active, fullscreen = FALSE;
2732 ModestWindowMgr *mgr;
2734 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2736 /* Check if we want to toggle the toolbar vuew in fullscreen
2738 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2739 "ViewShowToolbarFullScreen")) {
2743 /* Toggle toolbar */
2744 mgr = modest_runtime_get_window_mgr ();
2745 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2749 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2750 ModestMsgEditWindow *window)
2752 modest_msg_edit_window_select_font (window);
2756 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2757 const gchar *display_name,
2760 /* Do not change the application name if the widget has not
2761 the focus. This callback could be called even if the folder
2762 view has not the focus, because the handled signal could be
2763 emitted when the folder view is redrawn */
2764 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2766 gtk_window_set_title (window, display_name);
2768 gtk_window_set_title (window, " ");
2773 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2775 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2776 modest_msg_edit_window_select_contacts (window);
2780 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2782 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2783 modest_msg_edit_window_check_names (window);
2788 create_move_to_dialog (ModestWindow *win,
2789 GtkWidget *folder_view,
2790 GtkWidget **tree_view)
2792 GtkWidget *dialog, *scroll;
2794 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2796 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2798 GTK_RESPONSE_ACCEPT,
2800 GTK_RESPONSE_REJECT,
2803 /* Create scrolled window */
2804 scroll = gtk_scrolled_window_new (NULL, NULL);
2805 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2806 GTK_POLICY_AUTOMATIC,
2807 GTK_POLICY_AUTOMATIC);
2809 /* Create folder view */
2810 *tree_view = modest_platform_create_folder_view (NULL);
2812 /* It could happen that we're trying to move a message from a
2813 window (msg window for example) after the main window was
2814 closed, so we can not just get the model of the folder
2816 if (MODEST_IS_FOLDER_VIEW (folder_view))
2817 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2818 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2820 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2821 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2823 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2825 /* Add scroll to dialog */
2826 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2827 scroll, FALSE, FALSE, 0);
2829 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2831 /* Select INBOX or local account */
2832 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2838 * Returns TRUE if at least one of the headers of the list belongs to
2839 * a message that has been fully retrieved.
2842 has_retrieved_msgs (TnyList *list)
2845 gboolean found = FALSE;
2847 iter = tny_list_create_iterator (list);
2848 while (tny_iterator_is_done (iter) && !found) {
2850 TnyHeaderFlags flags;
2852 header = TNY_HEADER (tny_iterator_get_current (iter));
2853 flags = tny_header_get_flags (header);
2854 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2858 tny_iterator_next (iter);
2860 g_object_unref (iter);
2866 * Shows a confirmation dialog to the user when we're moving messages
2867 * from a remote server to the local storage. Returns the dialog
2868 * response. If it's other kind of movement the it always returns
2872 msgs_move_to_confirmation (GtkWindow *win,
2873 TnyFolder *dest_folder,
2876 gint response = GTK_RESPONSE_OK;
2878 /* If the destination is a local folder */
2879 if (modest_tny_folder_is_local_folder (dest_folder)) {
2880 TnyFolder *src_folder;
2884 /* Get source folder */
2885 iter = tny_list_create_iterator (headers);
2886 header = TNY_HEADER (tny_iterator_get_current (iter));
2887 src_folder = tny_header_get_folder (header);
2888 g_object_unref (header);
2889 g_object_unref (iter);
2891 /* if no src_folder, message may be an attahcment */
2892 if (src_folder == NULL)
2893 return GTK_RESPONSE_CANCEL;
2895 /* If the source is a remote folder */
2896 if (!modest_tny_folder_is_local_folder (src_folder)) {
2897 const gchar *message;
2899 if (has_retrieved_msgs (headers))
2900 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2901 tny_list_get_length (headers));
2903 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2904 tny_list_get_length (headers));
2906 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2907 (const gchar *) message);
2909 g_object_unref (src_folder);
2916 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2918 ModestMsgViewWindow *self = NULL;
2919 gboolean last, first;
2921 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2922 self = MODEST_MSG_VIEW_WINDOW (object);
2924 last = modest_msg_view_window_last_message_selected (self);
2925 first = modest_msg_view_window_first_message_selected (self);
2927 /* No more messages to view, so close this window */
2928 /* gboolean ret_value; */
2929 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2930 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
2932 modest_msg_view_window_select_previous_message (self);
2934 modest_msg_view_window_select_next_message (self);
2938 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2941 GObject *win = modest_mail_operation_get_source (mail_op);
2942 const GError *error = NULL;
2943 const gchar *message = NULL;
2945 /* Get error message */
2946 error = modest_mail_operation_get_error (mail_op);
2947 if (error != NULL && error->message != NULL) {
2948 message = error->message;
2950 message = _("mail_in_ui_folder_move_target_error");
2953 /* Show notification dialog */
2954 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2955 g_object_unref (win);
2959 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
2962 GObject *win = modest_mail_operation_get_source (mail_op);
2963 const GError *error = modest_mail_operation_get_error (mail_op);
2965 g_return_if_fail (error != NULL);
2966 if (error->message != NULL)
2967 g_printerr ("modest: %s\n", error->message);
2969 g_printerr ("modest: unkonw error on sedn&receive operation");
2971 /* Show error message */
2972 if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE)
2973 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2974 _CS("sfil_ib_unable_to_receive"));
2976 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2977 _CS("sfil_ib_unable_to_send"));
2978 g_object_unref (win);
2982 open_msg_for_purge_cb (ModestMailOperation *mail_op,
2989 gint pending_purges = 0;
2990 gboolean some_purged = FALSE;
2991 ModestWindow *win = MODEST_WINDOW (user_data);
2995 /* Once the message has been retrieved for purging, we check if
2996 * it's all ok for purging */
2998 parts = tny_simple_list_new ();
2999 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3000 iter = tny_list_create_iterator (parts);
3002 while (!tny_iterator_is_done (iter)) {
3004 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3005 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3006 if (tny_mime_part_is_purged (part))
3011 tny_iterator_next (iter);
3014 if (pending_purges>0) {
3016 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3018 if (response == GTK_RESPONSE_OK) {
3019 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3020 tny_iterator_first (iter);
3021 while (!tny_iterator_is_done (iter)) {
3024 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3025 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3026 tny_mime_part_set_purged (part);
3027 tny_iterator_next (iter);
3030 tny_msg_rewrite_cache (msg);
3033 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3036 /* remove attachments */
3037 tny_iterator_first (iter);
3038 while (!tny_iterator_is_done (iter)) {
3041 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3042 g_object_unref (part);
3043 tny_iterator_next (iter);
3046 g_object_unref (iter);
3047 g_object_unref (parts);
3051 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3052 ModestMainWindow *win)
3054 GtkWidget *header_view;
3055 TnyList *header_list;
3058 TnyHeaderFlags flags;
3059 ModestWindow *msg_view_window = NULL;
3062 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3064 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3065 MODEST_WIDGET_TYPE_HEADER_VIEW);
3067 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3069 if (tny_list_get_length (header_list) == 1) {
3070 iter = tny_list_create_iterator (header_list);
3071 header = TNY_HEADER (tny_iterator_get_current (iter));
3072 g_object_unref (iter);
3077 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3078 header, &msg_view_window);
3079 flags = tny_header_get_flags (header);
3080 if (!(flags & TNY_HEADER_FLAG_CACHED))
3083 if (msg_view_window != NULL)
3084 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3086 /* do nothing; uid was registered before, so window is probably on it's way */
3087 g_warning ("debug: header %p has already been registered", header);
3090 ModestMailOperation *mail_op = NULL;
3091 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3092 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3094 modest_ui_actions_get_msgs_full_error_handler,
3096 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3097 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3099 g_object_unref (mail_op);
3102 g_object_unref (header);
3104 g_object_unref (header_list);
3108 * UI handler for the "Move to" action when invoked from the
3112 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3113 ModestMainWindow *win)
3115 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3116 GtkWidget *header_view = NULL;
3118 TnyFolderStore *folder_store = NULL;
3119 ModestMailOperation *mail_op = NULL;
3121 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3123 /* Get the folder view */
3124 folder_view = modest_main_window_get_child_widget (win,
3125 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3127 /* Get header view */
3128 header_view = modest_main_window_get_child_widget (win,
3129 MODEST_WIDGET_TYPE_HEADER_VIEW);
3131 /* Create and run the dialog */
3132 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3133 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3134 result = gtk_dialog_run (GTK_DIALOG(dialog));
3135 g_object_ref (tree_view);
3137 /* We do this to save an indentation level ;-) */
3138 if (result != GTK_RESPONSE_ACCEPT)
3141 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3143 if (TNY_IS_ACCOUNT (folder_store) &&
3144 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3147 /* Get folder or messages to transfer */
3148 if (gtk_widget_is_focus (folder_view)) {
3149 TnyFolderStore *src_folder;
3150 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3152 /* Clean folder on header view before moving it */
3153 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3155 if (TNY_IS_FOLDER (src_folder)) {
3157 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3159 modest_ui_actions_move_folder_error_handler,
3161 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3163 modest_mail_operation_xfer_folder (mail_op,
3164 TNY_FOLDER (src_folder),
3167 /* Unref mail operation */
3168 g_object_unref (G_OBJECT (mail_op));
3172 g_object_unref (G_OBJECT (src_folder));
3174 if (gtk_widget_is_focus (header_view)) {
3178 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3180 /* Ask for user confirmation */
3181 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3182 TNY_FOLDER (folder_store),
3185 /* Transfer messages */
3186 if (response == GTK_RESPONSE_OK) {
3188 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3190 modest_ui_actions_move_folder_error_handler,
3192 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3195 modest_mail_operation_xfer_msgs (mail_op,
3197 TNY_FOLDER (folder_store),
3202 g_object_unref (G_OBJECT (mail_op));
3204 g_object_unref (headers);
3208 if (folder_store != NULL)
3209 g_object_unref (folder_store);
3210 gtk_widget_destroy (dialog);
3215 * UI handler for the "Move to" action when invoked from the
3216 * ModestMsgViewWindow
3219 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3220 ModestMsgViewWindow *win)
3222 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3224 ModestMainWindow *main_window;
3228 /* Get the folder view */
3229 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3231 folder_view = modest_main_window_get_child_widget (main_window,
3232 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3236 /* Create and run the dialog */
3237 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3238 result = gtk_dialog_run (GTK_DIALOG(dialog));
3239 g_object_ref (tree_view);
3241 if (result == GTK_RESPONSE_ACCEPT) {
3242 TnyFolderStore *folder_store;
3245 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3247 /* Create header list */
3248 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3250 headers = tny_simple_list_new ();
3251 tny_list_prepend (headers, G_OBJECT (header));
3252 g_object_unref (header);
3254 /* Ask user for confirmation. MSG-NOT404 */
3255 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3256 TNY_FOLDER (folder_store),
3259 /* Transfer current msg */
3260 if (response == GTK_RESPONSE_OK) {
3261 ModestMailOperation *mail_op;
3263 /* Create mail op */
3264 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3265 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3268 /* Transfer messages */
3269 modest_mail_operation_xfer_msgs (mail_op,
3271 TNY_FOLDER (folder_store),
3273 transfer_msgs_from_viewer_cb,
3275 g_object_unref (G_OBJECT (mail_op));
3277 g_object_unref (headers);
3278 g_object_unref (folder_store);
3280 gtk_widget_destroy (dialog);
3284 modest_ui_actions_on_move_to (GtkAction *action,
3287 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3288 MODEST_IS_MSG_VIEW_WINDOW (win));
3290 if (MODEST_IS_MAIN_WINDOW (win))
3291 modest_ui_actions_on_main_window_move_to (action,
3292 MODEST_MAIN_WINDOW (win));
3294 modest_ui_actions_on_msg_view_window_move_to (action,
3295 MODEST_MSG_VIEW_WINDOW (win));
3299 * Calls #HeadersFunc for each header already selected in the main
3300 * window or the message currently being shown in the msg view window
3303 do_headers_action (ModestWindow *win,
3307 TnyList *headers_list;
3313 headers_list = get_selected_headers (win);
3317 /* Get the folder */
3318 iter = tny_list_create_iterator (headers_list);
3319 header = TNY_HEADER (tny_iterator_get_current (iter));
3320 folder = tny_header_get_folder (header);
3321 g_object_unref (header);
3323 /* Call the function for each header */
3324 while (!tny_iterator_is_done (iter)) {
3325 header = TNY_HEADER (tny_iterator_get_current (iter));
3326 func (header, win, user_data);
3327 g_object_unref (header);
3328 tny_iterator_next (iter);
3331 /* Trick: do a poke status in order to speed up the signaling
3333 tny_folder_poke_status (folder);
3336 g_object_unref (folder);
3337 g_object_unref (iter);
3338 g_object_unref (headers_list);
3342 modest_ui_actions_view_attachment (GtkAction *action,
3343 ModestWindow *window)
3345 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3346 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3348 /* not supported window for this action */
3349 g_return_if_reached ();
3354 modest_ui_actions_save_attachments (GtkAction *action,
3355 ModestWindow *window)
3357 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3358 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3360 /* not supported window for this action */
3361 g_return_if_reached ();
3366 modest_ui_actions_remove_attachments (GtkAction *action,
3367 ModestWindow *window)
3369 if (MODEST_IS_MAIN_WINDOW (window)) {
3370 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3371 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3372 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3374 /* not supported window for this action */
3375 g_return_if_reached ();
3380 modest_ui_actions_on_settings (GtkAction *action,
3385 dialog = modest_platform_get_global_settings_dialog ();
3386 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3387 gtk_widget_show_all (dialog);
3389 gtk_dialog_run (GTK_DIALOG (dialog));
3391 gtk_widget_destroy (dialog);
3395 modest_ui_actions_on_help (GtkAction *action,
3398 const gchar *help_id = NULL;
3400 if (MODEST_IS_MAIN_WINDOW (win)) {
3401 const gchar *action_name;
3402 action_name = gtk_action_get_name (action);
3404 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3405 !strcmp (action_name, "HeaderViewCSMHelp")) {
3406 GtkWidget *folder_view;
3407 TnyFolderStore *folder_store;
3408 /* Get selected folder */
3409 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3410 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3411 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3413 /* Switch help_id */
3414 if (TNY_IS_FOLDER (folder_store)) {
3415 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3416 case TNY_FOLDER_TYPE_NORMAL:
3417 help_id = "applications_email_userfolder";
3419 case TNY_FOLDER_TYPE_INBOX:
3420 help_id = "applications_email_inbox";
3422 case TNY_FOLDER_TYPE_OUTBOX:
3423 help_id = "applications_email_outbox";
3425 case TNY_FOLDER_TYPE_SENT:
3426 help_id = "applications_email_sent";
3428 case TNY_FOLDER_TYPE_DRAFTS:
3429 help_id = "applications_email_drafts";
3431 case TNY_FOLDER_TYPE_ARCHIVE:
3432 help_id = "applications_email_archive";
3438 g_object_unref (folder_store);
3440 help_id = "applications_email_mainview";
3442 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3443 help_id = "applications_email_viewer";
3444 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3445 help_id = "applications_email_editor";
3447 modest_platform_show_help (GTK_WINDOW (win), help_id);
3451 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3452 ModestWindow *window)
3454 ModestMailOperation *mail_op;
3458 headers = get_selected_headers (window);
3462 /* Create mail operation */
3463 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3465 modest_ui_actions_get_msgs_full_error_handler,
3467 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3468 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3471 g_object_unref (headers);
3472 g_object_unref (mail_op);
3476 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3477 ModestWindow *window)
3479 g_return_if_fail (MODEST_IS_WINDOW (window));
3482 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3486 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3487 ModestWindow *window)
3489 g_return_if_fail (MODEST_IS_WINDOW (window));
3492 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3496 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3497 ModestWindow *window)
3499 g_return_if_fail (MODEST_IS_WINDOW (window));
3502 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3506 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3507 ModestWindow *window)
3509 g_return_if_fail (MODEST_IS_WINDOW (window));
3512 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3516 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3517 ModestWindow *window)
3519 g_return_if_fail (MODEST_IS_WINDOW (window));
3522 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3526 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3527 ModestWindow *window)
3529 g_return_if_fail (MODEST_IS_WINDOW (window));
3532 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3536 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3537 ModestWindow *window)
3539 g_return_if_fail (MODEST_IS_WINDOW (window));
3542 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3546 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3547 ModestWindow *window)
3549 g_return_if_fail (MODEST_IS_WINDOW (window));
3552 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3556 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3558 g_return_if_fail (MODEST_IS_WINDOW (window));
3561 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3565 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3567 g_return_if_fail (MODEST_IS_WINDOW (window));
3569 modest_platform_show_search_messages (GTK_WINDOW (window));
3573 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3575 g_return_if_fail (MODEST_IS_WINDOW (win));
3576 modest_platform_show_addressbook (GTK_WINDOW (win));
3581 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3582 ModestWindow *window)
3584 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3586 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3590 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3591 ModestMailOperationState *state,
3594 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3596 /* Set send/receive operation finished */
3597 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3598 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));