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 /* Get the headers, either from the header view (if win is the main window),
322 * or from the message view window: */
323 header_list = get_selected_headers (win);
324 if (!header_list) return;
326 /* Check if any of the headers are already opened, or in the process of being opened */
327 if (MODEST_IS_MAIN_WINDOW (win)) {
329 iter = tny_list_create_iterator (header_list);
331 mgr = modest_runtime_get_window_mgr ();
332 while (!tny_iterator_is_done (iter) && !found) {
333 header = TNY_HEADER (tny_iterator_get_current (iter));
335 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
336 g_object_unref (header);
339 tny_iterator_next (iter);
341 g_object_unref (iter);
346 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
347 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
349 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
353 g_object_unref (header_list);
359 if (tny_list_get_length(header_list) == 1) {
360 iter = tny_list_create_iterator (header_list);
361 header = TNY_HEADER (tny_iterator_get_current (iter));
363 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
364 g_object_unref (header);
367 g_object_unref (iter);
369 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
370 tny_list_get_length(header_list)), desc);
372 /* Confirmation dialog */
373 printf("DEBUG: %s\n", __FUNCTION__);
374 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
378 if (response == GTK_RESPONSE_OK) {
379 ModestWindow *main_window = NULL;
380 ModestWindowMgr *mgr = NULL;
381 GtkTreeModel *model = NULL;
382 GtkTreeSelection *sel = NULL;
383 GList *sel_list = NULL, *tmp = NULL;
384 GtkTreeRowReference *row_reference = NULL;
385 GtkTreePath *next_path = NULL;
387 /* Find last selected row */
388 if (MODEST_IS_MAIN_WINDOW (win)) {
389 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
390 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
391 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
392 for (tmp=sel_list; tmp; tmp=tmp->next) {
393 if (tmp->next == NULL) {
394 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
395 gtk_tree_path_next (next_path);
396 row_reference = gtk_tree_row_reference_new (model, next_path);
397 gtk_tree_path_free (next_path);
402 /* Remove each header. If it's a view window header_view == NULL */
403 do_headers_action (win, headers_action_delete, header_view);
405 /* refresh the header view (removing marked-as-deleted)*/
406 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
408 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
409 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
411 /* Get main window */
412 mgr = modest_runtime_get_window_mgr ();
413 main_window = modest_window_mgr_get_main_window (mgr);
416 /* Move cursor to next row */
419 /* Select next row */
420 if (gtk_tree_row_reference_valid (row_reference)) {
421 next_path = gtk_tree_row_reference_get_path (row_reference);
422 gtk_tree_selection_select_path (sel, next_path);
423 gtk_tree_path_free (next_path);
425 if (row_reference != NULL)
426 gtk_tree_row_reference_free (row_reference);
429 /* Update toolbar dimming state */
430 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
433 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
434 g_list_free (sel_list);
440 g_object_unref (header_list);
446 /* delete either message or folder, based on where we are */
448 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
450 g_return_if_fail (MODEST_IS_WINDOW(win));
452 /* Check first if the header view has the focus */
453 if (MODEST_IS_MAIN_WINDOW (win)) {
455 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
456 MODEST_WIDGET_TYPE_FOLDER_VIEW);
457 if (gtk_widget_is_focus (w)) {
458 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
462 modest_ui_actions_on_delete_message (action, win);
468 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
470 #ifdef MODEST_PLATFORM_MAEMO
471 modest_osso_save_state();
472 #endif /* MODEST_PLATFORM_MAEMO */
474 g_debug ("closing down, clearing %d item(s) from operation queue",
475 modest_mail_operation_queue_num_elements
476 (modest_runtime_get_mail_operation_queue()));
478 /* cancel all outstanding operations */
479 modest_mail_operation_queue_cancel_all
480 (modest_runtime_get_mail_operation_queue());
482 g_debug ("queue has been cleared");
484 /* note: when modest-tny-account-store is finalized,
485 it will automatically set all network connections
492 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
496 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
498 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
499 /* gtk_widget_destroy (GTK_WIDGET (win)); */
500 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
501 /* gboolean ret_value; */
502 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
503 /* } else if (MODEST_IS_WINDOW (win)) { */
504 /* gtk_widget_destroy (GTK_WIDGET (win)); */
506 /* g_return_if_reached (); */
511 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
513 GtkClipboard *clipboard = NULL;
514 gchar *selection = NULL;
516 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
517 selection = gtk_clipboard_wait_for_text (clipboard);
519 /* Question: why is the clipboard being used here?
520 * It doesn't really make a lot of sense. */
524 modest_address_book_add_address (selection);
530 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
532 /* This is currently only implemented for Maemo */
533 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
534 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
535 run_account_setup_wizard (win);
538 /* Show the list of accounts: */
539 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
540 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
542 /* Don't make this a modal window, because secondary windows will then
543 * be unusable, freezing the UI: */
544 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
545 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
548 GtkWidget *dialog, *label;
550 /* Create the widgets */
552 dialog = gtk_dialog_new_with_buttons ("Message",
554 GTK_DIALOG_DESTROY_WITH_PARENT,
558 label = gtk_label_new ("Hello World!");
560 /* Ensure that the dialog box is destroyed when the user responds. */
562 g_signal_connect_swapped (dialog, "response",
563 G_CALLBACK (gtk_widget_destroy),
566 /* Add the label, and show everything we've added to the dialog. */
568 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
570 gtk_widget_show_all (dialog);
571 #endif /* MODEST_PLATFORM_MAEMO */
575 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
577 ModestWindow *main_window = MODEST_WINDOW (user_data);
579 /* Save any changes. */
580 modest_connection_specific_smtp_window_save_server_accounts (
581 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
582 modest_window_get_active_account (main_window));
583 gtk_widget_destroy (GTK_WIDGET (window));
589 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
591 /* This is currently only implemented for Maemo,
592 * because it requires an API (libconic) to detect different connection
595 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
597 /* Create the window if necessary: */
598 const gchar *active_account_name = modest_window_get_active_account (win);
600 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
601 * or show the default account?
602 * If we show the default account then the account name should be shown in
603 * the window when we show it. */
604 if (!active_account_name) {
605 g_warning ("%s: No account is active.", __FUNCTION__);
609 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
610 modest_connection_specific_smtp_window_fill_with_connections (
611 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
612 modest_runtime_get_account_mgr(),
613 active_account_name);
615 /* Show the window: */
616 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
617 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
618 gtk_widget_show (specific_window);
620 /* Save changes when the window is hidden: */
621 g_signal_connect (specific_window, "hide",
622 G_CALLBACK (on_smtp_servers_window_hide), win);
623 #endif /* MODEST_PLATFORM_MAEMO */
627 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
629 ModestWindow *msg_win = NULL;
631 TnyFolder *folder = NULL;
632 gchar *account_name = NULL;
633 gchar *from_str = NULL;
634 /* GError *err = NULL; */
635 TnyAccount *account = NULL;
636 ModestWindowMgr *mgr;
637 gchar *signature = NULL, *blank_and_signature = NULL;
639 /* if there are no accounts yet, just show the wizard */
640 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
641 run_account_setup_wizard (win);
645 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
647 account_name = g_strdup (modest_window_get_active_account (win));
649 g_printerr ("modest: no account found\n");
653 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
655 TNY_ACCOUNT_TYPE_STORE);
657 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
661 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
663 g_printerr ("modest: failed get from string for '%s'\n", account_name);
667 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
668 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
669 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
670 MODEST_ACCOUNT_SIGNATURE, FALSE);
671 blank_and_signature = g_strconcat ("\n", signature, NULL);
674 blank_and_signature = g_strdup ("");
677 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
679 g_printerr ("modest: failed to create new msg\n");
683 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
685 g_printerr ("modest: failed to find Drafts folder\n");
690 /* Create and register edit window */
691 /* This is destroyed by TOOD. */
692 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
693 mgr = modest_runtime_get_window_mgr ();
694 modest_window_mgr_register_window (mgr, msg_win);
697 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
699 gtk_widget_show_all (GTK_WIDGET (msg_win));
702 g_free (account_name);
704 g_free (blank_and_signature);
706 g_object_unref (msg_win);
708 g_object_unref (G_OBJECT(account));
710 g_object_unref (G_OBJECT(msg));
712 g_object_unref (G_OBJECT(folder));
716 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
720 ModestMailOperationStatus status;
722 /* If there is no message or the operation was not successful */
723 status = modest_mail_operation_get_status (mail_op);
724 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
726 /* Remove the header from the preregistered uids */
727 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
737 open_msg_cb (ModestMailOperation *mail_op,
742 ModestWindowMgr *mgr = NULL;
743 ModestWindow *parent_win = NULL;
744 ModestWindow *win = NULL;
745 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
746 gchar *account = NULL;
749 /* Do nothing if there was any problem with the mail
750 operation. The error will be shown by the error_handler of
751 the mail operation */
752 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
756 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
757 folder = tny_header_get_folder (header);
759 /* Mark header as read */
760 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
763 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
765 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
767 /* Gets folder type (OUTBOX headers will be opened in edit window */
768 if (modest_tny_folder_is_local_folder (folder))
769 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
771 /* If the header is in the drafts folder then open the editor,
772 else the message view window */
773 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
774 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
775 /* we cannot edit without a valid account... */
776 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
777 run_account_setup_wizard(parent_win);
780 win = modest_msg_edit_window_new (msg, account, TRUE);
783 gchar *uid = modest_tny_folder_get_header_unique_id (header);
785 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
786 GtkWidget *header_view;
787 GtkTreeSelection *sel;
788 GList *sel_list = NULL;
791 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
792 MODEST_WIDGET_TYPE_HEADER_VIEW);
794 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
795 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
797 if (sel_list != NULL) {
798 GtkTreeRowReference *row_reference;
800 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
801 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
802 g_list_free (sel_list);
804 win = modest_msg_view_window_new_with_header_model (msg,
809 gtk_tree_row_reference_free (row_reference);
811 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
814 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
819 /* Register and show new window */
821 mgr = modest_runtime_get_window_mgr ();
822 modest_window_mgr_register_window (mgr, win);
823 g_object_unref (win);
824 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
825 gtk_widget_show_all (GTK_WIDGET(win));
828 /* Update toolbar dimming state */
829 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
830 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
836 g_object_unref (parent_win);
837 g_object_unref (folder);
841 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
845 GObject *win = modest_mail_operation_get_source (mail_op);
847 error = modest_mail_operation_get_error (mail_op);
848 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
850 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
852 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
855 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
856 _("mail_ni_ui_folder_get_msg_folder_error"));
860 g_object_unref (win);
864 * This function is used by both modest_ui_actions_on_open and
865 * modest_ui_actions_on_header_activated. This way we always do the
866 * same when trying to open messages.
869 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
871 ModestWindowMgr *mgr = NULL;
872 TnyIterator *iter = NULL;
873 ModestMailOperation *mail_op = NULL;
874 TnyList *not_opened_headers = NULL;
875 TnyHeaderFlags flags = 0;
877 /* Look if we already have a message view for each header. If
878 true, then remove the header from the list of headers to
880 mgr = modest_runtime_get_window_mgr ();
881 iter = tny_list_create_iterator (headers);
882 not_opened_headers = tny_simple_list_new ();
884 while (!tny_iterator_is_done (iter)) {
886 ModestWindow *window = NULL;
887 TnyHeader *header = NULL;
888 gboolean found = FALSE;
890 header = TNY_HEADER (tny_iterator_get_current (iter));
892 flags = tny_header_get_flags (header);
895 found = modest_window_mgr_find_registered_header (mgr, header, &window);
897 /* Do not open again the message and present the
898 window to the user */
901 gtk_window_present (GTK_WINDOW (window));
903 /* the header has been registered already, we don't do
904 * anything but wait for the window to come up*/
905 g_debug ("header %p already registered, waiting for window", header);
907 tny_list_append (not_opened_headers, G_OBJECT (header));
911 g_object_unref (header);
913 tny_iterator_next (iter);
915 g_object_unref (iter);
918 /* If some messages would have to be downloaded, ask the user to
919 * make a connection. It's generally easier to do this here (in the mainloop)
920 * than later in a thread:
922 if (tny_list_get_length (not_opened_headers) > 0) {
924 gboolean found = FALSE;
926 iter = tny_list_create_iterator (not_opened_headers);
927 while (!tny_iterator_is_done (iter) && !found) {
928 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
929 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
932 tny_iterator_next (iter);
934 g_object_unref (header);
936 g_object_unref (iter);
938 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
939 g_object_unref (not_opened_headers);
944 /* Register the headers before actually creating the windows: */
945 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
946 while (!tny_iterator_is_done (iter_not_opened)) {
947 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
949 modest_window_mgr_register_header (mgr, header);
950 g_object_unref (header);
953 tny_iterator_next (iter_not_opened);
955 g_object_unref (iter_not_opened);
956 iter_not_opened = NULL;
958 /* Open each message */
959 if (tny_list_get_length (not_opened_headers) > 0) {
960 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
962 modest_ui_actions_get_msgs_full_error_handler,
964 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
965 if (tny_list_get_length (not_opened_headers) > 1) {
966 modest_mail_operation_get_msgs_full (mail_op,
972 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
973 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
974 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
975 g_object_unref (header);
976 g_object_unref (iter);
978 g_object_unref (mail_op);
982 if (not_opened_headers != NULL)
983 g_object_unref (not_opened_headers);
987 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
992 headers = get_selected_headers (win);
997 _modest_ui_actions_open (headers, win);
999 g_object_unref(headers);
1004 free_reply_forward_helper (gpointer data)
1006 ReplyForwardHelper *helper;
1008 helper = (ReplyForwardHelper *) data;
1009 g_free (helper->account_name);
1010 g_slice_free (ReplyForwardHelper, helper);
1014 reply_forward_cb (ModestMailOperation *mail_op,
1020 ReplyForwardHelper *rf_helper;
1021 ModestWindow *msg_win = NULL;
1022 ModestEditType edit_type;
1024 TnyAccount *account = NULL;
1025 ModestWindowMgr *mgr = NULL;
1026 gchar *signature = NULL;
1028 /* If there was any error. The mail operation could be NULL,
1029 this means that we already have the message downloaded and
1030 that we didn't do a mail operation to retrieve it */
1031 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1034 g_return_if_fail (user_data != NULL);
1035 rf_helper = (ReplyForwardHelper *) user_data;
1037 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1038 rf_helper->account_name);
1039 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1040 rf_helper->account_name,
1041 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1042 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1043 rf_helper->account_name,
1044 MODEST_ACCOUNT_SIGNATURE, FALSE);
1047 /* Create reply mail */
1048 switch (rf_helper->action) {
1051 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1052 rf_helper->reply_forward_type,
1053 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1055 case ACTION_REPLY_TO_ALL:
1057 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1058 MODEST_TNY_MSG_REPLY_MODE_ALL);
1059 edit_type = MODEST_EDIT_TYPE_REPLY;
1061 case ACTION_FORWARD:
1063 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1064 edit_type = MODEST_EDIT_TYPE_FORWARD;
1067 g_return_if_reached ();
1074 g_printerr ("modest: failed to create message\n");
1078 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1079 rf_helper->account_name,
1080 TNY_ACCOUNT_TYPE_STORE);
1082 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1086 /* Create and register the windows */
1087 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1088 mgr = modest_runtime_get_window_mgr ();
1089 modest_window_mgr_register_window (mgr, msg_win);
1091 if (rf_helper->parent_window != NULL) {
1092 gdouble parent_zoom;
1094 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1095 modest_window_set_zoom (msg_win, parent_zoom);
1098 /* Show edit window */
1099 gtk_widget_show_all (GTK_WIDGET (msg_win));
1103 g_object_unref (msg_win);
1105 g_object_unref (G_OBJECT (new_msg));
1107 g_object_unref (G_OBJECT (account));
1108 /* g_object_unref (msg); */
1109 free_reply_forward_helper (rf_helper);
1113 * Checks a list of headers. If any of them are not currently
1114 * downloaded (CACHED) then it asks the user for permission to
1117 * Returns FALSE if the user does not want to download the
1118 * messages. Returns TRUE if the user allowed the download or if all
1119 * of them are currently downloaded
1122 download_uncached_messages (TnyList *header_list,
1128 gint uncached_messages = 0;
1130 iter = tny_list_create_iterator (header_list);
1131 while (!tny_iterator_is_done (iter)) {
1134 header = TNY_HEADER (tny_iterator_get_current (iter));
1136 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1137 uncached_messages ++;
1138 g_object_unref (header);
1141 tny_iterator_next (iter);
1143 g_object_unref (iter);
1145 /* Ask for user permission to download the messages */
1147 if (uncached_messages > 0) {
1148 GtkResponseType response;
1150 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1151 _("emev_nc_include_original"));
1154 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1155 ngettext("mcen_nc_get_msg",
1157 uncached_messages));
1158 if (response == GTK_RESPONSE_CANCEL)
1161 /* If a download will be necessary, make sure that we have a connection: */
1162 retval = modest_platform_connect_and_wait(win, NULL);
1170 * Common code for the reply and forward actions
1173 reply_forward (ReplyForwardAction action, ModestWindow *win)
1175 ModestMailOperation *mail_op = NULL;
1176 TnyList *header_list = NULL;
1177 ReplyForwardHelper *rf_helper = NULL;
1178 guint reply_forward_type;
1179 gboolean continue_download = TRUE;
1180 gboolean do_retrieve = TRUE;
1182 g_return_if_fail (MODEST_IS_WINDOW(win));
1184 /* we need an account when editing */
1185 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1186 run_account_setup_wizard (win);
1190 header_list = get_selected_headers (win);
1194 reply_forward_type =
1195 modest_conf_get_int (modest_runtime_get_conf (),
1196 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1199 /* Check that the messages have been previously downloaded */
1200 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1202 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1203 if (!continue_download) {
1204 g_object_unref (header_list);
1208 /* We assume that we can only select messages of the
1209 same folder and that we reply all of them from the
1210 same account. In fact the interface currently only
1211 allows single selection */
1214 rf_helper = g_slice_new0 (ReplyForwardHelper);
1215 rf_helper->reply_forward_type = reply_forward_type;
1216 rf_helper->action = action;
1217 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1219 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1220 rf_helper->parent_window = GTK_WIDGET (win);
1221 if (!rf_helper->account_name)
1222 rf_helper->account_name =
1223 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1225 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1228 /* Get header and message. Do not free them here, the
1229 reply_forward_cb must do it */
1230 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1231 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1232 if (!msg || !header) {
1234 g_object_unref (msg);
1235 g_printerr ("modest: no message found\n");
1238 reply_forward_cb (NULL, header, msg, rf_helper);
1241 g_object_unref (header);
1246 /* Only reply/forward to one message */
1247 iter = tny_list_create_iterator (header_list);
1248 header = TNY_HEADER (tny_iterator_get_current (iter));
1249 g_object_unref (iter);
1252 /* Retrieve messages */
1254 mail_op = modest_mail_operation_new_with_error_handling (
1255 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1257 modest_ui_actions_get_msgs_full_error_handler,
1259 modest_mail_operation_queue_add (
1260 modest_runtime_get_mail_operation_queue (), mail_op);
1262 modest_mail_operation_get_msg (mail_op,
1267 g_object_unref(mail_op);
1269 /* we put a ref here to prevent double unref as the reply
1270 * forward callback unrefs the header at its end */
1271 reply_forward_cb (NULL, header, NULL, rf_helper);
1275 g_object_unref (header);
1281 g_object_unref (header_list);
1285 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1287 g_return_if_fail (MODEST_IS_WINDOW(win));
1289 reply_forward (ACTION_REPLY, win);
1293 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1295 g_return_if_fail (MODEST_IS_WINDOW(win));
1297 reply_forward (ACTION_FORWARD, win);
1301 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1303 g_return_if_fail (MODEST_IS_WINDOW(win));
1305 reply_forward (ACTION_REPLY_TO_ALL, win);
1309 modest_ui_actions_on_next (GtkAction *action,
1310 ModestWindow *window)
1312 if (MODEST_IS_MAIN_WINDOW (window)) {
1313 GtkWidget *header_view;
1315 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1316 MODEST_WIDGET_TYPE_HEADER_VIEW);
1320 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1321 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1322 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1324 g_return_if_reached ();
1329 modest_ui_actions_on_prev (GtkAction *action,
1330 ModestWindow *window)
1332 g_return_if_fail (MODEST_IS_WINDOW(window));
1334 if (MODEST_IS_MAIN_WINDOW (window)) {
1335 GtkWidget *header_view;
1336 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1337 MODEST_WIDGET_TYPE_HEADER_VIEW);
1341 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1342 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1343 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1345 g_return_if_reached ();
1350 modest_ui_actions_on_sort (GtkAction *action,
1351 ModestWindow *window)
1353 g_return_if_fail (MODEST_IS_WINDOW(window));
1355 if (MODEST_IS_MAIN_WINDOW (window)) {
1356 GtkWidget *header_view;
1357 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1358 MODEST_WIDGET_TYPE_HEADER_VIEW);
1360 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1365 /* Show sorting dialog */
1366 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1371 new_messages_arrived (ModestMailOperation *self,
1375 if (new_messages == 0)
1378 modest_platform_on_new_msg ();
1382 * This function performs the send & receive required actions. The
1383 * window is used to create the mail operation. Typically it should
1384 * always be the main window, but we pass it as argument in order to
1388 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1390 gchar *acc_name = NULL;
1391 ModestMailOperation *mail_op;
1393 /* If no account name was provided then get the current account, and if
1394 there is no current account then pick the default one: */
1395 if (!account_name) {
1396 acc_name = g_strdup (modest_window_get_active_account(win));
1398 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1400 g_printerr ("modest: cannot get default account\n");
1404 acc_name = g_strdup (account_name);
1407 /* Set send/receive operation in progress */
1408 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1410 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1412 modest_ui_actions_send_receive_error_handler,
1415 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1416 G_CALLBACK (_on_send_receive_progress_changed),
1419 /* Send & receive. */
1420 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1421 /* Receive and then send. The operation is tagged initially as
1422 a receive operation because the account update performs a
1423 receive and then a send. The operation changes its type
1424 internally, so the progress objects will receive the proper
1425 progress information */
1426 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1427 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1428 g_object_unref (G_OBJECT (mail_op));
1436 modest_ui_actions_do_cancel_send (const gchar *account_name,
1439 TnyTransportAccount *transport_account;
1440 TnySendQueue *send_queue = NULL;
1441 GError *error = NULL;
1443 /* Get transport account */
1445 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1446 (modest_runtime_get_account_store(),
1448 TNY_ACCOUNT_TYPE_TRANSPORT));
1449 if (!transport_account) {
1450 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1455 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1456 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1457 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1458 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1459 "modest: could not find send queue for account\n");
1461 /* Keeep messages in outbox folder */
1462 tny_send_queue_cancel (send_queue, FALSE, &error);
1466 if (transport_account != NULL)
1467 g_object_unref (G_OBJECT (transport_account));
1471 modest_ui_actions_cancel_send_all (ModestWindow *win)
1473 GSList *account_names, *iter;
1475 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1478 iter = account_names;
1480 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1481 iter = g_slist_next (iter);
1484 modest_account_mgr_free_account_names (account_names);
1485 account_names = NULL;
1489 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1492 /* Check if accounts exist */
1493 gboolean accounts_exist =
1494 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1496 /* If not, allow the user to create an account before trying to send/receive. */
1497 if (!accounts_exist)
1498 modest_ui_actions_on_accounts (NULL, win);
1500 /* Cancel all sending operaitons */
1501 modest_ui_actions_cancel_send_all (win);
1505 * Refreshes all accounts. This function will be used by automatic
1509 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1511 GSList *account_names, *iter;
1513 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1516 iter = account_names;
1518 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1519 iter = g_slist_next (iter);
1522 modest_account_mgr_free_account_names (account_names);
1523 account_names = NULL;
1527 modest_do_refresh_current_folder(ModestWindow *win)
1529 /* Refresh currently selected folder. Note that if we only
1530 want to retreive the headers, then the refresh only will
1531 invoke a poke_status over all folders, i.e., only the
1532 total/unread count will be updated */
1533 if (MODEST_IS_MAIN_WINDOW (win)) {
1534 GtkWidget *header_view, *folder_view;
1535 TnyFolderStore *folder_store;
1537 /* Get folder and header view */
1539 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1540 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1542 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1544 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1546 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1547 MODEST_WIDGET_TYPE_HEADER_VIEW);
1549 /* We do not need to set the contents style
1550 because it hasn't changed. We also do not
1551 need to save the widget status. Just force
1553 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1554 TNY_FOLDER (folder_store),
1555 folder_refreshed_cb,
1556 MODEST_MAIN_WINDOW (win));
1560 g_object_unref (folder_store);
1566 * Handler of the click on Send&Receive button in the main toolbar
1569 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1571 /* Check if accounts exist */
1572 gboolean accounts_exist =
1573 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1575 /* If not, allow the user to create an account before trying to send/receive. */
1576 if (!accounts_exist)
1577 modest_ui_actions_on_accounts (NULL, win);
1579 modest_do_refresh_current_folder (win);
1581 /* Refresh the active account */
1582 modest_ui_actions_do_send_receive (NULL, win);
1587 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1590 GtkWidget *header_view;
1592 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1594 header_view = modest_main_window_get_child_widget (main_window,
1595 MODEST_WIDGET_TYPE_HEADER_VIEW);
1599 conf = modest_runtime_get_conf ();
1601 /* what is saved/restored is depending on the style; thus; we save with
1602 * old style, then update the style, and restore for this new style
1604 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1606 if (modest_header_view_get_style
1607 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1608 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1609 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1611 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1612 MODEST_HEADER_VIEW_STYLE_DETAILS);
1614 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1615 MODEST_CONF_HEADER_VIEW_KEY);
1620 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1622 ModestMainWindow *main_window)
1624 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1625 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1627 /* in the case the folder is empty, show the empty folder message and focus
1629 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1630 if (modest_header_view_is_empty (header_view)) {
1631 TnyFolder *folder = modest_header_view_get_folder (header_view);
1632 GtkWidget *folder_view =
1633 modest_main_window_get_child_widget (main_window,
1634 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1636 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1637 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1641 /* If no header has been selected then exit */
1646 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1647 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1649 /* Update Main window title */
1650 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1651 const gchar *subject = tny_header_get_subject (header);
1652 if (subject && strlen(subject) > 0)
1653 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1655 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1658 /* Update toolbar dimming state */
1659 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1663 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1665 ModestMainWindow *main_window)
1669 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1674 headers = tny_simple_list_new ();
1675 tny_list_prepend (headers, G_OBJECT (header));
1677 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1679 g_object_unref (headers);
1683 set_active_account_from_tny_account (TnyAccount *account,
1684 ModestWindow *window)
1686 const gchar *server_acc_name = tny_account_get_id (account);
1688 /* We need the TnyAccount provided by the
1689 account store because that is the one that
1690 knows the name of the Modest account */
1691 TnyAccount *modest_server_account = modest_server_account =
1692 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1693 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1696 const gchar *modest_acc_name =
1697 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1698 modest_window_set_active_account (window, modest_acc_name);
1699 g_object_unref (modest_server_account);
1704 folder_refreshed_cb (ModestMailOperation *mail_op,
1708 ModestMainWindow *win = NULL;
1709 GtkWidget *header_view;
1710 TnyFolder *current_folder;
1712 g_return_if_fail (TNY_IS_FOLDER (folder));
1714 win = MODEST_MAIN_WINDOW (user_data);
1716 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1719 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1720 if (current_folder != NULL && folder != current_folder) {
1725 /* Check if folder is empty and set headers view contents style */
1726 if (tny_folder_get_all_count (folder) == 0) {
1727 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1728 modest_main_window_set_contents_style (win,
1729 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1731 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1736 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1737 TnyFolderStore *folder_store,
1739 ModestMainWindow *main_window)
1742 GtkWidget *header_view;
1744 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1746 header_view = modest_main_window_get_child_widget(main_window,
1747 MODEST_WIDGET_TYPE_HEADER_VIEW);
1751 conf = modest_runtime_get_conf ();
1753 if (TNY_IS_ACCOUNT (folder_store)) {
1755 /* Update active account */
1756 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1757 /* Show account details */
1758 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1761 if (TNY_IS_FOLDER (folder_store) && selected) {
1763 /* Update the active account */
1764 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1766 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1767 g_object_unref (account);
1771 /* Set the header style by default, it could
1772 be changed later by the refresh callback to
1774 modest_main_window_set_contents_style (main_window,
1775 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1777 /* Set folder on header view. This function
1778 will call tny_folder_refresh_async so we
1779 pass a callback that will be called when
1780 finished. We use that callback to set the
1781 empty view if there are no messages */
1782 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1783 TNY_FOLDER (folder_store),
1784 folder_refreshed_cb,
1787 /* Restore configuration. We need to do this
1788 *after* the set_folder because the widget
1789 memory asks the header view about its
1791 modest_widget_memory_restore (modest_runtime_get_conf (),
1792 G_OBJECT(header_view),
1793 MODEST_CONF_HEADER_VIEW_KEY);
1795 /* Update the active account */
1796 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1797 /* Save only if we're seeing headers */
1798 if (modest_main_window_get_contents_style (main_window) ==
1799 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1800 modest_widget_memory_save (conf, G_OBJECT (header_view),
1801 MODEST_CONF_HEADER_VIEW_KEY);
1802 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1806 /* Update toolbar dimming state */
1807 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1811 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1818 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1820 online = tny_device_is_online (modest_runtime_get_device());
1823 /* already online -- the item is simply not there... */
1824 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1826 GTK_MESSAGE_WARNING,
1828 _("The %s you selected cannot be found"),
1830 gtk_dialog_run (GTK_DIALOG(dialog));
1832 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1836 GTK_RESPONSE_REJECT,
1838 GTK_RESPONSE_ACCEPT,
1840 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1841 "Do you want to get online?"), item);
1842 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1843 gtk_label_new (txt), FALSE, FALSE, 0);
1844 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1847 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1848 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1849 /* TODO: Comment about why is this commented out: */
1850 /* modest_platform_connect_and_wait (); */
1853 gtk_widget_destroy (dialog);
1857 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1860 /* g_message ("%s %s", __FUNCTION__, link); */
1865 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1868 modest_platform_activate_uri (link);
1872 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1875 modest_platform_show_uri_popup (link);
1879 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1882 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1886 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1887 const gchar *address,
1890 /* g_message ("%s %s", __FUNCTION__, address); */
1894 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1896 TnyTransportAccount *transport_account;
1897 ModestMailOperation *mail_operation;
1899 gchar *account_name, *from;
1900 ModestAccountMgr *account_mgr;
1901 gchar *info_text = NULL;
1903 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1905 data = modest_msg_edit_window_get_msg_data (edit_window);
1907 account_mgr = modest_runtime_get_account_mgr();
1908 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1910 account_name = modest_account_mgr_get_default_account (account_mgr);
1911 if (!account_name) {
1912 g_printerr ("modest: no account found\n");
1913 modest_msg_edit_window_free_msg_data (edit_window, data);
1917 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1918 account_name = g_strdup (data->account_name);
1922 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1923 (modest_runtime_get_account_store(),
1925 TNY_ACCOUNT_TYPE_TRANSPORT));
1926 if (!transport_account) {
1927 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1928 g_free (account_name);
1929 modest_msg_edit_window_free_msg_data (edit_window, data);
1932 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1934 /* Create the mail operation */
1935 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1936 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1938 modest_mail_operation_save_to_drafts (mail_operation,
1950 data->priority_flags);
1953 g_free (account_name);
1954 g_object_unref (G_OBJECT (transport_account));
1955 g_object_unref (G_OBJECT (mail_operation));
1957 modest_msg_edit_window_free_msg_data (edit_window, data);
1959 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1960 modest_platform_information_banner (NULL, NULL, info_text);
1964 /* For instance, when clicking the Send toolbar button when editing a message: */
1966 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1968 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1970 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
1973 /* Offer the connection dialog, if necessary: */
1974 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
1977 /* FIXME: Code added just for testing. The final version will
1978 use the send queue provided by tinymail and some
1980 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1981 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1983 account_name = modest_account_mgr_get_default_account (account_mgr);
1985 if (!account_name) {
1986 /* Run account setup wizard */
1987 run_account_setup_wizard(MODEST_WINDOW(edit_window));
1991 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1993 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1994 account_name = g_strdup (data->account_name);
1997 /* Get the currently-active transport account for this modest account: */
1998 TnyTransportAccount *transport_account =
1999 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2000 (modest_runtime_get_account_store(),
2002 if (!transport_account) {
2003 /* Run account setup wizard */
2004 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2008 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2010 /* mail content checks and dialogs */
2011 if (data->subject == NULL || data->subject[0] == '\0') {
2012 GtkResponseType response;
2013 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2014 _("mcen_nc_subject_is_empty_send"));
2015 if (response == GTK_RESPONSE_CANCEL) {
2016 g_free (account_name);
2021 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2022 GtkResponseType response;
2023 gchar *note_message;
2024 gchar *note_subject = data->subject;
2025 if (note_subject == NULL || note_subject[0] == '\0')
2026 note_subject = _("mail_va_no_subject");
2027 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2028 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2030 g_free (note_message);
2031 if (response == GTK_RESPONSE_CANCEL) {
2032 g_free (account_name);
2037 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2039 /* Create the mail operation */
2040 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2041 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2043 modest_mail_operation_send_new_mail (mail_operation,
2054 data->priority_flags);
2058 g_free (account_name);
2059 g_object_unref (G_OBJECT (transport_account));
2060 g_object_unref (G_OBJECT (mail_operation));
2062 modest_msg_edit_window_free_msg_data (edit_window, data);
2063 modest_msg_edit_window_set_sent (edit_window, TRUE);
2065 /* Save settings and close the window: */
2066 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2070 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2071 ModestMsgEditWindow *window)
2073 ModestMsgEditFormatState *format_state = NULL;
2075 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2076 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2078 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2081 format_state = modest_msg_edit_window_get_format_state (window);
2082 g_return_if_fail (format_state != NULL);
2084 format_state->bold = gtk_toggle_action_get_active (action);
2085 modest_msg_edit_window_set_format_state (window, format_state);
2086 g_free (format_state);
2091 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2092 ModestMsgEditWindow *window)
2094 ModestMsgEditFormatState *format_state = NULL;
2096 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2097 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2099 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2102 format_state = modest_msg_edit_window_get_format_state (window);
2103 g_return_if_fail (format_state != NULL);
2105 format_state->italics = gtk_toggle_action_get_active (action);
2106 modest_msg_edit_window_set_format_state (window, format_state);
2107 g_free (format_state);
2112 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2113 ModestMsgEditWindow *window)
2115 ModestMsgEditFormatState *format_state = NULL;
2117 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2118 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2120 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2123 format_state = modest_msg_edit_window_get_format_state (window);
2124 g_return_if_fail (format_state != NULL);
2126 format_state->bullet = gtk_toggle_action_get_active (action);
2127 modest_msg_edit_window_set_format_state (window, format_state);
2128 g_free (format_state);
2133 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2134 GtkRadioAction *selected,
2135 ModestMsgEditWindow *window)
2137 ModestMsgEditFormatState *format_state = NULL;
2138 GtkJustification value;
2140 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2142 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2145 value = gtk_radio_action_get_current_value (selected);
2147 format_state = modest_msg_edit_window_get_format_state (window);
2148 g_return_if_fail (format_state != NULL);
2150 format_state->justification = value;
2151 modest_msg_edit_window_set_format_state (window, format_state);
2152 g_free (format_state);
2156 modest_ui_actions_on_select_editor_color (GtkAction *action,
2157 ModestMsgEditWindow *window)
2159 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2160 g_return_if_fail (GTK_IS_ACTION (action));
2162 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2165 modest_msg_edit_window_select_color (window);
2169 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2170 ModestMsgEditWindow *window)
2172 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2173 g_return_if_fail (GTK_IS_ACTION (action));
2175 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2178 modest_msg_edit_window_select_background_color (window);
2182 modest_ui_actions_on_insert_image (GtkAction *action,
2183 ModestMsgEditWindow *window)
2185 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2186 g_return_if_fail (GTK_IS_ACTION (action));
2188 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2191 modest_msg_edit_window_insert_image (window);
2195 modest_ui_actions_on_attach_file (GtkAction *action,
2196 ModestMsgEditWindow *window)
2198 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2199 g_return_if_fail (GTK_IS_ACTION (action));
2201 modest_msg_edit_window_offer_attach_file (window);
2205 modest_ui_actions_on_remove_attachments (GtkAction *action,
2206 ModestMsgEditWindow *window)
2208 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2209 g_return_if_fail (GTK_IS_ACTION (action));
2211 modest_msg_edit_window_remove_attachments (window, NULL);
2215 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2218 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2219 const GError *error = modest_mail_operation_get_error (mail_op);
2223 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2224 modest_mail_operation_get_error (mail_op)->message);
2229 modest_ui_actions_create_folder(GtkWidget *parent_window,
2230 GtkWidget *folder_view)
2232 TnyFolderStore *parent_folder;
2234 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2236 if (parent_folder) {
2237 gboolean finished = FALSE;
2239 gchar *folder_name = NULL, *suggested_name = NULL;
2241 /* Run the new folder dialog */
2243 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2248 g_free (suggested_name);
2249 suggested_name = NULL;
2251 if (result == GTK_RESPONSE_REJECT) {
2254 ModestMailOperation *mail_op;
2255 TnyFolder *new_folder = NULL;
2257 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2258 G_OBJECT(parent_window),
2259 modest_ui_actions_new_folder_error_handler,
2262 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2264 new_folder = modest_mail_operation_create_folder (mail_op,
2266 (const gchar *) folder_name);
2268 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2271 g_object_unref (new_folder);
2274 g_object_unref (mail_op);
2277 suggested_name = folder_name;
2281 g_object_unref (parent_folder);
2286 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2288 GtkWidget *folder_view;
2290 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2292 folder_view = modest_main_window_get_child_widget (main_window,
2293 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2297 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2301 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2304 GObject *win = modest_mail_operation_get_source (mail_op);
2305 const GError *error = NULL;
2306 const gchar *message = NULL;
2308 /* Get error message */
2309 error = modest_mail_operation_get_error (mail_op);
2310 if (error != NULL && error->message != NULL) {
2311 message = error->message;
2313 message = _("!!! FIXME: Unable to rename");
2316 /* Show notification dialog */
2317 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2318 g_object_unref (win);
2322 modest_ui_actions_on_rename_folder (GtkAction *action,
2323 ModestMainWindow *main_window)
2325 TnyFolderStore *folder;
2326 GtkWidget *folder_view;
2327 GtkWidget *header_view;
2329 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2331 folder_view = modest_main_window_get_child_widget (main_window,
2332 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2336 header_view = modest_main_window_get_child_widget (main_window,
2337 MODEST_WIDGET_TYPE_HEADER_VIEW);
2342 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2346 /* Offer the connection dialog if necessary: */
2347 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2348 g_object_unref (G_OBJECT (folder));
2353 if (TNY_IS_FOLDER (folder)) {
2356 const gchar *current_name;
2358 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2359 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2360 current_name, &folder_name);
2362 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2363 ModestMailOperation *mail_op;
2366 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2367 G_OBJECT(main_window),
2368 modest_ui_actions_rename_folder_error_handler,
2372 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2375 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2377 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2378 TNY_FOLDER(folder), TRUE);
2381 modest_header_view_clear ((ModestHeaderView *) header_view);
2383 modest_mail_operation_rename_folder (mail_op,
2384 TNY_FOLDER (folder),
2385 (const gchar *) folder_name);
2387 g_object_unref (mail_op);
2388 g_free (folder_name);
2391 g_object_unref (folder);
2395 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2398 GObject *win = modest_mail_operation_get_source (mail_op);
2400 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2401 _("mail_in_ui_folder_delete_error"));
2402 g_object_unref (win);
2406 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2408 TnyFolderStore *folder;
2409 GtkWidget *folder_view;
2413 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2415 folder_view = modest_main_window_get_child_widget (main_window,
2416 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2420 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2422 /* Show an error if it's an account */
2423 if (!TNY_IS_FOLDER (folder)) {
2424 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2425 _("mail_in_ui_folder_delete_error"));
2426 g_object_unref (G_OBJECT (folder));
2430 /* Offer the connection dialog if necessary: */
2431 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2432 g_object_unref (G_OBJECT (folder));
2437 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2438 tny_folder_get_name (TNY_FOLDER (folder)));
2439 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2440 (const gchar *) message);
2443 if (response == GTK_RESPONSE_OK) {
2444 ModestMailOperation *mail_op =
2445 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2446 G_OBJECT(main_window),
2447 modest_ui_actions_delete_folder_error_handler,
2450 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2452 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2453 g_object_unref (G_OBJECT (mail_op));
2456 g_object_unref (G_OBJECT (folder));
2460 modest_ui_actions_on_delete_folder (GtkAction *action,
2461 ModestMainWindow *main_window)
2463 GtkWidget *folder_view;
2464 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2466 delete_folder (main_window, FALSE);
2467 folder_view = modest_main_window_get_child_widget (main_window,
2468 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2471 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2475 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2477 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2479 delete_folder (main_window, TRUE);
2484 show_error (GtkWidget *parent_widget, const gchar* text)
2486 hildon_banner_show_information(parent_widget, NULL, text);
2489 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2491 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2498 gtk_dialog_run (dialog);
2499 gtk_widget_destroy (GTK_WIDGET (dialog));
2504 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2505 const gchar* server_account_name,
2510 ModestMainWindow *main_window)
2512 g_return_if_fail(server_account_name);
2513 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2515 /* Initalize output parameters: */
2522 #ifdef MODEST_PLATFORM_MAEMO
2523 /* Maemo uses a different (awkward) button order,
2524 * It should probably just use gtk_alternative_dialog_button_order ().
2526 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2530 GTK_RESPONSE_ACCEPT,
2532 GTK_RESPONSE_REJECT,
2535 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2539 GTK_RESPONSE_REJECT,
2541 GTK_RESPONSE_ACCEPT,
2543 #endif /* MODEST_PLATFORM_MAEMO */
2545 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2547 gchar *server_name = modest_server_account_get_hostname (
2548 modest_runtime_get_account_mgr(), server_account_name);
2549 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2550 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2555 /* This causes a warning because the logical ID has no %s in it,
2556 * though the translation does, but there is not much we can do about that: */
2557 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2558 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2561 g_free (server_name);
2565 gchar *initial_username = modest_server_account_get_username (
2566 modest_runtime_get_account_mgr(), server_account_name);
2568 GtkWidget *entry_username = gtk_entry_new ();
2569 if (initial_username)
2570 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2571 /* Dim this if a connection has ever succeeded with this username,
2572 * as per the UI spec: */
2573 const gboolean username_known =
2574 modest_server_account_get_username_has_succeeded(
2575 modest_runtime_get_account_mgr(), server_account_name);
2576 gtk_widget_set_sensitive (entry_username, !username_known);
2578 #ifdef MODEST_PLATFORM_MAEMO
2579 /* Auto-capitalization is the default, so let's turn it off: */
2580 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2582 /* Create a size group to be used by all captions.
2583 * Note that HildonCaption does not create a default size group if we do not specify one.
2584 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2585 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2587 GtkWidget *caption = hildon_caption_new (sizegroup,
2588 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2589 gtk_widget_show (entry_username);
2590 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2591 FALSE, FALSE, MODEST_MARGIN_HALF);
2592 gtk_widget_show (caption);
2594 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2596 #endif /* MODEST_PLATFORM_MAEMO */
2599 GtkWidget *entry_password = gtk_entry_new ();
2600 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2601 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2603 #ifdef MODEST_PLATFORM_MAEMO
2604 /* Auto-capitalization is the default, so let's turn it off: */
2605 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2606 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2608 caption = hildon_caption_new (sizegroup,
2609 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2610 gtk_widget_show (entry_password);
2611 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2612 FALSE, FALSE, MODEST_MARGIN_HALF);
2613 gtk_widget_show (caption);
2614 g_object_unref (sizegroup);
2616 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2618 #endif /* MODEST_PLATFORM_MAEMO */
2620 /* This is not in the Maemo UI spec:
2621 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2622 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2626 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2628 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2630 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2632 modest_server_account_set_username (
2633 modest_runtime_get_account_mgr(), server_account_name,
2636 const gboolean username_was_changed =
2637 (strcmp (*username, initial_username) != 0);
2638 if (username_was_changed) {
2639 g_warning ("%s: tinymail does not yet support changing the "
2640 "username in the get_password() callback.\n", __FUNCTION__);
2645 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2647 /* We do not save the password in the configuration,
2648 * because this function is only called for passwords that should
2649 * not be remembered:
2650 modest_server_account_set_password (
2651 modest_runtime_get_account_mgr(), server_account_name,
2660 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2672 /* This is not in the Maemo UI spec:
2673 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2679 gtk_widget_destroy (dialog);
2681 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2685 modest_ui_actions_on_cut (GtkAction *action,
2686 ModestWindow *window)
2688 GtkWidget *focused_widget;
2689 GtkClipboard *clipboard;
2691 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2692 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2693 if (GTK_IS_EDITABLE (focused_widget)) {
2694 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2695 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2696 gtk_clipboard_store (clipboard);
2697 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2698 GtkTextBuffer *buffer;
2700 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2701 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2702 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2703 gtk_clipboard_store (clipboard);
2704 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2705 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2706 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2707 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2712 modest_ui_actions_on_copy (GtkAction *action,
2713 ModestWindow *window)
2715 GtkClipboard *clipboard;
2716 GtkWidget *focused_widget;
2718 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2719 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2721 if (GTK_IS_LABEL (focused_widget)) {
2722 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2723 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2724 gtk_clipboard_store (clipboard);
2725 } else if (GTK_IS_EDITABLE (focused_widget)) {
2726 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2727 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2728 gtk_clipboard_store (clipboard);
2729 } else if (GTK_IS_HTML (focused_widget)) {
2730 gtk_html_copy (GTK_HTML (focused_widget));
2731 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2732 gtk_clipboard_store (clipboard);
2733 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2734 GtkTextBuffer *buffer;
2735 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2736 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2737 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2738 gtk_clipboard_store (clipboard);
2739 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2740 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2741 TnyIterator *iter = tny_list_create_iterator (header_list);
2742 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2744 gboolean ask = FALSE;
2746 TnyFolder *folder = tny_header_get_folder (header);
2747 TnyAccount *account = tny_folder_get_account (folder);
2748 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2749 /* If it's POP then ask */
2750 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2751 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2752 g_object_unref (account);
2753 g_object_unref (folder);
2754 g_object_unref (header);
2757 g_object_unref (iter);
2759 /* Check that the messages have been previously downloaded */
2760 gboolean continue_download = TRUE;
2762 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2763 if (continue_download)
2764 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2765 g_object_unref (header_list);
2766 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2767 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2770 /* Show information banner */
2771 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2776 modest_ui_actions_on_undo (GtkAction *action,
2777 ModestWindow *window)
2779 ModestEmailClipboard *clipboard = NULL;
2781 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2782 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2783 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2784 /* Clear clipboard source */
2785 clipboard = modest_runtime_get_email_clipboard ();
2786 modest_email_clipboard_clear (clipboard);
2789 g_return_if_reached ();
2794 modest_ui_actions_on_redo (GtkAction *action,
2795 ModestWindow *window)
2797 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2798 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2801 g_return_if_reached ();
2807 paste_msgs_cb (const GObject *object, gpointer user_data)
2809 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2810 g_return_if_fail (GTK_IS_WIDGET (user_data));
2812 /* destroy information note */
2813 gtk_widget_destroy (GTK_WIDGET(user_data));
2817 paste_as_attachment_free (gpointer data)
2819 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2821 gtk_widget_destroy (helper->banner);
2822 g_object_unref (helper->banner);
2827 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2832 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2833 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2838 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2843 modest_ui_actions_on_paste (GtkAction *action,
2844 ModestWindow *window)
2846 GtkWidget *focused_widget = NULL;
2847 GtkWidget *inf_note = NULL;
2848 ModestMailOperation *mail_op = NULL;
2850 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2851 if (GTK_IS_EDITABLE (focused_widget)) {
2852 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2853 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2854 ModestEmailClipboard *e_clipboard = NULL;
2855 e_clipboard = modest_runtime_get_email_clipboard ();
2856 if (modest_email_clipboard_cleared (e_clipboard)) {
2857 GtkTextBuffer *buffer;
2858 GtkClipboard *clipboard;
2860 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2861 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2862 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2863 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2864 ModestMailOperation *mail_op;
2865 TnyFolder *src_folder;
2868 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2869 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2870 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2871 _CS("ckct_nw_pasting"));
2872 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2873 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2875 if (helper->banner != NULL) {
2876 g_object_ref (G_OBJECT (helper->banner));
2877 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2878 gtk_widget_show (GTK_WIDGET (helper->banner));
2882 modest_mail_operation_get_msgs_full (mail_op,
2884 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2886 paste_as_attachment_free);
2889 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2890 ModestEmailClipboard *clipboard = NULL;
2891 TnyFolder *src_folder = NULL;
2892 TnyFolderStore *folder_store = NULL;
2893 TnyList *data = NULL;
2894 gboolean delete = FALSE;
2896 /* Check clipboard source */
2897 clipboard = modest_runtime_get_email_clipboard ();
2898 if (modest_email_clipboard_cleared (clipboard))
2901 /* Get elements to paste */
2902 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2904 /* Create a new mail operation */
2905 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2906 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2909 /* Get destination folder */
2910 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2912 /* Launch notification */
2913 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2914 _CS("ckct_nw_pasting"));
2915 if (inf_note != NULL) {
2916 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2917 gtk_widget_show (GTK_WIDGET(inf_note));
2920 /* transfer messages */
2922 modest_mail_operation_xfer_msgs (mail_op,
2924 TNY_FOLDER (folder_store),
2929 } else if (src_folder != NULL) {
2930 modest_mail_operation_xfer_folder (mail_op,
2940 g_object_unref (data);
2941 if (src_folder != NULL)
2942 g_object_unref (src_folder);
2943 if (folder_store != NULL)
2944 g_object_unref (folder_store);
2950 modest_ui_actions_on_select_all (GtkAction *action,
2951 ModestWindow *window)
2953 GtkWidget *focused_widget;
2955 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2956 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2957 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2958 } else if (GTK_IS_LABEL (focused_widget)) {
2959 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2960 } else if (GTK_IS_EDITABLE (focused_widget)) {
2961 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2962 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2963 GtkTextBuffer *buffer;
2964 GtkTextIter start, end;
2966 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2967 gtk_text_buffer_get_start_iter (buffer, &start);
2968 gtk_text_buffer_get_end_iter (buffer, &end);
2969 gtk_text_buffer_select_range (buffer, &start, &end);
2970 } else if (GTK_IS_HTML (focused_widget)) {
2971 gtk_html_select_all (GTK_HTML (focused_widget));
2972 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2973 GtkWidget *header_view = focused_widget;
2974 GtkTreeSelection *selection = NULL;
2976 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2977 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2978 MODEST_WIDGET_TYPE_HEADER_VIEW);
2980 /* Select all messages */
2981 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2982 gtk_tree_selection_select_all (selection);
2984 /* Set focuse on header view */
2985 gtk_widget_grab_focus (header_view);
2991 modest_ui_actions_on_mark_as_read (GtkAction *action,
2992 ModestWindow *window)
2994 g_return_if_fail (MODEST_IS_WINDOW(window));
2996 /* Mark each header as read */
2997 do_headers_action (window, headers_action_mark_as_read, NULL);
3001 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3002 ModestWindow *window)
3004 g_return_if_fail (MODEST_IS_WINDOW(window));
3006 /* Mark each header as read */
3007 do_headers_action (window, headers_action_mark_as_unread, NULL);
3011 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3012 GtkRadioAction *selected,
3013 ModestWindow *window)
3017 value = gtk_radio_action_get_current_value (selected);
3018 if (MODEST_IS_WINDOW (window)) {
3019 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3023 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3024 GtkRadioAction *selected,
3025 ModestWindow *window)
3027 TnyHeaderFlags flags;
3028 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3030 flags = gtk_radio_action_get_current_value (selected);
3031 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3034 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3035 GtkRadioAction *selected,
3036 ModestWindow *window)
3040 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3042 file_format = gtk_radio_action_get_current_value (selected);
3043 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3048 modest_ui_actions_on_zoom_plus (GtkAction *action,
3049 ModestWindow *window)
3051 g_return_if_fail (MODEST_IS_WINDOW (window));
3053 modest_window_zoom_plus (MODEST_WINDOW (window));
3057 modest_ui_actions_on_zoom_minus (GtkAction *action,
3058 ModestWindow *window)
3060 g_return_if_fail (MODEST_IS_WINDOW (window));
3062 modest_window_zoom_minus (MODEST_WINDOW (window));
3066 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3067 ModestWindow *window)
3069 ModestWindowMgr *mgr;
3070 gboolean fullscreen, active;
3071 g_return_if_fail (MODEST_IS_WINDOW (window));
3073 mgr = modest_runtime_get_window_mgr ();
3075 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3076 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3078 if (active != fullscreen) {
3079 modest_window_mgr_set_fullscreen_mode (mgr, active);
3080 gtk_window_present (GTK_WINDOW (window));
3085 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3086 ModestWindow *window)
3088 ModestWindowMgr *mgr;
3089 gboolean fullscreen;
3091 g_return_if_fail (MODEST_IS_WINDOW (window));
3093 mgr = modest_runtime_get_window_mgr ();
3094 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3095 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3097 gtk_window_present (GTK_WINDOW (window));
3101 * Used by modest_ui_actions_on_details to call do_headers_action
3104 headers_action_show_details (TnyHeader *header,
3105 ModestWindow *window,
3112 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3115 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3116 gtk_widget_show_all (dialog);
3117 gtk_dialog_run (GTK_DIALOG (dialog));
3119 gtk_widget_destroy (dialog);
3123 * Show the folder details in a ModestDetailsDialog widget
3126 show_folder_details (TnyFolder *folder,
3132 dialog = modest_details_dialog_new_with_folder (window, folder);
3135 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3136 gtk_widget_show_all (dialog);
3137 gtk_dialog_run (GTK_DIALOG (dialog));
3139 gtk_widget_destroy (dialog);
3143 * Show the header details in a ModestDetailsDialog widget
3146 modest_ui_actions_on_details (GtkAction *action,
3149 TnyList * headers_list;
3153 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3156 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3159 g_object_unref (msg);
3161 headers_list = get_selected_headers (win);
3165 iter = tny_list_create_iterator (headers_list);
3167 header = TNY_HEADER (tny_iterator_get_current (iter));
3169 headers_action_show_details (header, win, NULL);
3170 g_object_unref (header);
3173 g_object_unref (iter);
3174 g_object_unref (headers_list);
3176 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3177 GtkWidget *folder_view, *header_view;
3179 /* Check which widget has the focus */
3180 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3181 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3182 if (gtk_widget_is_focus (folder_view)) {
3183 TnyFolderStore *folder_store
3184 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3185 if (!folder_store) {
3186 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3189 /* Show only when it's a folder */
3190 /* This function should not be called for account items,
3191 * because we dim the menu item for them. */
3192 if (TNY_IS_FOLDER (folder_store)) {
3193 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3196 g_object_unref (folder_store);
3199 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3200 MODEST_WIDGET_TYPE_HEADER_VIEW);
3201 /* Show details of each header */
3202 do_headers_action (win, headers_action_show_details, header_view);
3208 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3209 ModestMsgEditWindow *window)
3211 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3213 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3217 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3218 ModestMsgEditWindow *window)
3220 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3222 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3226 modest_ui_actions_toggle_folders_view (GtkAction *action,
3227 ModestMainWindow *main_window)
3229 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3231 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3232 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3234 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3238 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3239 ModestWindow *window)
3241 gboolean active, fullscreen = FALSE;
3242 ModestWindowMgr *mgr;
3244 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3246 /* Check if we want to toggle the toolbar vuew in fullscreen
3248 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3249 "ViewShowToolbarFullScreen")) {
3253 /* Toggle toolbar */
3254 mgr = modest_runtime_get_window_mgr ();
3255 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3259 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3260 ModestMsgEditWindow *window)
3262 modest_msg_edit_window_select_font (window);
3266 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3267 const gchar *display_name,
3270 /* Do not change the application name if the widget has not
3271 the focus. This callback could be called even if the folder
3272 view has not the focus, because the handled signal could be
3273 emitted when the folder view is redrawn */
3274 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3276 gtk_window_set_title (window, display_name);
3278 gtk_window_set_title (window, " ");
3283 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3286 modest_msg_edit_window_select_contacts (window);
3290 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3292 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3293 modest_msg_edit_window_check_names (window, FALSE);
3297 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3299 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3300 GTK_WIDGET (user_data));
3304 create_move_to_dialog (GtkWindow *win,
3305 GtkWidget *folder_view,
3306 GtkWidget **tree_view)
3308 GtkWidget *dialog, *scroll;
3309 GtkWidget *new_button;
3311 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3313 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3316 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3317 /* We do this manually so GTK+ does not associate a response ID for
3319 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3320 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3321 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3323 /* Create scrolled window */
3324 scroll = gtk_scrolled_window_new (NULL, NULL);
3325 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3326 GTK_POLICY_AUTOMATIC,
3327 GTK_POLICY_AUTOMATIC);
3329 /* Create folder view */
3330 *tree_view = modest_platform_create_folder_view (NULL);
3332 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3334 /* It could happen that we're trying to move a message from a
3335 window (msg window for example) after the main window was
3336 closed, so we can not just get the model of the folder
3338 if (MODEST_IS_FOLDER_VIEW (folder_view))
3339 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3340 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3342 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3343 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3345 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3347 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3349 /* Add scroll to dialog */
3350 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3351 scroll, TRUE, TRUE, 0);
3353 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3354 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3360 * Returns TRUE if at least one of the headers of the list belongs to
3361 * a message that has been fully retrieved.
3364 has_retrieved_msgs (TnyList *list)
3367 gboolean found = FALSE;
3369 iter = tny_list_create_iterator (list);
3370 while (tny_iterator_is_done (iter) && !found) {
3372 TnyHeaderFlags flags = 0;
3374 header = TNY_HEADER (tny_iterator_get_current (iter));
3376 flags = tny_header_get_flags (header);
3377 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3380 g_object_unref (header);
3384 tny_iterator_next (iter);
3386 g_object_unref (iter);
3392 * Shows a confirmation dialog to the user when we're moving messages
3393 * from a remote server to the local storage. Returns the dialog
3394 * response. If it's other kind of movement the it always returns
3398 msgs_move_to_confirmation (GtkWindow *win,
3399 TnyFolder *dest_folder,
3402 gint response = GTK_RESPONSE_OK;
3404 /* If the destination is a local folder */
3405 if (modest_tny_folder_is_local_folder (dest_folder)) {
3406 TnyFolder *src_folder = NULL;
3407 TnyIterator *iter = NULL;
3408 TnyHeader *header = NULL;
3410 /* Get source folder */
3411 iter = tny_list_create_iterator (headers);
3412 header = TNY_HEADER (tny_iterator_get_current (iter));
3414 src_folder = tny_header_get_folder (header);
3415 g_object_unref (header);
3418 g_object_unref (iter);
3420 /* if no src_folder, message may be an attahcment */
3421 if (src_folder == NULL)
3422 return GTK_RESPONSE_CANCEL;
3424 /* If the source is a remote folder */
3425 if (!modest_tny_folder_is_local_folder (src_folder)) {
3426 const gchar *message;
3428 if (has_retrieved_msgs (headers))
3429 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3430 tny_list_get_length (headers));
3432 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3433 tny_list_get_length (headers));
3435 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3436 (const gchar *) message);
3439 g_object_unref (src_folder);
3448 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3450 ModestMsgViewWindow *self = NULL;
3452 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3453 self = MODEST_MSG_VIEW_WINDOW (object);
3455 if (!modest_msg_view_window_select_next_message (self))
3456 if (!modest_msg_view_window_select_previous_message (self))
3457 /* No more messages to view, so close this window */
3458 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3462 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3465 GObject *win = modest_mail_operation_get_source (mail_op);
3466 const GError *error = NULL;
3467 const gchar *message = NULL;
3469 /* Get error message */
3470 error = modest_mail_operation_get_error (mail_op);
3471 if (error != NULL && error->message != NULL) {
3472 message = error->message;
3474 message = _("mail_in_ui_folder_move_target_error");
3477 /* Show notification dialog */
3478 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3479 g_object_unref (win);
3483 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3486 GObject *win = modest_mail_operation_get_source (mail_op);
3487 const GError *error = modest_mail_operation_get_error (mail_op);
3489 g_return_if_fail (error != NULL);
3490 if (error->message != NULL)
3491 g_printerr ("modest: %s\n", error->message);
3493 g_printerr ("modest: unkonw error on send&receive operation");
3495 /* Show error message */
3496 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3497 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3498 /* _CS("sfil_ib_unable_to_receive")); */
3500 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3501 /* _CS("sfil_ib_unable_to_send")); */
3502 g_object_unref (win);
3506 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3513 gint pending_purges = 0;
3514 gboolean some_purged = FALSE;
3515 ModestWindow *win = MODEST_WINDOW (user_data);
3516 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3518 /* If there was any error */
3519 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3520 modest_window_mgr_unregister_header (mgr, header);
3524 /* Once the message has been retrieved for purging, we check if
3525 * it's all ok for purging */
3527 parts = tny_simple_list_new ();
3528 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3529 iter = tny_list_create_iterator (parts);
3531 while (!tny_iterator_is_done (iter)) {
3533 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3534 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3535 if (tny_mime_part_is_purged (part))
3542 g_object_unref (part);
3544 tny_iterator_next (iter);
3547 if (pending_purges>0) {
3549 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3551 if (response == GTK_RESPONSE_OK) {
3552 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3553 tny_iterator_first (iter);
3554 while (!tny_iterator_is_done (iter)) {
3557 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3558 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3559 tny_mime_part_set_purged (part);
3562 g_object_unref (part);
3564 tny_iterator_next (iter);
3567 tny_msg_rewrite_cache (msg);
3570 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3573 /* remove attachments */
3574 tny_iterator_first (iter);
3575 while (!tny_iterator_is_done (iter)) {
3578 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3580 /* One for the reference given by tny_iterator_get_current(): */
3581 g_object_unref (part);
3583 /* TODO: Is this meant to remove the attachment by doing another unref()?
3584 * Otherwise, this seems useless. */
3587 tny_iterator_next (iter);
3589 modest_window_mgr_unregister_header (mgr, header);
3591 g_object_unref (iter);
3592 g_object_unref (parts);
3596 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3597 ModestMainWindow *win)
3599 GtkWidget *header_view;
3600 TnyList *header_list;
3603 TnyHeaderFlags flags;
3604 ModestWindow *msg_view_window = NULL;
3607 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3609 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3610 MODEST_WIDGET_TYPE_HEADER_VIEW);
3612 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3614 if (tny_list_get_length (header_list) == 1) {
3615 iter = tny_list_create_iterator (header_list);
3616 header = TNY_HEADER (tny_iterator_get_current (iter));
3617 g_object_unref (iter);
3622 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3623 header, &msg_view_window);
3624 flags = tny_header_get_flags (header);
3625 if (!(flags & TNY_HEADER_FLAG_CACHED))
3628 if (msg_view_window != NULL)
3629 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3631 /* do nothing; uid was registered before, so window is probably on it's way */
3632 g_warning ("debug: header %p has already been registered", header);
3635 ModestMailOperation *mail_op = NULL;
3636 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3637 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3639 modest_ui_actions_get_msgs_full_error_handler,
3641 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3642 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3644 g_object_unref (mail_op);
3647 g_object_unref (header);
3649 g_object_unref (header_list);
3653 * Utility function that transfer messages from both the main window
3654 * and the msg view window when using the "Move to" dialog
3657 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3660 TnyList *headers = NULL;
3662 TnyAccount *dst_account = NULL;
3663 const gchar *proto_str = NULL;
3664 gboolean dst_is_pop = FALSE;
3666 if (!TNY_IS_FOLDER (dst_folder)) {
3667 modest_platform_information_banner (GTK_WIDGET (win),
3669 _CS("ckdg_ib_unable_to_move_to_current_location"));
3673 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3674 proto_str = tny_account_get_proto (dst_account);
3675 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3676 MODEST_PROTOCOL_STORE_POP);
3677 g_object_unref (dst_account);
3679 /* Get selected headers */
3680 headers = get_selected_headers (MODEST_WINDOW (win));
3683 modest_platform_information_banner (GTK_WIDGET (win),
3685 ngettext("mail_in_ui_folder_move_target_error",
3686 "mail_in_ui_folder_move_targets_error",
3687 tny_list_get_length (headers)));
3688 g_object_unref (headers);
3692 /* Ask for user confirmation */
3693 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3694 TNY_FOLDER (dst_folder),
3697 /* Transfer messages */
3698 if (response == GTK_RESPONSE_OK) {
3699 ModestMailOperation *mail_op =
3700 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3702 modest_ui_actions_move_folder_error_handler,
3704 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3707 modest_mail_operation_xfer_msgs (mail_op,
3709 TNY_FOLDER (dst_folder),
3711 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3714 g_object_unref (G_OBJECT (mail_op));
3716 g_object_unref (headers);
3721 * UI handler for the "Move to" action when invoked from the
3725 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3726 GtkWidget *folder_view,
3727 TnyFolderStore *dst_folder,
3728 ModestMainWindow *win)
3730 GtkWidget *header_view = NULL;
3731 ModestMailOperation *mail_op = NULL;
3732 TnyFolderStore *src_folder;
3734 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3736 /* Get the source folder */
3737 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3739 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3740 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3744 /* Get header view */
3746 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3748 /* Get folder or messages to transfer */
3749 if (gtk_widget_is_focus (folder_view)) {
3751 /* Allow only to transfer folders to the local root folder */
3752 if (TNY_IS_ACCOUNT (dst_folder) &&
3753 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3756 /* Clean folder on header view before moving it */
3757 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3759 if (TNY_IS_FOLDER (src_folder)) {
3761 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3763 modest_ui_actions_move_folder_error_handler,
3765 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3768 modest_mail_operation_xfer_folder (mail_op,
3769 TNY_FOLDER (src_folder),
3772 /* Unref mail operation */
3773 g_object_unref (G_OBJECT (mail_op));
3775 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3777 } else if (gtk_widget_is_focus (header_view)) {
3778 /* Transfer messages */
3779 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3784 g_object_unref (src_folder);
3789 * UI handler for the "Move to" action when invoked from the
3790 * ModestMsgViewWindow
3793 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3794 TnyFolderStore *dst_folder,
3795 ModestMsgViewWindow *win)
3797 TnyHeader *header = NULL;
3798 TnyFolder *src_folder;
3800 /* Create header list */
3801 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3802 src_folder = tny_header_get_folder(header);
3803 g_object_unref (header);
3805 /* Transfer the message */
3806 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3807 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3809 g_object_unref (src_folder);
3813 modest_ui_actions_on_move_to (GtkAction *action,
3816 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3818 TnyFolderStore *dst_folder = NULL;
3819 ModestMainWindow *main_window;
3821 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3822 MODEST_IS_MSG_VIEW_WINDOW (win));
3824 /* Get the main window if exists */
3825 if (MODEST_IS_MAIN_WINDOW (win))
3826 main_window = MODEST_MAIN_WINDOW (win);
3829 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3831 /* Get the folder view widget if exists */
3833 folder_view = modest_main_window_get_child_widget (main_window,
3834 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3838 /* Create and run the dialog */
3839 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3840 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3841 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3842 result = gtk_dialog_run (GTK_DIALOG(dialog));
3843 g_object_ref (tree_view);
3844 gtk_widget_destroy (dialog);
3846 if (result != GTK_RESPONSE_ACCEPT)
3849 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3850 /* Offer the connection dialog if necessary: */
3851 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3854 /* Do window specific stuff */
3855 if (MODEST_IS_MAIN_WINDOW (win))
3856 modest_ui_actions_on_main_window_move_to (action,
3859 MODEST_MAIN_WINDOW (win));
3861 modest_ui_actions_on_msg_view_window_move_to (action,
3863 MODEST_MSG_VIEW_WINDOW (win));
3866 g_object_unref (dst_folder);
3870 * Calls #HeadersFunc for each header already selected in the main
3871 * window or the message currently being shown in the msg view window
3874 do_headers_action (ModestWindow *win,
3878 TnyList *headers_list = NULL;
3879 TnyIterator *iter = NULL;
3880 TnyHeader *header = NULL;
3881 TnyFolder *folder = NULL;
3884 headers_list = get_selected_headers (win);
3888 /* Get the folder */
3889 iter = tny_list_create_iterator (headers_list);
3890 header = TNY_HEADER (tny_iterator_get_current (iter));
3892 folder = tny_header_get_folder (header);
3893 g_object_unref (header);
3896 /* Call the function for each header */
3897 while (!tny_iterator_is_done (iter)) {
3898 header = TNY_HEADER (tny_iterator_get_current (iter));
3899 func (header, win, user_data);
3900 g_object_unref (header);
3901 tny_iterator_next (iter);
3904 /* Trick: do a poke status in order to speed up the signaling
3906 tny_folder_poke_status (folder);
3909 g_object_unref (folder);
3910 g_object_unref (iter);
3911 g_object_unref (headers_list);
3915 modest_ui_actions_view_attachment (GtkAction *action,
3916 ModestWindow *window)
3918 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3919 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3921 /* not supported window for this action */
3922 g_return_if_reached ();
3927 modest_ui_actions_save_attachments (GtkAction *action,
3928 ModestWindow *window)
3930 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3931 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3933 /* not supported window for this action */
3934 g_return_if_reached ();
3939 modest_ui_actions_remove_attachments (GtkAction *action,
3940 ModestWindow *window)
3942 if (MODEST_IS_MAIN_WINDOW (window)) {
3943 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3944 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3945 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3947 /* not supported window for this action */
3948 g_return_if_reached ();
3953 modest_ui_actions_on_settings (GtkAction *action,
3958 dialog = modest_platform_get_global_settings_dialog ();
3959 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3960 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3961 gtk_widget_show_all (dialog);
3963 gtk_dialog_run (GTK_DIALOG (dialog));
3965 gtk_widget_destroy (dialog);
3969 modest_ui_actions_on_help (GtkAction *action,
3972 const gchar *help_id = NULL;
3974 if (MODEST_IS_MAIN_WINDOW (win)) {
3975 const gchar *action_name;
3976 action_name = gtk_action_get_name (action);
3978 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3979 !strcmp (action_name, "HeaderViewCSMHelp")) {
3980 GtkWidget *folder_view;
3981 TnyFolderStore *folder_store;
3982 /* Get selected folder */
3983 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3984 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3985 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3987 /* Switch help_id */
3988 if (TNY_IS_FOLDER (folder_store)) {
3989 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
3990 case TNY_FOLDER_TYPE_NORMAL:
3991 help_id = "applications_email_managefolders";
3993 case TNY_FOLDER_TYPE_INBOX:
3994 help_id = "applications_email_inbox";
3996 case TNY_FOLDER_TYPE_OUTBOX:
3997 help_id = "applications_email_outbox";
3999 case TNY_FOLDER_TYPE_SENT:
4000 help_id = "applications_email_sent";
4002 case TNY_FOLDER_TYPE_DRAFTS:
4003 help_id = "applications_email_drafts";
4005 case TNY_FOLDER_TYPE_ARCHIVE:
4006 help_id = "applications_email_managefolders";
4009 help_id = "applications_email_managefolders";
4012 help_id = "applications_email_mainview";
4014 g_object_unref (folder_store);
4016 help_id = "applications_email_mainview";
4018 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4019 help_id = "applications_email_viewer";
4020 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4021 help_id = "applications_email_editor";
4023 modest_platform_show_help (GTK_WINDOW (win), help_id);
4027 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4028 ModestWindow *window)
4030 ModestMailOperation *mail_op;
4034 headers = get_selected_headers (window);
4038 /* Create mail operation */
4039 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4041 modest_ui_actions_get_msgs_full_error_handler,
4043 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4044 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4047 g_object_unref (headers);
4048 g_object_unref (mail_op);
4052 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4053 ModestWindow *window)
4055 g_return_if_fail (MODEST_IS_WINDOW (window));
4058 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4062 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4063 ModestWindow *window)
4065 g_return_if_fail (MODEST_IS_WINDOW (window));
4068 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4072 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4073 ModestWindow *window)
4075 g_return_if_fail (MODEST_IS_WINDOW (window));
4078 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4082 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4083 ModestWindow *window)
4085 g_return_if_fail (MODEST_IS_WINDOW (window));
4088 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4092 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4093 ModestWindow *window)
4095 g_return_if_fail (MODEST_IS_WINDOW (window));
4098 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4102 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4103 ModestWindow *window)
4105 g_return_if_fail (MODEST_IS_WINDOW (window));
4108 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4112 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4113 ModestWindow *window)
4115 g_return_if_fail (MODEST_IS_WINDOW (window));
4118 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4122 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4123 ModestWindow *window)
4125 g_return_if_fail (MODEST_IS_WINDOW (window));
4128 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4132 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4134 g_return_if_fail (MODEST_IS_WINDOW (window));
4137 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4141 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4143 g_return_if_fail (MODEST_IS_WINDOW (window));
4145 modest_platform_show_search_messages (GTK_WINDOW (window));
4149 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4151 g_return_if_fail (MODEST_IS_WINDOW (win));
4152 modest_platform_show_addressbook (GTK_WINDOW (win));
4157 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4158 ModestWindow *window)
4160 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4162 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4166 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4167 ModestMailOperationState *state,
4170 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4172 /* Set send/receive operation finished */
4173 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4174 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));