1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
49 #ifdef MODEST_PLATFORM_MAEMO
50 #include "maemo/modest-osso-state-saving.h"
51 #endif /* MODEST_PLATFORM_MAEMO */
53 #include "widgets/modest-ui-constants.h"
54 #include <widgets/modest-main-window.h>
55 #include <widgets/modest-msg-view-window.h>
56 #include <widgets/modest-account-view-window.h>
57 #include <widgets/modest-details-dialog.h>
58 #include <widgets/modest-attachments-view.h>
59 #include "widgets/modest-folder-view.h"
60 #include "widgets/modest-global-settings-dialog.h"
61 #include "modest-connection-specific-smtp-window.h"
62 #include "modest-account-mgr-helpers.h"
63 #include "modest-mail-operation.h"
64 #include "modest-text-utils.h"
66 #ifdef MODEST_HAVE_EASYSETUP
67 #include "easysetup/modest-easysetup-wizard.h"
68 #endif /* MODEST_HAVE_EASYSETUP */
70 #include <modest-widget-memory.h>
71 #include <tny-error.h>
72 #include <tny-simple-list.h>
73 #include <tny-msg-view.h>
74 #include <tny-device.h>
75 #include <tny-merge-folder.h>
77 #include <gtkhtml/gtkhtml.h>
79 typedef struct _GetMsgAsyncHelper {
81 ModestMailOperation *mail_op;
88 typedef enum _ReplyForwardAction {
94 typedef struct _ReplyForwardHelper {
95 guint reply_forward_type;
96 ReplyForwardAction action;
98 GtkWidget *parent_window;
103 * The do_headers_action uses this kind of functions to perform some
104 * action to each member of a list of headers
106 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
109 do_headers_action (ModestWindow *win,
114 static void open_msg_cb (ModestMailOperation *mail_op,
119 static void reply_forward_cb (ModestMailOperation *mail_op,
124 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
127 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
128 ModestMailOperationState *state,
134 run_account_setup_wizard (ModestWindow *win)
136 ModestEasysetupWizardDialog *wizard;
138 g_return_if_fail (MODEST_IS_WINDOW(win));
140 wizard = modest_easysetup_wizard_dialog_new ();
141 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
142 gtk_dialog_run (GTK_DIALOG (wizard));
143 gtk_widget_destroy (GTK_WIDGET (wizard));
148 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
151 const gchar *authors[] = {
152 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
155 about = gtk_about_dialog_new ();
156 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
157 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
158 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
159 _("Copyright (c) 2006, Nokia Corporation\n"
160 "All rights reserved."));
161 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
162 _("a modest e-mail client\n\n"
163 "design and implementation: Dirk-Jan C. Binnema\n"
164 "contributions from the fine people at KC and Ig\n"
165 "uses the tinymail email framework written by Philip van Hoof"));
166 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
167 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
169 gtk_dialog_run (GTK_DIALOG (about));
170 gtk_widget_destroy(about);
174 * Gets the list of currently selected messages. If the win is the
175 * main window, then it returns a newly allocated list of the headers
176 * selected in the header view. If win is the msg view window, then
177 * the value returned is a list with just a single header.
179 * The caller of this funcion must free the list.
182 get_selected_headers (ModestWindow *win)
184 if (MODEST_IS_MAIN_WINDOW(win)) {
185 GtkWidget *header_view;
187 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
188 MODEST_WIDGET_TYPE_HEADER_VIEW);
189 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
191 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
192 /* for MsgViewWindows, we simply return a list with one element */
194 TnyList *list = NULL;
196 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
197 if (header != NULL) {
198 list = tny_simple_list_new ();
199 tny_list_prepend (list, G_OBJECT(header));
200 g_object_unref (G_OBJECT(header));
210 headers_action_mark_as_read (TnyHeader *header,
214 TnyHeaderFlags flags;
216 g_return_if_fail (TNY_IS_HEADER(header));
218 flags = tny_header_get_flags (header);
219 if (flags & TNY_HEADER_FLAG_SEEN) return;
220 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
224 headers_action_mark_as_unread (TnyHeader *header,
228 TnyHeaderFlags flags;
230 g_return_if_fail (TNY_IS_HEADER(header));
232 flags = tny_header_get_flags (header);
233 if (flags & TNY_HEADER_FLAG_SEEN) {
234 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
240 headers_action_delete (TnyHeader *header,
244 ModestMailOperation *mail_op = NULL;
246 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
247 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
250 /* Always delete. TODO: Move to trash still not supported */
251 modest_mail_operation_remove_msg (mail_op, header, FALSE);
252 g_object_unref (G_OBJECT (mail_op));
256 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
258 TnyList *header_list = NULL;
259 TnyIterator *iter = NULL;
260 TnyHeader *header = NULL;
261 gchar *message = NULL;
265 ModestWindowMgr *mgr;
266 GtkWidget *header_view;
268 g_return_if_fail (MODEST_IS_WINDOW(win));
270 /* Check first if the header view has the focus */
271 if (MODEST_IS_MAIN_WINDOW (win)) {
272 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
273 MODEST_WIDGET_TYPE_HEADER_VIEW);
274 if (!gtk_widget_is_focus (header_view))
278 header_list = get_selected_headers (win);
279 if (!header_list) return;
281 /* Check if any of the headers is already opened, or in the process of being opened */
282 iter = tny_list_create_iterator (header_list);
284 mgr = modest_runtime_get_window_mgr ();
285 while (!tny_iterator_is_done (iter) && !found) {
286 header = TNY_HEADER (tny_iterator_get_current (iter));
287 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
288 g_object_unref (header);
289 tny_iterator_next (iter);
291 g_object_unref (iter);
296 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
297 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
299 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
303 g_object_unref (header_list);
308 if (tny_list_get_length(header_list) == 1) {
309 iter = tny_list_create_iterator (header_list);
310 header = TNY_HEADER (tny_iterator_get_current (iter));
311 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
312 g_object_unref (header);
313 g_object_unref (iter);
315 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
316 tny_list_get_length(header_list)), desc);
318 /* Confirmation dialog */
319 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
323 if (response == GTK_RESPONSE_OK) {
324 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
326 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
330 /* Remove each header */
331 do_headers_action (win, headers_action_delete, NULL);
333 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
334 gtk_widget_destroy (GTK_WIDGET(win));
338 /* Update toolbar dimming state */
339 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
344 g_object_unref (header_list);
349 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
351 #ifdef MODEST_PLATFORM_MAEMO
352 modest_osso_save_state();
353 #endif /* MODEST_PLATFORM_MAEMO */
355 g_debug ("closing down, clearing %d item(s) from operation queue",
356 modest_mail_operation_queue_num_elements
357 (modest_runtime_get_mail_operation_queue()));
359 /* cancel all outstanding operations */
360 modest_mail_operation_queue_cancel_all
361 (modest_runtime_get_mail_operation_queue());
363 g_debug ("queue has been cleared");
365 /* note: when modest-tny-account-store is finalized,
366 it will automatically set all network connections
373 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
376 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
378 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
379 /* gtk_widget_destroy (GTK_WIDGET (win)); */
380 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
381 /* gboolean ret_value; */
382 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
383 /* } else if (MODEST_IS_WINDOW (win)) { */
384 /* gtk_widget_destroy (GTK_WIDGET (win)); */
386 /* g_return_if_reached (); */
391 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
393 GtkClipboard *clipboard = NULL;
394 gchar *selection = NULL;
396 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
397 selection = gtk_clipboard_wait_for_text (clipboard);
399 /* Question: why is the clipboard being used here?
400 * It doesn't really make a lot of sense. */
404 modest_address_book_add_address (selection);
410 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
412 /* This is currently only implemented for Maemo */
413 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
414 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
415 run_account_setup_wizard (win);
418 /* Show the list of accounts: */
419 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
420 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
421 gtk_dialog_run (account_win);
422 gtk_widget_destroy (GTK_WIDGET(account_win));
425 GtkWidget *dialog, *label;
427 /* Create the widgets */
429 dialog = gtk_dialog_new_with_buttons ("Message",
431 GTK_DIALOG_DESTROY_WITH_PARENT,
435 label = gtk_label_new ("Hello World!");
437 /* Ensure that the dialog box is destroyed when the user responds. */
439 g_signal_connect_swapped (dialog, "response",
440 G_CALLBACK (gtk_widget_destroy),
443 /* Add the label, and show everything we've added to the dialog. */
445 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
447 gtk_widget_show_all (dialog);
448 #endif /* MODEST_PLATFORM_MAEMO */
452 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
454 ModestWindow *main_window = MODEST_WINDOW (user_data);
456 /* Save any changes. */
457 modest_connection_specific_smtp_window_save_server_accounts (
458 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
459 modest_window_get_active_account (main_window));
460 gtk_widget_destroy (GTK_WIDGET (window));
466 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
468 /* This is currently only implemented for Maemo,
469 * because it requires an API (libconic) to detect different connection
472 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
474 /* Create the window if necessary: */
475 const gchar *active_account_name = modest_window_get_active_account (win);
477 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
478 * or show the default account?
479 * If we show the default account then the account name should be shown in
480 * the window when we show it. */
481 if (!active_account_name) {
482 g_warning ("%s: No account is active.", __FUNCTION__);
486 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
487 modest_connection_specific_smtp_window_fill_with_connections (
488 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
489 modest_runtime_get_account_mgr(),
490 active_account_name);
492 /* Show the window: */
493 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
494 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
495 gtk_widget_show (specific_window);
497 /* Save changes when the window is hidden: */
498 g_signal_connect (specific_window, "hide",
499 G_CALLBACK (on_smtp_servers_window_hide), win);
500 #endif /* MODEST_PLATFORM_MAEMO */
504 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
506 ModestWindow *msg_win = NULL;
508 TnyFolder *folder = NULL;
509 gchar *account_name = NULL;
510 gchar *from_str = NULL;
511 /* GError *err = NULL; */
512 TnyAccount *account = NULL;
513 ModestWindowMgr *mgr;
514 gchar *signature = NULL, *blank_and_signature = NULL;
516 /* if there are no accounts yet, just show the wizard */
517 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
518 run_account_setup_wizard (win);
522 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
524 account_name = g_strdup (modest_window_get_active_account (win));
526 g_printerr ("modest: no account found\n");
530 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
532 TNY_ACCOUNT_TYPE_STORE);
534 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
538 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
540 g_printerr ("modest: failed get from string for '%s'\n", account_name);
544 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
545 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
546 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
547 MODEST_ACCOUNT_SIGNATURE, FALSE);
548 blank_and_signature = g_strconcat ("\n", signature, NULL);
551 blank_and_signature = g_strdup ("");
554 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
556 g_printerr ("modest: failed to create new msg\n");
560 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
562 g_printerr ("modest: failed to find Drafts folder\n");
567 /* Create and register edit window */
568 /* This is destroyed by TOOD. */
569 msg_win = modest_msg_edit_window_new (msg, account_name);
570 mgr = modest_runtime_get_window_mgr ();
571 modest_window_mgr_register_window (mgr, msg_win);
574 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
576 gtk_widget_show_all (GTK_WIDGET (msg_win));
579 g_free (account_name);
581 g_free (blank_and_signature);
583 g_object_unref (msg_win);
585 g_object_unref (G_OBJECT(account));
587 g_object_unref (G_OBJECT(msg));
589 g_object_unref (G_OBJECT(folder));
593 open_msg_cb (ModestMailOperation *mail_op,
598 ModestWindowMgr *mgr = NULL;
599 ModestWindow *parent_win = NULL;
600 ModestWindow *win = NULL;
601 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
602 gchar *account = NULL;
605 /* TODO: Show an error? (review the specs) */
609 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
610 folder = tny_header_get_folder (header);
612 /* Mark header as read */
613 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
616 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
618 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
620 /* Gets folder type (OUTBOX headers will be opened in edit window */
621 if (modest_tny_folder_is_local_folder (folder))
622 folder_type = modest_tny_folder_get_local_folder_type (folder);
624 /* If the header is in the drafts folder then open the editor,
625 else the message view window */
626 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
627 /* we cannot edit without a valid account... */
628 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
629 run_account_setup_wizard(parent_win);
632 win = modest_msg_edit_window_new (msg, account);
634 gchar *uid = modest_tny_folder_get_header_unique_id (header);
636 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
637 GtkWidget *header_view;
638 GtkTreeSelection *sel;
639 GList *sel_list = NULL;
642 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
643 MODEST_WIDGET_TYPE_HEADER_VIEW);
645 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
646 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
648 if (sel_list != NULL) {
649 GtkTreeRowReference *row_reference;
651 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
652 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
653 g_list_free (sel_list);
655 win = modest_msg_view_window_new_with_header_model (msg,
660 gtk_tree_row_reference_free (row_reference);
662 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
665 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
670 /* Register and show new window */
672 mgr = modest_runtime_get_window_mgr ();
673 modest_window_mgr_register_window (mgr, win);
674 g_object_unref (win);
675 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
676 gtk_widget_show_all (GTK_WIDGET(win));
679 /* Update toolbar dimming state */
680 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
681 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
687 g_object_unref (parent_win);
688 /* g_object_unref (msg); */
689 g_object_unref (folder);
693 * This function is the error handler of the
694 * modest_mail_operation_get_msgs_full operation
697 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
702 error = modest_mail_operation_get_error (mail_op);
703 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
704 GObject *win = modest_mail_operation_get_source (mail_op);
706 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
708 g_object_unref (win);
713 * This function is used by both modest_ui_actions_on_open and
714 * modest_ui_actions_on_header_activated. This way we always do the
715 * same when trying to open messages.
718 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
720 ModestWindowMgr *mgr = NULL;
721 TnyIterator *iter = NULL;
722 ModestMailOperation *mail_op1 = NULL;
723 ModestMailOperation *mail_op2 = NULL;
724 TnyList *not_opened_headers = NULL;
725 TnyList *not_opened_cached_headers = NULL;
726 TnyHeaderFlags flags;
728 /* Look if we already have a message view for each header. If
729 true, then remove the header from the list of headers to
731 mgr = modest_runtime_get_window_mgr ();
732 iter = tny_list_create_iterator (headers);
733 not_opened_headers = tny_simple_list_new ();
734 not_opened_cached_headers = tny_simple_list_new ();
735 while (!tny_iterator_is_done (iter)) {
737 ModestWindow *window;
741 header = TNY_HEADER (tny_iterator_get_current (iter));
742 flags = tny_header_get_flags (header);
745 found = modest_window_mgr_find_registered_header (mgr, header, &window);
747 /* Do not open again the message and present the
748 window to the user */
751 gtk_window_present (GTK_WINDOW (window));
753 /* the header has been registered already, we don't do
754 * anything but wait for the window to come up*/
755 g_warning ("debug: header %p already registered, waiting for window",
758 /* register the header before actually creating the window */
759 modest_window_mgr_register_header (mgr, header);
761 if (!(flags & TNY_HEADER_FLAG_CACHED))
762 tny_list_append (not_opened_headers, G_OBJECT (header));
763 /* Check if msg has already been retreived */
765 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
767 g_object_unref (header);
768 tny_iterator_next (iter);
771 /* Open each uncached message */
772 if (tny_list_get_length (not_opened_headers) > 0) {
773 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
775 modest_ui_actions_get_msgs_full_error_handler,
777 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
778 if (tny_list_get_length (not_opened_headers) > 1) {
779 modest_mail_operation_get_msgs_full (mail_op1,
785 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
786 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
787 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
788 g_object_unref (header);
789 g_object_unref (iter);
793 /* Open each cached message */
794 if (tny_list_get_length (not_opened_cached_headers) > 0) {
795 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
797 modest_ui_actions_get_msgs_full_error_handler,
799 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
800 if (tny_list_get_length (not_opened_cached_headers) > 1) {
801 modest_mail_operation_get_msgs_full (mail_op2,
807 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
808 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
809 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
810 g_object_unref (header);
811 g_object_unref (iter);
816 if (not_opened_headers != NULL)
817 g_object_unref (not_opened_headers);
818 if (not_opened_cached_headers != NULL)
819 g_object_unref (not_opened_cached_headers);
821 g_object_unref (iter);
822 if (mail_op1 != NULL)
823 g_object_unref (mail_op1);
824 if (mail_op2 != NULL)
825 g_object_unref (mail_op2);
829 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
834 headers = get_selected_headers (win);
839 _modest_ui_actions_open (headers, win);
841 g_object_unref(headers);
846 free_reply_forward_helper (gpointer data)
848 ReplyForwardHelper *helper;
850 helper = (ReplyForwardHelper *) data;
851 g_free (helper->account_name);
852 g_slice_free (ReplyForwardHelper, helper);
856 reply_forward_cb (ModestMailOperation *mail_op,
862 ReplyForwardHelper *rf_helper;
863 ModestWindow *msg_win = NULL;
864 ModestEditType edit_type;
866 TnyAccount *account = NULL;
867 ModestWindowMgr *mgr = NULL;
868 gchar *signature = NULL;
870 g_return_if_fail (user_data != NULL);
871 rf_helper = (ReplyForwardHelper *) user_data;
873 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
874 rf_helper->account_name);
875 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
876 rf_helper->account_name,
877 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
878 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
879 rf_helper->account_name,
880 MODEST_ACCOUNT_SIGNATURE, FALSE);
883 /* Create reply mail */
884 switch (rf_helper->action) {
887 modest_tny_msg_create_reply_msg (msg, from, signature,
888 rf_helper->reply_forward_type,
889 MODEST_TNY_MSG_REPLY_MODE_SENDER);
891 case ACTION_REPLY_TO_ALL:
893 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
894 MODEST_TNY_MSG_REPLY_MODE_ALL);
895 edit_type = MODEST_EDIT_TYPE_REPLY;
899 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
900 edit_type = MODEST_EDIT_TYPE_FORWARD;
903 g_return_if_reached ();
910 g_printerr ("modest: failed to create message\n");
914 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
915 rf_helper->account_name,
916 TNY_ACCOUNT_TYPE_STORE);
918 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
922 /* Create and register the windows */
923 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
924 mgr = modest_runtime_get_window_mgr ();
925 modest_window_mgr_register_window (mgr, msg_win);
927 if (rf_helper->parent_window != NULL) {
930 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
931 modest_window_set_zoom (msg_win, parent_zoom);
934 /* Show edit window */
935 gtk_widget_show_all (GTK_WIDGET (msg_win));
939 g_object_unref (msg_win);
941 g_object_unref (G_OBJECT (new_msg));
943 g_object_unref (G_OBJECT (account));
944 /* g_object_unref (msg); */
945 g_object_unref (header);
949 * Checks a list of headers. If any of them are not currently
950 * downloaded (CACHED) then it asks the user for permission to
953 * Returns FALSE if the user does not want to download the
954 * messages. Returns TRUE if the user allowed the download or if all
955 * of them are currently downloaded
958 download_uncached_messages (TnyList *header_list, GtkWindow *win)
962 gint uncached_messages = 0;
964 iter = tny_list_create_iterator (header_list);
965 while (!tny_iterator_is_done (iter)) {
967 TnyHeaderFlags flags;
969 header = TNY_HEADER (tny_iterator_get_current (iter));
970 flags = tny_header_get_flags (header);
971 /* TODO: is this the right flag?, it seems that some
972 headers that have been previously downloaded do not
974 if (! (flags & TNY_HEADER_FLAG_CACHED))
975 uncached_messages ++;
976 g_object_unref (header);
977 tny_iterator_next (iter);
979 g_object_unref (iter);
981 /* Ask for user permission to download the messages */
983 if (uncached_messages > 0) {
984 GtkResponseType response;
986 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
987 ngettext("mcen_nc_get_msg",
990 if (response == GTK_RESPONSE_CANCEL)
998 * Common code for the reply and forward actions
1001 reply_forward (ReplyForwardAction action, ModestWindow *win)
1003 ModestMailOperation *mail_op = NULL;
1004 TnyList *header_list = NULL;
1005 ReplyForwardHelper *rf_helper = NULL;
1006 guint reply_forward_type;
1007 gboolean continue_download;
1009 g_return_if_fail (MODEST_IS_WINDOW(win));
1011 /* we need an account when editing */
1012 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1013 run_account_setup_wizard (win);
1017 header_list = get_selected_headers (win);
1021 /* Check that the messages have been previously downloaded */
1022 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1023 if (!continue_download) {
1024 g_object_unref (header_list);
1028 reply_forward_type =
1029 modest_conf_get_int (modest_runtime_get_conf (),
1030 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1032 /* We assume that we can only select messages of the
1033 same folder and that we reply all of them from the
1034 same account. In fact the interface currently only
1035 allows single selection */
1038 rf_helper = g_slice_new0 (ReplyForwardHelper);
1039 rf_helper->reply_forward_type = reply_forward_type;
1040 rf_helper->action = action;
1041 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1042 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1043 rf_helper->parent_window = GTK_WIDGET (win);
1044 if (!rf_helper->account_name)
1045 rf_helper->account_name =
1046 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1048 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1051 /* Get header and message. Do not free them here, the
1052 reply_forward_cb must do it */
1053 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1054 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1055 if (!msg || !header) {
1057 g_object_unref (msg);
1059 g_object_unref (header);
1060 g_printerr ("modest: no message found\n");
1063 reply_forward_cb (NULL, header, msg, rf_helper);
1065 /* Retrieve messages */
1066 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1068 modest_ui_actions_get_msgs_full_error_handler,
1070 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1071 modest_mail_operation_get_msgs_full (mail_op,
1075 free_reply_forward_helper);
1078 g_object_unref(mail_op);
1082 g_object_unref (header_list);
1086 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1088 g_return_if_fail (MODEST_IS_WINDOW(win));
1090 reply_forward (ACTION_REPLY, win);
1094 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1096 g_return_if_fail (MODEST_IS_WINDOW(win));
1098 reply_forward (ACTION_FORWARD, win);
1102 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1104 g_return_if_fail (MODEST_IS_WINDOW(win));
1106 reply_forward (ACTION_REPLY_TO_ALL, win);
1110 modest_ui_actions_on_next (GtkAction *action,
1111 ModestWindow *window)
1113 if (MODEST_IS_MAIN_WINDOW (window)) {
1114 GtkWidget *header_view;
1116 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1117 MODEST_WIDGET_TYPE_HEADER_VIEW);
1121 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1122 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1123 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1125 g_return_if_reached ();
1130 modest_ui_actions_on_prev (GtkAction *action,
1131 ModestWindow *window)
1133 g_return_if_fail (MODEST_IS_WINDOW(window));
1135 if (MODEST_IS_MAIN_WINDOW (window)) {
1136 GtkWidget *header_view;
1137 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1138 MODEST_WIDGET_TYPE_HEADER_VIEW);
1142 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1143 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1144 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1146 g_return_if_reached ();
1151 modest_ui_actions_on_sort (GtkAction *action,
1152 ModestWindow *window)
1154 g_return_if_fail (MODEST_IS_WINDOW(window));
1156 if (MODEST_IS_MAIN_WINDOW (window)) {
1157 GtkWidget *header_view;
1158 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1159 MODEST_WIDGET_TYPE_HEADER_VIEW);
1163 /* Show sorting dialog */
1164 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1169 new_messages_arrived (ModestMailOperation *self,
1173 if (new_messages == 0)
1176 modest_platform_on_new_msg ();
1180 * This function performs the send & receive required actions. The
1181 * window is used to create the mail operation. Typically it should
1182 * always be the main window, but we pass it as argument in order to
1186 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1188 gchar *acc_name = NULL;
1189 ModestMailOperation *mail_op;
1191 /* If no account name was provided then get the current account, and if
1192 there is no current account then pick the default one: */
1193 if (!account_name) {
1194 acc_name = g_strdup (modest_window_get_active_account(win));
1196 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1198 g_printerr ("modest: cannot get default account\n");
1202 acc_name = g_strdup (account_name);
1205 /* Set send/receive operation in progress */
1206 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1208 /* mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win)); */
1209 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
1211 modest_ui_actions_send_receive_error_handler,
1214 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1215 G_CALLBACK (_on_send_receive_progress_changed),
1218 /* Send & receive. */
1219 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1220 /* Receive and then send. The operation is tagged initially as
1221 a receive operation because the account update performs a
1222 receive and then a send. The operation changes its type
1223 internally, so the progress objects will receive the proper
1224 progress information */
1225 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1226 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1227 g_object_unref (G_OBJECT (mail_op));
1234 * Refreshes all accounts. This function will be used by automatic
1238 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1240 GSList *account_names, *iter;
1242 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1245 iter = account_names;
1247 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1248 iter = g_slist_next (iter);
1251 modest_account_mgr_free_account_names (account_names);
1252 account_names = NULL;
1256 * Handler of the click on Send&Receive button in the main toolbar
1259 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1261 /* Check if accounts exist */
1262 gboolean accounts_exist =
1263 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1265 /* If not, allow the user to create an account before trying to send/receive. */
1266 if (!accounts_exist)
1267 modest_ui_actions_on_accounts (NULL, win);
1269 /* Refresh the active account */
1270 modest_ui_actions_do_send_receive (NULL, win);
1275 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1278 GtkWidget *header_view;
1280 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1282 header_view = modest_main_window_get_child_widget (main_window,
1283 MODEST_WIDGET_TYPE_HEADER_VIEW);
1287 conf = modest_runtime_get_conf ();
1289 /* what is saved/restored is depending on the style; thus; we save with
1290 * old style, then update the style, and restore for this new style
1292 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1294 if (modest_header_view_get_style
1295 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1296 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1297 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1299 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1300 MODEST_HEADER_VIEW_STYLE_DETAILS);
1302 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1303 MODEST_CONF_HEADER_VIEW_KEY);
1308 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1310 ModestMainWindow *main_window)
1312 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1313 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1315 /* If no header has been selected then exit */
1320 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1321 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1323 /* Update Main window title */
1324 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1325 const gchar *subject = tny_header_get_subject (header);
1326 if (subject && strlen(subject) > 0)
1327 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1329 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1332 /* Update toolbar dimming state */
1333 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1337 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1339 ModestMainWindow *main_window)
1343 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1348 headers = tny_simple_list_new ();
1349 tny_list_prepend (headers, G_OBJECT (header));
1351 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1353 g_object_unref (headers);
1357 set_active_account_from_tny_account (TnyAccount *account,
1358 ModestWindow *window)
1360 const gchar *server_acc_name = tny_account_get_id (account);
1362 /* We need the TnyAccount provided by the
1363 account store because that is the one that
1364 knows the name of the Modest account */
1365 TnyAccount *modest_server_account = modest_server_account =
1366 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1367 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1370 const gchar *modest_acc_name =
1371 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1372 modest_window_set_active_account (window, modest_acc_name);
1373 g_object_unref (modest_server_account);
1378 folder_refreshed_cb (const GObject *obj,
1382 ModestMainWindow *win = NULL;
1383 GtkWidget *header_view;
1385 g_return_if_fail (TNY_IS_FOLDER (folder));
1387 win = MODEST_MAIN_WINDOW (user_data);
1389 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1391 /* Check if folder is empty and set headers view contents style */
1392 if (tny_folder_get_all_count (folder) == 0) {
1393 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1394 modest_main_window_set_contents_style (win,
1395 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1397 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1402 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1403 TnyFolderStore *folder_store,
1405 ModestMainWindow *main_window)
1408 GtkWidget *header_view;
1410 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1412 header_view = modest_main_window_get_child_widget(main_window,
1413 MODEST_WIDGET_TYPE_HEADER_VIEW);
1417 conf = modest_runtime_get_conf ();
1419 if (TNY_IS_ACCOUNT (folder_store)) {
1421 /* Update active account */
1422 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1423 /* Show account details */
1424 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1427 if (TNY_IS_FOLDER (folder_store) && selected) {
1429 /* Update the active account */
1430 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1432 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1433 g_object_unref (account);
1437 /* Set the header style by default, it could
1438 be changed later by the refresh callback to
1440 modest_main_window_set_contents_style (main_window,
1441 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1443 /* Set folder on header view. This function
1444 will call tny_folder_refresh_async so we
1445 pass a callback that will be called when
1446 finished. We use that callback to set the
1447 empty view if there are no messages */
1448 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1449 TNY_FOLDER (folder_store),
1450 folder_refreshed_cb,
1453 /* Restore configuration. We need to do this
1454 *after* the set_folder because the widget
1455 memory asks the header view about its
1457 modest_widget_memory_restore (modest_runtime_get_conf (),
1458 G_OBJECT(header_view),
1459 MODEST_CONF_HEADER_VIEW_KEY);
1461 /* Update the active account */
1462 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1463 /* Save only if we're seeing headers */
1464 if (modest_main_window_get_contents_style (main_window) ==
1465 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1466 modest_widget_memory_save (conf, G_OBJECT (header_view),
1467 MODEST_CONF_HEADER_VIEW_KEY);
1468 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1472 /* Update toolbar dimming state */
1473 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1477 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1484 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1486 online = tny_device_is_online (modest_runtime_get_device());
1489 /* already online -- the item is simply not there... */
1490 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1492 GTK_MESSAGE_WARNING,
1494 _("The %s you selected cannot be found"),
1496 gtk_dialog_run (GTK_DIALOG(dialog));
1498 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1502 GTK_RESPONSE_REJECT,
1504 GTK_RESPONSE_ACCEPT,
1506 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1507 "Do you want to get online?"), item);
1508 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1509 gtk_label_new (txt), FALSE, FALSE, 0);
1510 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1513 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1514 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1515 // modest_platform_connect_and_wait ();
1518 gtk_widget_destroy (dialog);
1522 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1525 /* g_message ("%s %s", __FUNCTION__, link); */
1530 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1533 modest_platform_activate_uri (link);
1537 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1540 modest_platform_show_uri_popup (link);
1544 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1547 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1551 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1552 const gchar *address,
1555 /* g_message ("%s %s", __FUNCTION__, address); */
1559 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1561 TnyTransportAccount *transport_account;
1562 ModestMailOperation *mail_operation;
1564 gchar *account_name, *from;
1565 ModestAccountMgr *account_mgr;
1566 gchar *info_text = NULL;
1568 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1570 data = modest_msg_edit_window_get_msg_data (edit_window);
1572 account_mgr = modest_runtime_get_account_mgr();
1573 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1575 account_name = modest_account_mgr_get_default_account (account_mgr);
1576 if (!account_name) {
1577 g_printerr ("modest: no account found\n");
1578 modest_msg_edit_window_free_msg_data (edit_window, data);
1582 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1583 account_name = g_strdup (data->account_name);
1587 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1588 (modest_runtime_get_account_store(),
1590 TNY_ACCOUNT_TYPE_TRANSPORT));
1591 if (!transport_account) {
1592 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1593 g_free (account_name);
1594 modest_msg_edit_window_free_msg_data (edit_window, data);
1597 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1599 /* Create the mail operation */
1600 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1601 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1603 modest_mail_operation_save_to_drafts (mail_operation,
1614 data->priority_flags);
1617 g_free (account_name);
1618 g_object_unref (G_OBJECT (transport_account));
1619 g_object_unref (G_OBJECT (mail_operation));
1621 modest_msg_edit_window_free_msg_data (edit_window, data);
1623 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1624 modest_platform_information_banner (NULL, NULL, info_text);
1628 /* For instance, when clicking the Send toolbar button when editing a message: */
1630 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1632 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1634 if (!modest_msg_edit_window_check_names (edit_window))
1637 /* FIXME: Code added just for testing. The final version will
1638 use the send queue provided by tinymail and some
1640 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1641 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1643 account_name = modest_account_mgr_get_default_account (account_mgr);
1645 if (!account_name) {
1646 g_printerr ("modest: no account found\n");
1650 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1652 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1653 account_name = g_strdup (data->account_name);
1656 /* Get the currently-active transport account for this modest account: */
1657 TnyTransportAccount *transport_account =
1658 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1659 (modest_runtime_get_account_store(),
1661 if (!transport_account) {
1662 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1663 g_free (account_name);
1664 modest_msg_edit_window_free_msg_data (edit_window, data);
1668 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1670 /* mail content checks and dialogs */
1671 if (data->subject == NULL || data->subject[0] == '\0') {
1672 GtkResponseType response;
1673 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1674 _("mcen_nc_subject_is_empty_send"));
1675 if (response == GTK_RESPONSE_CANCEL) {
1676 g_free (account_name);
1681 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1682 GtkResponseType response;
1683 gchar *note_message;
1684 gchar *note_subject = data->subject;
1685 if (note_subject == NULL || note_subject[0] == '\0')
1686 note_subject = _("mail_va_no_subject");
1687 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1688 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1690 g_free (note_message);
1691 if (response == GTK_RESPONSE_CANCEL) {
1692 g_free (account_name);
1697 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1699 /* Create the mail operation */
1700 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1701 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1703 modest_mail_operation_send_new_mail (mail_operation,
1714 data->priority_flags);
1718 g_free (account_name);
1719 g_object_unref (G_OBJECT (transport_account));
1720 g_object_unref (G_OBJECT (mail_operation));
1722 modest_msg_edit_window_free_msg_data (edit_window, data);
1723 modest_msg_edit_window_set_sent (edit_window, TRUE);
1725 /* Save settings and close the window: */
1726 gtk_widget_destroy (GTK_WIDGET (edit_window));
1730 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1731 ModestMsgEditWindow *window)
1733 ModestMsgEditFormatState *format_state = NULL;
1735 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1736 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1738 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1741 format_state = modest_msg_edit_window_get_format_state (window);
1742 g_return_if_fail (format_state != NULL);
1744 format_state->bold = gtk_toggle_action_get_active (action);
1745 modest_msg_edit_window_set_format_state (window, format_state);
1746 g_free (format_state);
1751 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1752 ModestMsgEditWindow *window)
1754 ModestMsgEditFormatState *format_state = NULL;
1756 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1757 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1759 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1762 format_state = modest_msg_edit_window_get_format_state (window);
1763 g_return_if_fail (format_state != NULL);
1765 format_state->italics = gtk_toggle_action_get_active (action);
1766 modest_msg_edit_window_set_format_state (window, format_state);
1767 g_free (format_state);
1772 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1773 ModestMsgEditWindow *window)
1775 ModestMsgEditFormatState *format_state = NULL;
1777 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1778 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1780 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1783 format_state = modest_msg_edit_window_get_format_state (window);
1784 g_return_if_fail (format_state != NULL);
1786 format_state->bullet = gtk_toggle_action_get_active (action);
1787 modest_msg_edit_window_set_format_state (window, format_state);
1788 g_free (format_state);
1793 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1794 GtkRadioAction *selected,
1795 ModestMsgEditWindow *window)
1797 ModestMsgEditFormatState *format_state = NULL;
1798 GtkJustification value;
1800 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1802 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1805 value = gtk_radio_action_get_current_value (selected);
1807 format_state = modest_msg_edit_window_get_format_state (window);
1808 g_return_if_fail (format_state != NULL);
1810 format_state->justification = value;
1811 modest_msg_edit_window_set_format_state (window, format_state);
1812 g_free (format_state);
1816 modest_ui_actions_on_select_editor_color (GtkAction *action,
1817 ModestMsgEditWindow *window)
1819 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1820 g_return_if_fail (GTK_IS_ACTION (action));
1822 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1825 modest_msg_edit_window_select_color (window);
1829 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1830 ModestMsgEditWindow *window)
1832 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1833 g_return_if_fail (GTK_IS_ACTION (action));
1835 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1838 modest_msg_edit_window_select_background_color (window);
1842 modest_ui_actions_on_insert_image (GtkAction *action,
1843 ModestMsgEditWindow *window)
1845 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1846 g_return_if_fail (GTK_IS_ACTION (action));
1848 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1851 modest_msg_edit_window_insert_image (window);
1855 modest_ui_actions_on_attach_file (GtkAction *action,
1856 ModestMsgEditWindow *window)
1858 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1859 g_return_if_fail (GTK_IS_ACTION (action));
1861 modest_msg_edit_window_attach_file (window);
1865 modest_ui_actions_on_remove_attachments (GtkAction *action,
1866 ModestMsgEditWindow *window)
1868 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1869 g_return_if_fail (GTK_IS_ACTION (action));
1871 modest_msg_edit_window_remove_attachments (window, NULL);
1875 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1877 TnyFolderStore *parent_folder;
1878 GtkWidget *folder_view;
1880 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1882 folder_view = modest_main_window_get_child_widget (main_window,
1883 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1887 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1889 if (parent_folder) {
1890 gboolean finished = FALSE;
1892 gchar *folder_name = NULL, *suggested_name = NULL;
1894 /* Run the new folder dialog */
1896 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1901 if (result == GTK_RESPONSE_REJECT) {
1904 ModestMailOperation *mail_op;
1905 TnyFolder *new_folder = NULL;
1907 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1908 G_OBJECT(main_window));
1909 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1911 new_folder = modest_mail_operation_create_folder (mail_op,
1913 (const gchar *) folder_name);
1915 g_object_unref (new_folder);
1918 g_object_unref (mail_op);
1920 g_free (folder_name);
1924 g_object_unref (parent_folder);
1929 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1932 GObject *win = modest_mail_operation_get_source (mail_op);
1933 const GError *error = NULL;
1934 const gchar *message = NULL;
1936 /* Get error message */
1937 error = modest_mail_operation_get_error (mail_op);
1938 if (error != NULL && error->message != NULL) {
1939 message = error->message;
1941 message = _("!!! FIXME: Unable to rename");
1944 /* Show notification dialog */
1945 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
1946 g_object_unref (win);
1950 modest_ui_actions_on_rename_folder (GtkAction *action,
1951 ModestMainWindow *main_window)
1953 TnyFolderStore *folder;
1954 GtkWidget *folder_view;
1955 GtkWidget *header_view;
1957 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1959 folder_view = modest_main_window_get_child_widget (main_window,
1960 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1964 header_view = modest_main_window_get_child_widget (main_window,
1965 MODEST_WIDGET_TYPE_HEADER_VIEW);
1970 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1972 if (folder && TNY_IS_FOLDER (folder)) {
1975 const gchar *current_name;
1977 current_name = tny_folder_get_name (TNY_FOLDER (folder));
1978 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
1979 current_name, &folder_name);
1981 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
1982 ModestMailOperation *mail_op;
1985 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
1986 G_OBJECT(main_window),
1987 modest_ui_actions_rename_folder_error_handler,
1991 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1994 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
1996 modest_mail_operation_rename_folder (mail_op,
1997 TNY_FOLDER (folder),
1998 (const gchar *) folder_name);
2000 g_object_unref (mail_op);
2001 g_free (folder_name);
2003 g_object_unref (folder);
2008 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2011 GObject *win = modest_mail_operation_get_source (mail_op);
2013 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2014 _("mail_in_ui_folder_delete_error"));
2015 g_object_unref (win);
2019 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2021 TnyFolderStore *folder;
2022 GtkWidget *folder_view;
2026 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2028 folder_view = modest_main_window_get_child_widget (main_window,
2029 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2033 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2035 /* Show an error if it's an account */
2036 if (!TNY_IS_FOLDER (folder)) {
2037 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2038 _("mail_in_ui_folder_delete_error"));
2043 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2044 tny_folder_get_name (TNY_FOLDER (folder)));
2045 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2046 (const gchar *) message);
2049 if (response == GTK_RESPONSE_OK) {
2050 ModestMailOperation *mail_op =
2051 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2052 G_OBJECT(main_window),
2053 modest_ui_actions_delete_folder_error_handler,
2056 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2058 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2059 g_object_unref (G_OBJECT (mail_op));
2062 g_object_unref (G_OBJECT (folder));
2066 modest_ui_actions_on_delete_folder (GtkAction *action,
2067 ModestMainWindow *main_window)
2069 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2071 delete_folder (main_window, FALSE);
2075 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2077 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2079 delete_folder (main_window, TRUE);
2083 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2084 const gchar* server_account_name,
2089 ModestMainWindow *main_window)
2091 g_return_if_fail(server_account_name);
2092 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2094 /* Initalize output parameters: */
2101 #ifdef MODEST_PLATFORM_MAEMO
2102 /* Maemo uses a different (awkward) button order,
2103 * It should probably just use gtk_alternative_dialog_button_order ().
2105 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2109 GTK_RESPONSE_ACCEPT,
2111 GTK_RESPONSE_REJECT,
2114 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2118 GTK_RESPONSE_REJECT,
2120 GTK_RESPONSE_ACCEPT,
2122 #endif /* MODEST_PLATFORM_MAEMO */
2124 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2126 gchar *server_name = modest_server_account_get_hostname (
2127 modest_runtime_get_account_mgr(), server_account_name);
2128 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2129 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2134 /* This causes a warning because the logical ID has no %s in it,
2135 * though the translation does, but there is not much we can do about that: */
2136 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2137 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2140 g_free (server_name);
2144 gchar *initial_username = modest_server_account_get_username (
2145 modest_runtime_get_account_mgr(), server_account_name);
2147 GtkWidget *entry_username = gtk_entry_new ();
2148 if (initial_username)
2149 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2150 /* Dim this if a connection has ever succeeded with this username,
2151 * as per the UI spec: */
2152 const gboolean username_known =
2153 modest_server_account_get_username_has_succeeded(
2154 modest_runtime_get_account_mgr(), server_account_name);
2155 gtk_widget_set_sensitive (entry_username, !username_known);
2157 #ifdef MODEST_PLATFORM_MAEMO
2158 /* Auto-capitalization is the default, so let's turn it off: */
2159 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2161 /* Create a size group to be used by all captions.
2162 * Note that HildonCaption does not create a default size group if we do not specify one.
2163 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2164 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2166 GtkWidget *caption = hildon_caption_new (sizegroup,
2167 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2168 gtk_widget_show (entry_username);
2169 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2170 FALSE, FALSE, MODEST_MARGIN_HALF);
2171 gtk_widget_show (caption);
2173 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2175 #endif /* MODEST_PLATFORM_MAEMO */
2178 GtkWidget *entry_password = gtk_entry_new ();
2179 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2180 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2182 #ifdef MODEST_PLATFORM_MAEMO
2183 /* Auto-capitalization is the default, so let's turn it off: */
2184 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2185 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2187 caption = hildon_caption_new (sizegroup,
2188 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2189 gtk_widget_show (entry_password);
2190 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2191 FALSE, FALSE, MODEST_MARGIN_HALF);
2192 gtk_widget_show (caption);
2193 g_object_unref (sizegroup);
2195 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2197 #endif /* MODEST_PLATFORM_MAEMO */
2199 /* This is not in the Maemo UI spec:
2200 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2201 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2205 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2207 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2209 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2211 modest_server_account_set_username (
2212 modest_runtime_get_account_mgr(), server_account_name,
2215 const gboolean username_was_changed =
2216 (strcmp (*username, initial_username) != 0);
2217 if (username_was_changed) {
2218 g_warning ("%s: tinymail does not yet support changing the "
2219 "username in the get_password() callback.\n", __FUNCTION__);
2224 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2226 /* We do not save the password in the configuration,
2227 * because this function is only called for passwords that should
2228 * not be remembered:
2229 modest_server_account_set_password (
2230 modest_runtime_get_account_mgr(), server_account_name,
2249 /* This is not in the Maemo UI spec:
2250 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2256 gtk_widget_destroy (dialog);
2258 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2262 modest_ui_actions_on_cut (GtkAction *action,
2263 ModestWindow *window)
2265 GtkWidget *focused_widget;
2267 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2268 if (GTK_IS_EDITABLE (focused_widget)) {
2269 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2270 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2271 GtkTextBuffer *buffer;
2272 GtkClipboard *clipboard;
2274 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2275 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2276 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2277 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2278 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2279 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2280 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2285 modest_ui_actions_on_copy (GtkAction *action,
2286 ModestWindow *window)
2288 GtkClipboard *clipboard;
2289 GtkWidget *focused_widget;
2291 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2292 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2294 if (GTK_IS_LABEL (focused_widget)) {
2295 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2296 } else if (GTK_IS_EDITABLE (focused_widget)) {
2297 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2298 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2299 GtkTextBuffer *buffer;
2300 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2301 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2302 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2303 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2304 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2305 TnyIterator *iter = tny_list_create_iterator (header_list);
2306 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2307 TnyFolder *folder = tny_header_get_folder (header);
2308 TnyAccount *account = tny_folder_get_account (folder);
2309 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2310 /* If it's POP then ask */
2311 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2312 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2313 g_object_unref (account);
2314 g_object_unref (folder);
2315 g_object_unref (header);
2316 g_object_unref (iter);
2318 /* Check that the messages have been previously downloaded */
2319 gboolean continue_download = TRUE;
2321 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2322 if (continue_download)
2323 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2324 g_object_unref (header_list);
2325 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2326 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2329 /* Show information banner */
2330 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2335 modest_ui_actions_on_undo (GtkAction *action,
2336 ModestWindow *window)
2338 ModestEmailClipboard *clipboard = NULL;
2340 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2341 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2342 } if (MODEST_IS_MAIN_WINDOW (window)) {
2343 /* Clear clipboard source */
2344 clipboard = modest_runtime_get_email_clipboard ();
2345 modest_email_clipboard_clear (clipboard);
2348 g_return_if_reached ();
2353 modest_ui_actions_on_paste (GtkAction *action,
2354 ModestWindow *window)
2356 GtkWidget *focused_widget;
2357 ModestMailOperation *mail_op = NULL;
2359 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2360 if (GTK_IS_EDITABLE (focused_widget)) {
2361 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2362 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2363 GtkTextBuffer *buffer;
2364 GtkClipboard *clipboard;
2366 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2367 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2368 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2369 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2370 ModestEmailClipboard *clipboard = NULL;
2371 TnyFolder *src_folder = NULL;
2372 TnyFolderStore *folder_store = NULL;
2373 TnyList *data = NULL;
2374 gboolean delete = FALSE;
2376 /* Check clipboard source */
2377 clipboard = modest_runtime_get_email_clipboard ();
2378 if (modest_email_clipboard_cleared (clipboard))
2381 /* Get elements to paste */
2382 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2384 /* Create a new mail operation */
2385 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2386 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2389 /* Get destination folder */
2390 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2392 /* transfer messages */
2394 modest_mail_operation_xfer_msgs (mail_op,
2396 TNY_FOLDER (folder_store),
2401 } else if (src_folder != NULL) {
2402 modest_mail_operation_xfer_folder (mail_op,
2410 g_object_unref (data);
2411 if (src_folder != NULL)
2412 g_object_unref (src_folder);
2413 if (folder_store != NULL)
2414 g_object_unref (folder_store);
2419 modest_ui_actions_on_select_all (GtkAction *action,
2420 ModestWindow *window)
2422 GtkWidget *focused_widget;
2424 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2425 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2426 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2427 } else if (GTK_IS_LABEL (focused_widget)) {
2428 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2429 } else if (GTK_IS_EDITABLE (focused_widget)) {
2430 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2431 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2432 GtkTextBuffer *buffer;
2433 GtkTextIter start, end;
2435 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2436 gtk_text_buffer_get_start_iter (buffer, &start);
2437 gtk_text_buffer_get_end_iter (buffer, &end);
2438 gtk_text_buffer_select_range (buffer, &start, &end);
2439 } else if (GTK_IS_HTML (focused_widget)) {
2440 gtk_html_select_all (GTK_HTML (focused_widget));
2441 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2442 GtkWidget *header_view = focused_widget;
2443 GtkTreeSelection *selection = NULL;
2445 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2446 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2447 MODEST_WIDGET_TYPE_HEADER_VIEW);
2449 /* Select all messages */
2450 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2451 gtk_tree_selection_select_all (selection);
2453 /* Set focuse on header view */
2454 gtk_widget_grab_focus (header_view);
2460 modest_ui_actions_on_mark_as_read (GtkAction *action,
2461 ModestWindow *window)
2463 g_return_if_fail (MODEST_IS_WINDOW(window));
2465 /* Mark each header as read */
2466 do_headers_action (window, headers_action_mark_as_read, NULL);
2470 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2471 ModestWindow *window)
2473 g_return_if_fail (MODEST_IS_WINDOW(window));
2475 /* Mark each header as read */
2476 do_headers_action (window, headers_action_mark_as_unread, NULL);
2480 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2481 GtkRadioAction *selected,
2482 ModestWindow *window)
2486 value = gtk_radio_action_get_current_value (selected);
2487 if (MODEST_IS_WINDOW (window)) {
2488 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2492 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2493 GtkRadioAction *selected,
2494 ModestWindow *window)
2496 TnyHeaderFlags flags;
2497 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2499 flags = gtk_radio_action_get_current_value (selected);
2500 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2503 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2504 GtkRadioAction *selected,
2505 ModestWindow *window)
2509 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2511 file_format = gtk_radio_action_get_current_value (selected);
2512 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2517 modest_ui_actions_on_zoom_plus (GtkAction *action,
2518 ModestWindow *window)
2520 g_return_if_fail (MODEST_IS_WINDOW (window));
2522 modest_window_zoom_plus (MODEST_WINDOW (window));
2526 modest_ui_actions_on_zoom_minus (GtkAction *action,
2527 ModestWindow *window)
2529 g_return_if_fail (MODEST_IS_WINDOW (window));
2531 modest_window_zoom_minus (MODEST_WINDOW (window));
2535 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2536 ModestWindow *window)
2538 ModestWindowMgr *mgr;
2539 gboolean fullscreen, active;
2540 g_return_if_fail (MODEST_IS_WINDOW (window));
2542 mgr = modest_runtime_get_window_mgr ();
2544 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2545 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2547 if (active != fullscreen) {
2548 modest_window_mgr_set_fullscreen_mode (mgr, active);
2549 gtk_window_present (GTK_WINDOW (window));
2554 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2555 ModestWindow *window)
2557 ModestWindowMgr *mgr;
2558 gboolean fullscreen;
2560 g_return_if_fail (MODEST_IS_WINDOW (window));
2562 mgr = modest_runtime_get_window_mgr ();
2563 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2564 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2566 gtk_window_present (GTK_WINDOW (window));
2570 * Used by modest_ui_actions_on_details to call do_headers_action
2573 headers_action_show_details (TnyHeader *header,
2574 ModestWindow *window,
2581 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2584 gtk_widget_show_all (dialog);
2585 gtk_dialog_run (GTK_DIALOG (dialog));
2587 gtk_widget_destroy (dialog);
2591 * Show the folder details in a ModestDetailsDialog widget
2594 show_folder_details (TnyFolder *folder,
2600 dialog = modest_details_dialog_new_with_folder (window, folder);
2603 gtk_widget_show_all (dialog);
2604 gtk_dialog_run (GTK_DIALOG (dialog));
2606 gtk_widget_destroy (dialog);
2610 * Show the header details in a ModestDetailsDialog widget
2613 modest_ui_actions_on_details (GtkAction *action,
2616 TnyList * headers_list;
2620 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2623 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2626 g_object_unref (msg);
2628 headers_list = get_selected_headers (win);
2632 iter = tny_list_create_iterator (headers_list);
2634 header = TNY_HEADER (tny_iterator_get_current (iter));
2635 headers_action_show_details (header, win, NULL);
2636 g_object_unref (header);
2638 g_object_unref (iter);
2639 g_object_unref (headers_list);
2641 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2642 GtkWidget *folder_view, *header_view;
2644 /* Check which widget has the focus */
2645 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2646 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2647 if (gtk_widget_is_focus (folder_view)) {
2648 TnyFolderStore *folder_store
2649 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2650 if (!folder_store) {
2651 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2654 /* Show only when it's a folder */
2655 /* This function should not be called for account items,
2656 * because we dim the menu item for them. */
2657 if (TNY_IS_FOLDER (folder_store)) {
2658 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2661 g_object_unref (folder_store);
2664 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2665 MODEST_WIDGET_TYPE_HEADER_VIEW);
2666 /* Show details of each header */
2667 do_headers_action (win, headers_action_show_details, header_view);
2673 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2674 ModestMsgEditWindow *window)
2676 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2678 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2682 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2683 ModestMsgEditWindow *window)
2685 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2687 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2691 modest_ui_actions_toggle_folders_view (GtkAction *action,
2692 ModestMainWindow *main_window)
2696 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2698 conf = modest_runtime_get_conf ();
2700 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2701 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2703 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2707 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2708 ModestWindow *window)
2710 gboolean active, fullscreen = FALSE;
2711 ModestWindowMgr *mgr;
2713 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2715 /* Check if we want to toggle the toolbar vuew in fullscreen
2717 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2718 "ViewShowToolbarFullScreen")) {
2722 /* Toggle toolbar */
2723 mgr = modest_runtime_get_window_mgr ();
2724 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2728 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2729 ModestMsgEditWindow *window)
2731 modest_msg_edit_window_select_font (window);
2735 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2736 const gchar *display_name,
2739 /* Do not change the application name if the widget has not
2740 the focus. This callback could be called even if the folder
2741 view has not the focus, because the handled signal could be
2742 emitted when the folder view is redrawn */
2743 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2745 gtk_window_set_title (window, display_name);
2747 gtk_window_set_title (window, " ");
2752 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2754 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2755 modest_msg_edit_window_select_contacts (window);
2759 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2761 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2762 modest_msg_edit_window_check_names (window);
2767 create_move_to_dialog (ModestWindow *win,
2768 GtkWidget *folder_view,
2769 GtkWidget **tree_view)
2771 GtkWidget *dialog, *scroll;
2773 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2775 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2777 GTK_RESPONSE_ACCEPT,
2779 GTK_RESPONSE_REJECT,
2782 /* Create scrolled window */
2783 scroll = gtk_scrolled_window_new (NULL, NULL);
2784 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2785 GTK_POLICY_AUTOMATIC,
2786 GTK_POLICY_AUTOMATIC);
2788 /* Create folder view */
2789 *tree_view = modest_platform_create_folder_view (NULL);
2791 /* It could happen that we're trying to move a message from a
2792 window (msg window for example) after the main window was
2793 closed, so we can not just get the model of the folder
2795 if (MODEST_IS_FOLDER_VIEW (folder_view))
2796 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2797 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2799 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2800 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2802 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2804 /* Add scroll to dialog */
2805 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2806 scroll, FALSE, FALSE, 0);
2808 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2810 /* Select INBOX or local account */
2811 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2817 * Returns TRUE if at least one of the headers of the list belongs to
2818 * a message that has been fully retrieved.
2821 has_retrieved_msgs (TnyList *list)
2824 gboolean found = FALSE;
2826 iter = tny_list_create_iterator (list);
2827 while (tny_iterator_is_done (iter) && !found) {
2829 TnyHeaderFlags flags;
2831 header = TNY_HEADER (tny_iterator_get_current (iter));
2832 flags = tny_header_get_flags (header);
2833 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2837 tny_iterator_next (iter);
2839 g_object_unref (iter);
2845 * Shows a confirmation dialog to the user when we're moving messages
2846 * from a remote server to the local storage. Returns the dialog
2847 * response. If it's other kind of movement the it always returns
2851 msgs_move_to_confirmation (GtkWindow *win,
2852 TnyFolder *dest_folder,
2855 gint response = GTK_RESPONSE_OK;
2857 /* If the destination is a local folder */
2858 if (modest_tny_folder_is_local_folder (dest_folder)) {
2859 TnyFolder *src_folder;
2863 /* Get source folder */
2864 iter = tny_list_create_iterator (headers);
2865 header = TNY_HEADER (tny_iterator_get_current (iter));
2866 src_folder = tny_header_get_folder (header);
2867 g_object_unref (header);
2868 g_object_unref (iter);
2870 /* if no src_folder, message may be an attahcment */
2871 if (src_folder == NULL)
2872 return GTK_RESPONSE_CANCEL;
2874 /* If the source is a remote folder */
2875 if (!modest_tny_folder_is_local_folder (src_folder)) {
2876 const gchar *message;
2878 if (has_retrieved_msgs (headers))
2879 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2880 tny_list_get_length (headers));
2882 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2883 tny_list_get_length (headers));
2885 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2886 (const gchar *) message);
2888 g_object_unref (src_folder);
2895 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2897 ModestMsgViewWindow *self = NULL;
2898 gboolean last, first;
2900 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2901 self = MODEST_MSG_VIEW_WINDOW (object);
2903 last = modest_msg_view_window_last_message_selected (self);
2904 first = modest_msg_view_window_first_message_selected (self);
2906 /* No more messages to view, so close this window */
2907 /* gboolean ret_value; */
2908 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2909 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
2911 modest_msg_view_window_select_previous_message (self);
2913 modest_msg_view_window_select_next_message (self);
2917 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2920 GObject *win = modest_mail_operation_get_source (mail_op);
2921 const GError *error = NULL;
2922 const gchar *message = NULL;
2924 /* Get error message */
2925 error = modest_mail_operation_get_error (mail_op);
2926 if (error != NULL && error->message != NULL) {
2927 message = error->message;
2929 message = _("mail_in_ui_folder_move_target_error");
2932 /* Show notification dialog */
2933 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2934 g_object_unref (win);
2938 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
2941 GObject *win = modest_mail_operation_get_source (mail_op);
2942 const GError *error = modest_mail_operation_get_error (mail_op);
2944 g_return_if_fail (error != NULL);
2945 if (error->message != NULL)
2946 g_printerr ("modest: %s\n", error->message);
2948 g_printerr ("modest: unkonw error on sedn&receive operation");
2950 /* Show error message */
2951 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2952 _CS("sfil_ib_unable_to_send"));
2953 /* g_object_unref (win); */
2957 open_msg_for_purge_cb (ModestMailOperation *mail_op,
2964 gint pending_purges = 0;
2965 gboolean some_purged = FALSE;
2966 ModestWindow *win = MODEST_WINDOW (user_data);
2970 /* Once the message has been retrieved for purging, we check if
2971 * it's all ok for purging */
2973 parts = tny_simple_list_new ();
2974 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
2975 iter = tny_list_create_iterator (parts);
2977 while (!tny_iterator_is_done (iter)) {
2979 part = TNY_MIME_PART (tny_iterator_get_current (iter));
2980 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
2981 if (tny_mime_part_is_purged (part))
2986 tny_iterator_next (iter);
2989 if (pending_purges>0) {
2991 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
2993 if (response == GTK_RESPONSE_OK) {
2994 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
2995 tny_iterator_first (iter);
2996 while (!tny_iterator_is_done (iter)) {
2999 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3000 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3001 tny_mime_part_set_purged (part);
3002 tny_iterator_next (iter);
3005 tny_msg_rewrite_cache (msg);
3008 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3011 /* remove attachments */
3012 tny_iterator_first (iter);
3013 while (!tny_iterator_is_done (iter)) {
3016 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3017 g_object_unref (part);
3018 tny_iterator_next (iter);
3021 g_object_unref (iter);
3022 g_object_unref (parts);
3026 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3027 ModestMainWindow *win)
3029 GtkWidget *header_view;
3030 TnyList *header_list;
3033 TnyHeaderFlags flags;
3034 ModestWindow *msg_view_window = NULL;
3037 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3039 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3040 MODEST_WIDGET_TYPE_HEADER_VIEW);
3042 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3044 if (tny_list_get_length (header_list) == 1) {
3045 iter = tny_list_create_iterator (header_list);
3046 header = TNY_HEADER (tny_iterator_get_current (iter));
3047 g_object_unref (iter);
3052 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3053 header, &msg_view_window);
3054 flags = tny_header_get_flags (header);
3055 if (!(flags & TNY_HEADER_FLAG_CACHED))
3058 if (msg_view_window != NULL)
3059 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3061 /* do nothing; uid was registered before, so window is probably on it's way */
3062 g_warning ("debug: header %p has already been registered", header);
3065 ModestMailOperation *mail_op = NULL;
3066 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3067 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_OPEN,
3069 modest_ui_actions_get_msgs_full_error_handler,
3071 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3072 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3074 g_object_unref (mail_op);
3077 g_object_unref (header);
3079 g_object_unref (header_list);
3083 * UI handler for the "Move to" action when invoked from the
3087 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3088 ModestMainWindow *win)
3090 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3091 GtkWidget *header_view = NULL;
3093 TnyFolderStore *folder_store = NULL;
3094 ModestMailOperation *mail_op = NULL;
3096 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3098 /* Get the folder view */
3099 folder_view = modest_main_window_get_child_widget (win,
3100 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3102 /* Get header view */
3103 header_view = modest_main_window_get_child_widget (win,
3104 MODEST_WIDGET_TYPE_HEADER_VIEW);
3106 /* Create and run the dialog */
3107 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3108 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3109 result = gtk_dialog_run (GTK_DIALOG(dialog));
3110 g_object_ref (tree_view);
3112 /* We do this to save an indentation level ;-) */
3113 if (result != GTK_RESPONSE_ACCEPT)
3116 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3118 if (TNY_IS_ACCOUNT (folder_store) &&
3119 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3122 /* Get folder or messages to transfer */
3123 if (gtk_widget_is_focus (folder_view)) {
3124 TnyFolderStore *src_folder;
3125 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3127 /* Clean folder on header view before moving it */
3128 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3130 if (TNY_IS_FOLDER (src_folder)) {
3132 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3134 modest_ui_actions_move_folder_error_handler,
3136 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3138 modest_mail_operation_xfer_folder (mail_op,
3139 TNY_FOLDER (src_folder),
3142 /* Unref mail operation */
3143 g_object_unref (G_OBJECT (mail_op));
3147 g_object_unref (G_OBJECT (src_folder));
3149 if (gtk_widget_is_focus (header_view)) {
3153 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3155 /* Ask for user confirmation */
3156 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3157 TNY_FOLDER (folder_store),
3160 /* Transfer messages */
3161 if (response == GTK_RESPONSE_OK) {
3163 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3165 modest_ui_actions_move_folder_error_handler,
3167 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3170 modest_mail_operation_xfer_msgs (mail_op,
3172 TNY_FOLDER (folder_store),
3177 g_object_unref (G_OBJECT (mail_op));
3179 g_object_unref (headers);
3183 if (folder_store != NULL)
3184 g_object_unref (folder_store);
3185 gtk_widget_destroy (dialog);
3190 * UI handler for the "Move to" action when invoked from the
3191 * ModestMsgViewWindow
3194 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3195 ModestMsgViewWindow *win)
3197 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3199 ModestMainWindow *main_window;
3203 /* Get the folder view */
3204 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3206 folder_view = modest_main_window_get_child_widget (main_window,
3207 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3211 /* Create and run the dialog */
3212 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3213 result = gtk_dialog_run (GTK_DIALOG(dialog));
3214 g_object_ref (tree_view);
3216 if (result == GTK_RESPONSE_ACCEPT) {
3217 TnyFolderStore *folder_store;
3220 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3222 /* Create header list */
3223 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3225 headers = tny_simple_list_new ();
3226 tny_list_prepend (headers, G_OBJECT (header));
3227 g_object_unref (header);
3229 /* Ask user for confirmation. MSG-NOT404 */
3230 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3231 TNY_FOLDER (folder_store),
3234 /* Transfer current msg */
3235 if (response == GTK_RESPONSE_OK) {
3236 ModestMailOperation *mail_op;
3238 /* Create mail op */
3239 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3240 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3243 /* Transfer messages */
3244 modest_mail_operation_xfer_msgs (mail_op,
3246 TNY_FOLDER (folder_store),
3248 transfer_msgs_from_viewer_cb,
3250 g_object_unref (G_OBJECT (mail_op));
3252 g_object_unref (headers);
3253 g_object_unref (folder_store);
3255 gtk_widget_destroy (dialog);
3259 modest_ui_actions_on_move_to (GtkAction *action,
3262 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3263 MODEST_IS_MSG_VIEW_WINDOW (win));
3265 if (MODEST_IS_MAIN_WINDOW (win))
3266 modest_ui_actions_on_main_window_move_to (action,
3267 MODEST_MAIN_WINDOW (win));
3269 modest_ui_actions_on_msg_view_window_move_to (action,
3270 MODEST_MSG_VIEW_WINDOW (win));
3274 * Calls #HeadersFunc for each header already selected in the main
3275 * window or the message currently being shown in the msg view window
3278 do_headers_action (ModestWindow *win,
3282 TnyList *headers_list;
3288 headers_list = get_selected_headers (win);
3292 /* Get the folder */
3293 iter = tny_list_create_iterator (headers_list);
3294 header = TNY_HEADER (tny_iterator_get_current (iter));
3295 folder = tny_header_get_folder (header);
3296 g_object_unref (header);
3298 /* Call the function for each header */
3299 while (!tny_iterator_is_done (iter)) {
3300 header = TNY_HEADER (tny_iterator_get_current (iter));
3301 func (header, win, user_data);
3302 g_object_unref (header);
3303 tny_iterator_next (iter);
3306 /* Trick: do a poke status in order to speed up the signaling
3308 tny_folder_poke_status (folder);
3311 g_object_unref (folder);
3312 g_object_unref (iter);
3313 g_object_unref (headers_list);
3317 modest_ui_actions_view_attachment (GtkAction *action,
3318 ModestWindow *window)
3320 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3321 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3323 /* not supported window for this action */
3324 g_return_if_reached ();
3329 modest_ui_actions_save_attachments (GtkAction *action,
3330 ModestWindow *window)
3332 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3333 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3335 /* not supported window for this action */
3336 g_return_if_reached ();
3341 modest_ui_actions_remove_attachments (GtkAction *action,
3342 ModestWindow *window)
3344 if (MODEST_IS_MAIN_WINDOW (window)) {
3345 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3346 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3347 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3349 /* not supported window for this action */
3350 g_return_if_reached ();
3355 modest_ui_actions_on_settings (GtkAction *action,
3360 dialog = modest_platform_get_global_settings_dialog ();
3361 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3362 gtk_widget_show_all (dialog);
3364 gtk_dialog_run (GTK_DIALOG (dialog));
3366 gtk_widget_destroy (dialog);
3370 modest_ui_actions_on_help (GtkAction *action,
3373 const gchar *help_id = NULL;
3375 if (MODEST_IS_MAIN_WINDOW (win)) {
3376 const gchar *action_name;
3377 action_name = gtk_action_get_name (action);
3379 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3380 !strcmp (action_name, "HeaderViewCSMHelp")) {
3381 GtkWidget *folder_view;
3382 TnyFolderStore *folder_store;
3383 /* Get selected folder */
3384 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3385 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3386 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3388 /* Switch help_id */
3389 if (TNY_IS_FOLDER (folder_store)) {
3390 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3391 case TNY_FOLDER_TYPE_NORMAL:
3392 help_id = "applications_email_userfolder";
3394 case TNY_FOLDER_TYPE_INBOX:
3395 help_id = "applications_email_inbox";
3397 case TNY_FOLDER_TYPE_OUTBOX:
3398 help_id = "applications_email_outbox";
3400 case TNY_FOLDER_TYPE_SENT:
3401 help_id = "applications_email_sent";
3403 case TNY_FOLDER_TYPE_DRAFTS:
3404 help_id = "applications_email_drafts";
3406 case TNY_FOLDER_TYPE_ARCHIVE:
3407 help_id = "applications_email_archive";
3413 g_object_unref (folder_store);
3415 help_id = "applications_email_mainview";
3417 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3418 help_id = "applications_email_viewer";
3419 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3420 help_id = "applications_email_editor";
3422 modest_platform_show_help (GTK_WINDOW (win), help_id);
3426 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3427 ModestWindow *window)
3429 ModestMailOperation *mail_op;
3433 headers = get_selected_headers (window);
3437 /* Create mail operation */
3438 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3440 modest_ui_actions_get_msgs_full_error_handler,
3442 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3443 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3446 g_object_unref (headers);
3447 g_object_unref (mail_op);
3451 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3452 ModestWindow *window)
3454 g_return_if_fail (MODEST_IS_WINDOW (window));
3457 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3461 modest_ui_actions_on_edit_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_view_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_tools_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_attachment_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_toolbar_csm_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_folder_view_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_header_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_check_toolbar_dimming_rules (ModestWindow *window)
3533 g_return_if_fail (MODEST_IS_WINDOW (window));
3536 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3540 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3542 g_return_if_fail (MODEST_IS_WINDOW (window));
3544 modest_platform_show_search_messages (GTK_WINDOW (window));
3548 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3550 g_return_if_fail (MODEST_IS_WINDOW (win));
3551 modest_platform_show_addressbook (GTK_WINDOW (win));
3556 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3557 ModestWindow *window)
3559 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3561 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3565 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3566 ModestMailOperationState *state,
3569 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3571 /* Set send/receive operation finished */
3572 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3573 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));