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);
956 * Checks a list of headers. If any of them are not currently
957 * downloaded (CACHED) then it asks the user for permission to
960 * Returns FALSE if the user does not want to download the
961 * messages. Returns TRUE if the user allowed the download or if all
962 * of them are currently downloaded
965 download_uncached_messages (TnyList *header_list, GtkWindow *win)
969 gint uncached_messages = 0;
971 iter = tny_list_create_iterator (header_list);
972 while (!tny_iterator_is_done (iter)) {
974 TnyHeaderFlags flags;
976 header = TNY_HEADER (tny_iterator_get_current (iter));
977 flags = tny_header_get_flags (header);
978 /* TODO: is this the right flag?, it seems that some
979 headers that have been previously downloaded do not
981 if (! (flags & TNY_HEADER_FLAG_CACHED))
982 uncached_messages ++;
983 g_object_unref (header);
984 tny_iterator_next (iter);
986 g_object_unref (iter);
988 /* Ask for user permission to download the messages */
990 if (uncached_messages > 0) {
991 GtkResponseType response;
993 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
994 ngettext("mcen_nc_get_msg",
997 if (response == GTK_RESPONSE_CANCEL)
1005 * Common code for the reply and forward actions
1008 reply_forward (ReplyForwardAction action, ModestWindow *win)
1010 ModestMailOperation *mail_op = NULL;
1011 TnyList *header_list = NULL;
1012 ReplyForwardHelper *rf_helper = NULL;
1013 guint reply_forward_type;
1014 gboolean continue_download;
1016 g_return_if_fail (MODEST_IS_WINDOW(win));
1018 /* we need an account when editing */
1019 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1020 run_account_setup_wizard (win);
1024 header_list = get_selected_headers (win);
1028 /* Check that the messages have been previously downloaded */
1029 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1030 if (!continue_download) {
1031 g_object_unref (header_list);
1035 reply_forward_type =
1036 modest_conf_get_int (modest_runtime_get_conf (),
1037 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1039 /* We assume that we can only select messages of the
1040 same folder and that we reply all of them from the
1041 same account. In fact the interface currently only
1042 allows single selection */
1045 rf_helper = g_slice_new0 (ReplyForwardHelper);
1046 rf_helper->reply_forward_type = reply_forward_type;
1047 rf_helper->action = action;
1048 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1049 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1050 rf_helper->parent_window = GTK_WIDGET (win);
1051 if (!rf_helper->account_name)
1052 rf_helper->account_name =
1053 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1055 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1058 /* Get header and message. Do not free them here, the
1059 reply_forward_cb must do it */
1060 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1061 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1062 if (!msg || !header) {
1064 g_object_unref (msg);
1066 g_object_unref (header);
1067 g_printerr ("modest: no message found\n");
1070 reply_forward_cb (NULL, header, msg, rf_helper);
1072 /* Retrieve messages */
1073 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1075 modest_ui_actions_get_msgs_full_error_handler,
1077 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1078 modest_mail_operation_get_msgs_full (mail_op,
1082 free_reply_forward_helper);
1085 g_object_unref(mail_op);
1089 g_object_unref (header_list);
1093 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1095 g_return_if_fail (MODEST_IS_WINDOW(win));
1097 reply_forward (ACTION_REPLY, win);
1101 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1103 g_return_if_fail (MODEST_IS_WINDOW(win));
1105 reply_forward (ACTION_FORWARD, win);
1109 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1111 g_return_if_fail (MODEST_IS_WINDOW(win));
1113 reply_forward (ACTION_REPLY_TO_ALL, win);
1117 modest_ui_actions_on_next (GtkAction *action,
1118 ModestWindow *window)
1120 if (MODEST_IS_MAIN_WINDOW (window)) {
1121 GtkWidget *header_view;
1123 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1124 MODEST_WIDGET_TYPE_HEADER_VIEW);
1128 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1129 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1130 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1132 g_return_if_reached ();
1137 modest_ui_actions_on_prev (GtkAction *action,
1138 ModestWindow *window)
1140 g_return_if_fail (MODEST_IS_WINDOW(window));
1142 if (MODEST_IS_MAIN_WINDOW (window)) {
1143 GtkWidget *header_view;
1144 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1145 MODEST_WIDGET_TYPE_HEADER_VIEW);
1149 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1150 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1151 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1153 g_return_if_reached ();
1158 modest_ui_actions_on_sort (GtkAction *action,
1159 ModestWindow *window)
1161 g_return_if_fail (MODEST_IS_WINDOW(window));
1163 if (MODEST_IS_MAIN_WINDOW (window)) {
1164 GtkWidget *header_view;
1165 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1166 MODEST_WIDGET_TYPE_HEADER_VIEW);
1170 /* Show sorting dialog */
1171 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1176 new_messages_arrived (ModestMailOperation *self,
1180 if (new_messages == 0)
1183 modest_platform_on_new_msg ();
1187 * This function performs the send & receive required actions. The
1188 * window is used to create the mail operation. Typically it should
1189 * always be the main window, but we pass it as argument in order to
1193 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1195 gchar *acc_name = NULL;
1196 ModestMailOperation *mail_op;
1198 /* If no account name was provided then get the current account, and if
1199 there is no current account then pick the default one: */
1200 if (!account_name) {
1201 acc_name = g_strdup (modest_window_get_active_account(win));
1203 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1205 g_printerr ("modest: cannot get default account\n");
1209 acc_name = g_strdup (account_name);
1212 /* Set send/receive operation in progress */
1213 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1215 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1217 modest_ui_actions_send_receive_error_handler,
1220 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1221 G_CALLBACK (_on_send_receive_progress_changed),
1224 /* Send & receive. */
1225 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1226 /* Receive and then send. The operation is tagged initially as
1227 a receive operation because the account update performs a
1228 receive and then a send. The operation changes its type
1229 internally, so the progress objects will receive the proper
1230 progress information */
1231 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1232 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1233 g_object_unref (G_OBJECT (mail_op));
1240 * Refreshes all accounts. This function will be used by automatic
1244 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1246 GSList *account_names, *iter;
1248 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1251 iter = account_names;
1253 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1254 iter = g_slist_next (iter);
1257 modest_account_mgr_free_account_names (account_names);
1258 account_names = NULL;
1262 * Handler of the click on Send&Receive button in the main toolbar
1265 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1267 /* Check if accounts exist */
1268 gboolean accounts_exist =
1269 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1271 /* If not, allow the user to create an account before trying to send/receive. */
1272 if (!accounts_exist)
1273 modest_ui_actions_on_accounts (NULL, win);
1275 /* Refresh the active account */
1276 modest_ui_actions_do_send_receive (NULL, win);
1281 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1284 GtkWidget *header_view;
1286 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1288 header_view = modest_main_window_get_child_widget (main_window,
1289 MODEST_WIDGET_TYPE_HEADER_VIEW);
1293 conf = modest_runtime_get_conf ();
1295 /* what is saved/restored is depending on the style; thus; we save with
1296 * old style, then update the style, and restore for this new style
1298 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1300 if (modest_header_view_get_style
1301 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1302 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1303 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1305 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1306 MODEST_HEADER_VIEW_STYLE_DETAILS);
1308 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1309 MODEST_CONF_HEADER_VIEW_KEY);
1314 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1316 ModestMainWindow *main_window)
1318 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1319 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1321 /* If no header has been selected then exit */
1326 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1327 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1329 /* Update Main window title */
1330 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1331 const gchar *subject = tny_header_get_subject (header);
1332 if (subject && strlen(subject) > 0)
1333 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1335 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1338 /* Update toolbar dimming state */
1339 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1343 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1345 ModestMainWindow *main_window)
1349 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1354 headers = tny_simple_list_new ();
1355 tny_list_prepend (headers, G_OBJECT (header));
1357 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1359 g_object_unref (headers);
1363 set_active_account_from_tny_account (TnyAccount *account,
1364 ModestWindow *window)
1366 const gchar *server_acc_name = tny_account_get_id (account);
1368 /* We need the TnyAccount provided by the
1369 account store because that is the one that
1370 knows the name of the Modest account */
1371 TnyAccount *modest_server_account = modest_server_account =
1372 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1373 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1376 const gchar *modest_acc_name =
1377 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1378 modest_window_set_active_account (window, modest_acc_name);
1379 g_object_unref (modest_server_account);
1384 folder_refreshed_cb (const GObject *obj,
1388 ModestMainWindow *win = NULL;
1389 GtkWidget *header_view;
1391 g_return_if_fail (TNY_IS_FOLDER (folder));
1393 win = MODEST_MAIN_WINDOW (user_data);
1395 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1397 /* Check if folder is empty and set headers view contents style */
1398 if (tny_folder_get_all_count (folder) == 0) {
1399 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1400 modest_main_window_set_contents_style (win,
1401 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1403 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1408 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1409 TnyFolderStore *folder_store,
1411 ModestMainWindow *main_window)
1414 GtkWidget *header_view;
1416 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1418 header_view = modest_main_window_get_child_widget(main_window,
1419 MODEST_WIDGET_TYPE_HEADER_VIEW);
1423 conf = modest_runtime_get_conf ();
1425 if (TNY_IS_ACCOUNT (folder_store)) {
1427 /* Update active account */
1428 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1429 /* Show account details */
1430 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1433 if (TNY_IS_FOLDER (folder_store) && selected) {
1435 /* Update the active account */
1436 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1438 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1439 g_object_unref (account);
1443 /* Set the header style by default, it could
1444 be changed later by the refresh callback to
1446 modest_main_window_set_contents_style (main_window,
1447 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1449 /* Set folder on header view. This function
1450 will call tny_folder_refresh_async so we
1451 pass a callback that will be called when
1452 finished. We use that callback to set the
1453 empty view if there are no messages */
1454 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1455 TNY_FOLDER (folder_store),
1456 folder_refreshed_cb,
1459 /* Restore configuration. We need to do this
1460 *after* the set_folder because the widget
1461 memory asks the header view about its
1463 modest_widget_memory_restore (modest_runtime_get_conf (),
1464 G_OBJECT(header_view),
1465 MODEST_CONF_HEADER_VIEW_KEY);
1467 /* Update the active account */
1468 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1469 /* Save only if we're seeing headers */
1470 if (modest_main_window_get_contents_style (main_window) ==
1471 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1472 modest_widget_memory_save (conf, G_OBJECT (header_view),
1473 MODEST_CONF_HEADER_VIEW_KEY);
1474 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1478 /* Update toolbar dimming state */
1479 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1483 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1490 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1492 online = tny_device_is_online (modest_runtime_get_device());
1495 /* already online -- the item is simply not there... */
1496 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1498 GTK_MESSAGE_WARNING,
1500 _("The %s you selected cannot be found"),
1502 gtk_dialog_run (GTK_DIALOG(dialog));
1504 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1508 GTK_RESPONSE_REJECT,
1510 GTK_RESPONSE_ACCEPT,
1512 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1513 "Do you want to get online?"), item);
1514 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1515 gtk_label_new (txt), FALSE, FALSE, 0);
1516 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1519 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1520 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1521 // modest_platform_connect_and_wait ();
1524 gtk_widget_destroy (dialog);
1528 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1531 /* g_message ("%s %s", __FUNCTION__, link); */
1536 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1539 modest_platform_activate_uri (link);
1543 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1546 modest_platform_show_uri_popup (link);
1550 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1553 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1557 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1558 const gchar *address,
1561 /* g_message ("%s %s", __FUNCTION__, address); */
1565 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1567 TnyTransportAccount *transport_account;
1568 ModestMailOperation *mail_operation;
1570 gchar *account_name, *from;
1571 ModestAccountMgr *account_mgr;
1572 gchar *info_text = NULL;
1574 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1576 data = modest_msg_edit_window_get_msg_data (edit_window);
1578 account_mgr = modest_runtime_get_account_mgr();
1579 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1581 account_name = modest_account_mgr_get_default_account (account_mgr);
1582 if (!account_name) {
1583 g_printerr ("modest: no account found\n");
1584 modest_msg_edit_window_free_msg_data (edit_window, data);
1588 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1589 account_name = g_strdup (data->account_name);
1593 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1594 (modest_runtime_get_account_store(),
1596 TNY_ACCOUNT_TYPE_TRANSPORT));
1597 if (!transport_account) {
1598 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1599 g_free (account_name);
1600 modest_msg_edit_window_free_msg_data (edit_window, data);
1603 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1605 /* Create the mail operation */
1606 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1607 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1609 modest_mail_operation_save_to_drafts (mail_operation,
1620 data->priority_flags);
1623 g_free (account_name);
1624 g_object_unref (G_OBJECT (transport_account));
1625 g_object_unref (G_OBJECT (mail_operation));
1627 modest_msg_edit_window_free_msg_data (edit_window, data);
1629 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1630 modest_platform_information_banner (NULL, NULL, info_text);
1634 /* For instance, when clicking the Send toolbar button when editing a message: */
1636 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1638 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1640 if (!modest_msg_edit_window_check_names (edit_window))
1643 /* FIXME: Code added just for testing. The final version will
1644 use the send queue provided by tinymail and some
1646 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1647 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1649 account_name = modest_account_mgr_get_default_account (account_mgr);
1651 if (!account_name) {
1652 g_printerr ("modest: no account found\n");
1656 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1658 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1659 account_name = g_strdup (data->account_name);
1662 /* Get the currently-active transport account for this modest account: */
1663 TnyTransportAccount *transport_account =
1664 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1665 (modest_runtime_get_account_store(),
1667 if (!transport_account) {
1668 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1669 g_free (account_name);
1670 modest_msg_edit_window_free_msg_data (edit_window, data);
1674 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1676 /* mail content checks and dialogs */
1677 if (data->subject == NULL || data->subject[0] == '\0') {
1678 GtkResponseType response;
1679 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1680 _("mcen_nc_subject_is_empty_send"));
1681 if (response == GTK_RESPONSE_CANCEL) {
1682 g_free (account_name);
1687 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1688 GtkResponseType response;
1689 gchar *note_message;
1690 gchar *note_subject = data->subject;
1691 if (note_subject == NULL || note_subject[0] == '\0')
1692 note_subject = _("mail_va_no_subject");
1693 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1694 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1696 g_free (note_message);
1697 if (response == GTK_RESPONSE_CANCEL) {
1698 g_free (account_name);
1703 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1705 /* Create the mail operation */
1706 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1707 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1709 modest_mail_operation_send_new_mail (mail_operation,
1720 data->priority_flags);
1724 g_free (account_name);
1725 g_object_unref (G_OBJECT (transport_account));
1726 g_object_unref (G_OBJECT (mail_operation));
1728 modest_msg_edit_window_free_msg_data (edit_window, data);
1729 modest_msg_edit_window_set_sent (edit_window, TRUE);
1731 /* Save settings and close the window: */
1732 gtk_widget_destroy (GTK_WIDGET (edit_window));
1736 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1737 ModestMsgEditWindow *window)
1739 ModestMsgEditFormatState *format_state = NULL;
1741 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1742 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1744 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1747 format_state = modest_msg_edit_window_get_format_state (window);
1748 g_return_if_fail (format_state != NULL);
1750 format_state->bold = gtk_toggle_action_get_active (action);
1751 modest_msg_edit_window_set_format_state (window, format_state);
1752 g_free (format_state);
1757 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1758 ModestMsgEditWindow *window)
1760 ModestMsgEditFormatState *format_state = NULL;
1762 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1763 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1765 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1768 format_state = modest_msg_edit_window_get_format_state (window);
1769 g_return_if_fail (format_state != NULL);
1771 format_state->italics = gtk_toggle_action_get_active (action);
1772 modest_msg_edit_window_set_format_state (window, format_state);
1773 g_free (format_state);
1778 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1779 ModestMsgEditWindow *window)
1781 ModestMsgEditFormatState *format_state = NULL;
1783 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1784 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1786 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1789 format_state = modest_msg_edit_window_get_format_state (window);
1790 g_return_if_fail (format_state != NULL);
1792 format_state->bullet = gtk_toggle_action_get_active (action);
1793 modest_msg_edit_window_set_format_state (window, format_state);
1794 g_free (format_state);
1799 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1800 GtkRadioAction *selected,
1801 ModestMsgEditWindow *window)
1803 ModestMsgEditFormatState *format_state = NULL;
1804 GtkJustification value;
1806 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1808 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1811 value = gtk_radio_action_get_current_value (selected);
1813 format_state = modest_msg_edit_window_get_format_state (window);
1814 g_return_if_fail (format_state != NULL);
1816 format_state->justification = value;
1817 modest_msg_edit_window_set_format_state (window, format_state);
1818 g_free (format_state);
1822 modest_ui_actions_on_select_editor_color (GtkAction *action,
1823 ModestMsgEditWindow *window)
1825 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1826 g_return_if_fail (GTK_IS_ACTION (action));
1828 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1831 modest_msg_edit_window_select_color (window);
1835 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1836 ModestMsgEditWindow *window)
1838 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1839 g_return_if_fail (GTK_IS_ACTION (action));
1841 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1844 modest_msg_edit_window_select_background_color (window);
1848 modest_ui_actions_on_insert_image (GtkAction *action,
1849 ModestMsgEditWindow *window)
1851 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1852 g_return_if_fail (GTK_IS_ACTION (action));
1854 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1857 modest_msg_edit_window_insert_image (window);
1861 modest_ui_actions_on_attach_file (GtkAction *action,
1862 ModestMsgEditWindow *window)
1864 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1865 g_return_if_fail (GTK_IS_ACTION (action));
1867 modest_msg_edit_window_attach_file (window);
1871 modest_ui_actions_on_remove_attachments (GtkAction *action,
1872 ModestMsgEditWindow *window)
1874 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1875 g_return_if_fail (GTK_IS_ACTION (action));
1877 modest_msg_edit_window_remove_attachments (window, NULL);
1881 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1883 TnyFolderStore *parent_folder;
1884 GtkWidget *folder_view;
1886 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1888 folder_view = modest_main_window_get_child_widget (main_window,
1889 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1893 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1895 if (parent_folder) {
1896 gboolean finished = FALSE;
1898 gchar *folder_name = NULL, *suggested_name = NULL;
1900 /* Run the new folder dialog */
1902 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1907 if (result == GTK_RESPONSE_REJECT) {
1910 ModestMailOperation *mail_op;
1911 TnyFolder *new_folder = NULL;
1913 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1914 G_OBJECT(main_window));
1915 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1917 new_folder = modest_mail_operation_create_folder (mail_op,
1919 (const gchar *) folder_name);
1921 g_object_unref (new_folder);
1924 g_object_unref (mail_op);
1926 g_free (folder_name);
1930 g_object_unref (parent_folder);
1935 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1938 GObject *win = modest_mail_operation_get_source (mail_op);
1939 const GError *error = NULL;
1940 const gchar *message = NULL;
1942 /* Get error message */
1943 error = modest_mail_operation_get_error (mail_op);
1944 if (error != NULL && error->message != NULL) {
1945 message = error->message;
1947 message = _("!!! FIXME: Unable to rename");
1950 /* Show notification dialog */
1951 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
1952 g_object_unref (win);
1956 modest_ui_actions_on_rename_folder (GtkAction *action,
1957 ModestMainWindow *main_window)
1959 TnyFolderStore *folder;
1960 GtkWidget *folder_view;
1961 GtkWidget *header_view;
1963 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1965 folder_view = modest_main_window_get_child_widget (main_window,
1966 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1970 header_view = modest_main_window_get_child_widget (main_window,
1971 MODEST_WIDGET_TYPE_HEADER_VIEW);
1976 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1978 if (folder && TNY_IS_FOLDER (folder)) {
1981 const gchar *current_name;
1983 current_name = tny_folder_get_name (TNY_FOLDER (folder));
1984 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
1985 current_name, &folder_name);
1987 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
1988 ModestMailOperation *mail_op;
1991 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
1992 G_OBJECT(main_window),
1993 modest_ui_actions_rename_folder_error_handler,
1997 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2000 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2002 modest_mail_operation_rename_folder (mail_op,
2003 TNY_FOLDER (folder),
2004 (const gchar *) folder_name);
2006 g_object_unref (mail_op);
2007 g_free (folder_name);
2009 g_object_unref (folder);
2014 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2017 GObject *win = modest_mail_operation_get_source (mail_op);
2019 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2020 _("mail_in_ui_folder_delete_error"));
2021 g_object_unref (win);
2025 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2027 TnyFolderStore *folder;
2028 GtkWidget *folder_view;
2032 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2034 folder_view = modest_main_window_get_child_widget (main_window,
2035 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2039 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2041 /* Show an error if it's an account */
2042 if (!TNY_IS_FOLDER (folder)) {
2043 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2044 _("mail_in_ui_folder_delete_error"));
2049 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2050 tny_folder_get_name (TNY_FOLDER (folder)));
2051 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2052 (const gchar *) message);
2055 if (response == GTK_RESPONSE_OK) {
2056 ModestMailOperation *mail_op =
2057 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2058 G_OBJECT(main_window),
2059 modest_ui_actions_delete_folder_error_handler,
2062 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2064 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2065 g_object_unref (G_OBJECT (mail_op));
2068 g_object_unref (G_OBJECT (folder));
2072 modest_ui_actions_on_delete_folder (GtkAction *action,
2073 ModestMainWindow *main_window)
2075 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2077 delete_folder (main_window, FALSE);
2081 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2083 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2085 delete_folder (main_window, TRUE);
2089 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2090 const gchar* server_account_name,
2095 ModestMainWindow *main_window)
2097 g_return_if_fail(server_account_name);
2098 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2100 /* Initalize output parameters: */
2107 #ifdef MODEST_PLATFORM_MAEMO
2108 /* Maemo uses a different (awkward) button order,
2109 * It should probably just use gtk_alternative_dialog_button_order ().
2111 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2115 GTK_RESPONSE_ACCEPT,
2117 GTK_RESPONSE_REJECT,
2120 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2124 GTK_RESPONSE_REJECT,
2126 GTK_RESPONSE_ACCEPT,
2128 #endif /* MODEST_PLATFORM_MAEMO */
2130 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2132 gchar *server_name = modest_server_account_get_hostname (
2133 modest_runtime_get_account_mgr(), server_account_name);
2134 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2135 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2140 /* This causes a warning because the logical ID has no %s in it,
2141 * though the translation does, but there is not much we can do about that: */
2142 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2143 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2146 g_free (server_name);
2150 gchar *initial_username = modest_server_account_get_username (
2151 modest_runtime_get_account_mgr(), server_account_name);
2153 GtkWidget *entry_username = gtk_entry_new ();
2154 if (initial_username)
2155 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2156 /* Dim this if a connection has ever succeeded with this username,
2157 * as per the UI spec: */
2158 const gboolean username_known =
2159 modest_server_account_get_username_has_succeeded(
2160 modest_runtime_get_account_mgr(), server_account_name);
2161 gtk_widget_set_sensitive (entry_username, !username_known);
2163 #ifdef MODEST_PLATFORM_MAEMO
2164 /* Auto-capitalization is the default, so let's turn it off: */
2165 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2167 /* Create a size group to be used by all captions.
2168 * Note that HildonCaption does not create a default size group if we do not specify one.
2169 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2170 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2172 GtkWidget *caption = hildon_caption_new (sizegroup,
2173 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2174 gtk_widget_show (entry_username);
2175 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2176 FALSE, FALSE, MODEST_MARGIN_HALF);
2177 gtk_widget_show (caption);
2179 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2181 #endif /* MODEST_PLATFORM_MAEMO */
2184 GtkWidget *entry_password = gtk_entry_new ();
2185 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2186 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2188 #ifdef MODEST_PLATFORM_MAEMO
2189 /* Auto-capitalization is the default, so let's turn it off: */
2190 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2191 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2193 caption = hildon_caption_new (sizegroup,
2194 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2195 gtk_widget_show (entry_password);
2196 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2197 FALSE, FALSE, MODEST_MARGIN_HALF);
2198 gtk_widget_show (caption);
2199 g_object_unref (sizegroup);
2201 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2203 #endif /* MODEST_PLATFORM_MAEMO */
2205 /* This is not in the Maemo UI spec:
2206 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2207 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2211 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2213 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2215 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2217 modest_server_account_set_username (
2218 modest_runtime_get_account_mgr(), server_account_name,
2221 const gboolean username_was_changed =
2222 (strcmp (*username, initial_username) != 0);
2223 if (username_was_changed) {
2224 g_warning ("%s: tinymail does not yet support changing the "
2225 "username in the get_password() callback.\n", __FUNCTION__);
2230 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2232 /* We do not save the password in the configuration,
2233 * because this function is only called for passwords that should
2234 * not be remembered:
2235 modest_server_account_set_password (
2236 modest_runtime_get_account_mgr(), server_account_name,
2255 /* This is not in the Maemo UI spec:
2256 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2262 gtk_widget_destroy (dialog);
2264 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2268 modest_ui_actions_on_cut (GtkAction *action,
2269 ModestWindow *window)
2271 GtkWidget *focused_widget;
2273 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2274 if (GTK_IS_EDITABLE (focused_widget)) {
2275 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2276 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2277 GtkTextBuffer *buffer;
2278 GtkClipboard *clipboard;
2280 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2281 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2282 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2283 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2284 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2285 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2286 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2291 modest_ui_actions_on_copy (GtkAction *action,
2292 ModestWindow *window)
2294 GtkClipboard *clipboard;
2295 GtkWidget *focused_widget;
2297 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2298 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2300 if (GTK_IS_LABEL (focused_widget)) {
2301 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2302 } else if (GTK_IS_EDITABLE (focused_widget)) {
2303 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2304 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2305 GtkTextBuffer *buffer;
2306 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2307 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2308 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2309 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2310 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2311 TnyIterator *iter = tny_list_create_iterator (header_list);
2312 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2313 TnyFolder *folder = tny_header_get_folder (header);
2314 TnyAccount *account = tny_folder_get_account (folder);
2315 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2316 /* If it's POP then ask */
2317 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2318 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2319 g_object_unref (account);
2320 g_object_unref (folder);
2321 g_object_unref (header);
2322 g_object_unref (iter);
2324 /* Check that the messages have been previously downloaded */
2325 gboolean continue_download = TRUE;
2327 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2328 if (continue_download)
2329 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2330 g_object_unref (header_list);
2331 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2332 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2335 /* Show information banner */
2336 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2341 modest_ui_actions_on_undo (GtkAction *action,
2342 ModestWindow *window)
2344 ModestEmailClipboard *clipboard = NULL;
2346 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2347 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2348 } if (MODEST_IS_MAIN_WINDOW (window)) {
2349 /* Clear clipboard source */
2350 clipboard = modest_runtime_get_email_clipboard ();
2351 modest_email_clipboard_clear (clipboard);
2354 g_return_if_reached ();
2359 modest_ui_actions_on_paste (GtkAction *action,
2360 ModestWindow *window)
2362 GtkWidget *focused_widget;
2363 ModestMailOperation *mail_op = NULL;
2365 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2366 if (GTK_IS_EDITABLE (focused_widget)) {
2367 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2368 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2369 GtkTextBuffer *buffer;
2370 GtkClipboard *clipboard;
2372 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2373 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2374 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2375 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2376 ModestEmailClipboard *clipboard = NULL;
2377 TnyFolder *src_folder = NULL;
2378 TnyFolderStore *folder_store = NULL;
2379 TnyList *data = NULL;
2380 gboolean delete = FALSE;
2382 /* Check clipboard source */
2383 clipboard = modest_runtime_get_email_clipboard ();
2384 if (modest_email_clipboard_cleared (clipboard))
2387 /* Get elements to paste */
2388 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2390 /* Create a new mail operation */
2391 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2392 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2395 /* Get destination folder */
2396 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2398 /* transfer messages */
2400 modest_mail_operation_xfer_msgs (mail_op,
2402 TNY_FOLDER (folder_store),
2407 } else if (src_folder != NULL) {
2408 modest_mail_operation_xfer_folder (mail_op,
2416 g_object_unref (data);
2417 if (src_folder != NULL)
2418 g_object_unref (src_folder);
2419 if (folder_store != NULL)
2420 g_object_unref (folder_store);
2425 modest_ui_actions_on_select_all (GtkAction *action,
2426 ModestWindow *window)
2428 GtkWidget *focused_widget;
2430 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2431 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2432 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2433 } else if (GTK_IS_LABEL (focused_widget)) {
2434 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2435 } else if (GTK_IS_EDITABLE (focused_widget)) {
2436 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2437 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2438 GtkTextBuffer *buffer;
2439 GtkTextIter start, end;
2441 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2442 gtk_text_buffer_get_start_iter (buffer, &start);
2443 gtk_text_buffer_get_end_iter (buffer, &end);
2444 gtk_text_buffer_select_range (buffer, &start, &end);
2445 } else if (GTK_IS_HTML (focused_widget)) {
2446 gtk_html_select_all (GTK_HTML (focused_widget));
2447 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2448 GtkWidget *header_view = focused_widget;
2449 GtkTreeSelection *selection = NULL;
2451 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2452 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2453 MODEST_WIDGET_TYPE_HEADER_VIEW);
2455 /* Select all messages */
2456 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2457 gtk_tree_selection_select_all (selection);
2459 /* Set focuse on header view */
2460 gtk_widget_grab_focus (header_view);
2466 modest_ui_actions_on_mark_as_read (GtkAction *action,
2467 ModestWindow *window)
2469 g_return_if_fail (MODEST_IS_WINDOW(window));
2471 /* Mark each header as read */
2472 do_headers_action (window, headers_action_mark_as_read, NULL);
2476 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2477 ModestWindow *window)
2479 g_return_if_fail (MODEST_IS_WINDOW(window));
2481 /* Mark each header as read */
2482 do_headers_action (window, headers_action_mark_as_unread, NULL);
2486 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2487 GtkRadioAction *selected,
2488 ModestWindow *window)
2492 value = gtk_radio_action_get_current_value (selected);
2493 if (MODEST_IS_WINDOW (window)) {
2494 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2498 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2499 GtkRadioAction *selected,
2500 ModestWindow *window)
2502 TnyHeaderFlags flags;
2503 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2505 flags = gtk_radio_action_get_current_value (selected);
2506 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2509 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2510 GtkRadioAction *selected,
2511 ModestWindow *window)
2515 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2517 file_format = gtk_radio_action_get_current_value (selected);
2518 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2523 modest_ui_actions_on_zoom_plus (GtkAction *action,
2524 ModestWindow *window)
2526 g_return_if_fail (MODEST_IS_WINDOW (window));
2528 modest_window_zoom_plus (MODEST_WINDOW (window));
2532 modest_ui_actions_on_zoom_minus (GtkAction *action,
2533 ModestWindow *window)
2535 g_return_if_fail (MODEST_IS_WINDOW (window));
2537 modest_window_zoom_minus (MODEST_WINDOW (window));
2541 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2542 ModestWindow *window)
2544 ModestWindowMgr *mgr;
2545 gboolean fullscreen, active;
2546 g_return_if_fail (MODEST_IS_WINDOW (window));
2548 mgr = modest_runtime_get_window_mgr ();
2550 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2551 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2553 if (active != fullscreen) {
2554 modest_window_mgr_set_fullscreen_mode (mgr, active);
2555 gtk_window_present (GTK_WINDOW (window));
2560 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2561 ModestWindow *window)
2563 ModestWindowMgr *mgr;
2564 gboolean fullscreen;
2566 g_return_if_fail (MODEST_IS_WINDOW (window));
2568 mgr = modest_runtime_get_window_mgr ();
2569 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2570 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2572 gtk_window_present (GTK_WINDOW (window));
2576 * Used by modest_ui_actions_on_details to call do_headers_action
2579 headers_action_show_details (TnyHeader *header,
2580 ModestWindow *window,
2587 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2590 gtk_widget_show_all (dialog);
2591 gtk_dialog_run (GTK_DIALOG (dialog));
2593 gtk_widget_destroy (dialog);
2597 * Show the folder details in a ModestDetailsDialog widget
2600 show_folder_details (TnyFolder *folder,
2606 dialog = modest_details_dialog_new_with_folder (window, folder);
2609 gtk_widget_show_all (dialog);
2610 gtk_dialog_run (GTK_DIALOG (dialog));
2612 gtk_widget_destroy (dialog);
2616 * Show the header details in a ModestDetailsDialog widget
2619 modest_ui_actions_on_details (GtkAction *action,
2622 TnyList * headers_list;
2626 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2629 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2632 g_object_unref (msg);
2634 headers_list = get_selected_headers (win);
2638 iter = tny_list_create_iterator (headers_list);
2640 header = TNY_HEADER (tny_iterator_get_current (iter));
2641 headers_action_show_details (header, win, NULL);
2642 g_object_unref (header);
2644 g_object_unref (iter);
2645 g_object_unref (headers_list);
2647 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2648 GtkWidget *folder_view, *header_view;
2650 /* Check which widget has the focus */
2651 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2652 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2653 if (gtk_widget_is_focus (folder_view)) {
2654 TnyFolderStore *folder_store
2655 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2656 if (!folder_store) {
2657 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2660 /* Show only when it's a folder */
2661 /* This function should not be called for account items,
2662 * because we dim the menu item for them. */
2663 if (TNY_IS_FOLDER (folder_store)) {
2664 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2667 g_object_unref (folder_store);
2670 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2671 MODEST_WIDGET_TYPE_HEADER_VIEW);
2672 /* Show details of each header */
2673 do_headers_action (win, headers_action_show_details, header_view);
2679 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2680 ModestMsgEditWindow *window)
2682 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2684 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2688 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2689 ModestMsgEditWindow *window)
2691 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2693 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2697 modest_ui_actions_toggle_folders_view (GtkAction *action,
2698 ModestMainWindow *main_window)
2702 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2704 conf = modest_runtime_get_conf ();
2706 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2707 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2709 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2713 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2714 ModestWindow *window)
2716 gboolean active, fullscreen = FALSE;
2717 ModestWindowMgr *mgr;
2719 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2721 /* Check if we want to toggle the toolbar vuew in fullscreen
2723 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2724 "ViewShowToolbarFullScreen")) {
2728 /* Toggle toolbar */
2729 mgr = modest_runtime_get_window_mgr ();
2730 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2734 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2735 ModestMsgEditWindow *window)
2737 modest_msg_edit_window_select_font (window);
2741 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2742 const gchar *display_name,
2745 /* Do not change the application name if the widget has not
2746 the focus. This callback could be called even if the folder
2747 view has not the focus, because the handled signal could be
2748 emitted when the folder view is redrawn */
2749 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2751 gtk_window_set_title (window, display_name);
2753 gtk_window_set_title (window, " ");
2758 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2760 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2761 modest_msg_edit_window_select_contacts (window);
2765 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2767 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2768 modest_msg_edit_window_check_names (window);
2773 create_move_to_dialog (ModestWindow *win,
2774 GtkWidget *folder_view,
2775 GtkWidget **tree_view)
2777 GtkWidget *dialog, *scroll;
2779 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2781 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2783 GTK_RESPONSE_ACCEPT,
2785 GTK_RESPONSE_REJECT,
2788 /* Create scrolled window */
2789 scroll = gtk_scrolled_window_new (NULL, NULL);
2790 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2791 GTK_POLICY_AUTOMATIC,
2792 GTK_POLICY_AUTOMATIC);
2794 /* Create folder view */
2795 *tree_view = modest_platform_create_folder_view (NULL);
2797 /* It could happen that we're trying to move a message from a
2798 window (msg window for example) after the main window was
2799 closed, so we can not just get the model of the folder
2801 if (MODEST_IS_FOLDER_VIEW (folder_view))
2802 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2803 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2805 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2806 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2808 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2810 /* Add scroll to dialog */
2811 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2812 scroll, FALSE, FALSE, 0);
2814 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2816 /* Select INBOX or local account */
2817 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2823 * Returns TRUE if at least one of the headers of the list belongs to
2824 * a message that has been fully retrieved.
2827 has_retrieved_msgs (TnyList *list)
2830 gboolean found = FALSE;
2832 iter = tny_list_create_iterator (list);
2833 while (tny_iterator_is_done (iter) && !found) {
2835 TnyHeaderFlags flags;
2837 header = TNY_HEADER (tny_iterator_get_current (iter));
2838 flags = tny_header_get_flags (header);
2839 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2843 tny_iterator_next (iter);
2845 g_object_unref (iter);
2851 * Shows a confirmation dialog to the user when we're moving messages
2852 * from a remote server to the local storage. Returns the dialog
2853 * response. If it's other kind of movement the it always returns
2857 msgs_move_to_confirmation (GtkWindow *win,
2858 TnyFolder *dest_folder,
2861 gint response = GTK_RESPONSE_OK;
2863 /* If the destination is a local folder */
2864 if (modest_tny_folder_is_local_folder (dest_folder)) {
2865 TnyFolder *src_folder;
2869 /* Get source folder */
2870 iter = tny_list_create_iterator (headers);
2871 header = TNY_HEADER (tny_iterator_get_current (iter));
2872 src_folder = tny_header_get_folder (header);
2873 g_object_unref (header);
2874 g_object_unref (iter);
2876 /* if no src_folder, message may be an attahcment */
2877 if (src_folder == NULL)
2878 return GTK_RESPONSE_CANCEL;
2880 /* If the source is a remote folder */
2881 if (!modest_tny_folder_is_local_folder (src_folder)) {
2882 const gchar *message;
2884 if (has_retrieved_msgs (headers))
2885 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2886 tny_list_get_length (headers));
2888 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2889 tny_list_get_length (headers));
2891 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2892 (const gchar *) message);
2894 g_object_unref (src_folder);
2901 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2903 ModestMsgViewWindow *self = NULL;
2904 gboolean last, first;
2906 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2907 self = MODEST_MSG_VIEW_WINDOW (object);
2909 last = modest_msg_view_window_last_message_selected (self);
2910 first = modest_msg_view_window_first_message_selected (self);
2912 /* No more messages to view, so close this window */
2913 /* gboolean ret_value; */
2914 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2915 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
2917 modest_msg_view_window_select_previous_message (self);
2919 modest_msg_view_window_select_next_message (self);
2923 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2926 GObject *win = modest_mail_operation_get_source (mail_op);
2927 const GError *error = NULL;
2928 const gchar *message = NULL;
2930 /* Get error message */
2931 error = modest_mail_operation_get_error (mail_op);
2932 if (error != NULL && error->message != NULL) {
2933 message = error->message;
2935 message = _("mail_in_ui_folder_move_target_error");
2938 /* Show notification dialog */
2939 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2940 g_object_unref (win);
2944 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
2947 GObject *win = modest_mail_operation_get_source (mail_op);
2948 const GError *error = modest_mail_operation_get_error (mail_op);
2950 g_return_if_fail (error != NULL);
2951 if (error->message != NULL)
2952 g_printerr ("modest: %s\n", error->message);
2954 g_printerr ("modest: unkonw error on sedn&receive operation");
2956 /* Show error message */
2957 if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE)
2958 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2959 _CS("sfil_ib_unable_to_receive"));
2961 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2962 _CS("sfil_ib_unable_to_send"));
2963 g_object_unref (win);
2967 open_msg_for_purge_cb (ModestMailOperation *mail_op,
2974 gint pending_purges = 0;
2975 gboolean some_purged = FALSE;
2976 ModestWindow *win = MODEST_WINDOW (user_data);
2980 /* Once the message has been retrieved for purging, we check if
2981 * it's all ok for purging */
2983 parts = tny_simple_list_new ();
2984 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
2985 iter = tny_list_create_iterator (parts);
2987 while (!tny_iterator_is_done (iter)) {
2989 part = TNY_MIME_PART (tny_iterator_get_current (iter));
2990 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
2991 if (tny_mime_part_is_purged (part))
2996 tny_iterator_next (iter);
2999 if (pending_purges>0) {
3001 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3003 if (response == GTK_RESPONSE_OK) {
3004 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3005 tny_iterator_first (iter);
3006 while (!tny_iterator_is_done (iter)) {
3009 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3010 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3011 tny_mime_part_set_purged (part);
3012 tny_iterator_next (iter);
3015 tny_msg_rewrite_cache (msg);
3018 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3021 /* remove attachments */
3022 tny_iterator_first (iter);
3023 while (!tny_iterator_is_done (iter)) {
3026 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3027 g_object_unref (part);
3028 tny_iterator_next (iter);
3031 g_object_unref (iter);
3032 g_object_unref (parts);
3036 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3037 ModestMainWindow *win)
3039 GtkWidget *header_view;
3040 TnyList *header_list;
3043 TnyHeaderFlags flags;
3044 ModestWindow *msg_view_window = NULL;
3047 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3049 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3050 MODEST_WIDGET_TYPE_HEADER_VIEW);
3052 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3054 if (tny_list_get_length (header_list) == 1) {
3055 iter = tny_list_create_iterator (header_list);
3056 header = TNY_HEADER (tny_iterator_get_current (iter));
3057 g_object_unref (iter);
3062 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3063 header, &msg_view_window);
3064 flags = tny_header_get_flags (header);
3065 if (!(flags & TNY_HEADER_FLAG_CACHED))
3068 if (msg_view_window != NULL)
3069 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3071 /* do nothing; uid was registered before, so window is probably on it's way */
3072 g_warning ("debug: header %p has already been registered", header);
3075 ModestMailOperation *mail_op = NULL;
3076 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3077 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3079 modest_ui_actions_get_msgs_full_error_handler,
3081 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3082 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3084 g_object_unref (mail_op);
3087 g_object_unref (header);
3089 g_object_unref (header_list);
3093 * UI handler for the "Move to" action when invoked from the
3097 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3098 ModestMainWindow *win)
3100 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3101 GtkWidget *header_view = NULL;
3103 TnyFolderStore *folder_store = NULL;
3104 ModestMailOperation *mail_op = NULL;
3106 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3108 /* Get the folder view */
3109 folder_view = modest_main_window_get_child_widget (win,
3110 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3112 /* Get header view */
3113 header_view = modest_main_window_get_child_widget (win,
3114 MODEST_WIDGET_TYPE_HEADER_VIEW);
3116 /* Create and run the dialog */
3117 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3118 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3119 result = gtk_dialog_run (GTK_DIALOG(dialog));
3120 g_object_ref (tree_view);
3122 /* We do this to save an indentation level ;-) */
3123 if (result != GTK_RESPONSE_ACCEPT)
3126 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3128 if (TNY_IS_ACCOUNT (folder_store) &&
3129 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3132 /* Get folder or messages to transfer */
3133 if (gtk_widget_is_focus (folder_view)) {
3134 TnyFolderStore *src_folder;
3135 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3137 /* Clean folder on header view before moving it */
3138 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3140 if (TNY_IS_FOLDER (src_folder)) {
3142 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3144 modest_ui_actions_move_folder_error_handler,
3146 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3148 modest_mail_operation_xfer_folder (mail_op,
3149 TNY_FOLDER (src_folder),
3152 /* Unref mail operation */
3153 g_object_unref (G_OBJECT (mail_op));
3157 g_object_unref (G_OBJECT (src_folder));
3159 if (gtk_widget_is_focus (header_view)) {
3163 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3165 /* Ask for user confirmation */
3166 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3167 TNY_FOLDER (folder_store),
3170 /* Transfer messages */
3171 if (response == GTK_RESPONSE_OK) {
3173 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3175 modest_ui_actions_move_folder_error_handler,
3177 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3180 modest_mail_operation_xfer_msgs (mail_op,
3182 TNY_FOLDER (folder_store),
3187 g_object_unref (G_OBJECT (mail_op));
3189 g_object_unref (headers);
3193 if (folder_store != NULL)
3194 g_object_unref (folder_store);
3195 gtk_widget_destroy (dialog);
3200 * UI handler for the "Move to" action when invoked from the
3201 * ModestMsgViewWindow
3204 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3205 ModestMsgViewWindow *win)
3207 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3209 ModestMainWindow *main_window;
3213 /* Get the folder view */
3214 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3216 folder_view = modest_main_window_get_child_widget (main_window,
3217 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3221 /* Create and run the dialog */
3222 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3223 result = gtk_dialog_run (GTK_DIALOG(dialog));
3224 g_object_ref (tree_view);
3226 if (result == GTK_RESPONSE_ACCEPT) {
3227 TnyFolderStore *folder_store;
3230 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3232 /* Create header list */
3233 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3235 headers = tny_simple_list_new ();
3236 tny_list_prepend (headers, G_OBJECT (header));
3237 g_object_unref (header);
3239 /* Ask user for confirmation. MSG-NOT404 */
3240 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3241 TNY_FOLDER (folder_store),
3244 /* Transfer current msg */
3245 if (response == GTK_RESPONSE_OK) {
3246 ModestMailOperation *mail_op;
3248 /* Create mail op */
3249 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3250 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3253 /* Transfer messages */
3254 modest_mail_operation_xfer_msgs (mail_op,
3256 TNY_FOLDER (folder_store),
3258 transfer_msgs_from_viewer_cb,
3260 g_object_unref (G_OBJECT (mail_op));
3262 g_object_unref (headers);
3263 g_object_unref (folder_store);
3265 gtk_widget_destroy (dialog);
3269 modest_ui_actions_on_move_to (GtkAction *action,
3272 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3273 MODEST_IS_MSG_VIEW_WINDOW (win));
3275 if (MODEST_IS_MAIN_WINDOW (win))
3276 modest_ui_actions_on_main_window_move_to (action,
3277 MODEST_MAIN_WINDOW (win));
3279 modest_ui_actions_on_msg_view_window_move_to (action,
3280 MODEST_MSG_VIEW_WINDOW (win));
3284 * Calls #HeadersFunc for each header already selected in the main
3285 * window or the message currently being shown in the msg view window
3288 do_headers_action (ModestWindow *win,
3292 TnyList *headers_list;
3298 headers_list = get_selected_headers (win);
3302 /* Get the folder */
3303 iter = tny_list_create_iterator (headers_list);
3304 header = TNY_HEADER (tny_iterator_get_current (iter));
3305 folder = tny_header_get_folder (header);
3306 g_object_unref (header);
3308 /* Call the function for each header */
3309 while (!tny_iterator_is_done (iter)) {
3310 header = TNY_HEADER (tny_iterator_get_current (iter));
3311 func (header, win, user_data);
3312 g_object_unref (header);
3313 tny_iterator_next (iter);
3316 /* Trick: do a poke status in order to speed up the signaling
3318 tny_folder_poke_status (folder);
3321 g_object_unref (folder);
3322 g_object_unref (iter);
3323 g_object_unref (headers_list);
3327 modest_ui_actions_view_attachment (GtkAction *action,
3328 ModestWindow *window)
3330 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3331 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3333 /* not supported window for this action */
3334 g_return_if_reached ();
3339 modest_ui_actions_save_attachments (GtkAction *action,
3340 ModestWindow *window)
3342 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3343 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3345 /* not supported window for this action */
3346 g_return_if_reached ();
3351 modest_ui_actions_remove_attachments (GtkAction *action,
3352 ModestWindow *window)
3354 if (MODEST_IS_MAIN_WINDOW (window)) {
3355 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3356 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3357 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3359 /* not supported window for this action */
3360 g_return_if_reached ();
3365 modest_ui_actions_on_settings (GtkAction *action,
3370 dialog = modest_platform_get_global_settings_dialog ();
3371 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3372 gtk_widget_show_all (dialog);
3374 gtk_dialog_run (GTK_DIALOG (dialog));
3376 gtk_widget_destroy (dialog);
3380 modest_ui_actions_on_help (GtkAction *action,
3383 const gchar *help_id = NULL;
3385 if (MODEST_IS_MAIN_WINDOW (win)) {
3386 const gchar *action_name;
3387 action_name = gtk_action_get_name (action);
3389 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3390 !strcmp (action_name, "HeaderViewCSMHelp")) {
3391 GtkWidget *folder_view;
3392 TnyFolderStore *folder_store;
3393 /* Get selected folder */
3394 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3395 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3396 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3398 /* Switch help_id */
3399 if (TNY_IS_FOLDER (folder_store)) {
3400 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3401 case TNY_FOLDER_TYPE_NORMAL:
3402 help_id = "applications_email_userfolder";
3404 case TNY_FOLDER_TYPE_INBOX:
3405 help_id = "applications_email_inbox";
3407 case TNY_FOLDER_TYPE_OUTBOX:
3408 help_id = "applications_email_outbox";
3410 case TNY_FOLDER_TYPE_SENT:
3411 help_id = "applications_email_sent";
3413 case TNY_FOLDER_TYPE_DRAFTS:
3414 help_id = "applications_email_drafts";
3416 case TNY_FOLDER_TYPE_ARCHIVE:
3417 help_id = "applications_email_archive";
3423 g_object_unref (folder_store);
3425 help_id = "applications_email_mainview";
3427 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3428 help_id = "applications_email_viewer";
3429 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3430 help_id = "applications_email_editor";
3432 modest_platform_show_help (GTK_WINDOW (win), help_id);
3436 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3437 ModestWindow *window)
3439 ModestMailOperation *mail_op;
3443 headers = get_selected_headers (window);
3447 /* Create mail operation */
3448 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3450 modest_ui_actions_get_msgs_full_error_handler,
3452 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3453 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3456 g_object_unref (headers);
3457 g_object_unref (mail_op);
3461 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3462 ModestWindow *window)
3464 g_return_if_fail (MODEST_IS_WINDOW (window));
3467 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3471 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3472 ModestWindow *window)
3474 g_return_if_fail (MODEST_IS_WINDOW (window));
3477 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3481 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3482 ModestWindow *window)
3484 g_return_if_fail (MODEST_IS_WINDOW (window));
3487 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3491 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3492 ModestWindow *window)
3494 g_return_if_fail (MODEST_IS_WINDOW (window));
3497 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3501 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3502 ModestWindow *window)
3504 g_return_if_fail (MODEST_IS_WINDOW (window));
3507 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3511 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3512 ModestWindow *window)
3514 g_return_if_fail (MODEST_IS_WINDOW (window));
3517 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3521 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3522 ModestWindow *window)
3524 g_return_if_fail (MODEST_IS_WINDOW (window));
3527 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3531 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3532 ModestWindow *window)
3534 g_return_if_fail (MODEST_IS_WINDOW (window));
3537 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3541 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3543 g_return_if_fail (MODEST_IS_WINDOW (window));
3546 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3550 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3552 g_return_if_fail (MODEST_IS_WINDOW (window));
3554 modest_platform_show_search_messages (GTK_WINDOW (window));
3558 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3560 g_return_if_fail (MODEST_IS_WINDOW (win));
3561 modest_platform_show_addressbook (GTK_WINDOW (win));
3566 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3567 ModestWindow *window)
3569 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3571 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3575 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3576 ModestMailOperationState *state,
3579 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3581 /* Set send/receive operation finished */
3582 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3583 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));