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 = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1654 TnyFolder *new_folder = NULL;
1656 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1659 new_folder = modest_mail_operation_create_folder (mail_op,
1661 (const gchar *) folder_name);
1663 g_object_unref (new_folder);
1667 /* /\* TODO: check error and follow proper actions *\/ */
1668 /* /\* suggested_name = X; *\/ */
1669 /* /\* Show error to the user *\/ */
1670 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1671 /* _("mail_in_ui_folder_create_error")); */
1673 g_object_unref (mail_op);
1675 g_free (folder_name);
1679 g_object_unref (parent_folder);
1684 modest_ui_actions_on_rename_folder (GtkAction *action,
1685 ModestMainWindow *main_window)
1687 TnyFolderStore *folder;
1688 GtkWidget *folder_view;
1689 GtkWidget *header_view;
1691 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1693 folder_view = modest_main_window_get_child_widget (main_window,
1694 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1698 header_view = modest_main_window_get_child_widget (main_window,
1699 MODEST_WIDGET_TYPE_HEADER_VIEW);
1704 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1706 if (folder && TNY_IS_FOLDER (folder)) {
1708 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1709 _("Please enter a new name for the folder"));
1711 if (folder_name != NULL && strlen (folder_name) > 0) {
1712 ModestMailOperation *mail_op;
1714 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1715 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1718 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1720 modest_mail_operation_rename_folder (mail_op,
1721 TNY_FOLDER (folder),
1722 (const gchar *) folder_name);
1724 g_object_unref (mail_op);
1725 g_free (folder_name);
1727 g_object_unref (folder);
1732 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1735 GObject *win = modest_mail_operation_get_source (mail_op);
1737 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1738 _("mail_in_ui_folder_delete_error"));
1742 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1744 TnyFolderStore *folder;
1745 GtkWidget *folder_view;
1749 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1751 folder_view = modest_main_window_get_child_widget (main_window,
1752 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1756 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1758 /* Show an error if it's an account */
1759 if (!TNY_IS_FOLDER (folder)) {
1760 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1761 _("mail_in_ui_folder_delete_error"));
1766 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1767 tny_folder_get_name (TNY_FOLDER (folder)));
1768 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1769 (const gchar *) message);
1772 if (response == GTK_RESPONSE_OK) {
1773 ModestMailOperation *mail_op =
1774 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1775 G_OBJECT(main_window),
1776 modest_ui_actions_delete_folder_error_handler,
1779 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1781 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1782 g_object_unref (G_OBJECT (mail_op));
1785 g_object_unref (G_OBJECT (folder));
1789 modest_ui_actions_on_delete_folder (GtkAction *action,
1790 ModestMainWindow *main_window)
1792 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1794 delete_folder (main_window, FALSE);
1798 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1800 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1802 delete_folder (main_window, TRUE);
1806 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1807 const gchar* server_account_name,
1812 ModestMainWindow *main_window)
1814 g_return_if_fail(server_account_name);
1815 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1817 /* Initalize output parameters: */
1824 #ifdef MODEST_PLATFORM_MAEMO
1825 /* Maemo uses a different (awkward) button order,
1826 * It should probably just use gtk_alternative_dialog_button_order ().
1828 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1832 GTK_RESPONSE_ACCEPT,
1834 GTK_RESPONSE_REJECT,
1837 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1841 GTK_RESPONSE_REJECT,
1843 GTK_RESPONSE_ACCEPT,
1845 #endif /* MODEST_PLATFORM_MAEMO */
1847 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1849 gchar *server_name = modest_server_account_get_hostname (
1850 modest_runtime_get_account_mgr(), server_account_name);
1852 /* This causes a warning because the logical ID has no %s in it,
1853 * though the translation does, but there is not much we can do about that: */
1854 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1855 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1858 g_free (server_name);
1862 gchar *initial_username = modest_server_account_get_username (
1863 modest_runtime_get_account_mgr(), server_account_name);
1865 GtkWidget *entry_username = gtk_entry_new ();
1866 if (initial_username)
1867 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1868 /* Dim this if a connection has ever succeeded with this username,
1869 * as per the UI spec: */
1870 const gboolean username_known =
1871 modest_server_account_get_username_has_succeeded(
1872 modest_runtime_get_account_mgr(), server_account_name);
1873 gtk_widget_set_sensitive (entry_username, !username_known);
1875 #ifdef MODEST_PLATFORM_MAEMO
1876 /* Auto-capitalization is the default, so let's turn it off: */
1877 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1879 /* Create a size group to be used by all captions.
1880 * Note that HildonCaption does not create a default size group if we do not specify one.
1881 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1882 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1884 GtkWidget *caption = hildon_caption_new (sizegroup,
1885 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1886 gtk_widget_show (entry_username);
1887 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1888 FALSE, FALSE, MODEST_MARGIN_HALF);
1889 gtk_widget_show (caption);
1891 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1893 #endif /* MODEST_PLATFORM_MAEMO */
1896 GtkWidget *entry_password = gtk_entry_new ();
1897 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1898 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1900 #ifdef MODEST_PLATFORM_MAEMO
1901 /* Auto-capitalization is the default, so let's turn it off: */
1902 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1903 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1905 caption = hildon_caption_new (sizegroup,
1906 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1907 gtk_widget_show (entry_password);
1908 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1909 FALSE, FALSE, MODEST_MARGIN_HALF);
1910 gtk_widget_show (caption);
1911 g_object_unref (sizegroup);
1913 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1915 #endif /* MODEST_PLATFORM_MAEMO */
1917 /* This is not in the Maemo UI spec:
1918 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1919 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1923 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1925 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1927 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1929 modest_server_account_set_username (
1930 modest_runtime_get_account_mgr(), server_account_name,
1933 const gboolean username_was_changed =
1934 (strcmp (*username, initial_username) != 0);
1935 if (username_was_changed) {
1936 /* To actually use a changed username,
1937 * we must reset the connection, according to pvanhoof.
1938 * This _might_ be a sensible way to do that: */
1939 TnyDevice *device = modest_runtime_get_device();
1940 tny_device_force_offline (device);
1941 tny_device_force_online (device);
1946 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1948 /* We do not save the password in the configuration,
1949 * because this function is only called for passwords that should
1950 * not be remembered:
1951 modest_server_account_set_password (
1952 modest_runtime_get_account_mgr(), server_account_name,
1971 /* This is not in the Maemo UI spec:
1972 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1978 gtk_widget_destroy (dialog);
1980 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
1984 modest_ui_actions_on_cut (GtkAction *action,
1985 ModestWindow *window)
1987 GtkWidget *focused_widget;
1989 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1990 if (GTK_IS_EDITABLE (focused_widget)) {
1991 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1992 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1993 GtkTextBuffer *buffer;
1994 GtkClipboard *clipboard;
1996 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1997 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1998 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2003 modest_ui_actions_on_copy (GtkAction *action,
2004 ModestWindow *window)
2006 GtkClipboard *clipboard;
2007 GtkWidget *focused_widget;
2009 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2010 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2011 if (GTK_IS_LABEL (focused_widget)) {
2012 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2013 } else if (GTK_IS_EDITABLE (focused_widget)) {
2014 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2015 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2016 GtkTextBuffer *buffer;
2018 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2019 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2024 modest_ui_actions_on_undo (GtkAction *action,
2025 ModestWindow *window)
2027 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2028 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2030 g_return_if_reached ();
2035 modest_ui_actions_on_paste (GtkAction *action,
2036 ModestWindow *window)
2038 GtkWidget *focused_widget;
2040 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2041 if (GTK_IS_EDITABLE (focused_widget)) {
2042 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2043 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2044 GtkTextBuffer *buffer;
2045 GtkClipboard *clipboard;
2047 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2048 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2049 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2054 modest_ui_actions_on_select_all (GtkAction *action,
2055 ModestWindow *window)
2057 GtkWidget *focused_widget;
2059 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2060 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2061 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2062 } else if (GTK_IS_LABEL (focused_widget)) {
2063 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2064 } else if (GTK_IS_EDITABLE (focused_widget)) {
2065 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2066 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2067 GtkTextBuffer *buffer;
2068 GtkTextIter start, end;
2070 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2071 gtk_text_buffer_get_start_iter (buffer, &start);
2072 gtk_text_buffer_get_end_iter (buffer, &end);
2073 gtk_text_buffer_select_range (buffer, &start, &end);
2078 modest_ui_actions_on_mark_as_read (GtkAction *action,
2079 ModestWindow *window)
2081 g_return_if_fail (MODEST_IS_WINDOW(window));
2083 /* Mark each header as read */
2084 do_headers_action (window, headers_action_mark_as_read, NULL);
2088 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2089 ModestWindow *window)
2091 g_return_if_fail (MODEST_IS_WINDOW(window));
2093 /* Mark each header as read */
2094 do_headers_action (window, headers_action_mark_as_unread, NULL);
2098 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2099 GtkRadioAction *selected,
2100 ModestWindow *window)
2104 value = gtk_radio_action_get_current_value (selected);
2105 if (MODEST_IS_WINDOW (window)) {
2106 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2110 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2111 GtkRadioAction *selected,
2112 ModestWindow *window)
2114 TnyHeaderFlags flags;
2115 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2117 flags = gtk_radio_action_get_current_value (selected);
2118 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2121 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2122 GtkRadioAction *selected,
2123 ModestWindow *window)
2127 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2129 file_format = gtk_radio_action_get_current_value (selected);
2130 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2135 modest_ui_actions_on_zoom_plus (GtkAction *action,
2136 ModestWindow *window)
2138 g_return_if_fail (MODEST_IS_WINDOW (window));
2140 modest_window_zoom_plus (MODEST_WINDOW (window));
2144 modest_ui_actions_on_zoom_minus (GtkAction *action,
2145 ModestWindow *window)
2147 g_return_if_fail (MODEST_IS_WINDOW (window));
2149 modest_window_zoom_minus (MODEST_WINDOW (window));
2153 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2154 ModestWindow *window)
2156 ModestWindowMgr *mgr;
2157 gboolean fullscreen, active;
2158 g_return_if_fail (MODEST_IS_WINDOW (window));
2160 mgr = modest_runtime_get_window_mgr ();
2162 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2163 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2165 if (active != fullscreen) {
2166 modest_window_mgr_set_fullscreen_mode (mgr, active);
2167 gtk_window_present (GTK_WINDOW (window));
2172 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2173 ModestWindow *window)
2175 ModestWindowMgr *mgr;
2176 gboolean fullscreen;
2178 g_return_if_fail (MODEST_IS_WINDOW (window));
2180 mgr = modest_runtime_get_window_mgr ();
2181 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2182 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2184 gtk_window_present (GTK_WINDOW (window));
2188 * Used by modest_ui_actions_on_details to call do_headers_action
2191 headers_action_show_details (TnyHeader *header,
2192 ModestWindow *window,
2199 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2202 gtk_widget_show_all (dialog);
2203 gtk_dialog_run (GTK_DIALOG (dialog));
2205 gtk_widget_destroy (dialog);
2209 * Show the folder details in a ModestDetailsDialog widget
2212 show_folder_details (TnyFolder *folder,
2218 dialog = modest_details_dialog_new_with_folder (window, folder);
2221 gtk_widget_show_all (dialog);
2222 gtk_dialog_run (GTK_DIALOG (dialog));
2224 gtk_widget_destroy (dialog);
2228 * Show the header details in a ModestDetailsDialog widget
2231 modest_ui_actions_on_details (GtkAction *action,
2234 TnyList * headers_list;
2238 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2241 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2244 g_object_unref (msg);
2246 headers_list = get_selected_headers (win);
2250 iter = tny_list_create_iterator (headers_list);
2252 header = TNY_HEADER (tny_iterator_get_current (iter));
2253 headers_action_show_details (header, win, NULL);
2254 g_object_unref (header);
2256 g_object_unref (iter);
2257 g_object_unref (headers_list);
2259 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2260 GtkWidget *folder_view, *header_view;
2262 /* Check which widget has the focus */
2263 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2264 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2265 if (gtk_widget_is_focus (folder_view)) {
2268 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2270 /* Show only when it's a folder */
2271 if (!folder || !TNY_IS_FOLDER (folder))
2274 show_folder_details (folder, GTK_WINDOW (win));
2277 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2278 MODEST_WIDGET_TYPE_HEADER_VIEW);
2279 /* Show details of each header */
2280 do_headers_action (win, headers_action_show_details, header_view);
2286 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2287 ModestMsgEditWindow *window)
2289 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2291 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2295 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2296 ModestMsgEditWindow *window)
2298 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2300 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2304 modest_ui_actions_toggle_folders_view (GtkAction *action,
2305 ModestMainWindow *main_window)
2309 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2311 conf = modest_runtime_get_conf ();
2313 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2314 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2316 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2320 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2321 ModestWindow *window)
2323 gboolean active, fullscreen = FALSE;
2324 ModestWindowMgr *mgr;
2326 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2328 /* Check if we want to toggle the toolbar vuew in fullscreen
2330 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2331 "ViewShowToolbarFullScreen")) {
2335 /* Toggle toolbar */
2336 mgr = modest_runtime_get_window_mgr ();
2337 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2341 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2342 ModestMsgEditWindow *window)
2344 modest_msg_edit_window_select_font (window);
2348 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2349 const gchar *display_name,
2352 /* Do not change the application name if the widget has not
2353 the focus. This callback could be called even if the folder
2354 view has not the focus, because the handled signal could be
2355 emitted when the folder view is redrawn */
2356 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2358 gtk_window_set_title (window, display_name);
2360 gtk_window_set_title (window, " ");
2365 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2367 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2368 modest_msg_edit_window_select_contacts (window);
2372 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2374 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2375 modest_msg_edit_window_check_names (window);
2380 create_move_to_dialog (ModestWindow *win,
2381 GtkWidget *folder_view,
2382 GtkWidget **tree_view)
2384 GtkWidget *dialog, *scroll;
2386 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2388 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2390 GTK_RESPONSE_ACCEPT,
2392 GTK_RESPONSE_REJECT,
2395 /* Create scrolled window */
2396 scroll = gtk_scrolled_window_new (NULL, NULL);
2397 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2398 GTK_POLICY_AUTOMATIC,
2399 GTK_POLICY_AUTOMATIC);
2401 /* Create folder view */
2402 *tree_view = modest_folder_view_new (NULL);
2403 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2404 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2405 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2407 /* Add scroll to dialog */
2408 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2409 scroll, FALSE, FALSE, 0);
2411 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2417 * Returns TRUE if at least one of the headers of the list belongs to
2418 * a message that has been fully retrieved.
2421 has_retrieved_msgs (TnyList *list)
2424 gboolean found = FALSE;
2426 iter = tny_list_create_iterator (list);
2427 while (tny_iterator_is_done (iter) && !found) {
2429 TnyHeaderFlags flags;
2431 header = TNY_HEADER (tny_iterator_get_current (iter));
2432 flags = tny_header_get_flags (header);
2433 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2437 tny_iterator_next (iter);
2439 g_object_unref (iter);
2445 * Shows a confirmation dialog to the user when we're moving messages
2446 * from a remote server to the local storage. Returns the dialog
2447 * response. If it's other kind of movement the it always returns
2451 msgs_move_to_confirmation (GtkWindow *win,
2452 TnyFolder *dest_folder,
2455 gint response = GTK_RESPONSE_OK;
2457 /* If the destination is a local folder */
2458 if (modest_tny_folder_is_local_folder (dest_folder)) {
2459 TnyFolder *src_folder;
2463 /* Get source folder */
2464 iter = tny_list_create_iterator (headers);
2465 header = TNY_HEADER (tny_iterator_get_current (iter));
2466 src_folder = tny_header_get_folder (header);
2467 g_object_unref (header);
2468 g_object_unref (iter);
2470 /* If the source is a remote folder */
2471 if (!modest_tny_folder_is_local_folder (src_folder)) {
2472 const gchar *message;
2474 if (tny_list_get_length (headers) == 1)
2475 if (has_retrieved_msgs (headers))
2476 message = _("mcen_nc_move_retrieve");
2478 message = _("mcen_nc_move_header");
2480 if (has_retrieved_msgs (headers))
2481 message = _("mcen_nc_move_retrieves");
2483 message = _("mcen_nc_move_headers");
2485 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2486 (const gchar *) message);
2488 g_object_unref (src_folder);
2495 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2497 ModestMsgViewWindow *self = NULL;
2498 gboolean found = FALSE;
2500 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2501 self = MODEST_MSG_VIEW_WINDOW (object);
2503 found = modest_msg_view_window_select_first_message (self);
2504 g_return_if_fail (found);
2508 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2511 GObject *win = modest_mail_operation_get_source (mail_op);
2513 /* TODO: show error message */
2514 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2515 _("mail_in_ui_folder_move_target_error"));
2519 * UI handler for the "Move to" action when invoked from the
2523 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2524 ModestMainWindow *win)
2526 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2527 GtkWidget *header_view = NULL;
2529 TnyFolderStore *folder_store = NULL;
2530 ModestMailOperation *mail_op = NULL;
2532 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2534 /* Get the folder view */
2535 folder_view = modest_main_window_get_child_widget (win,
2536 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2538 /* Get header view */
2539 header_view = modest_main_window_get_child_widget (win,
2540 MODEST_WIDGET_TYPE_HEADER_VIEW);
2542 /* Create and run the dialog */
2543 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2544 result = gtk_dialog_run (GTK_DIALOG(dialog));
2545 g_object_ref (tree_view);
2547 /* We do this to save an indentation level ;-) */
2548 if (result != GTK_RESPONSE_ACCEPT)
2551 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2553 if (TNY_IS_ACCOUNT (folder_store))
2556 /* Get folder or messages to transfer */
2557 if (gtk_widget_is_focus (folder_view)) {
2558 TnyFolderStore *src_folder;
2559 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2561 /* Clean folder on header view before moving it */
2562 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2564 if (TNY_IS_FOLDER (src_folder)) {
2566 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2568 modest_ui_actions_move_folder_error_handler,
2570 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2572 modest_mail_operation_xfer_folder (mail_op,
2573 TNY_FOLDER (src_folder),
2576 /* Unref mail operation */
2577 g_object_unref (G_OBJECT (mail_op));
2581 g_object_unref (G_OBJECT (src_folder));
2583 if (gtk_widget_is_focus (header_view)) {
2587 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2589 /* Ask for user confirmation */
2590 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2591 TNY_FOLDER (folder_store),
2594 /* Transfer messages */
2595 if (response == GTK_RESPONSE_OK) {
2596 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2597 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2600 modest_mail_operation_xfer_msgs (mail_op,
2602 TNY_FOLDER (folder_store),
2607 g_object_unref (G_OBJECT (mail_op));
2609 g_object_unref (headers);
2612 g_object_unref (folder_store);
2614 gtk_widget_destroy (dialog);
2619 * UI handler for the "Move to" action when invoked from the
2620 * ModestMsgViewWindow
2623 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2624 ModestMsgViewWindow *win)
2626 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2628 ModestMainWindow *main_window;
2632 /* Get the folder view */
2633 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2634 folder_view = modest_main_window_get_child_widget (main_window,
2635 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2637 /* Create and run the dialog */
2638 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2639 result = gtk_dialog_run (GTK_DIALOG(dialog));
2640 g_object_ref (tree_view);
2642 if (result == GTK_RESPONSE_ACCEPT) {
2643 TnyFolderStore *folder_store;
2646 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2648 /* Create header list */
2649 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2650 headers = tny_simple_list_new ();
2651 tny_list_prepend (headers, G_OBJECT (header));
2652 g_object_unref (header);
2654 /* Ask user for confirmation. MSG-NOT404 */
2655 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2656 TNY_FOLDER (folder_store),
2659 /* Transfer current msg */
2660 if (response == GTK_RESPONSE_OK) {
2661 ModestMailOperation *mail_op;
2663 /* Create mail op */
2664 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2665 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2668 /* Transfer messages */
2669 modest_mail_operation_xfer_msgs (mail_op,
2671 TNY_FOLDER (folder_store),
2673 tranasfer_msgs_from_viewer_cb,
2675 g_object_unref (G_OBJECT (mail_op));
2677 g_object_unref (headers);
2678 g_object_unref (folder_store);
2680 gtk_widget_destroy (dialog);
2684 modest_ui_actions_on_move_to (GtkAction *action,
2687 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2688 MODEST_IS_MSG_VIEW_WINDOW (win));
2690 if (MODEST_IS_MAIN_WINDOW (win))
2691 modest_ui_actions_on_main_window_move_to (action,
2692 MODEST_MAIN_WINDOW (win));
2694 modest_ui_actions_on_msg_view_window_move_to (action,
2695 MODEST_MSG_VIEW_WINDOW (win));
2699 * Calls #HeadersFunc for each header already selected in the main
2700 * window or the message currently being shown in the msg view window
2703 do_headers_action (ModestWindow *win,
2707 TnyList *headers_list;
2711 headers_list = get_selected_headers (win);
2715 /* Call the function for each header */
2716 iter = tny_list_create_iterator (headers_list);
2717 while (!tny_iterator_is_done (iter)) {
2720 header = TNY_HEADER (tny_iterator_get_current (iter));
2721 func (header, win, user_data);
2722 g_object_unref (header);
2723 tny_iterator_next (iter);
2725 g_object_unref (iter);
2726 g_object_unref (headers_list);
2730 modest_ui_actions_view_attachment (GtkAction *action,
2731 ModestWindow *window)
2733 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2734 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2736 /* not supported window for this action */
2737 g_return_if_reached ();
2742 modest_ui_actions_save_attachments (GtkAction *action,
2743 ModestWindow *window)
2745 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2746 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2748 /* not supported window for this action */
2749 g_return_if_reached ();
2754 modest_ui_actions_remove_attachments (GtkAction *action,
2755 ModestWindow *window)
2757 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2758 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2760 /* not supported window for this action */
2761 g_return_if_reached ();
2766 modest_ui_actions_on_settings (GtkAction *action,
2771 dialog = modest_platform_get_global_settings_dialog ();
2772 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2773 gtk_widget_show (dialog);
2775 gtk_dialog_run (GTK_DIALOG (dialog));
2777 gtk_widget_destroy (dialog);
2781 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2782 ModestWindow *window)
2784 ModestMailOperation *mail_op;
2788 headers = get_selected_headers (window);
2792 /* Create mail operation */
2793 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2795 modest_ui_actions_get_msgs_full_error_handler,
2797 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2798 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2801 g_object_unref (headers);
2802 g_object_unref (mail_op);
2806 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2807 ModestWindow *window)
2809 g_return_if_fail (MODEST_IS_WINDOW (window));
2812 modest_window_check_dimming_rules (window);
2816 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2817 ModestWindow *window)
2819 g_return_if_fail (MODEST_IS_WINDOW (window));
2822 modest_window_check_dimming_rules (window);
2826 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2827 ModestWindow *window)
2829 g_return_if_fail (MODEST_IS_WINDOW (window));
2832 modest_window_check_dimming_rules (window);
2836 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2837 ModestWindow *window)
2839 g_return_if_fail (MODEST_IS_WINDOW (window));
2842 modest_window_check_dimming_rules (window);
2846 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2847 ModestWindow *window)
2849 g_return_if_fail (MODEST_IS_WINDOW (window));
2852 modest_window_check_dimming_rules (window);