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 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2465 delete_folder (main_window, FALSE);
2469 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2471 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2473 delete_folder (main_window, TRUE);
2478 show_error (GtkWidget *parent_widget, const gchar* text)
2480 hildon_banner_show_information(parent_widget, NULL, text);
2483 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2485 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2492 gtk_dialog_run (dialog);
2493 gtk_widget_destroy (GTK_WIDGET (dialog));
2498 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2499 const gchar* server_account_name,
2504 ModestMainWindow *main_window)
2506 g_return_if_fail(server_account_name);
2507 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2509 /* Initalize output parameters: */
2516 #ifdef MODEST_PLATFORM_MAEMO
2517 /* Maemo uses a different (awkward) button order,
2518 * It should probably just use gtk_alternative_dialog_button_order ().
2520 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2524 GTK_RESPONSE_ACCEPT,
2526 GTK_RESPONSE_REJECT,
2529 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2533 GTK_RESPONSE_REJECT,
2535 GTK_RESPONSE_ACCEPT,
2537 #endif /* MODEST_PLATFORM_MAEMO */
2539 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2541 gchar *server_name = modest_server_account_get_hostname (
2542 modest_runtime_get_account_mgr(), server_account_name);
2543 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2544 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2549 /* This causes a warning because the logical ID has no %s in it,
2550 * though the translation does, but there is not much we can do about that: */
2551 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2552 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2555 g_free (server_name);
2559 gchar *initial_username = modest_server_account_get_username (
2560 modest_runtime_get_account_mgr(), server_account_name);
2562 GtkWidget *entry_username = gtk_entry_new ();
2563 if (initial_username)
2564 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2565 /* Dim this if a connection has ever succeeded with this username,
2566 * as per the UI spec: */
2567 const gboolean username_known =
2568 modest_server_account_get_username_has_succeeded(
2569 modest_runtime_get_account_mgr(), server_account_name);
2570 gtk_widget_set_sensitive (entry_username, !username_known);
2572 #ifdef MODEST_PLATFORM_MAEMO
2573 /* Auto-capitalization is the default, so let's turn it off: */
2574 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2576 /* Create a size group to be used by all captions.
2577 * Note that HildonCaption does not create a default size group if we do not specify one.
2578 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2579 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2581 GtkWidget *caption = hildon_caption_new (sizegroup,
2582 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2583 gtk_widget_show (entry_username);
2584 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2585 FALSE, FALSE, MODEST_MARGIN_HALF);
2586 gtk_widget_show (caption);
2588 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2590 #endif /* MODEST_PLATFORM_MAEMO */
2593 GtkWidget *entry_password = gtk_entry_new ();
2594 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2595 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2597 #ifdef MODEST_PLATFORM_MAEMO
2598 /* Auto-capitalization is the default, so let's turn it off: */
2599 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2600 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2602 caption = hildon_caption_new (sizegroup,
2603 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2604 gtk_widget_show (entry_password);
2605 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2606 FALSE, FALSE, MODEST_MARGIN_HALF);
2607 gtk_widget_show (caption);
2608 g_object_unref (sizegroup);
2610 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2612 #endif /* MODEST_PLATFORM_MAEMO */
2614 /* This is not in the Maemo UI spec:
2615 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2616 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2620 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2622 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2624 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2626 modest_server_account_set_username (
2627 modest_runtime_get_account_mgr(), server_account_name,
2630 const gboolean username_was_changed =
2631 (strcmp (*username, initial_username) != 0);
2632 if (username_was_changed) {
2633 g_warning ("%s: tinymail does not yet support changing the "
2634 "username in the get_password() callback.\n", __FUNCTION__);
2639 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2641 /* We do not save the password in the configuration,
2642 * because this function is only called for passwords that should
2643 * not be remembered:
2644 modest_server_account_set_password (
2645 modest_runtime_get_account_mgr(), server_account_name,
2654 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2666 /* This is not in the Maemo UI spec:
2667 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2673 gtk_widget_destroy (dialog);
2675 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2679 modest_ui_actions_on_cut (GtkAction *action,
2680 ModestWindow *window)
2682 GtkWidget *focused_widget;
2683 GtkClipboard *clipboard;
2685 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2686 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2687 if (GTK_IS_EDITABLE (focused_widget)) {
2688 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2689 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2690 gtk_clipboard_store (clipboard);
2691 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2692 GtkTextBuffer *buffer;
2694 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2695 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2696 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2697 gtk_clipboard_store (clipboard);
2698 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2699 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2700 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2701 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2706 modest_ui_actions_on_copy (GtkAction *action,
2707 ModestWindow *window)
2709 GtkClipboard *clipboard;
2710 GtkWidget *focused_widget;
2712 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2713 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2715 if (GTK_IS_LABEL (focused_widget)) {
2716 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2717 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2718 gtk_clipboard_store (clipboard);
2719 } else if (GTK_IS_EDITABLE (focused_widget)) {
2720 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2721 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2722 gtk_clipboard_store (clipboard);
2723 } else if (GTK_IS_HTML (focused_widget)) {
2724 gtk_html_copy (GTK_HTML (focused_widget));
2725 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2726 gtk_clipboard_store (clipboard);
2727 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2728 GtkTextBuffer *buffer;
2729 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2730 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2731 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2732 gtk_clipboard_store (clipboard);
2733 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2734 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2735 TnyIterator *iter = tny_list_create_iterator (header_list);
2736 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2738 gboolean ask = FALSE;
2740 TnyFolder *folder = tny_header_get_folder (header);
2741 TnyAccount *account = tny_folder_get_account (folder);
2742 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2743 /* If it's POP then ask */
2744 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2745 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2746 g_object_unref (account);
2747 g_object_unref (folder);
2748 g_object_unref (header);
2751 g_object_unref (iter);
2753 /* Check that the messages have been previously downloaded */
2754 gboolean continue_download = TRUE;
2756 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2757 if (continue_download)
2758 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2759 g_object_unref (header_list);
2760 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2761 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2764 /* Show information banner */
2765 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2770 modest_ui_actions_on_undo (GtkAction *action,
2771 ModestWindow *window)
2773 ModestEmailClipboard *clipboard = NULL;
2775 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2776 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2777 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2778 /* Clear clipboard source */
2779 clipboard = modest_runtime_get_email_clipboard ();
2780 modest_email_clipboard_clear (clipboard);
2783 g_return_if_reached ();
2788 modest_ui_actions_on_redo (GtkAction *action,
2789 ModestWindow *window)
2791 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2792 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2795 g_return_if_reached ();
2801 paste_msgs_cb (const GObject *object, gpointer user_data)
2803 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2804 g_return_if_fail (GTK_IS_WIDGET (user_data));
2806 /* destroy information note */
2807 gtk_widget_destroy (GTK_WIDGET(user_data));
2811 paste_as_attachment_free (gpointer data)
2813 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2815 gtk_widget_destroy (helper->banner);
2816 g_object_unref (helper->banner);
2821 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2826 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2827 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2832 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2837 modest_ui_actions_on_paste (GtkAction *action,
2838 ModestWindow *window)
2840 GtkWidget *focused_widget = NULL;
2841 GtkWidget *inf_note = NULL;
2842 ModestMailOperation *mail_op = NULL;
2844 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2845 if (GTK_IS_EDITABLE (focused_widget)) {
2846 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2847 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2848 ModestEmailClipboard *e_clipboard = NULL;
2849 e_clipboard = modest_runtime_get_email_clipboard ();
2850 if (modest_email_clipboard_cleared (e_clipboard)) {
2851 GtkTextBuffer *buffer;
2852 GtkClipboard *clipboard;
2854 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2855 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2856 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2857 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2858 ModestMailOperation *mail_op;
2859 TnyFolder *src_folder;
2862 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2863 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2864 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2865 _CS("ckct_nw_pasting"));
2866 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2867 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2869 if (helper->banner != NULL) {
2870 g_object_ref (G_OBJECT (helper->banner));
2871 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2872 gtk_widget_show (GTK_WIDGET (helper->banner));
2876 modest_mail_operation_get_msgs_full (mail_op,
2878 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2880 paste_as_attachment_free);
2883 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2884 ModestEmailClipboard *clipboard = NULL;
2885 TnyFolder *src_folder = NULL;
2886 TnyFolderStore *folder_store = NULL;
2887 TnyList *data = NULL;
2888 gboolean delete = FALSE;
2890 /* Check clipboard source */
2891 clipboard = modest_runtime_get_email_clipboard ();
2892 if (modest_email_clipboard_cleared (clipboard))
2895 /* Get elements to paste */
2896 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2898 /* Create a new mail operation */
2899 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2900 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2903 /* Get destination folder */
2904 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2906 /* Launch notification */
2907 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2908 _CS("ckct_nw_pasting"));
2909 if (inf_note != NULL) {
2910 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2911 gtk_widget_show (GTK_WIDGET(inf_note));
2914 /* transfer messages */
2916 modest_mail_operation_xfer_msgs (mail_op,
2918 TNY_FOLDER (folder_store),
2923 } else if (src_folder != NULL) {
2924 modest_mail_operation_xfer_folder (mail_op,
2934 g_object_unref (data);
2935 if (src_folder != NULL)
2936 g_object_unref (src_folder);
2937 if (folder_store != NULL)
2938 g_object_unref (folder_store);
2944 modest_ui_actions_on_select_all (GtkAction *action,
2945 ModestWindow *window)
2947 GtkWidget *focused_widget;
2949 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2950 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2951 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2952 } else if (GTK_IS_LABEL (focused_widget)) {
2953 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2954 } else if (GTK_IS_EDITABLE (focused_widget)) {
2955 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2956 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2957 GtkTextBuffer *buffer;
2958 GtkTextIter start, end;
2960 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2961 gtk_text_buffer_get_start_iter (buffer, &start);
2962 gtk_text_buffer_get_end_iter (buffer, &end);
2963 gtk_text_buffer_select_range (buffer, &start, &end);
2964 } else if (GTK_IS_HTML (focused_widget)) {
2965 gtk_html_select_all (GTK_HTML (focused_widget));
2966 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2967 GtkWidget *header_view = focused_widget;
2968 GtkTreeSelection *selection = NULL;
2970 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2971 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2972 MODEST_WIDGET_TYPE_HEADER_VIEW);
2974 /* Select all messages */
2975 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2976 gtk_tree_selection_select_all (selection);
2978 /* Set focuse on header view */
2979 gtk_widget_grab_focus (header_view);
2985 modest_ui_actions_on_mark_as_read (GtkAction *action,
2986 ModestWindow *window)
2988 g_return_if_fail (MODEST_IS_WINDOW(window));
2990 /* Mark each header as read */
2991 do_headers_action (window, headers_action_mark_as_read, NULL);
2995 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2996 ModestWindow *window)
2998 g_return_if_fail (MODEST_IS_WINDOW(window));
3000 /* Mark each header as read */
3001 do_headers_action (window, headers_action_mark_as_unread, NULL);
3005 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3006 GtkRadioAction *selected,
3007 ModestWindow *window)
3011 value = gtk_radio_action_get_current_value (selected);
3012 if (MODEST_IS_WINDOW (window)) {
3013 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3017 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3018 GtkRadioAction *selected,
3019 ModestWindow *window)
3021 TnyHeaderFlags flags;
3022 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3024 flags = gtk_radio_action_get_current_value (selected);
3025 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3028 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3029 GtkRadioAction *selected,
3030 ModestWindow *window)
3034 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3036 file_format = gtk_radio_action_get_current_value (selected);
3037 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3042 modest_ui_actions_on_zoom_plus (GtkAction *action,
3043 ModestWindow *window)
3045 g_return_if_fail (MODEST_IS_WINDOW (window));
3047 modest_window_zoom_plus (MODEST_WINDOW (window));
3051 modest_ui_actions_on_zoom_minus (GtkAction *action,
3052 ModestWindow *window)
3054 g_return_if_fail (MODEST_IS_WINDOW (window));
3056 modest_window_zoom_minus (MODEST_WINDOW (window));
3060 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3061 ModestWindow *window)
3063 ModestWindowMgr *mgr;
3064 gboolean fullscreen, active;
3065 g_return_if_fail (MODEST_IS_WINDOW (window));
3067 mgr = modest_runtime_get_window_mgr ();
3069 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3070 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3072 if (active != fullscreen) {
3073 modest_window_mgr_set_fullscreen_mode (mgr, active);
3074 gtk_window_present (GTK_WINDOW (window));
3079 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3080 ModestWindow *window)
3082 ModestWindowMgr *mgr;
3083 gboolean fullscreen;
3085 g_return_if_fail (MODEST_IS_WINDOW (window));
3087 mgr = modest_runtime_get_window_mgr ();
3088 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3089 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3091 gtk_window_present (GTK_WINDOW (window));
3095 * Used by modest_ui_actions_on_details to call do_headers_action
3098 headers_action_show_details (TnyHeader *header,
3099 ModestWindow *window,
3106 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3109 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3110 gtk_widget_show_all (dialog);
3111 gtk_dialog_run (GTK_DIALOG (dialog));
3113 gtk_widget_destroy (dialog);
3117 * Show the folder details in a ModestDetailsDialog widget
3120 show_folder_details (TnyFolder *folder,
3126 dialog = modest_details_dialog_new_with_folder (window, folder);
3129 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3130 gtk_widget_show_all (dialog);
3131 gtk_dialog_run (GTK_DIALOG (dialog));
3133 gtk_widget_destroy (dialog);
3137 * Show the header details in a ModestDetailsDialog widget
3140 modest_ui_actions_on_details (GtkAction *action,
3143 TnyList * headers_list;
3147 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3150 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3153 g_object_unref (msg);
3155 headers_list = get_selected_headers (win);
3159 iter = tny_list_create_iterator (headers_list);
3161 header = TNY_HEADER (tny_iterator_get_current (iter));
3163 headers_action_show_details (header, win, NULL);
3164 g_object_unref (header);
3167 g_object_unref (iter);
3168 g_object_unref (headers_list);
3170 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3171 GtkWidget *folder_view, *header_view;
3173 /* Check which widget has the focus */
3174 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3175 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3176 if (gtk_widget_is_focus (folder_view)) {
3177 TnyFolderStore *folder_store
3178 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3179 if (!folder_store) {
3180 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3183 /* Show only when it's a folder */
3184 /* This function should not be called for account items,
3185 * because we dim the menu item for them. */
3186 if (TNY_IS_FOLDER (folder_store)) {
3187 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3190 g_object_unref (folder_store);
3193 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3194 MODEST_WIDGET_TYPE_HEADER_VIEW);
3195 /* Show details of each header */
3196 do_headers_action (win, headers_action_show_details, header_view);
3202 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3203 ModestMsgEditWindow *window)
3205 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3207 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3211 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3212 ModestMsgEditWindow *window)
3214 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3216 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3220 modest_ui_actions_toggle_folders_view (GtkAction *action,
3221 ModestMainWindow *main_window)
3223 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3225 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3226 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3228 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3232 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3233 ModestWindow *window)
3235 gboolean active, fullscreen = FALSE;
3236 ModestWindowMgr *mgr;
3238 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3240 /* Check if we want to toggle the toolbar vuew in fullscreen
3242 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3243 "ViewShowToolbarFullScreen")) {
3247 /* Toggle toolbar */
3248 mgr = modest_runtime_get_window_mgr ();
3249 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3253 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3254 ModestMsgEditWindow *window)
3256 modest_msg_edit_window_select_font (window);
3260 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3261 const gchar *display_name,
3264 /* Do not change the application name if the widget has not
3265 the focus. This callback could be called even if the folder
3266 view has not the focus, because the handled signal could be
3267 emitted when the folder view is redrawn */
3268 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3270 gtk_window_set_title (window, display_name);
3272 gtk_window_set_title (window, " ");
3277 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3279 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3280 modest_msg_edit_window_select_contacts (window);
3284 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3286 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3287 modest_msg_edit_window_check_names (window, FALSE);
3291 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3293 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3294 GTK_WIDGET (user_data));
3298 create_move_to_dialog (GtkWindow *win,
3299 GtkWidget *folder_view,
3300 GtkWidget **tree_view)
3302 GtkWidget *dialog, *scroll;
3303 GtkWidget *new_button;
3305 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3307 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3310 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3311 /* We do this manually so GTK+ does not associate a response ID for
3313 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3314 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3315 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3317 /* Create scrolled window */
3318 scroll = gtk_scrolled_window_new (NULL, NULL);
3319 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3320 GTK_POLICY_AUTOMATIC,
3321 GTK_POLICY_AUTOMATIC);
3323 /* Create folder view */
3324 *tree_view = modest_platform_create_folder_view (NULL);
3326 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3328 /* It could happen that we're trying to move a message from a
3329 window (msg window for example) after the main window was
3330 closed, so we can not just get the model of the folder
3332 if (MODEST_IS_FOLDER_VIEW (folder_view))
3333 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3334 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3336 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3337 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3339 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3341 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3343 /* Add scroll to dialog */
3344 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3345 scroll, TRUE, TRUE, 0);
3347 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3348 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3354 * Returns TRUE if at least one of the headers of the list belongs to
3355 * a message that has been fully retrieved.
3358 has_retrieved_msgs (TnyList *list)
3361 gboolean found = FALSE;
3363 iter = tny_list_create_iterator (list);
3364 while (tny_iterator_is_done (iter) && !found) {
3366 TnyHeaderFlags flags = 0;
3368 header = TNY_HEADER (tny_iterator_get_current (iter));
3370 flags = tny_header_get_flags (header);
3371 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3374 g_object_unref (header);
3378 tny_iterator_next (iter);
3380 g_object_unref (iter);
3386 * Shows a confirmation dialog to the user when we're moving messages
3387 * from a remote server to the local storage. Returns the dialog
3388 * response. If it's other kind of movement the it always returns
3392 msgs_move_to_confirmation (GtkWindow *win,
3393 TnyFolder *dest_folder,
3396 gint response = GTK_RESPONSE_OK;
3398 /* If the destination is a local folder */
3399 if (modest_tny_folder_is_local_folder (dest_folder)) {
3400 TnyFolder *src_folder = NULL;
3401 TnyIterator *iter = NULL;
3402 TnyHeader *header = NULL;
3404 /* Get source folder */
3405 iter = tny_list_create_iterator (headers);
3406 header = TNY_HEADER (tny_iterator_get_current (iter));
3408 src_folder = tny_header_get_folder (header);
3409 g_object_unref (header);
3412 g_object_unref (iter);
3414 /* if no src_folder, message may be an attahcment */
3415 if (src_folder == NULL)
3416 return GTK_RESPONSE_CANCEL;
3418 /* If the source is a remote folder */
3419 if (!modest_tny_folder_is_local_folder (src_folder)) {
3420 const gchar *message;
3422 if (has_retrieved_msgs (headers))
3423 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3424 tny_list_get_length (headers));
3426 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3427 tny_list_get_length (headers));
3429 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3430 (const gchar *) message);
3433 g_object_unref (src_folder);
3442 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3444 ModestMsgViewWindow *self = NULL;
3446 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3447 self = MODEST_MSG_VIEW_WINDOW (object);
3449 if (!modest_msg_view_window_select_next_message (self))
3450 if (!modest_msg_view_window_select_previous_message (self))
3451 /* No more messages to view, so close this window */
3452 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3456 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3459 GObject *win = modest_mail_operation_get_source (mail_op);
3460 const GError *error = NULL;
3461 const gchar *message = NULL;
3463 /* Get error message */
3464 error = modest_mail_operation_get_error (mail_op);
3465 if (error != NULL && error->message != NULL) {
3466 message = error->message;
3468 message = _("mail_in_ui_folder_move_target_error");
3471 /* Show notification dialog */
3472 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3473 g_object_unref (win);
3477 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3480 GObject *win = modest_mail_operation_get_source (mail_op);
3481 const GError *error = modest_mail_operation_get_error (mail_op);
3483 g_return_if_fail (error != NULL);
3484 if (error->message != NULL)
3485 g_printerr ("modest: %s\n", error->message);
3487 g_printerr ("modest: unkonw error on send&receive operation");
3489 /* Show error message */
3490 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3491 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3492 /* _CS("sfil_ib_unable_to_receive")); */
3494 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3495 /* _CS("sfil_ib_unable_to_send")); */
3496 g_object_unref (win);
3500 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3507 gint pending_purges = 0;
3508 gboolean some_purged = FALSE;
3509 ModestWindow *win = MODEST_WINDOW (user_data);
3510 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3512 /* If there was any error */
3513 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3514 modest_window_mgr_unregister_header (mgr, header);
3518 /* Once the message has been retrieved for purging, we check if
3519 * it's all ok for purging */
3521 parts = tny_simple_list_new ();
3522 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3523 iter = tny_list_create_iterator (parts);
3525 while (!tny_iterator_is_done (iter)) {
3527 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3528 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3529 if (tny_mime_part_is_purged (part))
3536 g_object_unref (part);
3538 tny_iterator_next (iter);
3541 if (pending_purges>0) {
3543 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3545 if (response == GTK_RESPONSE_OK) {
3546 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3547 tny_iterator_first (iter);
3548 while (!tny_iterator_is_done (iter)) {
3551 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3552 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3553 tny_mime_part_set_purged (part);
3556 g_object_unref (part);
3558 tny_iterator_next (iter);
3561 tny_msg_rewrite_cache (msg);
3564 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3567 /* remove attachments */
3568 tny_iterator_first (iter);
3569 while (!tny_iterator_is_done (iter)) {
3572 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3574 /* One for the reference given by tny_iterator_get_current(): */
3575 g_object_unref (part);
3577 /* TODO: Is this meant to remove the attachment by doing another unref()?
3578 * Otherwise, this seems useless. */
3581 tny_iterator_next (iter);
3583 modest_window_mgr_unregister_header (mgr, header);
3585 g_object_unref (iter);
3586 g_object_unref (parts);
3590 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3591 ModestMainWindow *win)
3593 GtkWidget *header_view;
3594 TnyList *header_list;
3597 TnyHeaderFlags flags;
3598 ModestWindow *msg_view_window = NULL;
3601 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3603 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3604 MODEST_WIDGET_TYPE_HEADER_VIEW);
3606 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3608 if (tny_list_get_length (header_list) == 1) {
3609 iter = tny_list_create_iterator (header_list);
3610 header = TNY_HEADER (tny_iterator_get_current (iter));
3611 g_object_unref (iter);
3616 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3617 header, &msg_view_window);
3618 flags = tny_header_get_flags (header);
3619 if (!(flags & TNY_HEADER_FLAG_CACHED))
3622 if (msg_view_window != NULL)
3623 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3625 /* do nothing; uid was registered before, so window is probably on it's way */
3626 g_warning ("debug: header %p has already been registered", header);
3629 ModestMailOperation *mail_op = NULL;
3630 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3631 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3633 modest_ui_actions_get_msgs_full_error_handler,
3635 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3636 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3638 g_object_unref (mail_op);
3641 g_object_unref (header);
3643 g_object_unref (header_list);
3647 * Utility function that transfer messages from both the main window
3648 * and the msg view window when using the "Move to" dialog
3651 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3654 TnyList *headers = NULL;
3657 if (!TNY_IS_FOLDER (dst_folder)) {
3658 modest_platform_information_banner (GTK_WIDGET (win),
3660 _CS("ckdg_ib_unable_to_move_to_current_location"));
3664 /* Get selected headers */
3665 headers = get_selected_headers (MODEST_WINDOW (win));
3667 /* Ask for user confirmation */
3668 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3669 TNY_FOLDER (dst_folder),
3672 /* Transfer messages */
3673 if (response == GTK_RESPONSE_OK) {
3674 ModestMailOperation *mail_op =
3675 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3677 modest_ui_actions_move_folder_error_handler,
3679 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3682 modest_mail_operation_xfer_msgs (mail_op,
3684 TNY_FOLDER (dst_folder),
3686 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3689 g_object_unref (G_OBJECT (mail_op));
3691 g_object_unref (headers);
3696 * UI handler for the "Move to" action when invoked from the
3700 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3701 GtkWidget *folder_view,
3702 TnyFolderStore *dst_folder,
3703 ModestMainWindow *win)
3705 GtkWidget *header_view = NULL;
3706 ModestMailOperation *mail_op = NULL;
3707 TnyFolderStore *src_folder;
3709 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3711 /* Get the source folder */
3712 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3714 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3715 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3719 /* Get header view */
3721 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3723 /* Get folder or messages to transfer */
3724 if (gtk_widget_is_focus (folder_view)) {
3726 /* Allow only to transfer folders to the local root folder */
3727 if (TNY_IS_ACCOUNT (dst_folder) &&
3728 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3731 /* Clean folder on header view before moving it */
3732 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3734 if (TNY_IS_FOLDER (src_folder)) {
3736 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3738 modest_ui_actions_move_folder_error_handler,
3740 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3743 modest_mail_operation_xfer_folder (mail_op,
3744 TNY_FOLDER (src_folder),
3747 /* Unref mail operation */
3748 g_object_unref (G_OBJECT (mail_op));
3750 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3752 } else if (gtk_widget_is_focus (header_view)) {
3753 /* Transfer messages */
3754 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3759 g_object_unref (src_folder);
3764 * UI handler for the "Move to" action when invoked from the
3765 * ModestMsgViewWindow
3768 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3769 TnyFolderStore *dst_folder,
3770 ModestMsgViewWindow *win)
3772 TnyHeader *header = NULL;
3773 TnyFolder *src_folder;
3775 /* Create header list */
3776 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3777 src_folder = tny_header_get_folder(header);
3778 g_object_unref (header);
3780 /* Transfer the message */
3781 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3782 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3784 g_object_unref (src_folder);
3788 modest_ui_actions_on_move_to (GtkAction *action,
3791 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3793 TnyFolderStore *dst_folder = NULL;
3794 ModestMainWindow *main_window;
3796 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3797 MODEST_IS_MSG_VIEW_WINDOW (win));
3799 /* Get the main window if exists */
3800 if (MODEST_IS_MAIN_WINDOW (win))
3801 main_window = MODEST_MAIN_WINDOW (win);
3804 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3806 /* Get the folder view widget if exists */
3808 folder_view = modest_main_window_get_child_widget (main_window,
3809 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3813 /* Create and run the dialog */
3814 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3815 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3816 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3817 result = gtk_dialog_run (GTK_DIALOG(dialog));
3818 g_object_ref (tree_view);
3819 gtk_widget_destroy (dialog);
3821 if (result != GTK_RESPONSE_ACCEPT)
3824 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3825 /* Offer the connection dialog if necessary: */
3826 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3829 /* Do window specific stuff */
3830 if (MODEST_IS_MAIN_WINDOW (win))
3831 modest_ui_actions_on_main_window_move_to (action,
3834 MODEST_MAIN_WINDOW (win));
3836 modest_ui_actions_on_msg_view_window_move_to (action,
3838 MODEST_MSG_VIEW_WINDOW (win));
3841 g_object_unref (dst_folder);
3845 * Calls #HeadersFunc for each header already selected in the main
3846 * window or the message currently being shown in the msg view window
3849 do_headers_action (ModestWindow *win,
3853 TnyList *headers_list = NULL;
3854 TnyIterator *iter = NULL;
3855 TnyHeader *header = NULL;
3856 TnyFolder *folder = NULL;
3859 headers_list = get_selected_headers (win);
3863 /* Get the folder */
3864 iter = tny_list_create_iterator (headers_list);
3865 header = TNY_HEADER (tny_iterator_get_current (iter));
3867 folder = tny_header_get_folder (header);
3868 g_object_unref (header);
3871 /* Call the function for each header */
3872 while (!tny_iterator_is_done (iter)) {
3873 header = TNY_HEADER (tny_iterator_get_current (iter));
3874 func (header, win, user_data);
3875 g_object_unref (header);
3876 tny_iterator_next (iter);
3879 /* Trick: do a poke status in order to speed up the signaling
3881 tny_folder_poke_status (folder);
3884 g_object_unref (folder);
3885 g_object_unref (iter);
3886 g_object_unref (headers_list);
3890 modest_ui_actions_view_attachment (GtkAction *action,
3891 ModestWindow *window)
3893 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3894 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3896 /* not supported window for this action */
3897 g_return_if_reached ();
3902 modest_ui_actions_save_attachments (GtkAction *action,
3903 ModestWindow *window)
3905 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3906 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3908 /* not supported window for this action */
3909 g_return_if_reached ();
3914 modest_ui_actions_remove_attachments (GtkAction *action,
3915 ModestWindow *window)
3917 if (MODEST_IS_MAIN_WINDOW (window)) {
3918 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3919 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3920 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3922 /* not supported window for this action */
3923 g_return_if_reached ();
3928 modest_ui_actions_on_settings (GtkAction *action,
3933 dialog = modest_platform_get_global_settings_dialog ();
3934 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3935 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3936 gtk_widget_show_all (dialog);
3938 gtk_dialog_run (GTK_DIALOG (dialog));
3940 gtk_widget_destroy (dialog);
3944 modest_ui_actions_on_help (GtkAction *action,
3947 const gchar *help_id = NULL;
3949 if (MODEST_IS_MAIN_WINDOW (win)) {
3950 const gchar *action_name;
3951 action_name = gtk_action_get_name (action);
3953 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3954 !strcmp (action_name, "HeaderViewCSMHelp")) {
3955 GtkWidget *folder_view;
3956 TnyFolderStore *folder_store;
3957 /* Get selected folder */
3958 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3959 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3960 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3962 /* Switch help_id */
3963 if (TNY_IS_FOLDER (folder_store)) {
3964 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
3965 case TNY_FOLDER_TYPE_NORMAL:
3966 help_id = "applications_email_managefolders";
3968 case TNY_FOLDER_TYPE_INBOX:
3969 help_id = "applications_email_inbox";
3971 case TNY_FOLDER_TYPE_OUTBOX:
3972 help_id = "applications_email_outbox";
3974 case TNY_FOLDER_TYPE_SENT:
3975 help_id = "applications_email_sent";
3977 case TNY_FOLDER_TYPE_DRAFTS:
3978 help_id = "applications_email_drafts";
3980 case TNY_FOLDER_TYPE_ARCHIVE:
3981 help_id = "applications_email_managefolders";
3984 help_id = "applications_email_managefolders";
3987 help_id = "applications_email_mainview";
3989 g_object_unref (folder_store);
3991 help_id = "applications_email_mainview";
3993 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3994 help_id = "applications_email_viewer";
3995 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3996 help_id = "applications_email_editor";
3998 modest_platform_show_help (GTK_WINDOW (win), help_id);
4002 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4003 ModestWindow *window)
4005 ModestMailOperation *mail_op;
4009 headers = get_selected_headers (window);
4013 /* Create mail operation */
4014 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4016 modest_ui_actions_get_msgs_full_error_handler,
4018 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4019 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4022 g_object_unref (headers);
4023 g_object_unref (mail_op);
4027 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4028 ModestWindow *window)
4030 g_return_if_fail (MODEST_IS_WINDOW (window));
4033 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4037 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4038 ModestWindow *window)
4040 g_return_if_fail (MODEST_IS_WINDOW (window));
4043 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4047 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4048 ModestWindow *window)
4050 g_return_if_fail (MODEST_IS_WINDOW (window));
4053 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4057 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4058 ModestWindow *window)
4060 g_return_if_fail (MODEST_IS_WINDOW (window));
4063 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4067 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4068 ModestWindow *window)
4070 g_return_if_fail (MODEST_IS_WINDOW (window));
4073 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4077 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4078 ModestWindow *window)
4080 g_return_if_fail (MODEST_IS_WINDOW (window));
4083 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4087 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4088 ModestWindow *window)
4090 g_return_if_fail (MODEST_IS_WINDOW (window));
4093 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4097 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4098 ModestWindow *window)
4100 g_return_if_fail (MODEST_IS_WINDOW (window));
4103 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4107 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4109 g_return_if_fail (MODEST_IS_WINDOW (window));
4112 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4116 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4118 g_return_if_fail (MODEST_IS_WINDOW (window));
4120 modest_platform_show_search_messages (GTK_WINDOW (window));
4124 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4126 g_return_if_fail (MODEST_IS_WINDOW (win));
4127 modest_platform_show_addressbook (GTK_WINDOW (win));
4132 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4133 ModestWindow *window)
4135 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4137 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4141 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4142 ModestMailOperationState *state,
4145 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4147 /* Set send/receive operation finished */
4148 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4149 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));