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;
105 * The do_headers_action uses this kind of functions to perform some
106 * action to each member of a list of headers
108 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
110 static void do_headers_action (ModestWindow *win,
114 static void open_msg_cb (ModestMailOperation *mail_op,
119 static void reply_forward_cb (ModestMailOperation *mail_op,
124 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
126 static void folder_refreshed_cb (ModestMailOperation *mail_op,
130 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
131 ModestMailOperationState *state,
137 run_account_setup_wizard (ModestWindow *win)
139 ModestEasysetupWizardDialog *wizard;
141 g_return_if_fail (MODEST_IS_WINDOW(win));
143 wizard = modest_easysetup_wizard_dialog_new ();
144 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
145 gtk_dialog_run (GTK_DIALOG (wizard));
146 gtk_widget_destroy (GTK_WIDGET (wizard));
151 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
154 const gchar *authors[] = {
155 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
158 about = gtk_about_dialog_new ();
159 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
160 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
161 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
162 _("Copyright (c) 2006, Nokia Corporation\n"
163 "All rights reserved."));
164 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
165 _("a modest e-mail client\n\n"
166 "design and implementation: Dirk-Jan C. Binnema\n"
167 "contributions from the fine people at KC and Ig\n"
168 "uses the tinymail email framework written by Philip van Hoof"));
169 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
170 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
172 gtk_dialog_run (GTK_DIALOG (about));
173 gtk_widget_destroy(about);
177 * Gets the list of currently selected messages. If the win is the
178 * main window, then it returns a newly allocated list of the headers
179 * selected in the header view. If win is the msg view window, then
180 * the value returned is a list with just a single header.
182 * The caller of this funcion must free the list.
185 get_selected_headers (ModestWindow *win)
187 if (MODEST_IS_MAIN_WINDOW(win)) {
188 GtkWidget *header_view;
190 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
191 MODEST_WIDGET_TYPE_HEADER_VIEW);
192 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
194 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
195 /* for MsgViewWindows, we simply return a list with one element */
197 TnyList *list = NULL;
199 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
200 if (header != NULL) {
201 list = tny_simple_list_new ();
202 tny_list_prepend (list, G_OBJECT(header));
203 g_object_unref (G_OBJECT(header));
213 headers_action_mark_as_read (TnyHeader *header,
217 TnyHeaderFlags flags;
219 g_return_if_fail (TNY_IS_HEADER(header));
221 flags = tny_header_get_flags (header);
222 if (flags & TNY_HEADER_FLAG_SEEN) return;
223 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
227 headers_action_mark_as_unread (TnyHeader *header,
231 TnyHeaderFlags flags;
233 g_return_if_fail (TNY_IS_HEADER(header));
235 flags = tny_header_get_flags (header);
236 if (flags & TNY_HEADER_FLAG_SEEN) {
237 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
241 /** A convenience method, because deleting a message is
242 * otherwise complicated, and it's best to change it in one place
245 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
247 ModestMailOperation *mail_op = NULL;
248 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
249 win ? G_OBJECT(win) : NULL);
250 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
253 /* Always delete. TODO: Move to trash still not supported */
254 modest_mail_operation_remove_msg (mail_op, header, FALSE);
255 g_object_unref (G_OBJECT (mail_op));
259 headers_action_delete (TnyHeader *header,
263 modest_do_message_delete (header, win);
265 /* refilter treemodel to hide marked-as-deleted rows */
266 /* if (MODEST_IS_HEADER_VIEW (user_data)) */
267 /* modest_header_view_refilter (MODEST_HEADER_VIEW (user_data)); */
270 /** After deleing a message that is currently visible in a window,
271 * show the next message from the list, or close the window if there are no more messages.
273 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
275 /* Close msg view window or select next */
276 if (modest_msg_view_window_last_message_selected (win) &&
277 modest_msg_view_window_first_message_selected (win)) {
278 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
280 modest_msg_view_window_select_next_message (win);
285 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
287 TnyList *header_list = NULL;
288 TnyIterator *iter = NULL;
289 TnyHeader *header = NULL;
290 gchar *message = NULL;
293 ModestWindowMgr *mgr;
294 GtkWidget *header_view = NULL;
296 g_return_if_fail (MODEST_IS_WINDOW(win));
298 /* Check first if the header view has the focus */
299 if (MODEST_IS_MAIN_WINDOW (win)) {
301 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
302 MODEST_WIDGET_TYPE_HEADER_VIEW);
303 if (!gtk_widget_is_focus (header_view))
307 header_list = get_selected_headers (win);
308 if (!header_list) return;
310 /* Check if any of the headers are already opened, or in the process of being opened */
311 if (MODEST_IS_MAIN_WINDOW (win)) {
313 iter = tny_list_create_iterator (header_list);
315 mgr = modest_runtime_get_window_mgr ();
316 while (!tny_iterator_is_done (iter) && !found) {
317 header = TNY_HEADER (tny_iterator_get_current (iter));
319 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
320 g_object_unref (header);
323 tny_iterator_next (iter);
325 g_object_unref (iter);
330 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
331 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
333 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
337 g_object_unref (header_list);
343 if (tny_list_get_length(header_list) == 1) {
344 iter = tny_list_create_iterator (header_list);
345 header = TNY_HEADER (tny_iterator_get_current (iter));
347 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
348 g_object_unref (header);
351 g_object_unref (iter);
353 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
354 tny_list_get_length(header_list)), desc);
356 /* Confirmation dialog */
357 printf("DEBUG: %s\n", __FUNCTION__);
358 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
362 if (response == GTK_RESPONSE_OK) {
363 ModestWindow *main_window = NULL;
364 ModestWindowMgr *mgr = NULL;
365 GtkTreeModel *model = NULL;
366 GtkTreeSelection *sel = NULL;
367 GList *sel_list = NULL, *tmp = NULL;
368 GtkTreeRowReference *row_reference = NULL;
369 GtkTreePath *next_path = NULL;
371 /* Find last selected row */
372 if (MODEST_IS_MAIN_WINDOW (win)) {
373 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
374 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
375 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
376 for (tmp=sel_list; tmp; tmp=tmp->next) {
377 if (tmp->next == NULL) {
378 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
379 gtk_tree_path_next (next_path);
380 row_reference = gtk_tree_row_reference_new (model, next_path);
381 gtk_tree_path_free (next_path);
386 /* Remove each header. If it's a view window header_view == NULL */
387 do_headers_action (win, headers_action_delete, header_view);
389 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
390 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
392 /* Get main window */
393 mgr = modest_runtime_get_window_mgr ();
394 main_window = modest_window_mgr_get_main_window (mgr);
397 /* Move cursor to next row */
400 /* Select next row */
401 if (gtk_tree_row_reference_valid (row_reference)) {
402 next_path = gtk_tree_row_reference_get_path (row_reference);
403 gtk_tree_selection_select_path (sel, next_path);
404 gtk_tree_path_free (next_path);
406 if (row_reference != NULL)
407 gtk_tree_row_reference_free (row_reference);
410 /* Update toolbar dimming state */
411 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
414 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
415 g_list_free (sel_list);
421 g_object_unref (header_list);
427 /* delete either message or folder, based on where we are */
429 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
431 g_return_if_fail (MODEST_IS_WINDOW(win));
433 /* Check first if the header view has the focus */
434 if (MODEST_IS_MAIN_WINDOW (win)) {
436 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
437 MODEST_WIDGET_TYPE_FOLDER_VIEW);
438 if (gtk_widget_is_focus (w)) {
439 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
443 modest_ui_actions_on_delete_message (action, win);
449 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
451 #ifdef MODEST_PLATFORM_MAEMO
452 modest_osso_save_state();
453 #endif /* MODEST_PLATFORM_MAEMO */
455 g_debug ("closing down, clearing %d item(s) from operation queue",
456 modest_mail_operation_queue_num_elements
457 (modest_runtime_get_mail_operation_queue()));
459 /* cancel all outstanding operations */
460 modest_mail_operation_queue_cancel_all
461 (modest_runtime_get_mail_operation_queue());
463 g_debug ("queue has been cleared");
465 /* note: when modest-tny-account-store is finalized,
466 it will automatically set all network connections
473 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
477 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
479 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
480 /* gtk_widget_destroy (GTK_WIDGET (win)); */
481 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
482 /* gboolean ret_value; */
483 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
484 /* } else if (MODEST_IS_WINDOW (win)) { */
485 /* gtk_widget_destroy (GTK_WIDGET (win)); */
487 /* g_return_if_reached (); */
492 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
494 GtkClipboard *clipboard = NULL;
495 gchar *selection = NULL;
497 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
498 selection = gtk_clipboard_wait_for_text (clipboard);
500 /* Question: why is the clipboard being used here?
501 * It doesn't really make a lot of sense. */
505 modest_address_book_add_address (selection);
511 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
513 /* This is currently only implemented for Maemo */
514 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
515 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
516 run_account_setup_wizard (win);
519 /* Show the list of accounts: */
520 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
521 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
524 GtkWidget *dialog, *label;
526 /* Create the widgets */
528 dialog = gtk_dialog_new_with_buttons ("Message",
530 GTK_DIALOG_DESTROY_WITH_PARENT,
534 label = gtk_label_new ("Hello World!");
536 /* Ensure that the dialog box is destroyed when the user responds. */
538 g_signal_connect_swapped (dialog, "response",
539 G_CALLBACK (gtk_widget_destroy),
542 /* Add the label, and show everything we've added to the dialog. */
544 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
546 gtk_widget_show_all (dialog);
547 #endif /* MODEST_PLATFORM_MAEMO */
551 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
553 ModestWindow *main_window = MODEST_WINDOW (user_data);
555 /* Save any changes. */
556 modest_connection_specific_smtp_window_save_server_accounts (
557 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
558 modest_window_get_active_account (main_window));
559 gtk_widget_destroy (GTK_WIDGET (window));
565 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
567 /* This is currently only implemented for Maemo,
568 * because it requires an API (libconic) to detect different connection
571 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
573 /* Create the window if necessary: */
574 const gchar *active_account_name = modest_window_get_active_account (win);
576 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
577 * or show the default account?
578 * If we show the default account then the account name should be shown in
579 * the window when we show it. */
580 if (!active_account_name) {
581 g_warning ("%s: No account is active.", __FUNCTION__);
585 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
586 modest_connection_specific_smtp_window_fill_with_connections (
587 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
588 modest_runtime_get_account_mgr(),
589 active_account_name);
591 /* Show the window: */
592 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
593 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
594 gtk_widget_show (specific_window);
596 /* Save changes when the window is hidden: */
597 g_signal_connect (specific_window, "hide",
598 G_CALLBACK (on_smtp_servers_window_hide), win);
599 #endif /* MODEST_PLATFORM_MAEMO */
603 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
605 ModestWindow *msg_win = NULL;
607 TnyFolder *folder = NULL;
608 gchar *account_name = NULL;
609 gchar *from_str = NULL;
610 /* GError *err = NULL; */
611 TnyAccount *account = NULL;
612 ModestWindowMgr *mgr;
613 gchar *signature = NULL, *blank_and_signature = NULL;
615 /* if there are no accounts yet, just show the wizard */
616 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
617 run_account_setup_wizard (win);
621 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
623 account_name = g_strdup (modest_window_get_active_account (win));
625 g_printerr ("modest: no account found\n");
629 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
631 TNY_ACCOUNT_TYPE_STORE);
633 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
637 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
639 g_printerr ("modest: failed get from string for '%s'\n", account_name);
643 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
644 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
645 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
646 MODEST_ACCOUNT_SIGNATURE, FALSE);
647 blank_and_signature = g_strconcat ("\n", signature, NULL);
650 blank_and_signature = g_strdup ("");
653 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
655 g_printerr ("modest: failed to create new msg\n");
659 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
661 g_printerr ("modest: failed to find Drafts folder\n");
666 /* Create and register edit window */
667 /* This is destroyed by TOOD. */
668 msg_win = modest_msg_edit_window_new (msg, account_name);
669 mgr = modest_runtime_get_window_mgr ();
670 modest_window_mgr_register_window (mgr, msg_win);
673 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
675 gtk_widget_show_all (GTK_WIDGET (msg_win));
678 g_free (account_name);
680 g_free (blank_and_signature);
682 g_object_unref (msg_win);
684 g_object_unref (G_OBJECT(account));
686 g_object_unref (G_OBJECT(msg));
688 g_object_unref (G_OBJECT(folder));
692 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
696 ModestMailOperationStatus status;
698 /* If there is no message or the operation was not successful */
699 status = modest_mail_operation_get_status (mail_op);
700 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
702 /* Remove the header from the preregistered uids */
703 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
713 open_msg_cb (ModestMailOperation *mail_op,
718 ModestWindowMgr *mgr = NULL;
719 ModestWindow *parent_win = NULL;
720 ModestWindow *win = NULL;
721 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
722 gchar *account = NULL;
725 /* Do nothing if there was any problem with the mail
726 operation. The error will be shown by the error_handler of
727 the mail operation */
728 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
732 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
733 folder = tny_header_get_folder (header);
735 /* Mark header as read */
736 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
739 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
741 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
743 /* Gets folder type (OUTBOX headers will be opened in edit window */
744 if (modest_tny_folder_is_local_folder (folder))
745 folder_type = modest_tny_folder_get_local_folder_type (folder);
747 /* If the header is in the drafts folder then open the editor,
748 else the message view window */
749 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
750 /* we cannot edit without a valid account... */
751 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
752 run_account_setup_wizard(parent_win);
755 win = modest_msg_edit_window_new (msg, account);
757 gchar *uid = modest_tny_folder_get_header_unique_id (header);
759 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
760 GtkWidget *header_view;
761 GtkTreeSelection *sel;
762 GList *sel_list = NULL;
765 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
766 MODEST_WIDGET_TYPE_HEADER_VIEW);
768 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
769 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
771 if (sel_list != NULL) {
772 GtkTreeRowReference *row_reference;
774 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
775 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
776 g_list_free (sel_list);
778 win = modest_msg_view_window_new_with_header_model (msg,
783 gtk_tree_row_reference_free (row_reference);
785 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
788 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
793 /* Register and show new window */
795 mgr = modest_runtime_get_window_mgr ();
796 modest_window_mgr_register_window (mgr, win);
797 g_object_unref (win);
798 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
799 gtk_widget_show_all (GTK_WIDGET(win));
802 /* Update toolbar dimming state */
803 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
804 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
810 g_object_unref (parent_win);
811 g_object_unref (folder);
815 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
819 GObject *win = modest_mail_operation_get_source (mail_op);
821 error = modest_mail_operation_get_error (mail_op);
822 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
824 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
826 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
829 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
830 _("mail_ni_ui_folder_get_msg_folder_error"));
834 g_object_unref (win);
838 * This function is used by both modest_ui_actions_on_open and
839 * modest_ui_actions_on_header_activated. This way we always do the
840 * same when trying to open messages.
843 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
845 ModestWindowMgr *mgr = NULL;
846 TnyIterator *iter = NULL;
847 ModestMailOperation *mail_op1 = NULL;
848 ModestMailOperation *mail_op2 = NULL;
849 TnyList *not_opened_headers = NULL;
850 TnyList *not_opened_cached_headers = NULL;
851 TnyHeaderFlags flags = 0;
853 /* Look if we already have a message view for each header. If
854 true, then remove the header from the list of headers to
856 mgr = modest_runtime_get_window_mgr ();
857 iter = tny_list_create_iterator (headers);
858 not_opened_headers = tny_simple_list_new ();
859 not_opened_cached_headers = tny_simple_list_new ();
860 while (!tny_iterator_is_done (iter)) {
862 ModestWindow *window = NULL;
863 TnyHeader *header = NULL;
864 gboolean found = FALSE;
866 header = TNY_HEADER (tny_iterator_get_current (iter));
868 flags = tny_header_get_flags (header);
871 found = modest_window_mgr_find_registered_header (mgr, header, &window);
873 /* Do not open again the message and present the
874 window to the user */
877 gtk_window_present (GTK_WINDOW (window));
879 /* the header has been registered already, we don't do
880 * anything but wait for the window to come up*/
881 g_warning ("debug: header %p already registered, waiting for window",
884 if (!(flags & TNY_HEADER_FLAG_CACHED))
885 tny_list_append (not_opened_headers, G_OBJECT (header));
886 /* Check if msg has already been retreived */
888 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
892 g_object_unref (header);
894 tny_iterator_next (iter);
896 g_object_unref (iter);
899 /* If some messages would have to be downloaded, ask the user to
900 * make a connection. It's generally easier to do this here (in the mainloop)
901 * than later in a thread:
903 if (tny_list_get_length (not_opened_cached_headers) > 0) {
904 gboolean connected = modest_platform_connect_and_wait (GTK_WINDOW (win), NULL);
906 /* Don't go further if a connection would be necessary but none is available: */
908 g_object_unref (not_opened_headers);
909 g_object_unref (not_opened_cached_headers);
914 /* Register the headers before actually creating the windows: */
915 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
916 while (!tny_iterator_is_done (iter_not_opened)) {
917 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
919 modest_window_mgr_register_header (mgr, header);
920 g_object_unref (header);
923 tny_iterator_next (iter_not_opened);
925 g_object_unref (iter_not_opened);
926 iter_not_opened = NULL;
928 TnyIterator *iter_cached = tny_list_create_iterator (not_opened_cached_headers);
929 while (!tny_iterator_is_done (iter_cached)) {
930 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_cached));
932 modest_window_mgr_register_header (mgr, header);
933 g_object_unref (header);
936 tny_iterator_next (iter_cached);
938 g_object_unref (iter_cached);
942 /* Open each uncached message */
943 if (tny_list_get_length (not_opened_headers) > 0) {
944 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
946 modest_ui_actions_get_msgs_full_error_handler,
948 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
949 if (tny_list_get_length (not_opened_headers) > 1) {
950 modest_mail_operation_get_msgs_full (mail_op1,
956 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
957 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
959 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
960 g_object_unref (header);
963 g_object_unref (iter);
967 /* Open each cached message */
968 if (tny_list_get_length (not_opened_cached_headers) > 0) {
969 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
971 modest_ui_actions_get_msgs_full_error_handler,
973 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
974 if (tny_list_get_length (not_opened_cached_headers) > 1) {
975 modest_mail_operation_get_msgs_full (mail_op2,
981 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
982 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
984 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
985 g_object_unref (header);
988 g_object_unref (iter);
993 if (not_opened_headers != NULL)
994 g_object_unref (not_opened_headers);
995 if (not_opened_cached_headers != NULL)
996 g_object_unref (not_opened_cached_headers);
998 g_object_unref (iter);
999 if (mail_op1 != NULL)
1000 g_object_unref (mail_op1);
1001 if (mail_op2 != NULL)
1002 g_object_unref (mail_op2);
1006 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1011 headers = get_selected_headers (win);
1016 _modest_ui_actions_open (headers, win);
1018 g_object_unref(headers);
1023 free_reply_forward_helper (gpointer data)
1025 ReplyForwardHelper *helper;
1027 helper = (ReplyForwardHelper *) data;
1028 g_free (helper->account_name);
1029 g_slice_free (ReplyForwardHelper, helper);
1033 reply_forward_cb (ModestMailOperation *mail_op,
1039 ReplyForwardHelper *rf_helper;
1040 ModestWindow *msg_win = NULL;
1041 ModestEditType edit_type;
1043 TnyAccount *account = NULL;
1044 ModestWindowMgr *mgr = NULL;
1045 gchar *signature = NULL;
1047 /* If there was any error. The mail operation could be NULL,
1048 this means that we already have the message downloaded and
1049 that we didn't do a mail operation to retrieve it */
1050 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1053 g_return_if_fail (user_data != NULL);
1054 rf_helper = (ReplyForwardHelper *) user_data;
1056 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1057 rf_helper->account_name);
1058 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1059 rf_helper->account_name,
1060 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1061 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1062 rf_helper->account_name,
1063 MODEST_ACCOUNT_SIGNATURE, FALSE);
1066 /* Create reply mail */
1067 switch (rf_helper->action) {
1070 modest_tny_msg_create_reply_msg (msg, from, signature,
1071 rf_helper->reply_forward_type,
1072 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1074 case ACTION_REPLY_TO_ALL:
1076 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
1077 MODEST_TNY_MSG_REPLY_MODE_ALL);
1078 edit_type = MODEST_EDIT_TYPE_REPLY;
1080 case ACTION_FORWARD:
1082 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1083 edit_type = MODEST_EDIT_TYPE_FORWARD;
1086 g_return_if_reached ();
1093 g_printerr ("modest: failed to create message\n");
1097 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1098 rf_helper->account_name,
1099 TNY_ACCOUNT_TYPE_STORE);
1101 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1105 /* Create and register the windows */
1106 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
1107 mgr = modest_runtime_get_window_mgr ();
1108 modest_window_mgr_register_window (mgr, msg_win);
1110 if (rf_helper->parent_window != NULL) {
1111 gdouble parent_zoom;
1113 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1114 modest_window_set_zoom (msg_win, parent_zoom);
1117 /* Show edit window */
1118 gtk_widget_show_all (GTK_WIDGET (msg_win));
1122 g_object_unref (msg_win);
1124 g_object_unref (G_OBJECT (new_msg));
1126 g_object_unref (G_OBJECT (account));
1127 /* g_object_unref (msg); */
1128 g_object_unref (header);
1129 free_reply_forward_helper (rf_helper);
1133 * Checks a list of headers. If any of them are not currently
1134 * downloaded (CACHED) then it asks the user for permission to
1137 * Returns FALSE if the user does not want to download the
1138 * messages. Returns TRUE if the user allowed the download or if all
1139 * of them are currently downloaded
1142 download_uncached_messages (TnyList *header_list, GtkWindow *win,
1147 gint uncached_messages = 0;
1149 iter = tny_list_create_iterator (header_list);
1150 while (!tny_iterator_is_done (iter)) {
1152 TnyHeaderFlags flags;
1154 header = TNY_HEADER (tny_iterator_get_current (iter));
1156 flags = tny_header_get_flags (header);
1157 /* TODO: is this the right flag?, it seems that some
1158 headers that have been previously downloaded do not
1160 if (! (flags & TNY_HEADER_FLAG_CACHED))
1161 uncached_messages ++;
1162 g_object_unref (header);
1165 tny_iterator_next (iter);
1167 g_object_unref (iter);
1169 /* Ask for user permission to download the messages */
1171 if (uncached_messages > 0) {
1172 GtkResponseType response;
1174 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1175 _("emev_nc_include_original"));
1178 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1179 ngettext("mcen_nc_get_msg",
1181 uncached_messages));
1182 if (response == GTK_RESPONSE_CANCEL)
1185 /* If a download will be necessary, make sure that we have a connection: */
1186 retval = modest_platform_connect_and_wait(win, NULL);
1194 * Common code for the reply and forward actions
1197 reply_forward (ReplyForwardAction action, ModestWindow *win)
1199 ModestMailOperation *mail_op = NULL;
1200 TnyList *header_list = NULL;
1201 ReplyForwardHelper *rf_helper = NULL;
1202 guint reply_forward_type;
1203 gboolean continue_download;
1205 g_return_if_fail (MODEST_IS_WINDOW(win));
1207 /* we need an account when editing */
1208 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1209 run_account_setup_wizard (win);
1213 header_list = get_selected_headers (win);
1217 /* Check that the messages have been previously downloaded */
1218 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1219 if (!continue_download) {
1220 g_object_unref (header_list);
1224 reply_forward_type =
1225 modest_conf_get_int (modest_runtime_get_conf (),
1226 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1228 /* We assume that we can only select messages of the
1229 same folder and that we reply all of them from the
1230 same account. In fact the interface currently only
1231 allows single selection */
1234 rf_helper = g_slice_new0 (ReplyForwardHelper);
1235 rf_helper->reply_forward_type = reply_forward_type;
1236 rf_helper->action = action;
1237 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1239 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1240 rf_helper->parent_window = GTK_WIDGET (win);
1241 if (!rf_helper->account_name)
1242 rf_helper->account_name =
1243 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1245 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1248 /* Get header and message. Do not free them here, the
1249 reply_forward_cb must do it */
1250 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1251 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1252 if (!msg || !header) {
1254 g_object_unref (msg);
1256 g_object_unref (header);
1257 g_printerr ("modest: no message found\n");
1260 reply_forward_cb (NULL, header, msg, rf_helper);
1266 /* Retrieve messages */
1267 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1269 modest_ui_actions_get_msgs_full_error_handler,
1271 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1273 /* Only reply/forward to one message */
1274 iter = tny_list_create_iterator (header_list);
1275 header = TNY_HEADER (tny_iterator_get_current (iter));
1276 g_object_unref (iter);
1279 modest_mail_operation_get_msg (mail_op,
1284 /* modest_mail_operation_get_msgs_full (mail_op, */
1286 /* reply_forward_cb, */
1288 /* free_reply_forward_helper); */
1290 g_object_unref (header);
1294 g_object_unref(mail_op);
1298 g_object_unref (header_list);
1302 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1304 g_return_if_fail (MODEST_IS_WINDOW(win));
1306 reply_forward (ACTION_REPLY, win);
1310 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1312 g_return_if_fail (MODEST_IS_WINDOW(win));
1314 reply_forward (ACTION_FORWARD, win);
1318 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1320 g_return_if_fail (MODEST_IS_WINDOW(win));
1322 reply_forward (ACTION_REPLY_TO_ALL, win);
1326 modest_ui_actions_on_next (GtkAction *action,
1327 ModestWindow *window)
1329 if (MODEST_IS_MAIN_WINDOW (window)) {
1330 GtkWidget *header_view;
1332 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1333 MODEST_WIDGET_TYPE_HEADER_VIEW);
1337 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1338 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1339 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1341 g_return_if_reached ();
1346 modest_ui_actions_on_prev (GtkAction *action,
1347 ModestWindow *window)
1349 g_return_if_fail (MODEST_IS_WINDOW(window));
1351 if (MODEST_IS_MAIN_WINDOW (window)) {
1352 GtkWidget *header_view;
1353 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1354 MODEST_WIDGET_TYPE_HEADER_VIEW);
1358 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1359 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1360 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1362 g_return_if_reached ();
1367 modest_ui_actions_on_sort (GtkAction *action,
1368 ModestWindow *window)
1370 g_return_if_fail (MODEST_IS_WINDOW(window));
1372 if (MODEST_IS_MAIN_WINDOW (window)) {
1373 GtkWidget *header_view;
1374 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1375 MODEST_WIDGET_TYPE_HEADER_VIEW);
1377 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1382 /* Show sorting dialog */
1383 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1388 new_messages_arrived (ModestMailOperation *self,
1392 if (new_messages == 0)
1395 modest_platform_on_new_msg ();
1399 * This function performs the send & receive required actions. The
1400 * window is used to create the mail operation. Typically it should
1401 * always be the main window, but we pass it as argument in order to
1405 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1407 gchar *acc_name = NULL;
1408 ModestMailOperation *mail_op;
1410 /* If no account name was provided then get the current account, and if
1411 there is no current account then pick the default one: */
1412 if (!account_name) {
1413 acc_name = g_strdup (modest_window_get_active_account(win));
1415 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1417 g_printerr ("modest: cannot get default account\n");
1421 acc_name = g_strdup (account_name);
1424 /* Set send/receive operation in progress */
1425 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1427 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1429 modest_ui_actions_send_receive_error_handler,
1432 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1433 G_CALLBACK (_on_send_receive_progress_changed),
1436 /* Send & receive. */
1437 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1438 /* Receive and then send. The operation is tagged initially as
1439 a receive operation because the account update performs a
1440 receive and then a send. The operation changes its type
1441 internally, so the progress objects will receive the proper
1442 progress information */
1443 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1444 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1445 g_object_unref (G_OBJECT (mail_op));
1453 modest_ui_actions_do_cancel_send (const gchar *account_name,
1456 TnyTransportAccount *transport_account;
1457 TnySendQueue *send_queue = NULL;
1458 GError *error = NULL;
1460 /* Get transport account */
1462 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1463 (modest_runtime_get_account_store(),
1465 TNY_ACCOUNT_TYPE_TRANSPORT));
1466 if (!transport_account) {
1467 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1472 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1473 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1474 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1475 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1476 "modest: could not find send queue for account\n");
1478 /* Keeep messages in outbox folder */
1479 tny_send_queue_cancel (send_queue, FALSE, &error);
1483 if (transport_account != NULL)
1484 g_object_unref (G_OBJECT (transport_account));
1488 modest_ui_actions_cancel_send_all (ModestWindow *win)
1490 GSList *account_names, *iter;
1492 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1495 iter = account_names;
1497 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1498 iter = g_slist_next (iter);
1501 modest_account_mgr_free_account_names (account_names);
1502 account_names = NULL;
1506 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1509 /* Check if accounts exist */
1510 gboolean accounts_exist =
1511 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1513 /* If not, allow the user to create an account before trying to send/receive. */
1514 if (!accounts_exist)
1515 modest_ui_actions_on_accounts (NULL, win);
1517 /* Cancel all sending operaitons */
1518 modest_ui_actions_cancel_send_all (win);
1522 * Refreshes all accounts. This function will be used by automatic
1526 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1528 GSList *account_names, *iter;
1530 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1533 iter = account_names;
1535 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1536 iter = g_slist_next (iter);
1539 modest_account_mgr_free_account_names (account_names);
1540 account_names = NULL;
1544 * Handler of the click on Send&Receive button in the main toolbar
1547 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1549 /* Check if accounts exist */
1550 gboolean accounts_exist =
1551 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1553 /* If not, allow the user to create an account before trying to send/receive. */
1554 if (!accounts_exist)
1555 modest_ui_actions_on_accounts (NULL, win);
1557 /* Refresh currently selected folder. Note that if we only
1558 want to retrive the headers, then the refresh only will
1559 invoke a poke_status over all folders, i.e., only the
1560 total/unread count will be updated */
1561 if (MODEST_IS_MAIN_WINDOW (win)) {
1562 GtkWidget *header_view, *folder_view;
1563 TnyFolderStore *folder_store;
1565 /* Get folder and header view */
1567 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1568 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1570 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1572 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1574 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1575 MODEST_WIDGET_TYPE_HEADER_VIEW);
1577 /* We do not need to set the contents style
1578 because it hasn't changed. We also do not
1579 need to save the widget status. Just force
1581 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1582 TNY_FOLDER (folder_store),
1583 folder_refreshed_cb,
1584 MODEST_MAIN_WINDOW (win));
1588 g_object_unref (folder_store);
1591 /* Refresh the active account */
1592 modest_ui_actions_do_send_receive (NULL, win);
1597 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1600 GtkWidget *header_view;
1602 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1604 header_view = modest_main_window_get_child_widget (main_window,
1605 MODEST_WIDGET_TYPE_HEADER_VIEW);
1609 conf = modest_runtime_get_conf ();
1611 /* what is saved/restored is depending on the style; thus; we save with
1612 * old style, then update the style, and restore for this new style
1614 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1616 if (modest_header_view_get_style
1617 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1618 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1619 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1621 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1622 MODEST_HEADER_VIEW_STYLE_DETAILS);
1624 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1625 MODEST_CONF_HEADER_VIEW_KEY);
1630 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1632 ModestMainWindow *main_window)
1634 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1635 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1637 /* If no header has been selected then exit */
1642 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1643 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1645 /* Update Main window title */
1646 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1647 const gchar *subject = tny_header_get_subject (header);
1648 if (subject && strlen(subject) > 0)
1649 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1651 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1654 /* Update toolbar dimming state */
1655 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1659 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1661 ModestMainWindow *main_window)
1665 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1670 headers = tny_simple_list_new ();
1671 tny_list_prepend (headers, G_OBJECT (header));
1673 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1675 g_object_unref (headers);
1679 set_active_account_from_tny_account (TnyAccount *account,
1680 ModestWindow *window)
1682 const gchar *server_acc_name = tny_account_get_id (account);
1684 /* We need the TnyAccount provided by the
1685 account store because that is the one that
1686 knows the name of the Modest account */
1687 TnyAccount *modest_server_account = modest_server_account =
1688 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1689 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1692 const gchar *modest_acc_name =
1693 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1694 modest_window_set_active_account (window, modest_acc_name);
1695 g_object_unref (modest_server_account);
1700 folder_refreshed_cb (ModestMailOperation *mail_op,
1704 ModestMainWindow *win = NULL;
1705 GtkWidget *header_view;
1706 TnyFolder *current_folder;
1708 g_return_if_fail (TNY_IS_FOLDER (folder));
1710 win = MODEST_MAIN_WINDOW (user_data);
1712 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1715 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1716 if (current_folder != NULL && folder != current_folder) {
1721 /* Check if folder is empty and set headers view contents style */
1722 if (tny_folder_get_all_count (folder) == 0) {
1723 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1724 modest_main_window_set_contents_style (win,
1725 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1727 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1732 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1733 TnyFolderStore *folder_store,
1735 ModestMainWindow *main_window)
1738 GtkWidget *header_view;
1740 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1742 header_view = modest_main_window_get_child_widget(main_window,
1743 MODEST_WIDGET_TYPE_HEADER_VIEW);
1747 conf = modest_runtime_get_conf ();
1749 if (TNY_IS_ACCOUNT (folder_store)) {
1751 /* Update active account */
1752 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1753 /* Show account details */
1754 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1757 if (TNY_IS_FOLDER (folder_store) && selected) {
1759 /* Update the active account */
1760 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1762 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1763 g_object_unref (account);
1767 /* Set the header style by default, it could
1768 be changed later by the refresh callback to
1770 modest_main_window_set_contents_style (main_window,
1771 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1773 /* Set folder on header view. This function
1774 will call tny_folder_refresh_async so we
1775 pass a callback that will be called when
1776 finished. We use that callback to set the
1777 empty view if there are no messages */
1778 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1779 TNY_FOLDER (folder_store),
1780 folder_refreshed_cb,
1783 /* Restore configuration. We need to do this
1784 *after* the set_folder because the widget
1785 memory asks the header view about its
1787 modest_widget_memory_restore (modest_runtime_get_conf (),
1788 G_OBJECT(header_view),
1789 MODEST_CONF_HEADER_VIEW_KEY);
1791 /* Update the active account */
1792 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1793 /* Save only if we're seeing headers */
1794 if (modest_main_window_get_contents_style (main_window) ==
1795 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1796 modest_widget_memory_save (conf, G_OBJECT (header_view),
1797 MODEST_CONF_HEADER_VIEW_KEY);
1798 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1802 /* Update toolbar dimming state */
1803 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1807 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1814 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1816 online = tny_device_is_online (modest_runtime_get_device());
1819 /* already online -- the item is simply not there... */
1820 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1822 GTK_MESSAGE_WARNING,
1824 _("The %s you selected cannot be found"),
1826 gtk_dialog_run (GTK_DIALOG(dialog));
1828 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1832 GTK_RESPONSE_REJECT,
1834 GTK_RESPONSE_ACCEPT,
1836 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1837 "Do you want to get online?"), item);
1838 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1839 gtk_label_new (txt), FALSE, FALSE, 0);
1840 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1843 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1844 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1845 // modest_platform_connect_and_wait ();
1848 gtk_widget_destroy (dialog);
1852 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1855 /* g_message ("%s %s", __FUNCTION__, link); */
1860 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1863 modest_platform_activate_uri (link);
1867 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1870 modest_platform_show_uri_popup (link);
1874 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1877 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1881 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1882 const gchar *address,
1885 /* g_message ("%s %s", __FUNCTION__, address); */
1889 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1891 TnyTransportAccount *transport_account;
1892 ModestMailOperation *mail_operation;
1894 gchar *account_name, *from;
1895 ModestAccountMgr *account_mgr;
1896 gchar *info_text = NULL;
1898 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1900 data = modest_msg_edit_window_get_msg_data (edit_window);
1902 account_mgr = modest_runtime_get_account_mgr();
1903 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1905 account_name = modest_account_mgr_get_default_account (account_mgr);
1906 if (!account_name) {
1907 g_printerr ("modest: no account found\n");
1908 modest_msg_edit_window_free_msg_data (edit_window, data);
1912 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1913 account_name = g_strdup (data->account_name);
1917 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1918 (modest_runtime_get_account_store(),
1920 TNY_ACCOUNT_TYPE_TRANSPORT));
1921 if (!transport_account) {
1922 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1923 g_free (account_name);
1924 modest_msg_edit_window_free_msg_data (edit_window, data);
1927 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1929 /* Create the mail operation */
1930 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1931 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1933 modest_mail_operation_save_to_drafts (mail_operation,
1945 data->priority_flags);
1948 g_free (account_name);
1949 g_object_unref (G_OBJECT (transport_account));
1950 g_object_unref (G_OBJECT (mail_operation));
1952 modest_msg_edit_window_free_msg_data (edit_window, data);
1954 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1955 modest_platform_information_banner (NULL, NULL, info_text);
1959 /* For instance, when clicking the Send toolbar button when editing a message: */
1961 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1963 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1965 if (!modest_msg_edit_window_check_names (edit_window))
1968 /* Offer the connection dialog, if necessary: */
1969 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
1972 /* FIXME: Code added just for testing. The final version will
1973 use the send queue provided by tinymail and some
1975 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1976 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1978 account_name = modest_account_mgr_get_default_account (account_mgr);
1980 if (!account_name) {
1981 g_printerr ("modest: no account found\n");
1985 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1987 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1988 account_name = g_strdup (data->account_name);
1991 /* Get the currently-active transport account for this modest account: */
1992 TnyTransportAccount *transport_account =
1993 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1994 (modest_runtime_get_account_store(),
1996 if (!transport_account) {
1997 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1998 g_free (account_name);
1999 modest_msg_edit_window_free_msg_data (edit_window, data);
2003 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2005 /* mail content checks and dialogs */
2006 if (data->subject == NULL || data->subject[0] == '\0') {
2007 GtkResponseType response;
2008 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2009 _("mcen_nc_subject_is_empty_send"));
2010 if (response == GTK_RESPONSE_CANCEL) {
2011 g_free (account_name);
2016 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2017 GtkResponseType response;
2018 gchar *note_message;
2019 gchar *note_subject = data->subject;
2020 if (note_subject == NULL || note_subject[0] == '\0')
2021 note_subject = _("mail_va_no_subject");
2022 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2023 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2025 g_free (note_message);
2026 if (response == GTK_RESPONSE_CANCEL) {
2027 g_free (account_name);
2032 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2034 /* Create the mail operation */
2035 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2036 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2038 modest_mail_operation_send_new_mail (mail_operation,
2049 data->priority_flags);
2053 g_free (account_name);
2054 g_object_unref (G_OBJECT (transport_account));
2055 g_object_unref (G_OBJECT (mail_operation));
2057 modest_msg_edit_window_free_msg_data (edit_window, data);
2058 modest_msg_edit_window_set_sent (edit_window, TRUE);
2060 /* Save settings and close the window: */
2061 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2065 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2066 ModestMsgEditWindow *window)
2068 ModestMsgEditFormatState *format_state = NULL;
2070 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2071 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2073 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2076 format_state = modest_msg_edit_window_get_format_state (window);
2077 g_return_if_fail (format_state != NULL);
2079 format_state->bold = gtk_toggle_action_get_active (action);
2080 modest_msg_edit_window_set_format_state (window, format_state);
2081 g_free (format_state);
2086 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2087 ModestMsgEditWindow *window)
2089 ModestMsgEditFormatState *format_state = NULL;
2091 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2092 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2094 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2097 format_state = modest_msg_edit_window_get_format_state (window);
2098 g_return_if_fail (format_state != NULL);
2100 format_state->italics = gtk_toggle_action_get_active (action);
2101 modest_msg_edit_window_set_format_state (window, format_state);
2102 g_free (format_state);
2107 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2108 ModestMsgEditWindow *window)
2110 ModestMsgEditFormatState *format_state = NULL;
2112 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2113 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2115 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2118 format_state = modest_msg_edit_window_get_format_state (window);
2119 g_return_if_fail (format_state != NULL);
2121 format_state->bullet = gtk_toggle_action_get_active (action);
2122 modest_msg_edit_window_set_format_state (window, format_state);
2123 g_free (format_state);
2128 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2129 GtkRadioAction *selected,
2130 ModestMsgEditWindow *window)
2132 ModestMsgEditFormatState *format_state = NULL;
2133 GtkJustification value;
2135 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2137 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2140 value = gtk_radio_action_get_current_value (selected);
2142 format_state = modest_msg_edit_window_get_format_state (window);
2143 g_return_if_fail (format_state != NULL);
2145 format_state->justification = value;
2146 modest_msg_edit_window_set_format_state (window, format_state);
2147 g_free (format_state);
2151 modest_ui_actions_on_select_editor_color (GtkAction *action,
2152 ModestMsgEditWindow *window)
2154 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2155 g_return_if_fail (GTK_IS_ACTION (action));
2157 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2160 modest_msg_edit_window_select_color (window);
2164 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2165 ModestMsgEditWindow *window)
2167 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2168 g_return_if_fail (GTK_IS_ACTION (action));
2170 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2173 modest_msg_edit_window_select_background_color (window);
2177 modest_ui_actions_on_insert_image (GtkAction *action,
2178 ModestMsgEditWindow *window)
2180 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2181 g_return_if_fail (GTK_IS_ACTION (action));
2183 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2186 modest_msg_edit_window_insert_image (window);
2190 modest_ui_actions_on_attach_file (GtkAction *action,
2191 ModestMsgEditWindow *window)
2193 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2194 g_return_if_fail (GTK_IS_ACTION (action));
2196 modest_msg_edit_window_attach_file (window);
2200 modest_ui_actions_on_remove_attachments (GtkAction *action,
2201 ModestMsgEditWindow *window)
2203 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2204 g_return_if_fail (GTK_IS_ACTION (action));
2206 modest_msg_edit_window_remove_attachments (window, NULL);
2210 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2213 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2214 const GError *error = modest_mail_operation_get_error (mail_op);
2218 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2219 modest_mail_operation_get_error (mail_op)->message);
2224 modest_ui_actions_create_folder(GtkWidget *parent_window,
2225 GtkWidget *folder_view)
2227 TnyFolderStore *parent_folder;
2229 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2231 if (parent_folder) {
2232 gboolean finished = FALSE;
2234 gchar *folder_name = NULL, *suggested_name = NULL;
2236 /* Run the new folder dialog */
2238 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2243 g_free (suggested_name);
2244 suggested_name = NULL;
2246 if (result == GTK_RESPONSE_REJECT) {
2249 ModestMailOperation *mail_op;
2250 TnyFolder *new_folder = NULL;
2252 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2253 G_OBJECT(parent_window),
2254 modest_ui_actions_new_folder_error_handler,
2257 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2259 new_folder = modest_mail_operation_create_folder (mail_op,
2261 (const gchar *) folder_name);
2263 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2266 g_object_unref (new_folder);
2269 g_object_unref (mail_op);
2272 suggested_name = folder_name;
2276 g_object_unref (parent_folder);
2281 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2283 GtkWidget *folder_view;
2285 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2287 folder_view = modest_main_window_get_child_widget (main_window,
2288 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2292 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2296 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2299 GObject *win = modest_mail_operation_get_source (mail_op);
2300 const GError *error = NULL;
2301 const gchar *message = NULL;
2303 /* Get error message */
2304 error = modest_mail_operation_get_error (mail_op);
2305 if (error != NULL && error->message != NULL) {
2306 message = error->message;
2308 message = _("!!! FIXME: Unable to rename");
2311 /* Show notification dialog */
2312 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2313 g_object_unref (win);
2317 modest_ui_actions_on_rename_folder (GtkAction *action,
2318 ModestMainWindow *main_window)
2320 TnyFolderStore *folder;
2321 GtkWidget *folder_view;
2322 GtkWidget *header_view;
2324 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2326 folder_view = modest_main_window_get_child_widget (main_window,
2327 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2331 header_view = modest_main_window_get_child_widget (main_window,
2332 MODEST_WIDGET_TYPE_HEADER_VIEW);
2337 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2341 /* Offer the connection dialog if necessary: */
2342 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2343 g_object_unref (G_OBJECT (folder));
2348 if (TNY_IS_FOLDER (folder)) {
2351 const gchar *current_name;
2353 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2354 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2355 current_name, &folder_name);
2357 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2358 ModestMailOperation *mail_op;
2361 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2362 G_OBJECT(main_window),
2363 modest_ui_actions_rename_folder_error_handler,
2367 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2370 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2372 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2373 TNY_FOLDER(folder), TRUE);
2376 modest_header_view_clear ((ModestHeaderView *) header_view);
2378 modest_mail_operation_rename_folder (mail_op,
2379 TNY_FOLDER (folder),
2380 (const gchar *) folder_name);
2382 g_object_unref (mail_op);
2383 g_free (folder_name);
2386 g_object_unref (folder);
2390 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2393 GObject *win = modest_mail_operation_get_source (mail_op);
2395 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2396 _("mail_in_ui_folder_delete_error"));
2397 g_object_unref (win);
2401 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2403 TnyFolderStore *folder;
2404 GtkWidget *folder_view;
2408 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2410 folder_view = modest_main_window_get_child_widget (main_window,
2411 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2415 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2417 /* Show an error if it's an account */
2418 if (!TNY_IS_FOLDER (folder)) {
2419 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2420 _("mail_in_ui_folder_delete_error"));
2421 g_object_unref (G_OBJECT (folder));
2425 /* Offer the connection dialog if necessary: */
2426 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2427 g_object_unref (G_OBJECT (folder));
2432 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2433 tny_folder_get_name (TNY_FOLDER (folder)));
2434 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2435 (const gchar *) message);
2438 if (response == GTK_RESPONSE_OK) {
2439 ModestMailOperation *mail_op =
2440 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2441 G_OBJECT(main_window),
2442 modest_ui_actions_delete_folder_error_handler,
2445 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2447 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2448 g_object_unref (G_OBJECT (mail_op));
2451 g_object_unref (G_OBJECT (folder));
2455 modest_ui_actions_on_delete_folder (GtkAction *action,
2456 ModestMainWindow *main_window)
2458 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2460 delete_folder (main_window, FALSE);
2464 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2466 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2468 delete_folder (main_window, TRUE);
2473 show_error (GtkWidget *parent_widget, const gchar* text)
2475 hildon_banner_show_information(parent_widget, NULL, text);
2478 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2480 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2487 gtk_dialog_run (dialog);
2488 gtk_widget_destroy (GTK_WIDGET (dialog));
2493 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2494 const gchar* server_account_name,
2499 ModestMainWindow *main_window)
2501 g_return_if_fail(server_account_name);
2502 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2504 /* Initalize output parameters: */
2511 #ifdef MODEST_PLATFORM_MAEMO
2512 /* Maemo uses a different (awkward) button order,
2513 * It should probably just use gtk_alternative_dialog_button_order ().
2515 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2519 GTK_RESPONSE_ACCEPT,
2521 GTK_RESPONSE_REJECT,
2524 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2528 GTK_RESPONSE_REJECT,
2530 GTK_RESPONSE_ACCEPT,
2532 #endif /* MODEST_PLATFORM_MAEMO */
2534 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2536 gchar *server_name = modest_server_account_get_hostname (
2537 modest_runtime_get_account_mgr(), server_account_name);
2538 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2539 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2544 /* This causes a warning because the logical ID has no %s in it,
2545 * though the translation does, but there is not much we can do about that: */
2546 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2547 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2550 g_free (server_name);
2554 gchar *initial_username = modest_server_account_get_username (
2555 modest_runtime_get_account_mgr(), server_account_name);
2557 GtkWidget *entry_username = gtk_entry_new ();
2558 if (initial_username)
2559 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2560 /* Dim this if a connection has ever succeeded with this username,
2561 * as per the UI spec: */
2562 const gboolean username_known =
2563 modest_server_account_get_username_has_succeeded(
2564 modest_runtime_get_account_mgr(), server_account_name);
2565 gtk_widget_set_sensitive (entry_username, !username_known);
2567 #ifdef MODEST_PLATFORM_MAEMO
2568 /* Auto-capitalization is the default, so let's turn it off: */
2569 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2571 /* Create a size group to be used by all captions.
2572 * Note that HildonCaption does not create a default size group if we do not specify one.
2573 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2574 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2576 GtkWidget *caption = hildon_caption_new (sizegroup,
2577 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2578 gtk_widget_show (entry_username);
2579 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2580 FALSE, FALSE, MODEST_MARGIN_HALF);
2581 gtk_widget_show (caption);
2583 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2585 #endif /* MODEST_PLATFORM_MAEMO */
2588 GtkWidget *entry_password = gtk_entry_new ();
2589 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2590 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2592 #ifdef MODEST_PLATFORM_MAEMO
2593 /* Auto-capitalization is the default, so let's turn it off: */
2594 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2595 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2597 caption = hildon_caption_new (sizegroup,
2598 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2599 gtk_widget_show (entry_password);
2600 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2601 FALSE, FALSE, MODEST_MARGIN_HALF);
2602 gtk_widget_show (caption);
2603 g_object_unref (sizegroup);
2605 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2607 #endif /* MODEST_PLATFORM_MAEMO */
2609 /* This is not in the Maemo UI spec:
2610 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2611 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2615 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2617 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2619 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2621 modest_server_account_set_username (
2622 modest_runtime_get_account_mgr(), server_account_name,
2625 const gboolean username_was_changed =
2626 (strcmp (*username, initial_username) != 0);
2627 if (username_was_changed) {
2628 g_warning ("%s: tinymail does not yet support changing the "
2629 "username in the get_password() callback.\n", __FUNCTION__);
2634 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2636 /* We do not save the password in the configuration,
2637 * because this function is only called for passwords that should
2638 * not be remembered:
2639 modest_server_account_set_password (
2640 modest_runtime_get_account_mgr(), server_account_name,
2649 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2661 /* This is not in the Maemo UI spec:
2662 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2668 gtk_widget_destroy (dialog);
2670 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2674 modest_ui_actions_on_cut (GtkAction *action,
2675 ModestWindow *window)
2677 GtkWidget *focused_widget;
2679 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2680 if (GTK_IS_EDITABLE (focused_widget)) {
2681 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2682 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2683 GtkTextBuffer *buffer;
2684 GtkClipboard *clipboard;
2686 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2687 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2688 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2689 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2690 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2691 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2692 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2693 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2698 modest_ui_actions_on_copy (GtkAction *action,
2699 ModestWindow *window)
2701 GtkClipboard *clipboard;
2702 GtkWidget *focused_widget;
2704 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2705 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2707 if (GTK_IS_LABEL (focused_widget)) {
2708 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2709 } else if (GTK_IS_EDITABLE (focused_widget)) {
2710 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2711 } else if (GTK_IS_HTML (focused_widget)) {
2712 gtk_html_copy (GTK_HTML (focused_widget));
2713 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2714 GtkTextBuffer *buffer;
2715 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2716 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2717 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2718 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2719 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2720 TnyIterator *iter = tny_list_create_iterator (header_list);
2721 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2723 gboolean ask = FALSE;
2725 TnyFolder *folder = tny_header_get_folder (header);
2726 TnyAccount *account = tny_folder_get_account (folder);
2727 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2728 /* If it's POP then ask */
2729 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2730 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2731 g_object_unref (account);
2732 g_object_unref (folder);
2733 g_object_unref (header);
2736 g_object_unref (iter);
2738 /* Check that the messages have been previously downloaded */
2739 gboolean continue_download = TRUE;
2741 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2742 if (continue_download)
2743 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2744 g_object_unref (header_list);
2745 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2746 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2749 /* Show information banner */
2750 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2755 modest_ui_actions_on_undo (GtkAction *action,
2756 ModestWindow *window)
2758 ModestEmailClipboard *clipboard = NULL;
2760 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2761 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2762 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2763 /* Clear clipboard source */
2764 clipboard = modest_runtime_get_email_clipboard ();
2765 modest_email_clipboard_clear (clipboard);
2768 g_return_if_reached ();
2773 modest_ui_actions_on_redo (GtkAction *action,
2774 ModestWindow *window)
2776 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2777 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2780 g_return_if_reached ();
2786 paste_msgs_cb (const GObject *object, gpointer user_data)
2788 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2789 g_return_if_fail (GTK_IS_WIDGET (user_data));
2791 /* destroy information note */
2792 gtk_widget_destroy (GTK_WIDGET(user_data));
2796 modest_ui_actions_on_paste (GtkAction *action,
2797 ModestWindow *window)
2799 GtkWidget *focused_widget = NULL;
2800 GtkWidget *inf_note = NULL;
2801 ModestMailOperation *mail_op = NULL;
2803 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2804 if (GTK_IS_EDITABLE (focused_widget)) {
2805 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2806 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2807 GtkTextBuffer *buffer;
2808 GtkClipboard *clipboard;
2810 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2811 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2812 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2813 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2814 ModestEmailClipboard *clipboard = NULL;
2815 TnyFolder *src_folder = NULL;
2816 TnyFolderStore *folder_store = NULL;
2817 TnyList *data = NULL;
2818 gboolean delete = FALSE;
2820 /* Check clipboard source */
2821 clipboard = modest_runtime_get_email_clipboard ();
2822 if (modest_email_clipboard_cleared (clipboard))
2825 /* Get elements to paste */
2826 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2828 /* Create a new mail operation */
2829 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2830 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2833 /* Get destination folder */
2834 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2836 /* Launch notification */
2837 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2838 _CS("ckct_nw_pasting"));
2839 if (inf_note != NULL) {
2840 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2841 gtk_widget_show (GTK_WIDGET(inf_note));
2844 /* transfer messages */
2846 modest_mail_operation_xfer_msgs (mail_op,
2848 TNY_FOLDER (folder_store),
2853 } else if (src_folder != NULL) {
2854 modest_mail_operation_xfer_folder (mail_op,
2864 g_object_unref (data);
2865 if (src_folder != NULL)
2866 g_object_unref (src_folder);
2867 if (folder_store != NULL)
2868 g_object_unref (folder_store);
2874 modest_ui_actions_on_select_all (GtkAction *action,
2875 ModestWindow *window)
2877 GtkWidget *focused_widget;
2879 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2880 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2881 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2882 } else if (GTK_IS_LABEL (focused_widget)) {
2883 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2884 } else if (GTK_IS_EDITABLE (focused_widget)) {
2885 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2886 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2887 GtkTextBuffer *buffer;
2888 GtkTextIter start, end;
2890 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2891 gtk_text_buffer_get_start_iter (buffer, &start);
2892 gtk_text_buffer_get_end_iter (buffer, &end);
2893 gtk_text_buffer_select_range (buffer, &start, &end);
2894 } else if (GTK_IS_HTML (focused_widget)) {
2895 gtk_html_select_all (GTK_HTML (focused_widget));
2896 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2897 GtkWidget *header_view = focused_widget;
2898 GtkTreeSelection *selection = NULL;
2900 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2901 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2902 MODEST_WIDGET_TYPE_HEADER_VIEW);
2904 /* Select all messages */
2905 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2906 gtk_tree_selection_select_all (selection);
2908 /* Set focuse on header view */
2909 gtk_widget_grab_focus (header_view);
2915 modest_ui_actions_on_mark_as_read (GtkAction *action,
2916 ModestWindow *window)
2918 g_return_if_fail (MODEST_IS_WINDOW(window));
2920 /* Mark each header as read */
2921 do_headers_action (window, headers_action_mark_as_read, NULL);
2925 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2926 ModestWindow *window)
2928 g_return_if_fail (MODEST_IS_WINDOW(window));
2930 /* Mark each header as read */
2931 do_headers_action (window, headers_action_mark_as_unread, NULL);
2935 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2936 GtkRadioAction *selected,
2937 ModestWindow *window)
2941 value = gtk_radio_action_get_current_value (selected);
2942 if (MODEST_IS_WINDOW (window)) {
2943 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2947 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2948 GtkRadioAction *selected,
2949 ModestWindow *window)
2951 TnyHeaderFlags flags;
2952 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2954 flags = gtk_radio_action_get_current_value (selected);
2955 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2958 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2959 GtkRadioAction *selected,
2960 ModestWindow *window)
2964 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2966 file_format = gtk_radio_action_get_current_value (selected);
2967 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2972 modest_ui_actions_on_zoom_plus (GtkAction *action,
2973 ModestWindow *window)
2975 g_return_if_fail (MODEST_IS_WINDOW (window));
2977 modest_window_zoom_plus (MODEST_WINDOW (window));
2981 modest_ui_actions_on_zoom_minus (GtkAction *action,
2982 ModestWindow *window)
2984 g_return_if_fail (MODEST_IS_WINDOW (window));
2986 modest_window_zoom_minus (MODEST_WINDOW (window));
2990 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2991 ModestWindow *window)
2993 ModestWindowMgr *mgr;
2994 gboolean fullscreen, active;
2995 g_return_if_fail (MODEST_IS_WINDOW (window));
2997 mgr = modest_runtime_get_window_mgr ();
2999 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3000 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3002 if (active != fullscreen) {
3003 modest_window_mgr_set_fullscreen_mode (mgr, active);
3004 gtk_window_present (GTK_WINDOW (window));
3009 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3010 ModestWindow *window)
3012 ModestWindowMgr *mgr;
3013 gboolean fullscreen;
3015 g_return_if_fail (MODEST_IS_WINDOW (window));
3017 mgr = modest_runtime_get_window_mgr ();
3018 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3019 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3021 gtk_window_present (GTK_WINDOW (window));
3025 * Used by modest_ui_actions_on_details to call do_headers_action
3028 headers_action_show_details (TnyHeader *header,
3029 ModestWindow *window,
3036 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3039 gtk_widget_show_all (dialog);
3040 gtk_dialog_run (GTK_DIALOG (dialog));
3042 gtk_widget_destroy (dialog);
3046 * Show the folder details in a ModestDetailsDialog widget
3049 show_folder_details (TnyFolder *folder,
3055 dialog = modest_details_dialog_new_with_folder (window, folder);
3058 gtk_widget_show_all (dialog);
3059 gtk_dialog_run (GTK_DIALOG (dialog));
3061 gtk_widget_destroy (dialog);
3065 * Show the header details in a ModestDetailsDialog widget
3068 modest_ui_actions_on_details (GtkAction *action,
3071 TnyList * headers_list;
3075 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3078 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3081 g_object_unref (msg);
3083 headers_list = get_selected_headers (win);
3087 iter = tny_list_create_iterator (headers_list);
3089 header = TNY_HEADER (tny_iterator_get_current (iter));
3091 headers_action_show_details (header, win, NULL);
3092 g_object_unref (header);
3095 g_object_unref (iter);
3096 g_object_unref (headers_list);
3098 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3099 GtkWidget *folder_view, *header_view;
3101 /* Check which widget has the focus */
3102 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3103 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3104 if (gtk_widget_is_focus (folder_view)) {
3105 TnyFolderStore *folder_store
3106 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3107 if (!folder_store) {
3108 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3111 /* Show only when it's a folder */
3112 /* This function should not be called for account items,
3113 * because we dim the menu item for them. */
3114 if (TNY_IS_FOLDER (folder_store)) {
3115 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3118 g_object_unref (folder_store);
3121 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3122 MODEST_WIDGET_TYPE_HEADER_VIEW);
3123 /* Show details of each header */
3124 do_headers_action (win, headers_action_show_details, header_view);
3130 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3131 ModestMsgEditWindow *window)
3133 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3135 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3139 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3140 ModestMsgEditWindow *window)
3142 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3144 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3148 modest_ui_actions_toggle_folders_view (GtkAction *action,
3149 ModestMainWindow *main_window)
3151 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3153 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3154 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3156 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3160 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3161 ModestWindow *window)
3163 gboolean active, fullscreen = FALSE;
3164 ModestWindowMgr *mgr;
3166 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3168 /* Check if we want to toggle the toolbar vuew in fullscreen
3170 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3171 "ViewShowToolbarFullScreen")) {
3175 /* Toggle toolbar */
3176 mgr = modest_runtime_get_window_mgr ();
3177 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3181 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3182 ModestMsgEditWindow *window)
3184 modest_msg_edit_window_select_font (window);
3188 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3189 const gchar *display_name,
3192 /* Do not change the application name if the widget has not
3193 the focus. This callback could be called even if the folder
3194 view has not the focus, because the handled signal could be
3195 emitted when the folder view is redrawn */
3196 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3198 gtk_window_set_title (window, display_name);
3200 gtk_window_set_title (window, " ");
3205 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3207 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3208 modest_msg_edit_window_select_contacts (window);
3212 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3214 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3215 modest_msg_edit_window_check_names (window);
3219 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3221 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3222 GTK_WIDGET (user_data));
3226 create_move_to_dialog (GtkWindow *win,
3227 GtkWidget *folder_view,
3228 GtkWidget **tree_view)
3230 GtkWidget *dialog, *scroll;
3231 GtkWidget *new_button;
3233 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3235 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3238 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3239 /* We do this manually so GTK+ does not associate a response ID for
3241 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3242 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3243 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3245 /* Create scrolled window */
3246 scroll = gtk_scrolled_window_new (NULL, NULL);
3247 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3248 GTK_POLICY_AUTOMATIC,
3249 GTK_POLICY_AUTOMATIC);
3251 /* Create folder view */
3252 *tree_view = modest_platform_create_folder_view (NULL);
3254 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3256 /* It could happen that we're trying to move a message from a
3257 window (msg window for example) after the main window was
3258 closed, so we can not just get the model of the folder
3260 if (MODEST_IS_FOLDER_VIEW (folder_view))
3261 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3262 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3264 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3265 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3267 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3269 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3271 /* Add scroll to dialog */
3272 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3273 scroll, TRUE, TRUE, 0);
3275 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3276 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3282 * Returns TRUE if at least one of the headers of the list belongs to
3283 * a message that has been fully retrieved.
3286 has_retrieved_msgs (TnyList *list)
3289 gboolean found = FALSE;
3291 iter = tny_list_create_iterator (list);
3292 while (tny_iterator_is_done (iter) && !found) {
3294 TnyHeaderFlags flags = 0;
3296 header = TNY_HEADER (tny_iterator_get_current (iter));
3298 flags = tny_header_get_flags (header);
3299 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3302 g_object_unref (header);
3306 tny_iterator_next (iter);
3308 g_object_unref (iter);
3314 * Shows a confirmation dialog to the user when we're moving messages
3315 * from a remote server to the local storage. Returns the dialog
3316 * response. If it's other kind of movement the it always returns
3320 msgs_move_to_confirmation (GtkWindow *win,
3321 TnyFolder *dest_folder,
3324 gint response = GTK_RESPONSE_OK;
3326 /* If the destination is a local folder */
3327 if (modest_tny_folder_is_local_folder (dest_folder)) {
3328 TnyFolder *src_folder = NULL;
3329 TnyIterator *iter = NULL;
3330 TnyHeader *header = NULL;
3332 /* Get source folder */
3333 iter = tny_list_create_iterator (headers);
3334 header = TNY_HEADER (tny_iterator_get_current (iter));
3336 src_folder = tny_header_get_folder (header);
3337 g_object_unref (header);
3340 g_object_unref (iter);
3342 /* if no src_folder, message may be an attahcment */
3343 if (src_folder == NULL)
3344 return GTK_RESPONSE_CANCEL;
3346 /* If the source is a remote folder */
3347 if (!modest_tny_folder_is_local_folder (src_folder)) {
3348 const gchar *message;
3350 if (has_retrieved_msgs (headers))
3351 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3352 tny_list_get_length (headers));
3354 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3355 tny_list_get_length (headers));
3357 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3358 (const gchar *) message);
3361 g_object_unref (src_folder);
3370 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3372 ModestMsgViewWindow *self = NULL;
3374 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3375 self = MODEST_MSG_VIEW_WINDOW (object);
3377 if (!modest_msg_view_window_select_next_message (self))
3378 if (!modest_msg_view_window_select_previous_message (self))
3379 /* No more messages to view, so close this window */
3380 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3384 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3387 GObject *win = modest_mail_operation_get_source (mail_op);
3388 const GError *error = NULL;
3389 const gchar *message = NULL;
3391 /* Get error message */
3392 error = modest_mail_operation_get_error (mail_op);
3393 if (error != NULL && error->message != NULL) {
3394 message = error->message;
3396 message = _("mail_in_ui_folder_move_target_error");
3399 /* Show notification dialog */
3400 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3401 g_object_unref (win);
3405 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3408 GObject *win = modest_mail_operation_get_source (mail_op);
3409 const GError *error = modest_mail_operation_get_error (mail_op);
3411 g_return_if_fail (error != NULL);
3412 if (error->message != NULL)
3413 g_printerr ("modest: %s\n", error->message);
3415 g_printerr ("modest: unkonw error on send&receive operation");
3417 /* Show error message */
3418 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3419 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3420 /* _CS("sfil_ib_unable_to_receive")); */
3422 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3423 /* _CS("sfil_ib_unable_to_send")); */
3424 g_object_unref (win);
3428 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3435 gint pending_purges = 0;
3436 gboolean some_purged = FALSE;
3437 ModestWindow *win = MODEST_WINDOW (user_data);
3438 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3440 /* If there was any error */
3441 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3442 modest_window_mgr_unregister_header (mgr, header);
3446 /* Once the message has been retrieved for purging, we check if
3447 * it's all ok for purging */
3449 parts = tny_simple_list_new ();
3450 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3451 iter = tny_list_create_iterator (parts);
3453 while (!tny_iterator_is_done (iter)) {
3455 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3456 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3457 if (tny_mime_part_is_purged (part))
3464 g_object_unref (part);
3466 tny_iterator_next (iter);
3469 if (pending_purges>0) {
3471 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3473 if (response == GTK_RESPONSE_OK) {
3474 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3475 tny_iterator_first (iter);
3476 while (!tny_iterator_is_done (iter)) {
3479 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3480 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3481 tny_mime_part_set_purged (part);
3484 g_object_unref (part);
3486 tny_iterator_next (iter);
3489 tny_msg_rewrite_cache (msg);
3492 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3495 /* remove attachments */
3496 tny_iterator_first (iter);
3497 while (!tny_iterator_is_done (iter)) {
3500 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3502 /* One for the reference given by tny_iterator_get_current(): */
3503 g_object_unref (part);
3505 /* TODO: Is this meant to remove the attachment by doing another unref()?
3506 * Otherwise, this seems useless. */
3509 tny_iterator_next (iter);
3511 modest_window_mgr_unregister_header (mgr, header);
3513 g_object_unref (iter);
3514 g_object_unref (parts);
3518 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3519 ModestMainWindow *win)
3521 GtkWidget *header_view;
3522 TnyList *header_list;
3525 TnyHeaderFlags flags;
3526 ModestWindow *msg_view_window = NULL;
3529 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3531 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3532 MODEST_WIDGET_TYPE_HEADER_VIEW);
3534 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3536 if (tny_list_get_length (header_list) == 1) {
3537 iter = tny_list_create_iterator (header_list);
3538 header = TNY_HEADER (tny_iterator_get_current (iter));
3539 g_object_unref (iter);
3544 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3545 header, &msg_view_window);
3546 flags = tny_header_get_flags (header);
3547 if (!(flags & TNY_HEADER_FLAG_CACHED))
3550 if (msg_view_window != NULL)
3551 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3553 /* do nothing; uid was registered before, so window is probably on it's way */
3554 g_warning ("debug: header %p has already been registered", header);
3557 ModestMailOperation *mail_op = NULL;
3558 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3559 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3561 modest_ui_actions_get_msgs_full_error_handler,
3563 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3564 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3566 g_object_unref (mail_op);
3569 g_object_unref (header);
3571 g_object_unref (header_list);
3575 * Utility function that transfer messages from both the main window
3576 * and the msg view window when using the "Move to" dialog
3579 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3582 TnyList *headers = NULL;
3585 if (!TNY_IS_FOLDER (dst_folder)) {
3586 modest_platform_information_banner (GTK_WIDGET (win),
3588 _CS("ckdg_ib_unable_to_move_to_current_location"));
3592 /* Get selected headers */
3593 headers = get_selected_headers (MODEST_WINDOW (win));
3595 /* Ask for user confirmation */
3596 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3597 TNY_FOLDER (dst_folder),
3600 /* Transfer messages */
3601 if (response == GTK_RESPONSE_OK) {
3602 ModestMailOperation *mail_op =
3603 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3605 modest_ui_actions_move_folder_error_handler,
3607 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3610 modest_mail_operation_xfer_msgs (mail_op,
3612 TNY_FOLDER (dst_folder),
3614 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3617 g_object_unref (G_OBJECT (mail_op));
3619 g_object_unref (headers);
3624 * UI handler for the "Move to" action when invoked from the
3628 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3629 GtkWidget *folder_view,
3630 TnyFolderStore *dst_folder,
3631 ModestMainWindow *win)
3633 GtkWidget *header_view = NULL;
3634 ModestMailOperation *mail_op = NULL;
3635 TnyFolderStore *src_folder;
3637 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3639 /* Get the source folder */
3640 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3642 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3643 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3647 /* Get header view */
3649 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3651 /* Get folder or messages to transfer */
3652 if (gtk_widget_is_focus (folder_view)) {
3654 /* Allow only to transfer folders to the local root folder */
3655 if (TNY_IS_ACCOUNT (dst_folder) &&
3656 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3659 /* Clean folder on header view before moving it */
3660 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3662 if (TNY_IS_FOLDER (src_folder)) {
3664 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3666 modest_ui_actions_move_folder_error_handler,
3668 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3671 modest_mail_operation_xfer_folder (mail_op,
3672 TNY_FOLDER (src_folder),
3675 /* Unref mail operation */
3676 g_object_unref (G_OBJECT (mail_op));
3678 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3680 } else if (gtk_widget_is_focus (header_view)) {
3681 /* Transfer messages */
3682 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3687 g_object_unref (src_folder);
3692 * UI handler for the "Move to" action when invoked from the
3693 * ModestMsgViewWindow
3696 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3697 TnyFolderStore *dst_folder,
3698 ModestMsgViewWindow *win)
3700 TnyHeader *header = NULL;
3701 TnyFolder *src_folder;
3703 /* Create header list */
3704 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3705 src_folder = tny_header_get_folder(header);
3706 g_object_unref (header);
3708 /* Transfer the message */
3709 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3710 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3712 g_object_unref (src_folder);
3716 modest_ui_actions_on_move_to (GtkAction *action,
3719 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3721 TnyFolderStore *dst_folder = NULL;
3722 ModestMainWindow *main_window;
3724 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3725 MODEST_IS_MSG_VIEW_WINDOW (win));
3727 /* Get the main window if exists */
3728 if (MODEST_IS_MAIN_WINDOW (win))
3729 main_window = MODEST_MAIN_WINDOW (win);
3732 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3734 /* Get the folder view widget if exists */
3736 folder_view = modest_main_window_get_child_widget (main_window,
3737 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3741 /* Create and run the dialog */
3742 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3743 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3744 result = gtk_dialog_run (GTK_DIALOG(dialog));
3745 g_object_ref (tree_view);
3746 gtk_widget_destroy (dialog);
3748 if (result != GTK_RESPONSE_ACCEPT)
3751 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3752 /* Offer the connection dialog if necessary: */
3753 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3756 /* Do window specific stuff */
3757 if (MODEST_IS_MAIN_WINDOW (win))
3758 modest_ui_actions_on_main_window_move_to (action,
3761 MODEST_MAIN_WINDOW (win));
3763 modest_ui_actions_on_msg_view_window_move_to (action,
3765 MODEST_MSG_VIEW_WINDOW (win));
3768 g_object_unref (dst_folder);
3772 * Calls #HeadersFunc for each header already selected in the main
3773 * window or the message currently being shown in the msg view window
3776 do_headers_action (ModestWindow *win,
3780 TnyList *headers_list = NULL;
3781 TnyIterator *iter = NULL;
3782 TnyHeader *header = NULL;
3783 TnyFolder *folder = NULL;
3786 headers_list = get_selected_headers (win);
3790 /* Get the folder */
3791 iter = tny_list_create_iterator (headers_list);
3792 header = TNY_HEADER (tny_iterator_get_current (iter));
3794 folder = tny_header_get_folder (header);
3795 g_object_unref (header);
3798 /* Call the function for each header */
3799 while (!tny_iterator_is_done (iter)) {
3800 header = TNY_HEADER (tny_iterator_get_current (iter));
3801 func (header, win, user_data);
3802 g_object_unref (header);
3803 tny_iterator_next (iter);
3806 /* Trick: do a poke status in order to speed up the signaling
3808 tny_folder_poke_status (folder);
3811 g_object_unref (folder);
3812 g_object_unref (iter);
3813 g_object_unref (headers_list);
3817 modest_ui_actions_view_attachment (GtkAction *action,
3818 ModestWindow *window)
3820 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3821 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3823 /* not supported window for this action */
3824 g_return_if_reached ();
3829 modest_ui_actions_save_attachments (GtkAction *action,
3830 ModestWindow *window)
3832 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3833 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3835 /* not supported window for this action */
3836 g_return_if_reached ();
3841 modest_ui_actions_remove_attachments (GtkAction *action,
3842 ModestWindow *window)
3844 if (MODEST_IS_MAIN_WINDOW (window)) {
3845 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3846 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3847 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3849 /* not supported window for this action */
3850 g_return_if_reached ();
3855 modest_ui_actions_on_settings (GtkAction *action,
3860 dialog = modest_platform_get_global_settings_dialog ();
3861 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3862 gtk_widget_show_all (dialog);
3864 gtk_dialog_run (GTK_DIALOG (dialog));
3866 gtk_widget_destroy (dialog);
3870 modest_ui_actions_on_help (GtkAction *action,
3873 const gchar *help_id = NULL;
3875 if (MODEST_IS_MAIN_WINDOW (win)) {
3876 const gchar *action_name;
3877 action_name = gtk_action_get_name (action);
3879 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3880 !strcmp (action_name, "HeaderViewCSMHelp")) {
3881 GtkWidget *folder_view;
3882 TnyFolderStore *folder_store;
3883 /* Get selected folder */
3884 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3885 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3886 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3888 /* Switch help_id */
3889 if (TNY_IS_FOLDER (folder_store)) {
3890 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
3891 case TNY_FOLDER_TYPE_NORMAL:
3892 help_id = "applications_email_managefolders";
3894 case TNY_FOLDER_TYPE_INBOX:
3895 help_id = "applications_email_inbox";
3897 case TNY_FOLDER_TYPE_OUTBOX:
3898 help_id = "applications_email_outbox";
3900 case TNY_FOLDER_TYPE_SENT:
3901 help_id = "applications_email_sent";
3903 case TNY_FOLDER_TYPE_DRAFTS:
3904 help_id = "applications_email_drafts";
3906 case TNY_FOLDER_TYPE_ARCHIVE:
3907 help_id = "applications_email_managefolders";
3910 help_id = "applications_email_managefolders";
3913 help_id = "applications_email_mainview";
3915 g_object_unref (folder_store);
3917 help_id = "applications_email_mainview";
3919 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3920 help_id = "applications_email_viewer";
3921 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3922 help_id = "applications_email_editor";
3924 modest_platform_show_help (GTK_WINDOW (win), help_id);
3928 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3929 ModestWindow *window)
3931 ModestMailOperation *mail_op;
3935 headers = get_selected_headers (window);
3939 /* Create mail operation */
3940 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3942 modest_ui_actions_get_msgs_full_error_handler,
3944 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3945 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3948 g_object_unref (headers);
3949 g_object_unref (mail_op);
3953 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3954 ModestWindow *window)
3956 g_return_if_fail (MODEST_IS_WINDOW (window));
3959 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3963 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3964 ModestWindow *window)
3966 g_return_if_fail (MODEST_IS_WINDOW (window));
3969 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3973 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3974 ModestWindow *window)
3976 g_return_if_fail (MODEST_IS_WINDOW (window));
3979 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3983 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3984 ModestWindow *window)
3986 g_return_if_fail (MODEST_IS_WINDOW (window));
3989 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3993 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3994 ModestWindow *window)
3996 g_return_if_fail (MODEST_IS_WINDOW (window));
3999 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4003 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4004 ModestWindow *window)
4006 g_return_if_fail (MODEST_IS_WINDOW (window));
4009 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4013 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4014 ModestWindow *window)
4016 g_return_if_fail (MODEST_IS_WINDOW (window));
4019 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4023 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4024 ModestWindow *window)
4026 g_return_if_fail (MODEST_IS_WINDOW (window));
4029 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4033 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4035 g_return_if_fail (MODEST_IS_WINDOW (window));
4038 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4042 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4044 g_return_if_fail (MODEST_IS_WINDOW (window));
4046 modest_platform_show_search_messages (GTK_WINDOW (window));
4050 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4052 g_return_if_fail (MODEST_IS_WINDOW (win));
4053 modest_platform_show_addressbook (GTK_WINDOW (win));
4058 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4059 ModestWindow *window)
4061 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4063 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4067 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4068 ModestMailOperationState *state,
4071 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4073 /* Set send/receive operation finished */
4074 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4075 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));