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 #include "maemo/modest-maemo-utils.h"
52 #include "maemo/modest-hildon-includes.h"
53 #endif /* MODEST_PLATFORM_MAEMO */
55 #include "widgets/modest-ui-constants.h"
56 #include <widgets/modest-main-window.h>
57 #include <widgets/modest-msg-view-window.h>
58 #include <widgets/modest-account-view-window.h>
59 #include <widgets/modest-details-dialog.h>
60 #include <widgets/modest-attachments-view.h>
61 #include "widgets/modest-folder-view.h"
62 #include "widgets/modest-global-settings-dialog.h"
63 #include "modest-connection-specific-smtp-window.h"
64 #include "modest-account-mgr-helpers.h"
65 #include "modest-mail-operation.h"
66 #include "modest-text-utils.h"
68 #ifdef MODEST_HAVE_EASYSETUP
69 #include "easysetup/modest-easysetup-wizard.h"
70 #endif /* MODEST_HAVE_EASYSETUP */
72 #include <modest-widget-memory.h>
73 #include <tny-error.h>
74 #include <tny-simple-list.h>
75 #include <tny-msg-view.h>
76 #include <tny-device.h>
77 #include <tny-merge-folder.h>
79 #include <gtkhtml/gtkhtml.h>
81 typedef struct _GetMsgAsyncHelper {
83 ModestMailOperation *mail_op;
90 typedef enum _ReplyForwardAction {
96 typedef struct _ReplyForwardHelper {
97 guint reply_forward_type;
98 ReplyForwardAction action;
100 GtkWidget *parent_window;
101 } ReplyForwardHelper;
103 typedef struct _PasteAsAttachmentHelper {
104 ModestMsgEditWindow *window;
106 } PasteAsAttachmentHelper;
110 * The do_headers_action uses this kind of functions to perform some
111 * action to each member of a list of headers
113 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
115 static void do_headers_action (ModestWindow *win,
119 static void open_msg_cb (ModestMailOperation *mail_op,
124 static void reply_forward_cb (ModestMailOperation *mail_op,
129 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
131 static void folder_refreshed_cb (ModestMailOperation *mail_op,
135 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
136 ModestMailOperationState *state,
140 download_uncached_messages (TnyList *header_list, GtkWindow *win,
145 run_account_setup_wizard (ModestWindow *win)
147 ModestEasysetupWizardDialog *wizard;
149 g_return_if_fail (MODEST_IS_WINDOW(win));
151 wizard = modest_easysetup_wizard_dialog_new ();
152 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
154 /* Don't make this a modal window, because secondary windows will then
155 * be unusable, freezing the UI: */
156 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
158 gtk_dialog_run (GTK_DIALOG (wizard));
159 gtk_widget_destroy (GTK_WIDGET (wizard));
164 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
167 const gchar *authors[] = {
168 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
171 about = gtk_about_dialog_new ();
172 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
173 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
174 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
175 _("Copyright (c) 2006, Nokia Corporation\n"
176 "All rights reserved."));
177 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
178 _("a modest e-mail client\n\n"
179 "design and implementation: Dirk-Jan C. Binnema\n"
180 "contributions from the fine people at KC and Ig\n"
181 "uses the tinymail email framework written by Philip van Hoof"));
182 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
183 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
184 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
185 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
187 gtk_dialog_run (GTK_DIALOG (about));
188 gtk_widget_destroy(about);
192 * Gets the list of currently selected messages. If the win is the
193 * main window, then it returns a newly allocated list of the headers
194 * selected in the header view. If win is the msg view window, then
195 * the value returned is a list with just a single header.
197 * The caller of this funcion must free the list.
200 get_selected_headers (ModestWindow *win)
202 if (MODEST_IS_MAIN_WINDOW(win)) {
203 GtkWidget *header_view;
205 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
206 MODEST_WIDGET_TYPE_HEADER_VIEW);
207 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
209 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
210 /* for MsgViewWindows, we simply return a list with one element */
212 TnyList *list = NULL;
214 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
215 if (header != NULL) {
216 list = tny_simple_list_new ();
217 tny_list_prepend (list, G_OBJECT(header));
218 g_object_unref (G_OBJECT(header));
228 headers_action_mark_as_read (TnyHeader *header,
232 TnyHeaderFlags flags;
234 g_return_if_fail (TNY_IS_HEADER(header));
236 flags = tny_header_get_flags (header);
237 if (flags & TNY_HEADER_FLAG_SEEN) return;
238 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
242 headers_action_mark_as_unread (TnyHeader *header,
246 TnyHeaderFlags flags;
248 g_return_if_fail (TNY_IS_HEADER(header));
250 flags = tny_header_get_flags (header);
251 if (flags & TNY_HEADER_FLAG_SEEN) {
252 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
256 /** A convenience method, because deleting a message is
257 * otherwise complicated, and it's best to change it in one place
260 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
262 ModestMailOperation *mail_op = NULL;
263 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
264 win ? G_OBJECT(win) : NULL);
265 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
268 /* Always delete. TODO: Move to trash still not supported */
269 modest_mail_operation_remove_msg (mail_op, header, FALSE);
270 g_object_unref (G_OBJECT (mail_op));
274 headers_action_delete (TnyHeader *header,
278 modest_do_message_delete (header, win);
281 /** After deleing a message that is currently visible in a window,
282 * show the next message from the list, or close the window if there are no more messages.
284 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
286 /* Close msg view window or select next */
287 if (modest_msg_view_window_last_message_selected (win) &&
288 modest_msg_view_window_first_message_selected (win)) {
289 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
291 if (!modest_msg_view_window_select_next_message (win)) {
293 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
299 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
301 TnyList *header_list = NULL;
302 TnyIterator *iter = NULL;
303 TnyHeader *header = NULL;
304 gchar *message = NULL;
307 ModestWindowMgr *mgr;
308 GtkWidget *header_view = NULL;
310 g_return_if_fail (MODEST_IS_WINDOW(win));
312 /* Check first if the header view has the focus */
313 if (MODEST_IS_MAIN_WINDOW (win)) {
315 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
316 MODEST_WIDGET_TYPE_HEADER_VIEW);
317 if (!gtk_widget_is_focus (header_view))
321 header_list = get_selected_headers (win);
322 if (!header_list) return;
324 /* Check if any of the headers are already opened, or in the process of being opened */
325 if (MODEST_IS_MAIN_WINDOW (win)) {
327 iter = tny_list_create_iterator (header_list);
329 mgr = modest_runtime_get_window_mgr ();
330 while (!tny_iterator_is_done (iter) && !found) {
331 header = TNY_HEADER (tny_iterator_get_current (iter));
333 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
334 g_object_unref (header);
337 tny_iterator_next (iter);
339 g_object_unref (iter);
344 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
345 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
347 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
351 g_object_unref (header_list);
357 if (tny_list_get_length(header_list) == 1) {
358 iter = tny_list_create_iterator (header_list);
359 header = TNY_HEADER (tny_iterator_get_current (iter));
361 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
362 g_object_unref (header);
365 g_object_unref (iter);
367 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
368 tny_list_get_length(header_list)), desc);
370 /* Confirmation dialog */
371 printf("DEBUG: %s\n", __FUNCTION__);
372 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
376 if (response == GTK_RESPONSE_OK) {
377 ModestWindow *main_window = NULL;
378 ModestWindowMgr *mgr = NULL;
379 GtkTreeModel *model = NULL;
380 GtkTreeSelection *sel = NULL;
381 GList *sel_list = NULL, *tmp = NULL;
382 GtkTreeRowReference *row_reference = NULL;
383 GtkTreePath *next_path = NULL;
385 /* Find last selected row */
386 if (MODEST_IS_MAIN_WINDOW (win)) {
387 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
388 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
389 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
390 for (tmp=sel_list; tmp; tmp=tmp->next) {
391 if (tmp->next == NULL) {
392 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
393 gtk_tree_path_next (next_path);
394 row_reference = gtk_tree_row_reference_new (model, next_path);
395 gtk_tree_path_free (next_path);
400 /* Remove each header. If it's a view window header_view == NULL */
401 do_headers_action (win, headers_action_delete, header_view);
403 /* refresh the header view (removing marked-as-deleted)*/
404 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
406 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
407 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
409 /* Get main window */
410 mgr = modest_runtime_get_window_mgr ();
411 main_window = modest_window_mgr_get_main_window (mgr);
414 /* Move cursor to next row */
417 /* Select next row */
418 if (gtk_tree_row_reference_valid (row_reference)) {
419 next_path = gtk_tree_row_reference_get_path (row_reference);
420 gtk_tree_selection_select_path (sel, next_path);
421 gtk_tree_path_free (next_path);
423 if (row_reference != NULL)
424 gtk_tree_row_reference_free (row_reference);
427 /* Update toolbar dimming state */
428 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
431 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
432 g_list_free (sel_list);
438 g_object_unref (header_list);
444 /* delete either message or folder, based on where we are */
446 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
448 g_return_if_fail (MODEST_IS_WINDOW(win));
450 /* Check first if the header view has the focus */
451 if (MODEST_IS_MAIN_WINDOW (win)) {
453 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
454 MODEST_WIDGET_TYPE_FOLDER_VIEW);
455 if (gtk_widget_is_focus (w)) {
456 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
460 modest_ui_actions_on_delete_message (action, win);
466 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
468 #ifdef MODEST_PLATFORM_MAEMO
469 modest_osso_save_state();
470 #endif /* MODEST_PLATFORM_MAEMO */
472 g_debug ("closing down, clearing %d item(s) from operation queue",
473 modest_mail_operation_queue_num_elements
474 (modest_runtime_get_mail_operation_queue()));
476 /* cancel all outstanding operations */
477 modest_mail_operation_queue_cancel_all
478 (modest_runtime_get_mail_operation_queue());
480 g_debug ("queue has been cleared");
482 /* note: when modest-tny-account-store is finalized,
483 it will automatically set all network connections
490 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
494 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
496 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
497 /* gtk_widget_destroy (GTK_WIDGET (win)); */
498 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
499 /* gboolean ret_value; */
500 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
501 /* } else if (MODEST_IS_WINDOW (win)) { */
502 /* gtk_widget_destroy (GTK_WIDGET (win)); */
504 /* g_return_if_reached (); */
509 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
511 GtkClipboard *clipboard = NULL;
512 gchar *selection = NULL;
514 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
515 selection = gtk_clipboard_wait_for_text (clipboard);
517 /* Question: why is the clipboard being used here?
518 * It doesn't really make a lot of sense. */
522 modest_address_book_add_address (selection);
528 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
530 /* This is currently only implemented for Maemo */
531 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
532 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
533 run_account_setup_wizard (win);
536 /* Show the list of accounts: */
537 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
538 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
540 /* Don't make this a modal window, because secondary windows will then
541 * be unusable, freezing the UI: */
542 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
543 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
546 GtkWidget *dialog, *label;
548 /* Create the widgets */
550 dialog = gtk_dialog_new_with_buttons ("Message",
552 GTK_DIALOG_DESTROY_WITH_PARENT,
556 label = gtk_label_new ("Hello World!");
558 /* Ensure that the dialog box is destroyed when the user responds. */
560 g_signal_connect_swapped (dialog, "response",
561 G_CALLBACK (gtk_widget_destroy),
564 /* Add the label, and show everything we've added to the dialog. */
566 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
568 gtk_widget_show_all (dialog);
569 #endif /* MODEST_PLATFORM_MAEMO */
573 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
575 ModestWindow *main_window = MODEST_WINDOW (user_data);
577 /* Save any changes. */
578 modest_connection_specific_smtp_window_save_server_accounts (
579 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
580 modest_window_get_active_account (main_window));
581 gtk_widget_destroy (GTK_WIDGET (window));
587 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
589 /* This is currently only implemented for Maemo,
590 * because it requires an API (libconic) to detect different connection
593 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
595 /* Create the window if necessary: */
596 const gchar *active_account_name = modest_window_get_active_account (win);
598 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
599 * or show the default account?
600 * If we show the default account then the account name should be shown in
601 * the window when we show it. */
602 if (!active_account_name) {
603 g_warning ("%s: No account is active.", __FUNCTION__);
607 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
608 modest_connection_specific_smtp_window_fill_with_connections (
609 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
610 modest_runtime_get_account_mgr(),
611 active_account_name);
613 /* Show the window: */
614 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
615 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
616 gtk_widget_show (specific_window);
618 /* Save changes when the window is hidden: */
619 g_signal_connect (specific_window, "hide",
620 G_CALLBACK (on_smtp_servers_window_hide), win);
621 #endif /* MODEST_PLATFORM_MAEMO */
625 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
627 ModestWindow *msg_win = NULL;
629 TnyFolder *folder = NULL;
630 gchar *account_name = NULL;
631 gchar *from_str = NULL;
632 /* GError *err = NULL; */
633 TnyAccount *account = NULL;
634 ModestWindowMgr *mgr;
635 gchar *signature = NULL, *blank_and_signature = NULL;
637 /* if there are no accounts yet, just show the wizard */
638 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
639 run_account_setup_wizard (win);
643 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
645 account_name = g_strdup (modest_window_get_active_account (win));
647 g_printerr ("modest: no account found\n");
651 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
653 TNY_ACCOUNT_TYPE_STORE);
655 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
659 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
661 g_printerr ("modest: failed get from string for '%s'\n", account_name);
665 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
666 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
667 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
668 MODEST_ACCOUNT_SIGNATURE, FALSE);
669 blank_and_signature = g_strconcat ("\n", signature, NULL);
672 blank_and_signature = g_strdup ("");
675 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
677 g_printerr ("modest: failed to create new msg\n");
681 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
683 g_printerr ("modest: failed to find Drafts folder\n");
688 /* Create and register edit window */
689 /* This is destroyed by TOOD. */
690 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
691 mgr = modest_runtime_get_window_mgr ();
692 modest_window_mgr_register_window (mgr, msg_win);
695 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
697 gtk_widget_show_all (GTK_WIDGET (msg_win));
700 g_free (account_name);
702 g_free (blank_and_signature);
704 g_object_unref (msg_win);
706 g_object_unref (G_OBJECT(account));
708 g_object_unref (G_OBJECT(msg));
710 g_object_unref (G_OBJECT(folder));
714 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
718 ModestMailOperationStatus status;
720 /* If there is no message or the operation was not successful */
721 status = modest_mail_operation_get_status (mail_op);
722 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
724 /* Remove the header from the preregistered uids */
725 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
735 open_msg_cb (ModestMailOperation *mail_op,
740 ModestWindowMgr *mgr = NULL;
741 ModestWindow *parent_win = NULL;
742 ModestWindow *win = NULL;
743 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
744 gchar *account = NULL;
747 /* Do nothing if there was any problem with the mail
748 operation. The error will be shown by the error_handler of
749 the mail operation */
750 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
754 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
755 folder = tny_header_get_folder (header);
757 /* Mark header as read */
758 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
761 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
763 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
765 /* Gets folder type (OUTBOX headers will be opened in edit window */
766 if (modest_tny_folder_is_local_folder (folder))
767 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
769 /* If the header is in the drafts folder then open the editor,
770 else the message view window */
771 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
772 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
773 /* we cannot edit without a valid account... */
774 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
775 run_account_setup_wizard(parent_win);
778 win = modest_msg_edit_window_new (msg, account, TRUE);
781 gchar *uid = modest_tny_folder_get_header_unique_id (header);
783 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
784 GtkWidget *header_view;
785 GtkTreeSelection *sel;
786 GList *sel_list = NULL;
789 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
790 MODEST_WIDGET_TYPE_HEADER_VIEW);
792 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
793 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
795 if (sel_list != NULL) {
796 GtkTreeRowReference *row_reference;
798 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
799 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
800 g_list_free (sel_list);
802 win = modest_msg_view_window_new_with_header_model (msg,
807 gtk_tree_row_reference_free (row_reference);
809 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
812 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
817 /* Register and show new window */
819 mgr = modest_runtime_get_window_mgr ();
820 modest_window_mgr_register_window (mgr, win);
821 g_object_unref (win);
822 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
823 gtk_widget_show_all (GTK_WIDGET(win));
826 /* Update toolbar dimming state */
827 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
828 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
834 g_object_unref (parent_win);
835 g_object_unref (folder);
839 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
843 GObject *win = modest_mail_operation_get_source (mail_op);
845 error = modest_mail_operation_get_error (mail_op);
846 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
848 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
850 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
853 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
854 _("mail_ni_ui_folder_get_msg_folder_error"));
858 g_object_unref (win);
862 * This function is used by both modest_ui_actions_on_open and
863 * modest_ui_actions_on_header_activated. This way we always do the
864 * same when trying to open messages.
867 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
869 ModestWindowMgr *mgr = NULL;
870 TnyIterator *iter = NULL;
871 ModestMailOperation *mail_op = NULL;
872 TnyList *not_opened_headers = NULL;
873 TnyHeaderFlags flags = 0;
875 /* Look if we already have a message view for each header. If
876 true, then remove the header from the list of headers to
878 mgr = modest_runtime_get_window_mgr ();
879 iter = tny_list_create_iterator (headers);
880 not_opened_headers = tny_simple_list_new ();
882 while (!tny_iterator_is_done (iter)) {
884 ModestWindow *window = NULL;
885 TnyHeader *header = NULL;
886 gboolean found = FALSE;
888 header = TNY_HEADER (tny_iterator_get_current (iter));
890 flags = tny_header_get_flags (header);
893 found = modest_window_mgr_find_registered_header (mgr, header, &window);
895 /* Do not open again the message and present the
896 window to the user */
899 gtk_window_present (GTK_WINDOW (window));
901 /* the header has been registered already, we don't do
902 * anything but wait for the window to come up*/
903 g_debug ("header %p already registered, waiting for window", header);
905 tny_list_append (not_opened_headers, G_OBJECT (header));
909 g_object_unref (header);
911 tny_iterator_next (iter);
913 g_object_unref (iter);
916 /* If some messages would have to be downloaded, ask the user to
917 * make a connection. It's generally easier to do this here (in the mainloop)
918 * than later in a thread:
920 if (tny_list_get_length (not_opened_headers) > 0) {
922 gboolean found = FALSE;
924 iter = tny_list_create_iterator (not_opened_headers);
925 while (!tny_iterator_is_done (iter) && !found) {
926 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
927 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
930 tny_iterator_next (iter);
932 g_object_unref (header);
934 g_object_unref (iter);
936 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
937 g_object_unref (not_opened_headers);
942 /* Register the headers before actually creating the windows: */
943 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
944 while (!tny_iterator_is_done (iter_not_opened)) {
945 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
947 modest_window_mgr_register_header (mgr, header);
948 g_object_unref (header);
951 tny_iterator_next (iter_not_opened);
953 g_object_unref (iter_not_opened);
954 iter_not_opened = NULL;
956 /* Open each message */
957 if (tny_list_get_length (not_opened_headers) > 0) {
958 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
960 modest_ui_actions_get_msgs_full_error_handler,
962 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
963 if (tny_list_get_length (not_opened_headers) > 1) {
964 modest_mail_operation_get_msgs_full (mail_op,
970 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
971 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
972 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
973 g_object_unref (header);
974 g_object_unref (iter);
976 g_object_unref (mail_op);
980 if (not_opened_headers != NULL)
981 g_object_unref (not_opened_headers);
985 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
990 headers = get_selected_headers (win);
995 _modest_ui_actions_open (headers, win);
997 g_object_unref(headers);
1002 free_reply_forward_helper (gpointer data)
1004 ReplyForwardHelper *helper;
1006 helper = (ReplyForwardHelper *) data;
1007 g_free (helper->account_name);
1008 g_slice_free (ReplyForwardHelper, helper);
1012 reply_forward_cb (ModestMailOperation *mail_op,
1018 ReplyForwardHelper *rf_helper;
1019 ModestWindow *msg_win = NULL;
1020 ModestEditType edit_type;
1022 TnyAccount *account = NULL;
1023 ModestWindowMgr *mgr = NULL;
1024 gchar *signature = NULL;
1026 /* If there was any error. The mail operation could be NULL,
1027 this means that we already have the message downloaded and
1028 that we didn't do a mail operation to retrieve it */
1029 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1032 g_return_if_fail (user_data != NULL);
1033 rf_helper = (ReplyForwardHelper *) user_data;
1035 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1036 rf_helper->account_name);
1037 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1038 rf_helper->account_name,
1039 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1040 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1041 rf_helper->account_name,
1042 MODEST_ACCOUNT_SIGNATURE, FALSE);
1045 /* Create reply mail */
1046 switch (rf_helper->action) {
1049 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1050 rf_helper->reply_forward_type,
1051 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1053 case ACTION_REPLY_TO_ALL:
1055 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1056 MODEST_TNY_MSG_REPLY_MODE_ALL);
1057 edit_type = MODEST_EDIT_TYPE_REPLY;
1059 case ACTION_FORWARD:
1061 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1062 edit_type = MODEST_EDIT_TYPE_FORWARD;
1065 g_return_if_reached ();
1072 g_printerr ("modest: failed to create message\n");
1076 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1077 rf_helper->account_name,
1078 TNY_ACCOUNT_TYPE_STORE);
1080 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1084 /* Create and register the windows */
1085 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1086 mgr = modest_runtime_get_window_mgr ();
1087 modest_window_mgr_register_window (mgr, msg_win);
1089 if (rf_helper->parent_window != NULL) {
1090 gdouble parent_zoom;
1092 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1093 modest_window_set_zoom (msg_win, parent_zoom);
1096 /* Show edit window */
1097 gtk_widget_show_all (GTK_WIDGET (msg_win));
1101 g_object_unref (msg_win);
1103 g_object_unref (G_OBJECT (new_msg));
1105 g_object_unref (G_OBJECT (account));
1106 /* g_object_unref (msg); */
1107 free_reply_forward_helper (rf_helper);
1111 * Checks a list of headers. If any of them are not currently
1112 * downloaded (CACHED) then it asks the user for permission to
1115 * Returns FALSE if the user does not want to download the
1116 * messages. Returns TRUE if the user allowed the download or if all
1117 * of them are currently downloaded
1120 download_uncached_messages (TnyList *header_list,
1126 gint uncached_messages = 0;
1128 iter = tny_list_create_iterator (header_list);
1129 while (!tny_iterator_is_done (iter)) {
1132 header = TNY_HEADER (tny_iterator_get_current (iter));
1134 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1135 uncached_messages ++;
1136 g_object_unref (header);
1139 tny_iterator_next (iter);
1141 g_object_unref (iter);
1143 /* Ask for user permission to download the messages */
1145 if (uncached_messages > 0) {
1146 GtkResponseType response;
1148 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1149 _("emev_nc_include_original"));
1152 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1153 ngettext("mcen_nc_get_msg",
1155 uncached_messages));
1156 if (response == GTK_RESPONSE_CANCEL)
1159 /* If a download will be necessary, make sure that we have a connection: */
1160 retval = modest_platform_connect_and_wait(win, NULL);
1168 * Common code for the reply and forward actions
1171 reply_forward (ReplyForwardAction action, ModestWindow *win)
1173 ModestMailOperation *mail_op = NULL;
1174 TnyList *header_list = NULL;
1175 ReplyForwardHelper *rf_helper = NULL;
1176 guint reply_forward_type;
1177 gboolean continue_download = TRUE;
1178 gboolean do_retrieve = TRUE;
1180 g_return_if_fail (MODEST_IS_WINDOW(win));
1182 /* we need an account when editing */
1183 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1184 run_account_setup_wizard (win);
1188 header_list = get_selected_headers (win);
1192 reply_forward_type =
1193 modest_conf_get_int (modest_runtime_get_conf (),
1194 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1197 /* Check that the messages have been previously downloaded */
1198 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1200 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1201 if (!continue_download) {
1202 g_object_unref (header_list);
1206 /* We assume that we can only select messages of the
1207 same folder and that we reply all of them from the
1208 same account. In fact the interface currently only
1209 allows single selection */
1212 rf_helper = g_slice_new0 (ReplyForwardHelper);
1213 rf_helper->reply_forward_type = reply_forward_type;
1214 rf_helper->action = action;
1215 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1217 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1218 rf_helper->parent_window = GTK_WIDGET (win);
1219 if (!rf_helper->account_name)
1220 rf_helper->account_name =
1221 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1223 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1226 /* Get header and message. Do not free them here, the
1227 reply_forward_cb must do it */
1228 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1229 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1230 if (!msg || !header) {
1232 g_object_unref (msg);
1233 g_printerr ("modest: no message found\n");
1236 reply_forward_cb (NULL, header, msg, rf_helper);
1239 g_object_unref (header);
1244 /* Only reply/forward to one message */
1245 iter = tny_list_create_iterator (header_list);
1246 header = TNY_HEADER (tny_iterator_get_current (iter));
1247 g_object_unref (iter);
1250 /* Retrieve messages */
1252 mail_op = modest_mail_operation_new_with_error_handling (
1253 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1255 modest_ui_actions_get_msgs_full_error_handler,
1257 modest_mail_operation_queue_add (
1258 modest_runtime_get_mail_operation_queue (), mail_op);
1260 modest_mail_operation_get_msg (mail_op,
1265 g_object_unref(mail_op);
1267 /* we put a ref here to prevent double unref as the reply
1268 * forward callback unrefs the header at its end */
1269 reply_forward_cb (NULL, header, NULL, rf_helper);
1273 g_object_unref (header);
1279 g_object_unref (header_list);
1283 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1285 g_return_if_fail (MODEST_IS_WINDOW(win));
1287 reply_forward (ACTION_REPLY, win);
1291 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1293 g_return_if_fail (MODEST_IS_WINDOW(win));
1295 reply_forward (ACTION_FORWARD, win);
1299 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1301 g_return_if_fail (MODEST_IS_WINDOW(win));
1303 reply_forward (ACTION_REPLY_TO_ALL, win);
1307 modest_ui_actions_on_next (GtkAction *action,
1308 ModestWindow *window)
1310 if (MODEST_IS_MAIN_WINDOW (window)) {
1311 GtkWidget *header_view;
1313 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1314 MODEST_WIDGET_TYPE_HEADER_VIEW);
1318 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1319 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1320 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1322 g_return_if_reached ();
1327 modest_ui_actions_on_prev (GtkAction *action,
1328 ModestWindow *window)
1330 g_return_if_fail (MODEST_IS_WINDOW(window));
1332 if (MODEST_IS_MAIN_WINDOW (window)) {
1333 GtkWidget *header_view;
1334 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1335 MODEST_WIDGET_TYPE_HEADER_VIEW);
1339 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1340 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1341 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1343 g_return_if_reached ();
1348 modest_ui_actions_on_sort (GtkAction *action,
1349 ModestWindow *window)
1351 g_return_if_fail (MODEST_IS_WINDOW(window));
1353 if (MODEST_IS_MAIN_WINDOW (window)) {
1354 GtkWidget *header_view;
1355 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1356 MODEST_WIDGET_TYPE_HEADER_VIEW);
1358 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1363 /* Show sorting dialog */
1364 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1369 new_messages_arrived (ModestMailOperation *self,
1373 if (new_messages == 0)
1376 modest_platform_on_new_msg ();
1380 * This function performs the send & receive required actions. The
1381 * window is used to create the mail operation. Typically it should
1382 * always be the main window, but we pass it as argument in order to
1386 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1388 gchar *acc_name = NULL;
1389 ModestMailOperation *mail_op;
1391 /* If no account name was provided then get the current account, and if
1392 there is no current account then pick the default one: */
1393 if (!account_name) {
1394 acc_name = g_strdup (modest_window_get_active_account(win));
1396 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1398 g_printerr ("modest: cannot get default account\n");
1402 acc_name = g_strdup (account_name);
1405 /* Set send/receive operation in progress */
1406 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1408 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1410 modest_ui_actions_send_receive_error_handler,
1413 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1414 G_CALLBACK (_on_send_receive_progress_changed),
1417 /* Send & receive. */
1418 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1419 /* Receive and then send. The operation is tagged initially as
1420 a receive operation because the account update performs a
1421 receive and then a send. The operation changes its type
1422 internally, so the progress objects will receive the proper
1423 progress information */
1424 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1425 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1426 g_object_unref (G_OBJECT (mail_op));
1434 modest_ui_actions_do_cancel_send (const gchar *account_name,
1437 TnyTransportAccount *transport_account;
1438 TnySendQueue *send_queue = NULL;
1439 GError *error = NULL;
1441 /* Get transport account */
1443 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1444 (modest_runtime_get_account_store(),
1446 TNY_ACCOUNT_TYPE_TRANSPORT));
1447 if (!transport_account) {
1448 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1453 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1454 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1455 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1456 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1457 "modest: could not find send queue for account\n");
1459 /* Keeep messages in outbox folder */
1460 tny_send_queue_cancel (send_queue, FALSE, &error);
1464 if (transport_account != NULL)
1465 g_object_unref (G_OBJECT (transport_account));
1469 modest_ui_actions_cancel_send_all (ModestWindow *win)
1471 GSList *account_names, *iter;
1473 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1476 iter = account_names;
1478 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1479 iter = g_slist_next (iter);
1482 modest_account_mgr_free_account_names (account_names);
1483 account_names = NULL;
1487 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1490 /* Check if accounts exist */
1491 gboolean accounts_exist =
1492 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1494 /* If not, allow the user to create an account before trying to send/receive. */
1495 if (!accounts_exist)
1496 modest_ui_actions_on_accounts (NULL, win);
1498 /* Cancel all sending operaitons */
1499 modest_ui_actions_cancel_send_all (win);
1503 * Refreshes all accounts. This function will be used by automatic
1507 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1509 GSList *account_names, *iter;
1511 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1514 iter = account_names;
1516 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1517 iter = g_slist_next (iter);
1520 modest_account_mgr_free_account_names (account_names);
1521 account_names = NULL;
1525 modest_do_refresh_current_folder(ModestWindow *win)
1527 /* Refresh currently selected folder. Note that if we only
1528 want to retreive the headers, then the refresh only will
1529 invoke a poke_status over all folders, i.e., only the
1530 total/unread count will be updated */
1531 if (MODEST_IS_MAIN_WINDOW (win)) {
1532 GtkWidget *header_view, *folder_view;
1533 TnyFolderStore *folder_store;
1535 /* Get folder and header view */
1537 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1538 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1540 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1542 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1544 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1545 MODEST_WIDGET_TYPE_HEADER_VIEW);
1547 /* We do not need to set the contents style
1548 because it hasn't changed. We also do not
1549 need to save the widget status. Just force
1551 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1552 TNY_FOLDER (folder_store),
1553 folder_refreshed_cb,
1554 MODEST_MAIN_WINDOW (win));
1558 g_object_unref (folder_store);
1564 * Handler of the click on Send&Receive button in the main toolbar
1567 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1569 /* Check if accounts exist */
1570 gboolean accounts_exist =
1571 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1573 /* If not, allow the user to create an account before trying to send/receive. */
1574 if (!accounts_exist)
1575 modest_ui_actions_on_accounts (NULL, win);
1577 modest_do_refresh_current_folder (win);
1579 /* Refresh the active account */
1580 modest_ui_actions_do_send_receive (NULL, win);
1585 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1588 GtkWidget *header_view;
1590 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1592 header_view = modest_main_window_get_child_widget (main_window,
1593 MODEST_WIDGET_TYPE_HEADER_VIEW);
1597 conf = modest_runtime_get_conf ();
1599 /* what is saved/restored is depending on the style; thus; we save with
1600 * old style, then update the style, and restore for this new style
1602 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1604 if (modest_header_view_get_style
1605 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1606 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1607 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1609 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1610 MODEST_HEADER_VIEW_STYLE_DETAILS);
1612 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1613 MODEST_CONF_HEADER_VIEW_KEY);
1618 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1620 ModestMainWindow *main_window)
1622 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1623 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1625 /* in the case the folder is empty, show the empty folder message and focus
1627 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1628 if (modest_header_view_is_empty (header_view)) {
1629 TnyFolder *folder = modest_header_view_get_folder (header_view);
1630 GtkWidget *folder_view =
1631 modest_main_window_get_child_widget (main_window,
1632 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1634 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1635 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1639 /* If no header has been selected then exit */
1644 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1645 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1647 /* Update Main window title */
1648 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1649 const gchar *subject = tny_header_get_subject (header);
1650 if (subject && strlen(subject) > 0)
1651 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1653 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1656 /* Update toolbar dimming state */
1657 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1661 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1663 ModestMainWindow *main_window)
1667 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1672 headers = tny_simple_list_new ();
1673 tny_list_prepend (headers, G_OBJECT (header));
1675 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1677 g_object_unref (headers);
1681 set_active_account_from_tny_account (TnyAccount *account,
1682 ModestWindow *window)
1684 const gchar *server_acc_name = tny_account_get_id (account);
1686 /* We need the TnyAccount provided by the
1687 account store because that is the one that
1688 knows the name of the Modest account */
1689 TnyAccount *modest_server_account = modest_server_account =
1690 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1691 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1694 const gchar *modest_acc_name =
1695 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1696 modest_window_set_active_account (window, modest_acc_name);
1697 g_object_unref (modest_server_account);
1702 folder_refreshed_cb (ModestMailOperation *mail_op,
1706 ModestMainWindow *win = NULL;
1707 GtkWidget *header_view;
1708 TnyFolder *current_folder;
1710 g_return_if_fail (TNY_IS_FOLDER (folder));
1712 win = MODEST_MAIN_WINDOW (user_data);
1714 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1717 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1718 if (current_folder != NULL && folder != current_folder) {
1723 /* Check if folder is empty and set headers view contents style */
1724 if (tny_folder_get_all_count (folder) == 0) {
1725 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1726 modest_main_window_set_contents_style (win,
1727 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1729 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1734 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1735 TnyFolderStore *folder_store,
1737 ModestMainWindow *main_window)
1740 GtkWidget *header_view;
1742 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1744 header_view = modest_main_window_get_child_widget(main_window,
1745 MODEST_WIDGET_TYPE_HEADER_VIEW);
1749 conf = modest_runtime_get_conf ();
1751 if (TNY_IS_ACCOUNT (folder_store)) {
1753 /* Update active account */
1754 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1755 /* Show account details */
1756 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1759 if (TNY_IS_FOLDER (folder_store) && selected) {
1761 /* Update the active account */
1762 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1764 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1765 g_object_unref (account);
1769 /* Set the header style by default, it could
1770 be changed later by the refresh callback to
1772 modest_main_window_set_contents_style (main_window,
1773 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1775 /* Set folder on header view. This function
1776 will call tny_folder_refresh_async so we
1777 pass a callback that will be called when
1778 finished. We use that callback to set the
1779 empty view if there are no messages */
1780 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1781 TNY_FOLDER (folder_store),
1782 folder_refreshed_cb,
1785 /* Restore configuration. We need to do this
1786 *after* the set_folder because the widget
1787 memory asks the header view about its
1789 modest_widget_memory_restore (modest_runtime_get_conf (),
1790 G_OBJECT(header_view),
1791 MODEST_CONF_HEADER_VIEW_KEY);
1793 /* Update the active account */
1794 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1795 /* Save only if we're seeing headers */
1796 if (modest_main_window_get_contents_style (main_window) ==
1797 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1798 modest_widget_memory_save (conf, G_OBJECT (header_view),
1799 MODEST_CONF_HEADER_VIEW_KEY);
1800 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1804 /* Update toolbar dimming state */
1805 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1809 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1816 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1818 online = tny_device_is_online (modest_runtime_get_device());
1821 /* already online -- the item is simply not there... */
1822 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1824 GTK_MESSAGE_WARNING,
1826 _("The %s you selected cannot be found"),
1828 gtk_dialog_run (GTK_DIALOG(dialog));
1830 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1834 GTK_RESPONSE_REJECT,
1836 GTK_RESPONSE_ACCEPT,
1838 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1839 "Do you want to get online?"), item);
1840 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1841 gtk_label_new (txt), FALSE, FALSE, 0);
1842 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1845 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1846 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1847 /* TODO: Comment about why is this commented out: */
1848 /* modest_platform_connect_and_wait (); */
1851 gtk_widget_destroy (dialog);
1855 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1858 /* g_message ("%s %s", __FUNCTION__, link); */
1863 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1866 modest_platform_activate_uri (link);
1870 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1873 modest_platform_show_uri_popup (link);
1877 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1880 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1884 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1885 const gchar *address,
1888 /* g_message ("%s %s", __FUNCTION__, address); */
1892 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1894 TnyTransportAccount *transport_account;
1895 ModestMailOperation *mail_operation;
1897 gchar *account_name, *from;
1898 ModestAccountMgr *account_mgr;
1899 gchar *info_text = NULL;
1901 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1903 data = modest_msg_edit_window_get_msg_data (edit_window);
1905 account_mgr = modest_runtime_get_account_mgr();
1906 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1908 account_name = modest_account_mgr_get_default_account (account_mgr);
1909 if (!account_name) {
1910 g_printerr ("modest: no account found\n");
1911 modest_msg_edit_window_free_msg_data (edit_window, data);
1915 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1916 account_name = g_strdup (data->account_name);
1920 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1921 (modest_runtime_get_account_store(),
1923 TNY_ACCOUNT_TYPE_TRANSPORT));
1924 if (!transport_account) {
1925 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1926 g_free (account_name);
1927 modest_msg_edit_window_free_msg_data (edit_window, data);
1930 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1932 /* Create the mail operation */
1933 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1934 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1936 modest_mail_operation_save_to_drafts (mail_operation,
1948 data->priority_flags);
1951 g_free (account_name);
1952 g_object_unref (G_OBJECT (transport_account));
1953 g_object_unref (G_OBJECT (mail_operation));
1955 modest_msg_edit_window_free_msg_data (edit_window, data);
1957 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1958 modest_platform_information_banner (NULL, NULL, info_text);
1962 /* For instance, when clicking the Send toolbar button when editing a message: */
1964 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1966 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1968 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
1971 /* Offer the connection dialog, if necessary: */
1972 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
1975 /* FIXME: Code added just for testing. The final version will
1976 use the send queue provided by tinymail and some
1978 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1979 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1981 account_name = modest_account_mgr_get_default_account (account_mgr);
1983 if (!account_name) {
1984 /* Run account setup wizard */
1985 run_account_setup_wizard(MODEST_WINDOW(edit_window));
1989 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1991 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1992 account_name = g_strdup (data->account_name);
1995 /* Get the currently-active transport account for this modest account: */
1996 TnyTransportAccount *transport_account =
1997 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1998 (modest_runtime_get_account_store(),
2000 if (!transport_account) {
2001 /* Run account setup wizard */
2002 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2006 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2008 /* mail content checks and dialogs */
2009 if (data->subject == NULL || data->subject[0] == '\0') {
2010 GtkResponseType response;
2011 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2012 _("mcen_nc_subject_is_empty_send"));
2013 if (response == GTK_RESPONSE_CANCEL) {
2014 g_free (account_name);
2019 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2020 GtkResponseType response;
2021 gchar *note_message;
2022 gchar *note_subject = data->subject;
2023 if (note_subject == NULL || note_subject[0] == '\0')
2024 note_subject = _("mail_va_no_subject");
2025 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2026 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2028 g_free (note_message);
2029 if (response == GTK_RESPONSE_CANCEL) {
2030 g_free (account_name);
2035 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2037 /* Create the mail operation */
2038 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2039 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2041 modest_mail_operation_send_new_mail (mail_operation,
2052 data->priority_flags);
2056 g_free (account_name);
2057 g_object_unref (G_OBJECT (transport_account));
2058 g_object_unref (G_OBJECT (mail_operation));
2060 modest_msg_edit_window_free_msg_data (edit_window, data);
2061 modest_msg_edit_window_set_sent (edit_window, TRUE);
2063 /* Save settings and close the window: */
2064 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2068 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2069 ModestMsgEditWindow *window)
2071 ModestMsgEditFormatState *format_state = NULL;
2073 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2074 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2076 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2079 format_state = modest_msg_edit_window_get_format_state (window);
2080 g_return_if_fail (format_state != NULL);
2082 format_state->bold = gtk_toggle_action_get_active (action);
2083 modest_msg_edit_window_set_format_state (window, format_state);
2084 g_free (format_state);
2089 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2090 ModestMsgEditWindow *window)
2092 ModestMsgEditFormatState *format_state = NULL;
2094 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2095 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2097 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2100 format_state = modest_msg_edit_window_get_format_state (window);
2101 g_return_if_fail (format_state != NULL);
2103 format_state->italics = gtk_toggle_action_get_active (action);
2104 modest_msg_edit_window_set_format_state (window, format_state);
2105 g_free (format_state);
2110 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2111 ModestMsgEditWindow *window)
2113 ModestMsgEditFormatState *format_state = NULL;
2115 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2116 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2118 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2121 format_state = modest_msg_edit_window_get_format_state (window);
2122 g_return_if_fail (format_state != NULL);
2124 format_state->bullet = gtk_toggle_action_get_active (action);
2125 modest_msg_edit_window_set_format_state (window, format_state);
2126 g_free (format_state);
2131 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2132 GtkRadioAction *selected,
2133 ModestMsgEditWindow *window)
2135 ModestMsgEditFormatState *format_state = NULL;
2136 GtkJustification value;
2138 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2140 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2143 value = gtk_radio_action_get_current_value (selected);
2145 format_state = modest_msg_edit_window_get_format_state (window);
2146 g_return_if_fail (format_state != NULL);
2148 format_state->justification = value;
2149 modest_msg_edit_window_set_format_state (window, format_state);
2150 g_free (format_state);
2154 modest_ui_actions_on_select_editor_color (GtkAction *action,
2155 ModestMsgEditWindow *window)
2157 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2158 g_return_if_fail (GTK_IS_ACTION (action));
2160 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2163 modest_msg_edit_window_select_color (window);
2167 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2168 ModestMsgEditWindow *window)
2170 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2171 g_return_if_fail (GTK_IS_ACTION (action));
2173 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2176 modest_msg_edit_window_select_background_color (window);
2180 modest_ui_actions_on_insert_image (GtkAction *action,
2181 ModestMsgEditWindow *window)
2183 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2184 g_return_if_fail (GTK_IS_ACTION (action));
2186 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2189 modest_msg_edit_window_insert_image (window);
2193 modest_ui_actions_on_attach_file (GtkAction *action,
2194 ModestMsgEditWindow *window)
2196 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2197 g_return_if_fail (GTK_IS_ACTION (action));
2199 modest_msg_edit_window_offer_attach_file (window);
2203 modest_ui_actions_on_remove_attachments (GtkAction *action,
2204 ModestMsgEditWindow *window)
2206 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2207 g_return_if_fail (GTK_IS_ACTION (action));
2209 modest_msg_edit_window_remove_attachments (window, NULL);
2213 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2216 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2217 const GError *error = modest_mail_operation_get_error (mail_op);
2221 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2222 modest_mail_operation_get_error (mail_op)->message);
2227 modest_ui_actions_create_folder(GtkWidget *parent_window,
2228 GtkWidget *folder_view)
2230 TnyFolderStore *parent_folder;
2232 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2234 if (parent_folder) {
2235 gboolean finished = FALSE;
2237 gchar *folder_name = NULL, *suggested_name = NULL;
2239 /* Run the new folder dialog */
2241 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2246 g_free (suggested_name);
2247 suggested_name = NULL;
2249 if (result == GTK_RESPONSE_REJECT) {
2252 ModestMailOperation *mail_op;
2253 TnyFolder *new_folder = NULL;
2255 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2256 G_OBJECT(parent_window),
2257 modest_ui_actions_new_folder_error_handler,
2260 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2262 new_folder = modest_mail_operation_create_folder (mail_op,
2264 (const gchar *) folder_name);
2266 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2269 g_object_unref (new_folder);
2272 g_object_unref (mail_op);
2275 suggested_name = folder_name;
2279 g_object_unref (parent_folder);
2284 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2286 GtkWidget *folder_view;
2288 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2290 folder_view = modest_main_window_get_child_widget (main_window,
2291 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2295 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2299 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2302 GObject *win = modest_mail_operation_get_source (mail_op);
2303 const GError *error = NULL;
2304 const gchar *message = NULL;
2306 /* Get error message */
2307 error = modest_mail_operation_get_error (mail_op);
2308 if (error != NULL && error->message != NULL) {
2309 message = error->message;
2311 message = _("!!! FIXME: Unable to rename");
2314 /* Show notification dialog */
2315 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2316 g_object_unref (win);
2320 modest_ui_actions_on_rename_folder (GtkAction *action,
2321 ModestMainWindow *main_window)
2323 TnyFolderStore *folder;
2324 GtkWidget *folder_view;
2325 GtkWidget *header_view;
2327 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2329 folder_view = modest_main_window_get_child_widget (main_window,
2330 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2334 header_view = modest_main_window_get_child_widget (main_window,
2335 MODEST_WIDGET_TYPE_HEADER_VIEW);
2340 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2344 /* Offer the connection dialog if necessary: */
2345 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2346 g_object_unref (G_OBJECT (folder));
2351 if (TNY_IS_FOLDER (folder)) {
2354 const gchar *current_name;
2356 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2357 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2358 current_name, &folder_name);
2360 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2361 ModestMailOperation *mail_op;
2364 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2365 G_OBJECT(main_window),
2366 modest_ui_actions_rename_folder_error_handler,
2370 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2373 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2375 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2376 TNY_FOLDER(folder), TRUE);
2379 modest_header_view_clear ((ModestHeaderView *) header_view);
2381 modest_mail_operation_rename_folder (mail_op,
2382 TNY_FOLDER (folder),
2383 (const gchar *) folder_name);
2385 g_object_unref (mail_op);
2386 g_free (folder_name);
2389 g_object_unref (folder);
2393 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2396 GObject *win = modest_mail_operation_get_source (mail_op);
2398 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2399 _("mail_in_ui_folder_delete_error"));
2400 g_object_unref (win);
2404 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2406 TnyFolderStore *folder;
2407 GtkWidget *folder_view;
2411 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2413 folder_view = modest_main_window_get_child_widget (main_window,
2414 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2418 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2420 /* Show an error if it's an account */
2421 if (!TNY_IS_FOLDER (folder)) {
2422 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2423 _("mail_in_ui_folder_delete_error"));
2424 g_object_unref (G_OBJECT (folder));
2428 /* Offer the connection dialog if necessary: */
2429 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2430 g_object_unref (G_OBJECT (folder));
2435 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2436 tny_folder_get_name (TNY_FOLDER (folder)));
2437 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2438 (const gchar *) message);
2441 if (response == GTK_RESPONSE_OK) {
2442 ModestMailOperation *mail_op =
2443 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2444 G_OBJECT(main_window),
2445 modest_ui_actions_delete_folder_error_handler,
2448 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2450 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2451 g_object_unref (G_OBJECT (mail_op));
2454 g_object_unref (G_OBJECT (folder));
2458 modest_ui_actions_on_delete_folder (GtkAction *action,
2459 ModestMainWindow *main_window)
2461 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2463 delete_folder (main_window, FALSE);
2467 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2469 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2471 delete_folder (main_window, TRUE);
2476 show_error (GtkWidget *parent_widget, const gchar* text)
2478 hildon_banner_show_information(parent_widget, NULL, text);
2481 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2483 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2490 gtk_dialog_run (dialog);
2491 gtk_widget_destroy (GTK_WIDGET (dialog));
2496 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2497 const gchar* server_account_name,
2502 ModestMainWindow *main_window)
2504 g_return_if_fail(server_account_name);
2505 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2507 /* Initalize output parameters: */
2514 #ifdef MODEST_PLATFORM_MAEMO
2515 /* Maemo uses a different (awkward) button order,
2516 * It should probably just use gtk_alternative_dialog_button_order ().
2518 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2522 GTK_RESPONSE_ACCEPT,
2524 GTK_RESPONSE_REJECT,
2527 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2531 GTK_RESPONSE_REJECT,
2533 GTK_RESPONSE_ACCEPT,
2535 #endif /* MODEST_PLATFORM_MAEMO */
2537 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2539 gchar *server_name = modest_server_account_get_hostname (
2540 modest_runtime_get_account_mgr(), server_account_name);
2541 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2542 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2547 /* This causes a warning because the logical ID has no %s in it,
2548 * though the translation does, but there is not much we can do about that: */
2549 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2550 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2553 g_free (server_name);
2557 gchar *initial_username = modest_server_account_get_username (
2558 modest_runtime_get_account_mgr(), server_account_name);
2560 GtkWidget *entry_username = gtk_entry_new ();
2561 if (initial_username)
2562 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2563 /* Dim this if a connection has ever succeeded with this username,
2564 * as per the UI spec: */
2565 const gboolean username_known =
2566 modest_server_account_get_username_has_succeeded(
2567 modest_runtime_get_account_mgr(), server_account_name);
2568 gtk_widget_set_sensitive (entry_username, !username_known);
2570 #ifdef MODEST_PLATFORM_MAEMO
2571 /* Auto-capitalization is the default, so let's turn it off: */
2572 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2574 /* Create a size group to be used by all captions.
2575 * Note that HildonCaption does not create a default size group if we do not specify one.
2576 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2577 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2579 GtkWidget *caption = hildon_caption_new (sizegroup,
2580 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2581 gtk_widget_show (entry_username);
2582 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2583 FALSE, FALSE, MODEST_MARGIN_HALF);
2584 gtk_widget_show (caption);
2586 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2588 #endif /* MODEST_PLATFORM_MAEMO */
2591 GtkWidget *entry_password = gtk_entry_new ();
2592 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2593 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2595 #ifdef MODEST_PLATFORM_MAEMO
2596 /* Auto-capitalization is the default, so let's turn it off: */
2597 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2598 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2600 caption = hildon_caption_new (sizegroup,
2601 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2602 gtk_widget_show (entry_password);
2603 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2604 FALSE, FALSE, MODEST_MARGIN_HALF);
2605 gtk_widget_show (caption);
2606 g_object_unref (sizegroup);
2608 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2610 #endif /* MODEST_PLATFORM_MAEMO */
2612 /* This is not in the Maemo UI spec:
2613 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2614 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2618 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2620 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2622 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2624 modest_server_account_set_username (
2625 modest_runtime_get_account_mgr(), server_account_name,
2628 const gboolean username_was_changed =
2629 (strcmp (*username, initial_username) != 0);
2630 if (username_was_changed) {
2631 g_warning ("%s: tinymail does not yet support changing the "
2632 "username in the get_password() callback.\n", __FUNCTION__);
2637 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2639 /* We do not save the password in the configuration,
2640 * because this function is only called for passwords that should
2641 * not be remembered:
2642 modest_server_account_set_password (
2643 modest_runtime_get_account_mgr(), server_account_name,
2652 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2664 /* This is not in the Maemo UI spec:
2665 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2671 gtk_widget_destroy (dialog);
2673 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2677 modest_ui_actions_on_cut (GtkAction *action,
2678 ModestWindow *window)
2680 GtkWidget *focused_widget;
2681 GtkClipboard *clipboard;
2683 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2684 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2685 if (GTK_IS_EDITABLE (focused_widget)) {
2686 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2687 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2688 gtk_clipboard_store (clipboard);
2689 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2690 GtkTextBuffer *buffer;
2692 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2693 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2694 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2695 gtk_clipboard_store (clipboard);
2696 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2697 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2698 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2699 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2704 modest_ui_actions_on_copy (GtkAction *action,
2705 ModestWindow *window)
2707 GtkClipboard *clipboard;
2708 GtkWidget *focused_widget;
2710 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2711 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2713 if (GTK_IS_LABEL (focused_widget)) {
2714 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2715 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2716 gtk_clipboard_store (clipboard);
2717 } else if (GTK_IS_EDITABLE (focused_widget)) {
2718 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2719 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2720 gtk_clipboard_store (clipboard);
2721 } else if (GTK_IS_HTML (focused_widget)) {
2722 gtk_html_copy (GTK_HTML (focused_widget));
2723 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2724 gtk_clipboard_store (clipboard);
2725 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2726 GtkTextBuffer *buffer;
2727 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2728 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2729 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2730 gtk_clipboard_store (clipboard);
2731 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2732 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2733 TnyIterator *iter = tny_list_create_iterator (header_list);
2734 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2736 gboolean ask = FALSE;
2738 TnyFolder *folder = tny_header_get_folder (header);
2739 TnyAccount *account = tny_folder_get_account (folder);
2740 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2741 /* If it's POP then ask */
2742 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2743 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2744 g_object_unref (account);
2745 g_object_unref (folder);
2746 g_object_unref (header);
2749 g_object_unref (iter);
2751 /* Check that the messages have been previously downloaded */
2752 gboolean continue_download = TRUE;
2754 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2755 if (continue_download)
2756 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2757 g_object_unref (header_list);
2758 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2759 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2762 /* Show information banner */
2763 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2768 modest_ui_actions_on_undo (GtkAction *action,
2769 ModestWindow *window)
2771 ModestEmailClipboard *clipboard = NULL;
2773 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2774 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2775 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2776 /* Clear clipboard source */
2777 clipboard = modest_runtime_get_email_clipboard ();
2778 modest_email_clipboard_clear (clipboard);
2781 g_return_if_reached ();
2786 modest_ui_actions_on_redo (GtkAction *action,
2787 ModestWindow *window)
2789 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2790 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2793 g_return_if_reached ();
2799 paste_msgs_cb (const GObject *object, gpointer user_data)
2801 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2802 g_return_if_fail (GTK_IS_WIDGET (user_data));
2804 /* destroy information note */
2805 gtk_widget_destroy (GTK_WIDGET(user_data));
2809 paste_as_attachment_free (gpointer data)
2811 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2813 gtk_widget_destroy (helper->banner);
2814 g_object_unref (helper->banner);
2819 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2824 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2825 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2830 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2835 modest_ui_actions_on_paste (GtkAction *action,
2836 ModestWindow *window)
2838 GtkWidget *focused_widget = NULL;
2839 GtkWidget *inf_note = NULL;
2840 ModestMailOperation *mail_op = NULL;
2842 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2843 if (GTK_IS_EDITABLE (focused_widget)) {
2844 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2845 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2846 ModestEmailClipboard *e_clipboard = NULL;
2847 e_clipboard = modest_runtime_get_email_clipboard ();
2848 if (modest_email_clipboard_cleared (e_clipboard)) {
2849 GtkTextBuffer *buffer;
2850 GtkClipboard *clipboard;
2852 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2853 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2854 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2855 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2856 ModestMailOperation *mail_op;
2857 TnyFolder *src_folder;
2860 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2861 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2862 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2863 _CS("ckct_nw_pasting"));
2864 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2865 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2867 if (helper->banner != NULL) {
2868 g_object_ref (G_OBJECT (helper->banner));
2869 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2870 gtk_widget_show (GTK_WIDGET (helper->banner));
2874 modest_mail_operation_get_msgs_full (mail_op,
2876 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2878 paste_as_attachment_free);
2881 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2882 ModestEmailClipboard *clipboard = NULL;
2883 TnyFolder *src_folder = NULL;
2884 TnyFolderStore *folder_store = NULL;
2885 TnyList *data = NULL;
2886 gboolean delete = FALSE;
2888 /* Check clipboard source */
2889 clipboard = modest_runtime_get_email_clipboard ();
2890 if (modest_email_clipboard_cleared (clipboard))
2893 /* Get elements to paste */
2894 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2896 /* Create a new mail operation */
2897 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2898 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2901 /* Get destination folder */
2902 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2904 /* Launch notification */
2905 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2906 _CS("ckct_nw_pasting"));
2907 if (inf_note != NULL) {
2908 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2909 gtk_widget_show (GTK_WIDGET(inf_note));
2912 /* transfer messages */
2914 modest_mail_operation_xfer_msgs (mail_op,
2916 TNY_FOLDER (folder_store),
2921 } else if (src_folder != NULL) {
2922 modest_mail_operation_xfer_folder (mail_op,
2932 g_object_unref (data);
2933 if (src_folder != NULL)
2934 g_object_unref (src_folder);
2935 if (folder_store != NULL)
2936 g_object_unref (folder_store);
2942 modest_ui_actions_on_select_all (GtkAction *action,
2943 ModestWindow *window)
2945 GtkWidget *focused_widget;
2947 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2948 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2949 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2950 } else if (GTK_IS_LABEL (focused_widget)) {
2951 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2952 } else if (GTK_IS_EDITABLE (focused_widget)) {
2953 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2954 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2955 GtkTextBuffer *buffer;
2956 GtkTextIter start, end;
2958 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2959 gtk_text_buffer_get_start_iter (buffer, &start);
2960 gtk_text_buffer_get_end_iter (buffer, &end);
2961 gtk_text_buffer_select_range (buffer, &start, &end);
2962 } else if (GTK_IS_HTML (focused_widget)) {
2963 gtk_html_select_all (GTK_HTML (focused_widget));
2964 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2965 GtkWidget *header_view = focused_widget;
2966 GtkTreeSelection *selection = NULL;
2968 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2969 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2970 MODEST_WIDGET_TYPE_HEADER_VIEW);
2972 /* Select all messages */
2973 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2974 gtk_tree_selection_select_all (selection);
2976 /* Set focuse on header view */
2977 gtk_widget_grab_focus (header_view);
2983 modest_ui_actions_on_mark_as_read (GtkAction *action,
2984 ModestWindow *window)
2986 g_return_if_fail (MODEST_IS_WINDOW(window));
2988 /* Mark each header as read */
2989 do_headers_action (window, headers_action_mark_as_read, NULL);
2993 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2994 ModestWindow *window)
2996 g_return_if_fail (MODEST_IS_WINDOW(window));
2998 /* Mark each header as read */
2999 do_headers_action (window, headers_action_mark_as_unread, NULL);
3003 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3004 GtkRadioAction *selected,
3005 ModestWindow *window)
3009 value = gtk_radio_action_get_current_value (selected);
3010 if (MODEST_IS_WINDOW (window)) {
3011 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3015 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3016 GtkRadioAction *selected,
3017 ModestWindow *window)
3019 TnyHeaderFlags flags;
3020 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3022 flags = gtk_radio_action_get_current_value (selected);
3023 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3026 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3027 GtkRadioAction *selected,
3028 ModestWindow *window)
3032 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3034 file_format = gtk_radio_action_get_current_value (selected);
3035 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3040 modest_ui_actions_on_zoom_plus (GtkAction *action,
3041 ModestWindow *window)
3043 g_return_if_fail (MODEST_IS_WINDOW (window));
3045 modest_window_zoom_plus (MODEST_WINDOW (window));
3049 modest_ui_actions_on_zoom_minus (GtkAction *action,
3050 ModestWindow *window)
3052 g_return_if_fail (MODEST_IS_WINDOW (window));
3054 modest_window_zoom_minus (MODEST_WINDOW (window));
3058 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3059 ModestWindow *window)
3061 ModestWindowMgr *mgr;
3062 gboolean fullscreen, active;
3063 g_return_if_fail (MODEST_IS_WINDOW (window));
3065 mgr = modest_runtime_get_window_mgr ();
3067 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3068 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3070 if (active != fullscreen) {
3071 modest_window_mgr_set_fullscreen_mode (mgr, active);
3072 gtk_window_present (GTK_WINDOW (window));
3077 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3078 ModestWindow *window)
3080 ModestWindowMgr *mgr;
3081 gboolean fullscreen;
3083 g_return_if_fail (MODEST_IS_WINDOW (window));
3085 mgr = modest_runtime_get_window_mgr ();
3086 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3087 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3089 gtk_window_present (GTK_WINDOW (window));
3093 * Used by modest_ui_actions_on_details to call do_headers_action
3096 headers_action_show_details (TnyHeader *header,
3097 ModestWindow *window,
3104 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3107 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3108 gtk_widget_show_all (dialog);
3109 gtk_dialog_run (GTK_DIALOG (dialog));
3111 gtk_widget_destroy (dialog);
3115 * Show the folder details in a ModestDetailsDialog widget
3118 show_folder_details (TnyFolder *folder,
3124 dialog = modest_details_dialog_new_with_folder (window, folder);
3127 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3128 gtk_widget_show_all (dialog);
3129 gtk_dialog_run (GTK_DIALOG (dialog));
3131 gtk_widget_destroy (dialog);
3135 * Show the header details in a ModestDetailsDialog widget
3138 modest_ui_actions_on_details (GtkAction *action,
3141 TnyList * headers_list;
3145 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3148 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3151 g_object_unref (msg);
3153 headers_list = get_selected_headers (win);
3157 iter = tny_list_create_iterator (headers_list);
3159 header = TNY_HEADER (tny_iterator_get_current (iter));
3161 headers_action_show_details (header, win, NULL);
3162 g_object_unref (header);
3165 g_object_unref (iter);
3166 g_object_unref (headers_list);
3168 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3169 GtkWidget *folder_view, *header_view;
3171 /* Check which widget has the focus */
3172 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3173 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3174 if (gtk_widget_is_focus (folder_view)) {
3175 TnyFolderStore *folder_store
3176 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3177 if (!folder_store) {
3178 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3181 /* Show only when it's a folder */
3182 /* This function should not be called for account items,
3183 * because we dim the menu item for them. */
3184 if (TNY_IS_FOLDER (folder_store)) {
3185 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3188 g_object_unref (folder_store);
3191 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3192 MODEST_WIDGET_TYPE_HEADER_VIEW);
3193 /* Show details of each header */
3194 do_headers_action (win, headers_action_show_details, header_view);
3200 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3201 ModestMsgEditWindow *window)
3203 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3205 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3209 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3210 ModestMsgEditWindow *window)
3212 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3214 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3218 modest_ui_actions_toggle_folders_view (GtkAction *action,
3219 ModestMainWindow *main_window)
3221 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3223 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3224 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3226 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3230 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3231 ModestWindow *window)
3233 gboolean active, fullscreen = FALSE;
3234 ModestWindowMgr *mgr;
3236 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3238 /* Check if we want to toggle the toolbar vuew in fullscreen
3240 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3241 "ViewShowToolbarFullScreen")) {
3245 /* Toggle toolbar */
3246 mgr = modest_runtime_get_window_mgr ();
3247 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3251 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3252 ModestMsgEditWindow *window)
3254 modest_msg_edit_window_select_font (window);
3258 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3259 const gchar *display_name,
3262 /* Do not change the application name if the widget has not
3263 the focus. This callback could be called even if the folder
3264 view has not the focus, because the handled signal could be
3265 emitted when the folder view is redrawn */
3266 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3268 gtk_window_set_title (window, display_name);
3270 gtk_window_set_title (window, " ");
3275 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3277 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3278 modest_msg_edit_window_select_contacts (window);
3282 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3284 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3285 modest_msg_edit_window_check_names (window, FALSE);
3289 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3291 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3292 GTK_WIDGET (user_data));
3296 create_move_to_dialog (GtkWindow *win,
3297 GtkWidget *folder_view,
3298 GtkWidget **tree_view)
3300 GtkWidget *dialog, *scroll;
3301 GtkWidget *new_button;
3303 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3305 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3308 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3309 /* We do this manually so GTK+ does not associate a response ID for
3311 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3312 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3313 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3315 /* Create scrolled window */
3316 scroll = gtk_scrolled_window_new (NULL, NULL);
3317 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3318 GTK_POLICY_AUTOMATIC,
3319 GTK_POLICY_AUTOMATIC);
3321 /* Create folder view */
3322 *tree_view = modest_platform_create_folder_view (NULL);
3324 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3326 /* It could happen that we're trying to move a message from a
3327 window (msg window for example) after the main window was
3328 closed, so we can not just get the model of the folder
3330 if (MODEST_IS_FOLDER_VIEW (folder_view))
3331 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3332 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3334 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3335 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3337 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3339 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3341 /* Add scroll to dialog */
3342 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3343 scroll, TRUE, TRUE, 0);
3345 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3346 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3352 * Returns TRUE if at least one of the headers of the list belongs to
3353 * a message that has been fully retrieved.
3356 has_retrieved_msgs (TnyList *list)
3359 gboolean found = FALSE;
3361 iter = tny_list_create_iterator (list);
3362 while (tny_iterator_is_done (iter) && !found) {
3364 TnyHeaderFlags flags = 0;
3366 header = TNY_HEADER (tny_iterator_get_current (iter));
3368 flags = tny_header_get_flags (header);
3369 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3372 g_object_unref (header);
3376 tny_iterator_next (iter);
3378 g_object_unref (iter);
3384 * Shows a confirmation dialog to the user when we're moving messages
3385 * from a remote server to the local storage. Returns the dialog
3386 * response. If it's other kind of movement the it always returns
3390 msgs_move_to_confirmation (GtkWindow *win,
3391 TnyFolder *dest_folder,
3394 gint response = GTK_RESPONSE_OK;
3396 /* If the destination is a local folder */
3397 if (modest_tny_folder_is_local_folder (dest_folder)) {
3398 TnyFolder *src_folder = NULL;
3399 TnyIterator *iter = NULL;
3400 TnyHeader *header = NULL;
3402 /* Get source folder */
3403 iter = tny_list_create_iterator (headers);
3404 header = TNY_HEADER (tny_iterator_get_current (iter));
3406 src_folder = tny_header_get_folder (header);
3407 g_object_unref (header);
3410 g_object_unref (iter);
3412 /* if no src_folder, message may be an attahcment */
3413 if (src_folder == NULL)
3414 return GTK_RESPONSE_CANCEL;
3416 /* If the source is a remote folder */
3417 if (!modest_tny_folder_is_local_folder (src_folder)) {
3418 const gchar *message;
3420 if (has_retrieved_msgs (headers))
3421 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3422 tny_list_get_length (headers));
3424 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3425 tny_list_get_length (headers));
3427 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3428 (const gchar *) message);
3431 g_object_unref (src_folder);
3440 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3442 ModestMsgViewWindow *self = NULL;
3444 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3445 self = MODEST_MSG_VIEW_WINDOW (object);
3447 if (!modest_msg_view_window_select_next_message (self))
3448 if (!modest_msg_view_window_select_previous_message (self))
3449 /* No more messages to view, so close this window */
3450 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3454 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3457 GObject *win = modest_mail_operation_get_source (mail_op);
3458 const GError *error = NULL;
3459 const gchar *message = NULL;
3461 /* Get error message */
3462 error = modest_mail_operation_get_error (mail_op);
3463 if (error != NULL && error->message != NULL) {
3464 message = error->message;
3466 message = _("mail_in_ui_folder_move_target_error");
3469 /* Show notification dialog */
3470 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3471 g_object_unref (win);
3475 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3478 GObject *win = modest_mail_operation_get_source (mail_op);
3479 const GError *error = modest_mail_operation_get_error (mail_op);
3481 g_return_if_fail (error != NULL);
3482 if (error->message != NULL)
3483 g_printerr ("modest: %s\n", error->message);
3485 g_printerr ("modest: unkonw error on send&receive operation");
3487 /* Show error message */
3488 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3489 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3490 /* _CS("sfil_ib_unable_to_receive")); */
3492 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3493 /* _CS("sfil_ib_unable_to_send")); */
3494 g_object_unref (win);
3498 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3505 gint pending_purges = 0;
3506 gboolean some_purged = FALSE;
3507 ModestWindow *win = MODEST_WINDOW (user_data);
3508 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3510 /* If there was any error */
3511 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3512 modest_window_mgr_unregister_header (mgr, header);
3516 /* Once the message has been retrieved for purging, we check if
3517 * it's all ok for purging */
3519 parts = tny_simple_list_new ();
3520 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3521 iter = tny_list_create_iterator (parts);
3523 while (!tny_iterator_is_done (iter)) {
3525 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3526 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3527 if (tny_mime_part_is_purged (part))
3534 g_object_unref (part);
3536 tny_iterator_next (iter);
3539 if (pending_purges>0) {
3541 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3543 if (response == GTK_RESPONSE_OK) {
3544 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3545 tny_iterator_first (iter);
3546 while (!tny_iterator_is_done (iter)) {
3549 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3550 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3551 tny_mime_part_set_purged (part);
3554 g_object_unref (part);
3556 tny_iterator_next (iter);
3559 tny_msg_rewrite_cache (msg);
3562 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3565 /* remove attachments */
3566 tny_iterator_first (iter);
3567 while (!tny_iterator_is_done (iter)) {
3570 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3572 /* One for the reference given by tny_iterator_get_current(): */
3573 g_object_unref (part);
3575 /* TODO: Is this meant to remove the attachment by doing another unref()?
3576 * Otherwise, this seems useless. */
3579 tny_iterator_next (iter);
3581 modest_window_mgr_unregister_header (mgr, header);
3583 g_object_unref (iter);
3584 g_object_unref (parts);
3588 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3589 ModestMainWindow *win)
3591 GtkWidget *header_view;
3592 TnyList *header_list;
3595 TnyHeaderFlags flags;
3596 ModestWindow *msg_view_window = NULL;
3599 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3601 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3602 MODEST_WIDGET_TYPE_HEADER_VIEW);
3604 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3606 if (tny_list_get_length (header_list) == 1) {
3607 iter = tny_list_create_iterator (header_list);
3608 header = TNY_HEADER (tny_iterator_get_current (iter));
3609 g_object_unref (iter);
3614 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3615 header, &msg_view_window);
3616 flags = tny_header_get_flags (header);
3617 if (!(flags & TNY_HEADER_FLAG_CACHED))
3620 if (msg_view_window != NULL)
3621 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3623 /* do nothing; uid was registered before, so window is probably on it's way */
3624 g_warning ("debug: header %p has already been registered", header);
3627 ModestMailOperation *mail_op = NULL;
3628 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3629 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3631 modest_ui_actions_get_msgs_full_error_handler,
3633 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3634 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3636 g_object_unref (mail_op);
3639 g_object_unref (header);
3641 g_object_unref (header_list);
3645 * Utility function that transfer messages from both the main window
3646 * and the msg view window when using the "Move to" dialog
3649 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3652 TnyList *headers = NULL;
3655 if (!TNY_IS_FOLDER (dst_folder)) {
3656 modest_platform_information_banner (GTK_WIDGET (win),
3658 _CS("ckdg_ib_unable_to_move_to_current_location"));
3662 /* Get selected headers */
3663 headers = get_selected_headers (MODEST_WINDOW (win));
3665 /* Ask for user confirmation */
3666 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3667 TNY_FOLDER (dst_folder),
3670 /* Transfer messages */
3671 if (response == GTK_RESPONSE_OK) {
3672 ModestMailOperation *mail_op =
3673 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3675 modest_ui_actions_move_folder_error_handler,
3677 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3680 modest_mail_operation_xfer_msgs (mail_op,
3682 TNY_FOLDER (dst_folder),
3684 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3687 g_object_unref (G_OBJECT (mail_op));
3689 g_object_unref (headers);
3694 * UI handler for the "Move to" action when invoked from the
3698 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3699 GtkWidget *folder_view,
3700 TnyFolderStore *dst_folder,
3701 ModestMainWindow *win)
3703 GtkWidget *header_view = NULL;
3704 ModestMailOperation *mail_op = NULL;
3705 TnyFolderStore *src_folder;
3707 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3709 /* Get the source folder */
3710 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3712 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3713 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3717 /* Get header view */
3719 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3721 /* Get folder or messages to transfer */
3722 if (gtk_widget_is_focus (folder_view)) {
3724 /* Allow only to transfer folders to the local root folder */
3725 if (TNY_IS_ACCOUNT (dst_folder) &&
3726 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3729 /* Clean folder on header view before moving it */
3730 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3732 if (TNY_IS_FOLDER (src_folder)) {
3734 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3736 modest_ui_actions_move_folder_error_handler,
3738 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3741 modest_mail_operation_xfer_folder (mail_op,
3742 TNY_FOLDER (src_folder),
3745 /* Unref mail operation */
3746 g_object_unref (G_OBJECT (mail_op));
3748 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3750 } else if (gtk_widget_is_focus (header_view)) {
3751 /* Transfer messages */
3752 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3757 g_object_unref (src_folder);
3762 * UI handler for the "Move to" action when invoked from the
3763 * ModestMsgViewWindow
3766 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3767 TnyFolderStore *dst_folder,
3768 ModestMsgViewWindow *win)
3770 TnyHeader *header = NULL;
3771 TnyFolder *src_folder;
3773 /* Create header list */
3774 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3775 src_folder = tny_header_get_folder(header);
3776 g_object_unref (header);
3778 /* Transfer the message */
3779 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3780 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3782 g_object_unref (src_folder);
3786 modest_ui_actions_on_move_to (GtkAction *action,
3789 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3791 TnyFolderStore *dst_folder = NULL;
3792 ModestMainWindow *main_window;
3794 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3795 MODEST_IS_MSG_VIEW_WINDOW (win));
3797 /* Get the main window if exists */
3798 if (MODEST_IS_MAIN_WINDOW (win))
3799 main_window = MODEST_MAIN_WINDOW (win);
3802 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3804 /* Get the folder view widget if exists */
3806 folder_view = modest_main_window_get_child_widget (main_window,
3807 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3811 /* Create and run the dialog */
3812 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3813 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3814 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3815 result = gtk_dialog_run (GTK_DIALOG(dialog));
3816 g_object_ref (tree_view);
3817 gtk_widget_destroy (dialog);
3819 if (result != GTK_RESPONSE_ACCEPT)
3822 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3823 /* Offer the connection dialog if necessary: */
3824 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3827 /* Do window specific stuff */
3828 if (MODEST_IS_MAIN_WINDOW (win))
3829 modest_ui_actions_on_main_window_move_to (action,
3832 MODEST_MAIN_WINDOW (win));
3834 modest_ui_actions_on_msg_view_window_move_to (action,
3836 MODEST_MSG_VIEW_WINDOW (win));
3839 g_object_unref (dst_folder);
3843 * Calls #HeadersFunc for each header already selected in the main
3844 * window or the message currently being shown in the msg view window
3847 do_headers_action (ModestWindow *win,
3851 TnyList *headers_list = NULL;
3852 TnyIterator *iter = NULL;
3853 TnyHeader *header = NULL;
3854 TnyFolder *folder = NULL;
3857 headers_list = get_selected_headers (win);
3861 /* Get the folder */
3862 iter = tny_list_create_iterator (headers_list);
3863 header = TNY_HEADER (tny_iterator_get_current (iter));
3865 folder = tny_header_get_folder (header);
3866 g_object_unref (header);
3869 /* Call the function for each header */
3870 while (!tny_iterator_is_done (iter)) {
3871 header = TNY_HEADER (tny_iterator_get_current (iter));
3872 func (header, win, user_data);
3873 g_object_unref (header);
3874 tny_iterator_next (iter);
3877 /* Trick: do a poke status in order to speed up the signaling
3879 tny_folder_poke_status (folder);
3882 g_object_unref (folder);
3883 g_object_unref (iter);
3884 g_object_unref (headers_list);
3888 modest_ui_actions_view_attachment (GtkAction *action,
3889 ModestWindow *window)
3891 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3892 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3894 /* not supported window for this action */
3895 g_return_if_reached ();
3900 modest_ui_actions_save_attachments (GtkAction *action,
3901 ModestWindow *window)
3903 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3904 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3906 /* not supported window for this action */
3907 g_return_if_reached ();
3912 modest_ui_actions_remove_attachments (GtkAction *action,
3913 ModestWindow *window)
3915 if (MODEST_IS_MAIN_WINDOW (window)) {
3916 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3917 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3918 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3920 /* not supported window for this action */
3921 g_return_if_reached ();
3926 modest_ui_actions_on_settings (GtkAction *action,
3931 dialog = modest_platform_get_global_settings_dialog ();
3932 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3933 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3934 gtk_widget_show_all (dialog);
3936 gtk_dialog_run (GTK_DIALOG (dialog));
3938 gtk_widget_destroy (dialog);
3942 modest_ui_actions_on_help (GtkAction *action,
3945 const gchar *help_id = NULL;
3947 if (MODEST_IS_MAIN_WINDOW (win)) {
3948 const gchar *action_name;
3949 action_name = gtk_action_get_name (action);
3951 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3952 !strcmp (action_name, "HeaderViewCSMHelp")) {
3953 GtkWidget *folder_view;
3954 TnyFolderStore *folder_store;
3955 /* Get selected folder */
3956 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3957 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3958 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3960 /* Switch help_id */
3961 if (TNY_IS_FOLDER (folder_store)) {
3962 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
3963 case TNY_FOLDER_TYPE_NORMAL:
3964 help_id = "applications_email_managefolders";
3966 case TNY_FOLDER_TYPE_INBOX:
3967 help_id = "applications_email_inbox";
3969 case TNY_FOLDER_TYPE_OUTBOX:
3970 help_id = "applications_email_outbox";
3972 case TNY_FOLDER_TYPE_SENT:
3973 help_id = "applications_email_sent";
3975 case TNY_FOLDER_TYPE_DRAFTS:
3976 help_id = "applications_email_drafts";
3978 case TNY_FOLDER_TYPE_ARCHIVE:
3979 help_id = "applications_email_managefolders";
3982 help_id = "applications_email_managefolders";
3985 help_id = "applications_email_mainview";
3987 g_object_unref (folder_store);
3989 help_id = "applications_email_mainview";
3991 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3992 help_id = "applications_email_viewer";
3993 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3994 help_id = "applications_email_editor";
3996 modest_platform_show_help (GTK_WINDOW (win), help_id);
4000 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4001 ModestWindow *window)
4003 ModestMailOperation *mail_op;
4007 headers = get_selected_headers (window);
4011 /* Create mail operation */
4012 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4014 modest_ui_actions_get_msgs_full_error_handler,
4016 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4017 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4020 g_object_unref (headers);
4021 g_object_unref (mail_op);
4025 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4026 ModestWindow *window)
4028 g_return_if_fail (MODEST_IS_WINDOW (window));
4031 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4035 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4036 ModestWindow *window)
4038 g_return_if_fail (MODEST_IS_WINDOW (window));
4041 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4045 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4046 ModestWindow *window)
4048 g_return_if_fail (MODEST_IS_WINDOW (window));
4051 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4055 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4056 ModestWindow *window)
4058 g_return_if_fail (MODEST_IS_WINDOW (window));
4061 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4065 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4066 ModestWindow *window)
4068 g_return_if_fail (MODEST_IS_WINDOW (window));
4071 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4075 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4076 ModestWindow *window)
4078 g_return_if_fail (MODEST_IS_WINDOW (window));
4081 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4085 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4086 ModestWindow *window)
4088 g_return_if_fail (MODEST_IS_WINDOW (window));
4091 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4095 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4096 ModestWindow *window)
4098 g_return_if_fail (MODEST_IS_WINDOW (window));
4101 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4105 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4107 g_return_if_fail (MODEST_IS_WINDOW (window));
4110 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4114 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4116 g_return_if_fail (MODEST_IS_WINDOW (window));
4118 modest_platform_show_search_messages (GTK_WINDOW (window));
4122 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4124 g_return_if_fail (MODEST_IS_WINDOW (win));
4125 modest_platform_show_addressbook (GTK_WINDOW (win));
4130 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4131 ModestWindow *window)
4133 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4135 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4139 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4140 ModestMailOperationState *state,
4143 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4145 /* Set send/receive operation finished */
4146 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4147 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));