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>
36 #include <modest-runtime.h>
37 #include <modest-tny-folder.h>
38 #include <modest-tny-msg.h>
39 #include <modest-tny-account.h>
40 #include <modest-address-book.h>
41 #include "modest-error.h"
42 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
47 #ifdef MODEST_PLATFORM_MAEMO
48 #include "maemo/modest-osso-state-saving.h"
49 #endif /* MODEST_PLATFORM_MAEMO */
51 #include "widgets/modest-ui-constants.h"
52 #include <widgets/modest-main-window.h>
53 #include <widgets/modest-msg-view-window.h>
54 #include <widgets/modest-account-view-window.h>
55 #include <widgets/modest-details-dialog.h>
56 #include <widgets/modest-attachments-view.h>
57 #include "widgets/modest-global-settings-dialog.h"
58 #include "modest-connection-specific-smtp-window.h"
59 #include "modest-account-mgr-helpers.h"
60 #include "modest-mail-operation.h"
61 #include "modest-text-utils.h"
63 #ifdef MODEST_HAVE_EASYSETUP
64 #include "easysetup/modest-easysetup-wizard.h"
65 #endif /* MODEST_HAVE_EASYSETUP */
67 #include <modest-widget-memory.h>
68 #include <tny-error.h>
69 #include <tny-simple-list.h>
70 #include <tny-msg-view.h>
71 #include <tny-device.h>
72 #include <tny-merge-folder.h>
74 typedef struct _GetMsgAsyncHelper {
76 ModestMailOperation *mail_op;
83 typedef enum _ReplyForwardAction {
89 typedef struct _ReplyForwardHelper {
90 guint reply_forward_type;
91 ReplyForwardAction action;
96 * The do_headers_action uses this kind of functions to perform some
97 * action to each member of a list of headers
99 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
102 do_headers_action (ModestWindow *win,
107 static void open_msg_cb (ModestMailOperation *mail_op,
112 static void reply_forward_cb (ModestMailOperation *mail_op,
117 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
119 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
122 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
125 const gchar *authors[] = {
126 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
129 about = gtk_about_dialog_new ();
130 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
131 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
132 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
133 _("Copyright (c) 2006, Nokia Corporation\n"
134 "All rights reserved."));
135 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
136 _("a modest e-mail client\n\n"
137 "design and implementation: Dirk-Jan C. Binnema\n"
138 "contributions from the fine people at KC and Ig\n"
139 "uses the tinymail email framework written by Philip van Hoof"));
140 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
141 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
143 gtk_dialog_run (GTK_DIALOG (about));
144 gtk_widget_destroy(about);
148 * Gets the list of currently selected messages. If the win is the
149 * main window, then it returns a newly allocated list of the headers
150 * selected in the header view. If win is the msg view window, then
151 * the value returned is a list with just a single header.
153 * The caller of this funcion must free the list.
156 get_selected_headers (ModestWindow *win)
158 if (MODEST_IS_MAIN_WINDOW(win)) {
159 GtkWidget *header_view;
161 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
162 MODEST_WIDGET_TYPE_HEADER_VIEW);
163 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
165 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
166 /* for MsgViewWindows, we simply return a list with one element */
168 TnyList *list = NULL;
170 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
171 if (header != NULL) {
172 list = tny_simple_list_new ();
173 tny_list_prepend (list, G_OBJECT(header));
174 g_object_unref (G_OBJECT(header));
184 headers_action_mark_as_read (TnyHeader *header,
188 TnyHeaderFlags flags;
190 g_return_if_fail (TNY_IS_HEADER(header));
192 flags = tny_header_get_flags (header);
193 if (flags & TNY_HEADER_FLAG_SEEN) return;
194 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
198 headers_action_mark_as_unread (TnyHeader *header,
202 TnyHeaderFlags flags;
204 g_return_if_fail (TNY_IS_HEADER(header));
206 flags = tny_header_get_flags (header);
207 if (flags & TNY_HEADER_FLAG_SEEN) {
208 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
214 headers_action_delete (TnyHeader *header,
218 ModestMailOperation *mail_op = NULL;
220 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
221 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
224 /* Always delete. TODO: Move to trash still not supported */
225 modest_mail_operation_remove_msg (mail_op, header, FALSE);
226 g_object_unref (G_OBJECT (mail_op));
230 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
232 TnyList *header_list = NULL;
233 TnyIterator *iter = NULL;
234 TnyHeader *header = NULL;
235 gchar *message = NULL;
239 g_return_if_fail (MODEST_IS_WINDOW(win));
241 header_list = get_selected_headers (win);
242 if (!header_list) return;
245 if (tny_list_get_length(header_list) > 1)
246 message = g_strdup(_("emev_nc_delete_messages"));
248 iter = tny_list_create_iterator (header_list);
249 header = TNY_HEADER (tny_iterator_get_current (iter));
250 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
251 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
254 /* Confirmation dialog */
255 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
259 if (response == GTK_RESPONSE_OK) {
260 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
262 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
266 /* Remove each header */
267 do_headers_action (win, headers_action_delete, NULL);
269 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
270 gtk_widget_destroy (GTK_WIDGET(win));
277 g_object_unref (header_list);
278 g_object_unref (iter);
283 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
285 #ifdef MODEST_PLATFORM_MAEMO
286 modest_osso_save_state();
287 #endif /* MODEST_PLATFORM_MAEMO */
293 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
295 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
296 gtk_widget_destroy (GTK_WIDGET (win));
297 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
299 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
300 } else if (MODEST_IS_WINDOW (win)) {
301 gtk_widget_destroy (GTK_WIDGET (win));
303 g_return_if_reached ();
308 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
310 GtkClipboard *clipboard = NULL;
311 gchar *selection = NULL;
313 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
314 selection = gtk_clipboard_wait_for_text (clipboard);
316 modest_address_book_add_address (selection);
321 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
323 /* This is currently only implemented for Maemo,
324 * because it requires a providers preset file which is not publically available.
326 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
327 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
328 TRUE /* enabled accounts only */);
329 gboolean accounts_exist = account_names != NULL;
330 g_slist_free (account_names);
332 if (!accounts_exist) {
333 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
334 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
335 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
336 gtk_dialog_run (GTK_DIALOG (wizard));
337 gtk_widget_destroy (GTK_WIDGET (wizard));
339 /* Show the list of accounts: */
340 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
341 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
342 gtk_dialog_run (account_win);
343 gtk_widget_destroy (GTK_WIDGET(account_win));
346 GtkWidget *dialog, *label;
348 /* Create the widgets */
350 dialog = gtk_dialog_new_with_buttons ("Message",
352 GTK_DIALOG_DESTROY_WITH_PARENT,
356 label = gtk_label_new ("Hello World!");
358 /* Ensure that the dialog box is destroyed when the user responds. */
360 g_signal_connect_swapped (dialog, "response",
361 G_CALLBACK (gtk_widget_destroy),
364 /* Add the label, and show everything we've added to the dialog. */
366 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
368 gtk_widget_show_all (dialog);
369 #endif /* MODEST_PLATFORM_MAEMO */
373 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
375 ModestWindow *main_window = MODEST_WINDOW (user_data);
377 /* Save any changes. */
378 modest_connection_specific_smtp_window_save_server_accounts (
379 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
380 modest_window_get_active_account (main_window));
381 gtk_widget_destroy (GTK_WIDGET (window));
385 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
387 /* This is currently only implemented for Maemo,
388 * because it requires an API (libconic) to detect different connection
391 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
393 /* Create the window if necessary: */
394 const gchar *active_account_name = modest_window_get_active_account (win);
396 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
397 * or show the default account?
398 * If we show the default account then the account name should be shown in
399 * the window when we show it. */
400 if (!active_account_name) {
401 g_warning ("%s: No account is active.", __FUNCTION__);
405 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
406 modest_connection_specific_smtp_window_fill_with_connections (
407 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
408 modest_runtime_get_account_mgr(),
409 active_account_name);
411 /* Show the window: */
412 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
413 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
414 gtk_widget_show (specific_window);
416 /* Save changes when the window is hidden: */
417 g_signal_connect (specific_window, "hide",
418 G_CALLBACK (on_smtp_servers_window_hide), win);
419 #endif /* MODEST_PLATFORM_MAEMO */
423 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
425 ModestWindow *msg_win;
427 TnyFolder *folder = NULL;
428 gchar *account_name = NULL;
429 gchar *from_str = NULL;
430 /* GError *err = NULL; */
431 TnyAccount *account = NULL;
432 ModestWindowMgr *mgr;
433 gchar *signature = NULL;
435 account_name = g_strdup(modest_window_get_active_account (win));
437 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
439 g_printerr ("modest: no account found\n");
443 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
445 TNY_ACCOUNT_TYPE_STORE);
447 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
451 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
453 g_printerr ("modest: failed get from string for '%s'\n", account_name);
457 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
458 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
459 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
460 MODEST_ACCOUNT_SIGNATURE, FALSE);
462 signature = g_strdup ("");
465 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
467 g_printerr ("modest: failed to create new msg\n");
471 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
473 g_printerr ("modest: failed to find Drafts folder\n");
477 /* tny_folder_add_msg (folder, msg, &err); */
479 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
481 /* g_error_free (err); */
485 /* Create and register edit window */
486 /* This is destroyed by TOOD. */
487 msg_win = modest_msg_edit_window_new (msg, account_name);
488 mgr = modest_runtime_get_window_mgr ();
489 modest_window_mgr_register_window (mgr, msg_win);
492 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
494 gtk_widget_show_all (GTK_WIDGET (msg_win));
497 g_free (account_name);
501 g_object_unref (G_OBJECT(account));
503 g_object_unref (G_OBJECT(msg));
505 g_object_unref (G_OBJECT(folder));
509 open_msg_cb (ModestMailOperation *mail_op,
514 ModestWindowMgr *mgr = NULL;
515 ModestWindow *parent_win = NULL;
516 ModestWindow *win = NULL;
517 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
518 gchar *account = NULL;
521 /* TODO: Show an error? (review the specs) */
525 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
526 folder = tny_header_get_folder (header);
528 /* Mark header as read */
529 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
532 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
534 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
536 /* Gets folder type (OUTBOX headers will be opened in edit window */
537 if (modest_tny_folder_is_local_folder (folder))
538 folder_type = modest_tny_folder_get_local_folder_type (folder);
540 /* If the header is in the drafts folder then open the editor,
541 else the message view window */
542 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
543 win = modest_msg_edit_window_new (msg, account);
545 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
546 GtkWidget *header_view;
547 GtkTreeSelection *sel;
548 GList *sel_list = NULL;
551 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
552 MODEST_WIDGET_TYPE_HEADER_VIEW);
554 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
555 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
557 if (sel_list != NULL) {
558 GtkTreeRowReference *row_reference;
560 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
561 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
562 g_list_free (sel_list);
564 win = modest_msg_view_window_new_with_header_model (msg,
568 gtk_tree_row_reference_free (row_reference);
570 win = modest_msg_view_window_new (msg, account);
573 win = modest_msg_view_window_new (msg, account);
577 /* Register and show new window */
579 mgr = modest_runtime_get_window_mgr ();
580 modest_window_mgr_register_window (mgr, win);
581 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
582 gtk_widget_show_all (GTK_WIDGET(win));
587 g_object_unref (msg);
588 g_object_unref (folder);
589 g_object_unref (header);
593 * This function is the error handler of the
594 * modest_mail_operation_get_msgs_full operation
597 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
602 error = modest_mail_operation_get_error (mail_op);
603 if (error->code == MODEST_MAIL_OPERATION_ERROR_SIZE_LIMIT) {
604 GObject *win = modest_mail_operation_get_source (mail_op);
606 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
612 * This function is used by both modest_ui_actions_on_open and
613 * modest_ui_actions_on_header_activated. This way we always do the
614 * same when trying to open messages.
617 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
619 ModestWindowMgr *mgr;
621 ModestMailOperation *mail_op;
623 /* Look if we already have a message view for each header. If
624 true, then remove the header from the list of headers to
626 mgr = modest_runtime_get_window_mgr ();
627 iter = tny_list_create_iterator (headers);
628 while (!tny_iterator_is_done (iter)) {
629 ModestWindow *window;
632 header = TNY_HEADER (tny_iterator_get_current (iter));
633 window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
635 tny_list_remove (headers, G_OBJECT (header));
637 g_object_unref (header);
638 tny_iterator_next (iter);
641 /* Open each message */
642 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
644 modest_ui_actions_get_msgs_full_error_handler,
646 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
647 modest_mail_operation_get_msgs_full (mail_op,
654 g_object_unref(mail_op);
658 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
663 headers = get_selected_headers (win);
668 _modest_ui_actions_open (headers, win);
670 g_object_unref(headers);
675 free_reply_forward_helper (gpointer data)
677 ReplyForwardHelper *helper;
679 helper = (ReplyForwardHelper *) data;
680 g_free (helper->account_name);
681 g_slice_free (ReplyForwardHelper, helper);
685 reply_forward_cb (ModestMailOperation *mail_op,
691 ReplyForwardHelper *rf_helper;
692 ModestWindow *msg_win;
693 ModestEditType edit_type;
696 TnyFolder *folder = NULL;
697 TnyAccount *account = NULL;
698 ModestWindowMgr *mgr;
699 gchar *signature = NULL;
701 g_return_if_fail (user_data != NULL);
702 rf_helper = (ReplyForwardHelper *) user_data;
704 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
705 rf_helper->account_name);
706 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
707 rf_helper->account_name,
708 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
709 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
710 rf_helper->account_name,
711 MODEST_ACCOUNT_SIGNATURE, FALSE);
714 /* Create reply mail */
715 switch (rf_helper->action) {
718 modest_tny_msg_create_reply_msg (msg, from, signature,
719 rf_helper->reply_forward_type,
720 MODEST_TNY_MSG_REPLY_MODE_SENDER);
722 case ACTION_REPLY_TO_ALL:
724 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
725 MODEST_TNY_MSG_REPLY_MODE_ALL);
726 edit_type = MODEST_EDIT_TYPE_REPLY;
730 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
731 edit_type = MODEST_EDIT_TYPE_FORWARD;
734 g_return_if_reached ();
741 g_printerr ("modest: failed to create message\n");
745 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
746 rf_helper->account_name,
747 TNY_ACCOUNT_TYPE_STORE);
749 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
753 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
755 g_printerr ("modest: failed to find Drafts folder\n");
759 tny_folder_add_msg (folder, msg, &err);
761 g_printerr ("modest: error adding msg to Drafts folder: %s",
767 /* Create and register the windows */
768 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
769 mgr = modest_runtime_get_window_mgr ();
770 modest_window_mgr_register_window (mgr, msg_win);
772 /* Show edit window */
773 gtk_widget_show_all (GTK_WIDGET (msg_win));
777 g_object_unref (G_OBJECT (new_msg));
779 g_object_unref (G_OBJECT (folder));
781 g_object_unref (G_OBJECT (account));
782 g_object_unref (msg);
783 g_object_unref (header);
787 * Checks a list of headers. If any of them are not currently
788 * downloaded (CACHED) then it asks the user for permission to
791 * Returns FALSE if the user does not want to download the
792 * messages. Returns TRUE if the user allowed the download or if all
793 * of them are currently downloaded
796 download_uncached_messages (TnyList *header_list, GtkWindow *win)
799 gboolean found, retval;
801 iter = tny_list_create_iterator (header_list);
803 while (!tny_iterator_is_done (iter) && !found) {
805 TnyHeaderFlags flags;
807 header = TNY_HEADER (tny_iterator_get_current (iter));
808 flags = tny_header_get_flags (header);
809 /* TODO: is this the right flag?, it seems that some
810 headers that have been previously downloaded do not
812 found = !(flags & TNY_HEADER_FLAG_CACHED);
813 g_object_unref (header);
814 tny_iterator_next (iter);
816 g_object_unref (iter);
818 /* Ask for user permission to download the messages */
821 GtkResponseType response;
823 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
824 _("mcen_nc_get_multi_msg_txt"));
825 if (response == GTK_RESPONSE_CANCEL)
833 * Common code for the reply and forward actions
836 reply_forward (ReplyForwardAction action, ModestWindow *win)
838 ModestMailOperation *mail_op = NULL;
839 TnyList *header_list = NULL;
840 ReplyForwardHelper *rf_helper = NULL;
841 guint reply_forward_type;
842 gboolean continue_download;
844 g_return_if_fail (MODEST_IS_WINDOW(win));
846 header_list = get_selected_headers (win);
850 /* Check that the messages have been previously downloaded */
851 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
852 if (!continue_download) {
853 g_object_unref (header_list);
858 modest_conf_get_int (modest_runtime_get_conf (),
859 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
861 /* We assume that we can only select messages of the
862 same folder and that we reply all of them from the
863 same account. In fact the interface currently only
864 allows single selection */
867 rf_helper = g_slice_new0 (ReplyForwardHelper);
868 rf_helper->reply_forward_type = reply_forward_type;
869 rf_helper->action = action;
870 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
871 if (!rf_helper->account_name)
872 rf_helper->account_name =
873 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
875 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
878 /* Get header and message. Do not free them here, the
879 reply_forward_cb must do it */
880 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
881 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
882 if (!msg || !header) {
884 g_object_unref (msg);
886 g_object_unref (header);
887 g_printerr ("modest: no message found\n");
890 reply_forward_cb (NULL, header, msg, rf_helper);
892 /* Retrieve messages */
893 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
895 modest_ui_actions_get_msgs_full_error_handler,
897 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
898 modest_mail_operation_get_msgs_full (mail_op,
902 free_reply_forward_helper);
905 g_object_unref(mail_op);
909 g_object_unref (header_list);
913 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
915 g_return_if_fail (MODEST_IS_WINDOW(win));
917 reply_forward (ACTION_REPLY, win);
921 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
923 g_return_if_fail (MODEST_IS_WINDOW(win));
925 reply_forward (ACTION_FORWARD, win);
929 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
931 g_return_if_fail (MODEST_IS_WINDOW(win));
933 reply_forward (ACTION_REPLY_TO_ALL, win);
937 modest_ui_actions_on_next (GtkAction *action,
938 ModestWindow *window)
940 if (MODEST_IS_MAIN_WINDOW (window)) {
941 GtkWidget *header_view;
943 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
944 MODEST_WIDGET_TYPE_HEADER_VIEW);
948 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
949 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
950 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
952 g_return_if_reached ();
957 modest_ui_actions_on_prev (GtkAction *action,
958 ModestWindow *window)
960 g_return_if_fail (MODEST_IS_WINDOW(window));
962 if (MODEST_IS_MAIN_WINDOW (window)) {
963 GtkWidget *header_view;
964 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
965 MODEST_WIDGET_TYPE_HEADER_VIEW);
969 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
970 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
971 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
973 g_return_if_reached ();
978 modest_ui_actions_on_sort (GtkAction *action,
979 ModestWindow *window)
981 g_return_if_fail (MODEST_IS_WINDOW(window));
983 if (MODEST_IS_MAIN_WINDOW (window)) {
984 GtkWidget *header_view;
985 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
986 MODEST_WIDGET_TYPE_HEADER_VIEW);
990 /* Show sorting dialog */
991 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
996 * This function performs the send & receive required actions. The
997 * window is used to create the mail operation. Typically it should
998 * always be the main window, but we pass it as argument in order to
1002 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1004 gchar *acc_name = NULL;
1005 ModestMailOperation *mail_op;
1007 /* If no account name was provided then get the current account, and if
1008 there is no current account then pick the default one: */
1009 if (!account_name) {
1010 acc_name = g_strdup (modest_window_get_active_account(win));
1012 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1014 g_printerr ("modest: cannot get default account\n");
1018 acc_name = g_strdup (account_name);
1021 /* Send & receive. */
1022 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1023 /* Receive and then send. The operation is tagged initially as
1024 a receive operation because the account update performs a
1025 receive and then a send. The operation changes its type
1026 internally, so the progress objects will receive the proper
1027 progress information */
1028 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1029 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1030 modest_mail_operation_update_account (mail_op, acc_name);
1031 g_object_unref (G_OBJECT (mail_op));
1038 * Refreshes all accounts. This function will be used by automatic
1042 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1044 GSList *account_names, *iter;
1046 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1049 iter = account_names;
1051 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1052 iter = g_slist_next (iter);
1055 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1056 g_slist_free (account_names);
1060 * Handler of the click on Send&Receive button in the main toolbar
1063 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1065 /* Check that at least one account exists: */
1066 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1067 TRUE /* enabled accounts only */);
1068 gboolean accounts_exist = account_names != NULL;
1069 g_slist_free (account_names);
1071 /* If not, allow the user to create an account before trying to send/receive. */
1072 if (!accounts_exist)
1073 modest_ui_actions_on_accounts (NULL, win);
1075 /* Refresh the active account */
1076 modest_ui_actions_do_send_receive (NULL, win);
1081 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1084 GtkWidget *header_view;
1086 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1088 header_view = modest_main_window_get_child_widget (main_window,
1089 MODEST_WIDGET_TYPE_HEADER_VIEW);
1093 conf = modest_runtime_get_conf ();
1095 /* what is saved/restored is depending on the style; thus; we save with
1096 * old style, then update the style, and restore for this new style
1098 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1100 if (modest_header_view_get_style
1101 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1102 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1103 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1105 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1106 MODEST_HEADER_VIEW_STYLE_DETAILS);
1108 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1109 MODEST_CONF_HEADER_VIEW_KEY);
1114 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1116 ModestMainWindow *main_window)
1118 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1120 /* If no header has been selected then exit */
1124 /* Update Main window title */
1125 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1126 const gchar *subject = tny_header_get_subject (header);
1127 if (subject && strcmp (subject, ""))
1128 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1130 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1135 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1137 ModestMainWindow *main_window)
1141 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1146 headers = tny_simple_list_new ();
1147 tny_list_prepend (headers, G_OBJECT (header));
1149 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1151 g_object_unref (headers);
1155 set_active_account_from_tny_account (TnyAccount *account,
1156 ModestWindow *window)
1158 const gchar *server_acc_name = tny_account_get_id (account);
1160 /* We need the TnyAccount provided by the
1161 account store because that is the one that
1162 knows the name of the Modest account */
1163 TnyAccount *modest_server_account = modest_server_account =
1164 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1167 const gchar *modest_acc_name =
1168 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1169 modest_window_set_active_account (window, modest_acc_name);
1170 g_object_unref (modest_server_account);
1174 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1175 TnyFolderStore *folder_store,
1177 ModestMainWindow *main_window)
1180 GtkWidget *header_view;
1182 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1184 header_view = modest_main_window_get_child_widget(main_window,
1185 MODEST_WIDGET_TYPE_HEADER_VIEW);
1189 conf = modest_runtime_get_conf ();
1191 if (TNY_IS_ACCOUNT (folder_store)) {
1192 /* Update active account */
1193 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1194 /* Show account details */
1195 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1196 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1197 //TODO: Set the virtual folder store as the "active account" somehow:
1198 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1200 if (TNY_IS_FOLDER (folder_store) && selected) {
1202 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1203 /* Update the active account */
1204 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1205 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1206 g_object_unref (account);
1209 /* Set folder on header view */
1210 modest_main_window_set_contents_style (main_window,
1211 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1212 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1213 TNY_FOLDER (folder_store));
1214 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1215 MODEST_CONF_HEADER_VIEW_KEY);
1217 /* Update the active account */
1218 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1219 /* Do not show folder */
1220 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1221 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1227 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1234 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1236 if (g_main_depth > 0)
1237 gdk_threads_enter ();
1238 online = tny_device_is_online (modest_runtime_get_device());
1241 /* already online -- the item is simply not there... */
1242 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1244 GTK_MESSAGE_WARNING,
1246 _("The %s you selected cannot be found"),
1248 gtk_dialog_run (GTK_DIALOG(dialog));
1250 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1254 GTK_RESPONSE_REJECT,
1256 GTK_RESPONSE_ACCEPT,
1258 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1259 "Do you want to get online?"), item);
1260 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1261 gtk_label_new (txt), FALSE, FALSE, 0);
1262 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1265 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1266 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1267 // modest_platform_connect_and_wait ();;
1270 gtk_widget_destroy (dialog);
1271 if (g_main_depth > 0)
1272 gdk_threads_leave ();
1276 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1279 /* g_message ("%s %s", __FUNCTION__, link); */
1284 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1287 modest_platform_activate_uri (link);
1291 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1294 modest_platform_show_uri_popup (link);
1298 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1301 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1305 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1306 const gchar *address,
1309 /* g_message ("%s %s", __FUNCTION__, address); */
1313 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1315 TnyTransportAccount *transport_account;
1316 ModestMailOperation *mail_operation;
1318 gchar *account_name, *from;
1319 ModestAccountMgr *account_mgr;
1321 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1323 data = modest_msg_edit_window_get_msg_data (edit_window);
1325 account_mgr = modest_runtime_get_account_mgr();
1326 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1328 account_name = modest_account_mgr_get_default_account (account_mgr);
1329 if (!account_name) {
1330 g_printerr ("modest: no account found\n");
1331 modest_msg_edit_window_free_msg_data (edit_window, data);
1335 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1336 (modest_runtime_get_account_store(),
1338 TNY_ACCOUNT_TYPE_TRANSPORT));
1339 if (!transport_account) {
1340 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1341 g_free (account_name);
1342 modest_msg_edit_window_free_msg_data (edit_window, data);
1345 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1347 /* Create the mail operation */
1348 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1349 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1351 modest_mail_operation_save_to_drafts (mail_operation,
1361 data->priority_flags);
1364 g_free (account_name);
1365 g_object_unref (G_OBJECT (transport_account));
1366 g_object_unref (G_OBJECT (mail_operation));
1368 modest_msg_edit_window_free_msg_data (edit_window, data);
1370 /* Save settings and close the window */
1371 gtk_widget_destroy (GTK_WIDGET (edit_window));
1374 /* For instance, when clicking the Send toolbar button when editing a message: */
1376 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1378 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1380 if (!modest_msg_edit_window_check_names (edit_window))
1383 /* FIXME: Code added just for testing. The final version will
1384 use the send queue provided by tinymail and some
1386 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1387 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1389 account_name = modest_account_mgr_get_default_account (account_mgr);
1391 if (!account_name) {
1392 g_printerr ("modest: no account found\n");
1396 /* Get the currently-active transport account for this modest account: */
1397 TnyTransportAccount *transport_account =
1398 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1399 (modest_runtime_get_account_store(),
1401 if (!transport_account) {
1402 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1403 g_free (account_name);
1407 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1409 /* Create the mail operation */
1410 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1411 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1413 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1414 modest_mail_operation_send_new_mail (mail_operation,
1424 data->priority_flags);
1428 g_free (account_name);
1429 g_object_unref (G_OBJECT (transport_account));
1430 g_object_unref (G_OBJECT (mail_operation));
1432 modest_msg_edit_window_free_msg_data (edit_window, data);
1434 /* Save settings and close the window: */
1435 gtk_widget_destroy (GTK_WIDGET (edit_window));
1439 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1440 ModestMsgEditWindow *window)
1442 ModestMsgEditFormatState *format_state = NULL;
1444 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1445 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1447 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1450 format_state = modest_msg_edit_window_get_format_state (window);
1451 g_return_if_fail (format_state != NULL);
1453 format_state->bold = gtk_toggle_action_get_active (action);
1454 modest_msg_edit_window_set_format_state (window, format_state);
1455 g_free (format_state);
1460 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1461 ModestMsgEditWindow *window)
1463 ModestMsgEditFormatState *format_state = NULL;
1465 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1466 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1468 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1471 format_state = modest_msg_edit_window_get_format_state (window);
1472 g_return_if_fail (format_state != NULL);
1474 format_state->italics = gtk_toggle_action_get_active (action);
1475 modest_msg_edit_window_set_format_state (window, format_state);
1476 g_free (format_state);
1481 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1482 ModestMsgEditWindow *window)
1484 ModestMsgEditFormatState *format_state = NULL;
1486 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1487 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1489 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1492 format_state = modest_msg_edit_window_get_format_state (window);
1493 g_return_if_fail (format_state != NULL);
1495 format_state->bullet = gtk_toggle_action_get_active (action);
1496 modest_msg_edit_window_set_format_state (window, format_state);
1497 g_free (format_state);
1502 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1503 GtkRadioAction *selected,
1504 ModestMsgEditWindow *window)
1506 ModestMsgEditFormatState *format_state = NULL;
1507 GtkJustification value;
1509 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1511 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1514 value = gtk_radio_action_get_current_value (selected);
1516 format_state = modest_msg_edit_window_get_format_state (window);
1517 g_return_if_fail (format_state != NULL);
1519 format_state->justification = value;
1520 modest_msg_edit_window_set_format_state (window, format_state);
1521 g_free (format_state);
1525 modest_ui_actions_on_select_editor_color (GtkAction *action,
1526 ModestMsgEditWindow *window)
1528 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1529 g_return_if_fail (GTK_IS_ACTION (action));
1531 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1534 modest_msg_edit_window_select_color (window);
1538 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1539 ModestMsgEditWindow *window)
1541 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1542 g_return_if_fail (GTK_IS_ACTION (action));
1544 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1547 modest_msg_edit_window_select_background_color (window);
1551 modest_ui_actions_on_insert_image (GtkAction *action,
1552 ModestMsgEditWindow *window)
1554 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1555 g_return_if_fail (GTK_IS_ACTION (action));
1557 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1560 modest_msg_edit_window_insert_image (window);
1564 modest_ui_actions_on_attach_file (GtkAction *action,
1565 ModestMsgEditWindow *window)
1567 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1568 g_return_if_fail (GTK_IS_ACTION (action));
1570 modest_msg_edit_window_attach_file (window);
1574 modest_ui_actions_on_remove_attachments (GtkAction *action,
1575 ModestMsgEditWindow *window)
1577 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1578 g_return_if_fail (GTK_IS_ACTION (action));
1580 modest_msg_edit_window_remove_attachments (window, NULL);
1584 * Shows a dialog with an entry that asks for some text. The returned
1585 * value must be freed by the caller. The dialog window title will be
1589 ask_for_folder_name (GtkWindow *parent_window,
1592 GtkWidget *dialog, *entry;
1593 gchar *folder_name = NULL;
1595 /* Ask for folder name */
1596 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1600 GTK_RESPONSE_REJECT,
1602 GTK_RESPONSE_ACCEPT,
1604 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1605 gtk_label_new(title),
1608 entry = gtk_entry_new_with_max_length (40);
1609 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1613 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1615 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1616 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1618 gtk_widget_destroy (dialog);
1624 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1626 TnyFolderStore *parent_folder;
1627 GtkWidget *folder_view;
1629 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1631 folder_view = modest_main_window_get_child_widget (main_window,
1632 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1636 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1638 if (parent_folder) {
1639 gboolean finished = FALSE;
1641 gchar *folder_name = NULL, *suggested_name = NULL;
1643 /* Run the new folder dialog */
1645 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1650 if (result == GTK_RESPONSE_REJECT) {
1653 ModestMailOperation *mail_op;
1654 TnyFolder *new_folder = NULL;
1656 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1657 G_OBJECT(main_window));
1658 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1660 new_folder = modest_mail_operation_create_folder (mail_op,
1662 (const gchar *) folder_name);
1664 g_object_unref (new_folder);
1667 g_object_unref (mail_op);
1669 g_free (folder_name);
1673 g_object_unref (parent_folder);
1678 modest_ui_actions_on_rename_folder (GtkAction *action,
1679 ModestMainWindow *main_window)
1681 TnyFolderStore *folder;
1682 GtkWidget *folder_view;
1683 GtkWidget *header_view;
1685 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1687 folder_view = modest_main_window_get_child_widget (main_window,
1688 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1692 header_view = modest_main_window_get_child_widget (main_window,
1693 MODEST_WIDGET_TYPE_HEADER_VIEW);
1698 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1700 if (folder && TNY_IS_FOLDER (folder)) {
1702 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1703 _("Please enter a new name for the folder"));
1705 if (folder_name != NULL && strlen (folder_name) > 0) {
1706 ModestMailOperation *mail_op;
1708 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1709 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1712 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1714 modest_mail_operation_rename_folder (mail_op,
1715 TNY_FOLDER (folder),
1716 (const gchar *) folder_name);
1718 g_object_unref (mail_op);
1719 g_free (folder_name);
1721 g_object_unref (folder);
1726 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1729 GObject *win = modest_mail_operation_get_source (mail_op);
1731 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1732 _("mail_in_ui_folder_delete_error"));
1736 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1738 TnyFolderStore *folder;
1739 GtkWidget *folder_view;
1743 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1745 folder_view = modest_main_window_get_child_widget (main_window,
1746 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1750 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1752 /* Show an error if it's an account */
1753 if (!TNY_IS_FOLDER (folder)) {
1754 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1755 _("mail_in_ui_folder_delete_error"));
1760 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1761 tny_folder_get_name (TNY_FOLDER (folder)));
1762 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1763 (const gchar *) message);
1766 if (response == GTK_RESPONSE_OK) {
1767 ModestMailOperation *mail_op =
1768 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1769 G_OBJECT(main_window),
1770 modest_ui_actions_delete_folder_error_handler,
1773 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1775 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1776 g_object_unref (G_OBJECT (mail_op));
1779 g_object_unref (G_OBJECT (folder));
1783 modest_ui_actions_on_delete_folder (GtkAction *action,
1784 ModestMainWindow *main_window)
1786 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1788 delete_folder (main_window, FALSE);
1792 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1794 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1796 delete_folder (main_window, TRUE);
1800 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1801 const gchar* server_account_name,
1806 ModestMainWindow *main_window)
1808 g_return_if_fail(server_account_name);
1809 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1811 /* Initalize output parameters: */
1818 #ifdef MODEST_PLATFORM_MAEMO
1819 /* Maemo uses a different (awkward) button order,
1820 * It should probably just use gtk_alternative_dialog_button_order ().
1822 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1826 GTK_RESPONSE_ACCEPT,
1828 GTK_RESPONSE_REJECT,
1831 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1835 GTK_RESPONSE_REJECT,
1837 GTK_RESPONSE_ACCEPT,
1839 #endif /* MODEST_PLATFORM_MAEMO */
1841 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1843 gchar *server_name = modest_server_account_get_hostname (
1844 modest_runtime_get_account_mgr(), server_account_name);
1846 /* This causes a warning because the logical ID has no %s in it,
1847 * though the translation does, but there is not much we can do about that: */
1848 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1849 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1852 g_free (server_name);
1856 gchar *initial_username = modest_server_account_get_username (
1857 modest_runtime_get_account_mgr(), server_account_name);
1859 GtkWidget *entry_username = gtk_entry_new ();
1860 if (initial_username)
1861 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1862 /* Dim this if a connection has ever succeeded with this username,
1863 * as per the UI spec: */
1864 const gboolean username_known =
1865 modest_server_account_get_username_has_succeeded(
1866 modest_runtime_get_account_mgr(), server_account_name);
1867 gtk_widget_set_sensitive (entry_username, !username_known);
1869 #ifdef MODEST_PLATFORM_MAEMO
1870 /* Auto-capitalization is the default, so let's turn it off: */
1871 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1873 /* Create a size group to be used by all captions.
1874 * Note that HildonCaption does not create a default size group if we do not specify one.
1875 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1876 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1878 GtkWidget *caption = hildon_caption_new (sizegroup,
1879 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1880 gtk_widget_show (entry_username);
1881 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1882 FALSE, FALSE, MODEST_MARGIN_HALF);
1883 gtk_widget_show (caption);
1885 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1887 #endif /* MODEST_PLATFORM_MAEMO */
1890 GtkWidget *entry_password = gtk_entry_new ();
1891 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1892 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1894 #ifdef MODEST_PLATFORM_MAEMO
1895 /* Auto-capitalization is the default, so let's turn it off: */
1896 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1897 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1899 caption = hildon_caption_new (sizegroup,
1900 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1901 gtk_widget_show (entry_password);
1902 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1903 FALSE, FALSE, MODEST_MARGIN_HALF);
1904 gtk_widget_show (caption);
1905 g_object_unref (sizegroup);
1907 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1909 #endif /* MODEST_PLATFORM_MAEMO */
1911 /* This is not in the Maemo UI spec:
1912 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1913 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1917 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1919 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1921 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1923 modest_server_account_set_username (
1924 modest_runtime_get_account_mgr(), server_account_name,
1927 const gboolean username_was_changed =
1928 (strcmp (*username, initial_username) != 0);
1929 if (username_was_changed) {
1930 /* To actually use a changed username,
1931 * we must reset the connection, according to pvanhoof.
1932 * This _might_ be a sensible way to do that: */
1933 TnyDevice *device = modest_runtime_get_device();
1934 tny_device_force_offline (device);
1935 tny_device_force_online (device);
1940 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1942 /* We do not save the password in the configuration,
1943 * because this function is only called for passwords that should
1944 * not be remembered:
1945 modest_server_account_set_password (
1946 modest_runtime_get_account_mgr(), server_account_name,
1965 /* This is not in the Maemo UI spec:
1966 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1972 gtk_widget_destroy (dialog);
1974 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
1978 modest_ui_actions_on_cut (GtkAction *action,
1979 ModestWindow *window)
1981 GtkWidget *focused_widget;
1983 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1984 if (GTK_IS_EDITABLE (focused_widget)) {
1985 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1986 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1987 GtkTextBuffer *buffer;
1988 GtkClipboard *clipboard;
1990 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1991 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1992 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1997 modest_ui_actions_on_copy (GtkAction *action,
1998 ModestWindow *window)
2000 GtkClipboard *clipboard;
2001 GtkWidget *focused_widget;
2003 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2004 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2005 if (GTK_IS_LABEL (focused_widget)) {
2006 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2007 } else if (GTK_IS_EDITABLE (focused_widget)) {
2008 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2009 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2010 GtkTextBuffer *buffer;
2012 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2013 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2018 modest_ui_actions_on_undo (GtkAction *action,
2019 ModestWindow *window)
2021 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2022 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2024 g_return_if_reached ();
2029 modest_ui_actions_on_paste (GtkAction *action,
2030 ModestWindow *window)
2032 GtkWidget *focused_widget;
2034 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2035 if (GTK_IS_EDITABLE (focused_widget)) {
2036 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2037 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2038 GtkTextBuffer *buffer;
2039 GtkClipboard *clipboard;
2041 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2042 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2043 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2048 modest_ui_actions_on_select_all (GtkAction *action,
2049 ModestWindow *window)
2051 GtkWidget *focused_widget;
2053 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2054 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2055 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2056 } else if (GTK_IS_LABEL (focused_widget)) {
2057 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2058 } else if (GTK_IS_EDITABLE (focused_widget)) {
2059 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2060 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2061 GtkTextBuffer *buffer;
2062 GtkTextIter start, end;
2064 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2065 gtk_text_buffer_get_start_iter (buffer, &start);
2066 gtk_text_buffer_get_end_iter (buffer, &end);
2067 gtk_text_buffer_select_range (buffer, &start, &end);
2072 modest_ui_actions_on_mark_as_read (GtkAction *action,
2073 ModestWindow *window)
2075 g_return_if_fail (MODEST_IS_WINDOW(window));
2077 /* Mark each header as read */
2078 do_headers_action (window, headers_action_mark_as_read, NULL);
2082 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2083 ModestWindow *window)
2085 g_return_if_fail (MODEST_IS_WINDOW(window));
2087 /* Mark each header as read */
2088 do_headers_action (window, headers_action_mark_as_unread, NULL);
2092 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2093 GtkRadioAction *selected,
2094 ModestWindow *window)
2098 value = gtk_radio_action_get_current_value (selected);
2099 if (MODEST_IS_WINDOW (window)) {
2100 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2104 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2105 GtkRadioAction *selected,
2106 ModestWindow *window)
2108 TnyHeaderFlags flags;
2109 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2111 flags = gtk_radio_action_get_current_value (selected);
2112 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2115 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2116 GtkRadioAction *selected,
2117 ModestWindow *window)
2121 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2123 file_format = gtk_radio_action_get_current_value (selected);
2124 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2129 modest_ui_actions_on_zoom_plus (GtkAction *action,
2130 ModestWindow *window)
2132 g_return_if_fail (MODEST_IS_WINDOW (window));
2134 modest_window_zoom_plus (MODEST_WINDOW (window));
2138 modest_ui_actions_on_zoom_minus (GtkAction *action,
2139 ModestWindow *window)
2141 g_return_if_fail (MODEST_IS_WINDOW (window));
2143 modest_window_zoom_minus (MODEST_WINDOW (window));
2147 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2148 ModestWindow *window)
2150 ModestWindowMgr *mgr;
2151 gboolean fullscreen, active;
2152 g_return_if_fail (MODEST_IS_WINDOW (window));
2154 mgr = modest_runtime_get_window_mgr ();
2156 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2157 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2159 if (active != fullscreen) {
2160 modest_window_mgr_set_fullscreen_mode (mgr, active);
2161 gtk_window_present (GTK_WINDOW (window));
2166 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2167 ModestWindow *window)
2169 ModestWindowMgr *mgr;
2170 gboolean fullscreen;
2172 g_return_if_fail (MODEST_IS_WINDOW (window));
2174 mgr = modest_runtime_get_window_mgr ();
2175 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2176 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2178 gtk_window_present (GTK_WINDOW (window));
2182 * Used by modest_ui_actions_on_details to call do_headers_action
2185 headers_action_show_details (TnyHeader *header,
2186 ModestWindow *window,
2193 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2196 gtk_widget_show_all (dialog);
2197 gtk_dialog_run (GTK_DIALOG (dialog));
2199 gtk_widget_destroy (dialog);
2203 * Show the folder details in a ModestDetailsDialog widget
2206 show_folder_details (TnyFolder *folder,
2212 dialog = modest_details_dialog_new_with_folder (window, folder);
2215 gtk_widget_show_all (dialog);
2216 gtk_dialog_run (GTK_DIALOG (dialog));
2218 gtk_widget_destroy (dialog);
2222 * Show the header details in a ModestDetailsDialog widget
2225 modest_ui_actions_on_details (GtkAction *action,
2228 TnyList * headers_list;
2232 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2235 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2238 g_object_unref (msg);
2240 headers_list = get_selected_headers (win);
2244 iter = tny_list_create_iterator (headers_list);
2246 header = TNY_HEADER (tny_iterator_get_current (iter));
2247 headers_action_show_details (header, win, NULL);
2248 g_object_unref (header);
2250 g_object_unref (iter);
2251 g_object_unref (headers_list);
2253 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2254 GtkWidget *folder_view, *header_view;
2256 /* Check which widget has the focus */
2257 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2258 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2259 if (gtk_widget_is_focus (folder_view)) {
2262 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2264 /* Show only when it's a folder */
2265 if (!folder || !TNY_IS_FOLDER (folder))
2268 show_folder_details (folder, GTK_WINDOW (win));
2271 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2272 MODEST_WIDGET_TYPE_HEADER_VIEW);
2273 /* Show details of each header */
2274 do_headers_action (win, headers_action_show_details, header_view);
2280 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2281 ModestMsgEditWindow *window)
2283 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2285 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2289 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2290 ModestMsgEditWindow *window)
2292 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2294 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2298 modest_ui_actions_toggle_folders_view (GtkAction *action,
2299 ModestMainWindow *main_window)
2303 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2305 conf = modest_runtime_get_conf ();
2307 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2308 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2310 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2314 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2315 ModestWindow *window)
2317 gboolean active, fullscreen = FALSE;
2318 ModestWindowMgr *mgr;
2320 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2322 /* Check if we want to toggle the toolbar vuew in fullscreen
2324 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2325 "ViewShowToolbarFullScreen")) {
2329 /* Toggle toolbar */
2330 mgr = modest_runtime_get_window_mgr ();
2331 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2335 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2336 ModestMsgEditWindow *window)
2338 modest_msg_edit_window_select_font (window);
2342 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2343 const gchar *display_name,
2346 /* Do not change the application name if the widget has not
2347 the focus. This callback could be called even if the folder
2348 view has not the focus, because the handled signal could be
2349 emitted when the folder view is redrawn */
2350 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2352 gtk_window_set_title (window, display_name);
2354 gtk_window_set_title (window, " ");
2359 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2361 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2362 modest_msg_edit_window_select_contacts (window);
2366 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2368 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2369 modest_msg_edit_window_check_names (window);
2374 create_move_to_dialog (ModestWindow *win,
2375 GtkWidget *folder_view,
2376 GtkWidget **tree_view)
2378 GtkWidget *dialog, *scroll;
2380 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2382 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2384 GTK_RESPONSE_ACCEPT,
2386 GTK_RESPONSE_REJECT,
2389 /* Create scrolled window */
2390 scroll = gtk_scrolled_window_new (NULL, NULL);
2391 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2392 GTK_POLICY_AUTOMATIC,
2393 GTK_POLICY_AUTOMATIC);
2395 /* Create folder view */
2396 *tree_view = modest_folder_view_new (NULL);
2397 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2398 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2399 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2401 /* Add scroll to dialog */
2402 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2403 scroll, FALSE, FALSE, 0);
2405 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2411 * Returns TRUE if at least one of the headers of the list belongs to
2412 * a message that has been fully retrieved.
2415 has_retrieved_msgs (TnyList *list)
2418 gboolean found = FALSE;
2420 iter = tny_list_create_iterator (list);
2421 while (tny_iterator_is_done (iter) && !found) {
2423 TnyHeaderFlags flags;
2425 header = TNY_HEADER (tny_iterator_get_current (iter));
2426 flags = tny_header_get_flags (header);
2427 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2431 tny_iterator_next (iter);
2433 g_object_unref (iter);
2439 * Shows a confirmation dialog to the user when we're moving messages
2440 * from a remote server to the local storage. Returns the dialog
2441 * response. If it's other kind of movement the it always returns
2445 msgs_move_to_confirmation (GtkWindow *win,
2446 TnyFolder *dest_folder,
2449 gint response = GTK_RESPONSE_OK;
2451 /* If the destination is a local folder */
2452 if (modest_tny_folder_is_local_folder (dest_folder)) {
2453 TnyFolder *src_folder;
2457 /* Get source folder */
2458 iter = tny_list_create_iterator (headers);
2459 header = TNY_HEADER (tny_iterator_get_current (iter));
2460 src_folder = tny_header_get_folder (header);
2461 g_object_unref (header);
2462 g_object_unref (iter);
2464 /* If the source is a remote folder */
2465 if (!modest_tny_folder_is_local_folder (src_folder)) {
2466 const gchar *message;
2468 if (tny_list_get_length (headers) == 1)
2469 if (has_retrieved_msgs (headers))
2470 message = _("mcen_nc_move_retrieve");
2472 message = _("mcen_nc_move_header");
2474 if (has_retrieved_msgs (headers))
2475 message = _("mcen_nc_move_retrieves");
2477 message = _("mcen_nc_move_headers");
2479 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2480 (const gchar *) message);
2482 g_object_unref (src_folder);
2489 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2491 ModestMsgViewWindow *self = NULL;
2492 gboolean found = FALSE;
2494 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2495 self = MODEST_MSG_VIEW_WINDOW (object);
2497 found = modest_msg_view_window_select_first_message (self);
2498 g_return_if_fail (found);
2502 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2505 GObject *win = modest_mail_operation_get_source (mail_op);
2507 /* TODO: show error message */
2508 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2509 _("mail_in_ui_folder_move_target_error"));
2513 * UI handler for the "Move to" action when invoked from the
2517 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2518 ModestMainWindow *win)
2520 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2521 GtkWidget *header_view = NULL;
2523 TnyFolderStore *folder_store = NULL;
2524 ModestMailOperation *mail_op = NULL;
2526 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2528 /* Get the folder view */
2529 folder_view = modest_main_window_get_child_widget (win,
2530 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2532 /* Get header view */
2533 header_view = modest_main_window_get_child_widget (win,
2534 MODEST_WIDGET_TYPE_HEADER_VIEW);
2536 /* Create and run the dialog */
2537 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2538 result = gtk_dialog_run (GTK_DIALOG(dialog));
2539 g_object_ref (tree_view);
2541 /* We do this to save an indentation level ;-) */
2542 if (result != GTK_RESPONSE_ACCEPT)
2545 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2547 if (TNY_IS_ACCOUNT (folder_store))
2550 /* Get folder or messages to transfer */
2551 if (gtk_widget_is_focus (folder_view)) {
2552 TnyFolderStore *src_folder;
2553 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2555 /* Clean folder on header view before moving it */
2556 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2558 if (TNY_IS_FOLDER (src_folder)) {
2560 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2562 modest_ui_actions_move_folder_error_handler,
2564 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2566 modest_mail_operation_xfer_folder (mail_op,
2567 TNY_FOLDER (src_folder),
2570 /* Unref mail operation */
2571 g_object_unref (G_OBJECT (mail_op));
2575 g_object_unref (G_OBJECT (src_folder));
2577 if (gtk_widget_is_focus (header_view)) {
2581 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2583 /* Ask for user confirmation */
2584 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2585 TNY_FOLDER (folder_store),
2588 /* Transfer messages */
2589 if (response == GTK_RESPONSE_OK) {
2590 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2591 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2594 modest_mail_operation_xfer_msgs (mail_op,
2596 TNY_FOLDER (folder_store),
2601 g_object_unref (G_OBJECT (mail_op));
2603 g_object_unref (headers);
2606 g_object_unref (folder_store);
2608 gtk_widget_destroy (dialog);
2613 * UI handler for the "Move to" action when invoked from the
2614 * ModestMsgViewWindow
2617 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2618 ModestMsgViewWindow *win)
2620 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2622 ModestMainWindow *main_window;
2626 /* Get the folder view */
2627 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2628 folder_view = modest_main_window_get_child_widget (main_window,
2629 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2631 /* Create and run the dialog */
2632 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2633 result = gtk_dialog_run (GTK_DIALOG(dialog));
2634 g_object_ref (tree_view);
2636 if (result == GTK_RESPONSE_ACCEPT) {
2637 TnyFolderStore *folder_store;
2640 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2642 /* Create header list */
2643 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2644 headers = tny_simple_list_new ();
2645 tny_list_prepend (headers, G_OBJECT (header));
2646 g_object_unref (header);
2648 /* Ask user for confirmation. MSG-NOT404 */
2649 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2650 TNY_FOLDER (folder_store),
2653 /* Transfer current msg */
2654 if (response == GTK_RESPONSE_OK) {
2655 ModestMailOperation *mail_op;
2657 /* Create mail op */
2658 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2659 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2662 /* Transfer messages */
2663 modest_mail_operation_xfer_msgs (mail_op,
2665 TNY_FOLDER (folder_store),
2667 tranasfer_msgs_from_viewer_cb,
2669 g_object_unref (G_OBJECT (mail_op));
2671 g_object_unref (headers);
2672 g_object_unref (folder_store);
2674 gtk_widget_destroy (dialog);
2678 modest_ui_actions_on_move_to (GtkAction *action,
2681 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2682 MODEST_IS_MSG_VIEW_WINDOW (win));
2684 if (MODEST_IS_MAIN_WINDOW (win))
2685 modest_ui_actions_on_main_window_move_to (action,
2686 MODEST_MAIN_WINDOW (win));
2688 modest_ui_actions_on_msg_view_window_move_to (action,
2689 MODEST_MSG_VIEW_WINDOW (win));
2693 * Calls #HeadersFunc for each header already selected in the main
2694 * window or the message currently being shown in the msg view window
2697 do_headers_action (ModestWindow *win,
2701 TnyList *headers_list;
2705 headers_list = get_selected_headers (win);
2709 /* Call the function for each header */
2710 iter = tny_list_create_iterator (headers_list);
2711 while (!tny_iterator_is_done (iter)) {
2714 header = TNY_HEADER (tny_iterator_get_current (iter));
2715 func (header, win, user_data);
2716 g_object_unref (header);
2717 tny_iterator_next (iter);
2719 g_object_unref (iter);
2720 g_object_unref (headers_list);
2724 modest_ui_actions_view_attachment (GtkAction *action,
2725 ModestWindow *window)
2727 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2728 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2730 /* not supported window for this action */
2731 g_return_if_reached ();
2736 modest_ui_actions_save_attachments (GtkAction *action,
2737 ModestWindow *window)
2739 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2740 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2742 /* not supported window for this action */
2743 g_return_if_reached ();
2748 modest_ui_actions_remove_attachments (GtkAction *action,
2749 ModestWindow *window)
2751 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2752 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2754 /* not supported window for this action */
2755 g_return_if_reached ();
2760 modest_ui_actions_on_settings (GtkAction *action,
2765 dialog = modest_platform_get_global_settings_dialog ();
2766 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2767 gtk_widget_show (dialog);
2769 gtk_dialog_run (GTK_DIALOG (dialog));
2771 gtk_widget_destroy (dialog);
2775 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2776 ModestWindow *window)
2778 ModestMailOperation *mail_op;
2782 headers = get_selected_headers (window);
2786 /* Create mail operation */
2787 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2789 modest_ui_actions_get_msgs_full_error_handler,
2791 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2792 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2795 g_object_unref (headers);
2796 g_object_unref (mail_op);
2800 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2801 ModestWindow *window)
2803 g_return_if_fail (MODEST_IS_WINDOW (window));
2806 modest_window_check_dimming_rules (window);
2810 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2811 ModestWindow *window)
2813 g_return_if_fail (MODEST_IS_WINDOW (window));
2816 modest_window_check_dimming_rules (window);
2820 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2821 ModestWindow *window)
2823 g_return_if_fail (MODEST_IS_WINDOW (window));
2826 modest_window_check_dimming_rules (window);
2830 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2831 ModestWindow *window)
2833 g_return_if_fail (MODEST_IS_WINDOW (window));
2836 modest_window_check_dimming_rules (window);
2840 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2841 ModestWindow *window)
2843 g_return_if_fail (MODEST_IS_WINDOW (window));
2846 modest_window_check_dimming_rules (window);