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 /* Question: why is the clipboard being used here?
317 * It doesn't really make a lot of sense. */
321 modest_address_book_add_address (selection);
327 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
329 /* This is currently only implemented for Maemo,
330 * because it requires a providers preset file which is not publically available.
332 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
333 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
334 TRUE /* enabled accounts only */);
335 gboolean accounts_exist = account_names != NULL;
336 g_slist_free (account_names);
338 if (!accounts_exist) {
339 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
340 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
341 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
342 gtk_dialog_run (GTK_DIALOG (wizard));
343 gtk_widget_destroy (GTK_WIDGET (wizard));
345 /* Show the list of accounts: */
346 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
347 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
348 gtk_dialog_run (account_win);
349 gtk_widget_destroy (GTK_WIDGET(account_win));
352 GtkWidget *dialog, *label;
354 /* Create the widgets */
356 dialog = gtk_dialog_new_with_buttons ("Message",
358 GTK_DIALOG_DESTROY_WITH_PARENT,
362 label = gtk_label_new ("Hello World!");
364 /* Ensure that the dialog box is destroyed when the user responds. */
366 g_signal_connect_swapped (dialog, "response",
367 G_CALLBACK (gtk_widget_destroy),
370 /* Add the label, and show everything we've added to the dialog. */
372 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
374 gtk_widget_show_all (dialog);
375 #endif /* MODEST_PLATFORM_MAEMO */
379 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
381 ModestWindow *main_window = MODEST_WINDOW (user_data);
383 /* Save any changes. */
384 modest_connection_specific_smtp_window_save_server_accounts (
385 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
386 modest_window_get_active_account (main_window));
387 gtk_widget_destroy (GTK_WIDGET (window));
391 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
393 /* This is currently only implemented for Maemo,
394 * because it requires an API (libconic) to detect different connection
397 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
399 /* Create the window if necessary: */
400 const gchar *active_account_name = modest_window_get_active_account (win);
402 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
403 * or show the default account?
404 * If we show the default account then the account name should be shown in
405 * the window when we show it. */
406 if (!active_account_name) {
407 g_warning ("%s: No account is active.", __FUNCTION__);
411 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
412 modest_connection_specific_smtp_window_fill_with_connections (
413 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
414 modest_runtime_get_account_mgr(),
415 active_account_name);
417 /* Show the window: */
418 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
419 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
420 gtk_widget_show (specific_window);
422 /* Save changes when the window is hidden: */
423 g_signal_connect (specific_window, "hide",
424 G_CALLBACK (on_smtp_servers_window_hide), win);
425 #endif /* MODEST_PLATFORM_MAEMO */
429 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
431 ModestWindow *msg_win;
433 TnyFolder *folder = NULL;
434 gchar *account_name = NULL;
435 gchar *from_str = NULL;
436 /* GError *err = NULL; */
437 TnyAccount *account = NULL;
438 ModestWindowMgr *mgr;
439 gchar *signature = NULL;
441 account_name = g_strdup(modest_window_get_active_account (win));
443 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
445 g_printerr ("modest: no account found\n");
449 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
451 TNY_ACCOUNT_TYPE_STORE);
453 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
457 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
459 g_printerr ("modest: failed get from string for '%s'\n", account_name);
463 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
464 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
465 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
466 MODEST_ACCOUNT_SIGNATURE, FALSE);
468 signature = g_strdup ("");
471 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
473 g_printerr ("modest: failed to create new msg\n");
477 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
479 g_printerr ("modest: failed to find Drafts folder\n");
483 /* tny_folder_add_msg (folder, msg, &err); */
485 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
487 /* g_error_free (err); */
491 /* Create and register edit window */
492 /* This is destroyed by TOOD. */
493 msg_win = modest_msg_edit_window_new (msg, account_name);
494 mgr = modest_runtime_get_window_mgr ();
495 modest_window_mgr_register_window (mgr, msg_win);
498 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
500 gtk_widget_show_all (GTK_WIDGET (msg_win));
503 g_free (account_name);
507 g_object_unref (G_OBJECT(account));
509 g_object_unref (G_OBJECT(msg));
511 g_object_unref (G_OBJECT(folder));
515 open_msg_cb (ModestMailOperation *mail_op,
520 ModestWindowMgr *mgr = NULL;
521 ModestWindow *parent_win = NULL;
522 ModestWindow *win = NULL;
523 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
524 gchar *account = NULL;
527 /* TODO: Show an error? (review the specs) */
531 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
532 folder = tny_header_get_folder (header);
534 /* Mark header as read */
535 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
538 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
540 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
542 /* Gets folder type (OUTBOX headers will be opened in edit window */
543 if (modest_tny_folder_is_local_folder (folder))
544 folder_type = modest_tny_folder_get_local_folder_type (folder);
546 /* If the header is in the drafts folder then open the editor,
547 else the message view window */
548 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
549 win = modest_msg_edit_window_new (msg, account);
551 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
552 GtkWidget *header_view;
553 GtkTreeSelection *sel;
554 GList *sel_list = NULL;
557 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
558 MODEST_WIDGET_TYPE_HEADER_VIEW);
560 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
561 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
563 if (sel_list != NULL) {
564 GtkTreeRowReference *row_reference;
566 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
567 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
568 g_list_free (sel_list);
570 win = modest_msg_view_window_new_with_header_model (msg,
574 gtk_tree_row_reference_free (row_reference);
576 win = modest_msg_view_window_new (msg, account);
579 win = modest_msg_view_window_new (msg, account);
583 /* Register and show new window */
585 mgr = modest_runtime_get_window_mgr ();
586 modest_window_mgr_register_window (mgr, win);
587 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
588 gtk_widget_show_all (GTK_WIDGET(win));
593 g_object_unref (msg);
594 g_object_unref (folder);
595 g_object_unref (header);
599 * This function is the error handler of the
600 * modest_mail_operation_get_msgs_full operation
603 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
608 error = modest_mail_operation_get_error (mail_op);
609 if (error->code == MODEST_MAIL_OPERATION_ERROR_SIZE_LIMIT) {
610 GObject *win = modest_mail_operation_get_source (mail_op);
612 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
618 * This function is used by both modest_ui_actions_on_open and
619 * modest_ui_actions_on_header_activated. This way we always do the
620 * same when trying to open messages.
623 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
625 ModestWindowMgr *mgr;
627 ModestMailOperation *mail_op;
629 /* Look if we already have a message view for each header. If
630 true, then remove the header from the list of headers to
632 mgr = modest_runtime_get_window_mgr ();
633 iter = tny_list_create_iterator (headers);
634 while (!tny_iterator_is_done (iter)) {
635 ModestWindow *window;
638 header = TNY_HEADER (tny_iterator_get_current (iter));
639 window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
641 tny_list_remove (headers, G_OBJECT (header));
643 g_object_unref (header);
644 tny_iterator_next (iter);
647 /* Open each message */
648 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
650 modest_ui_actions_get_msgs_full_error_handler,
652 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
653 modest_mail_operation_get_msgs_full (mail_op,
660 g_object_unref(mail_op);
664 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
669 headers = get_selected_headers (win);
674 _modest_ui_actions_open (headers, win);
676 g_object_unref(headers);
681 free_reply_forward_helper (gpointer data)
683 ReplyForwardHelper *helper;
685 helper = (ReplyForwardHelper *) data;
686 g_free (helper->account_name);
687 g_slice_free (ReplyForwardHelper, helper);
691 reply_forward_cb (ModestMailOperation *mail_op,
697 ReplyForwardHelper *rf_helper;
698 ModestWindow *msg_win;
699 ModestEditType edit_type;
702 TnyFolder *folder = NULL;
703 TnyAccount *account = NULL;
704 ModestWindowMgr *mgr;
705 gchar *signature = NULL;
707 g_return_if_fail (user_data != NULL);
708 rf_helper = (ReplyForwardHelper *) user_data;
710 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
711 rf_helper->account_name);
712 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
713 rf_helper->account_name,
714 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
715 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
716 rf_helper->account_name,
717 MODEST_ACCOUNT_SIGNATURE, FALSE);
720 /* Create reply mail */
721 switch (rf_helper->action) {
724 modest_tny_msg_create_reply_msg (msg, from, signature,
725 rf_helper->reply_forward_type,
726 MODEST_TNY_MSG_REPLY_MODE_SENDER);
728 case ACTION_REPLY_TO_ALL:
730 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
731 MODEST_TNY_MSG_REPLY_MODE_ALL);
732 edit_type = MODEST_EDIT_TYPE_REPLY;
736 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
737 edit_type = MODEST_EDIT_TYPE_FORWARD;
740 g_return_if_reached ();
747 g_printerr ("modest: failed to create message\n");
751 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
752 rf_helper->account_name,
753 TNY_ACCOUNT_TYPE_STORE);
755 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
759 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
761 g_printerr ("modest: failed to find Drafts folder\n");
765 tny_folder_add_msg (folder, msg, &err);
767 g_printerr ("modest: error adding msg to Drafts folder: %s",
773 /* Create and register the windows */
774 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
775 mgr = modest_runtime_get_window_mgr ();
776 modest_window_mgr_register_window (mgr, msg_win);
778 /* Show edit window */
779 gtk_widget_show_all (GTK_WIDGET (msg_win));
783 g_object_unref (G_OBJECT (new_msg));
785 g_object_unref (G_OBJECT (folder));
787 g_object_unref (G_OBJECT (account));
788 g_object_unref (msg);
789 g_object_unref (header);
793 * Checks a list of headers. If any of them are not currently
794 * downloaded (CACHED) then it asks the user for permission to
797 * Returns FALSE if the user does not want to download the
798 * messages. Returns TRUE if the user allowed the download or if all
799 * of them are currently downloaded
802 download_uncached_messages (TnyList *header_list, GtkWindow *win)
805 gboolean found, retval;
807 iter = tny_list_create_iterator (header_list);
809 while (!tny_iterator_is_done (iter) && !found) {
811 TnyHeaderFlags flags;
813 header = TNY_HEADER (tny_iterator_get_current (iter));
814 flags = tny_header_get_flags (header);
815 /* TODO: is this the right flag?, it seems that some
816 headers that have been previously downloaded do not
818 found = !(flags & TNY_HEADER_FLAG_CACHED);
819 g_object_unref (header);
820 tny_iterator_next (iter);
822 g_object_unref (iter);
824 /* Ask for user permission to download the messages */
827 GtkResponseType response;
829 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
830 _("mcen_nc_get_multi_msg_txt"));
831 if (response == GTK_RESPONSE_CANCEL)
839 * Common code for the reply and forward actions
842 reply_forward (ReplyForwardAction action, ModestWindow *win)
844 ModestMailOperation *mail_op = NULL;
845 TnyList *header_list = NULL;
846 ReplyForwardHelper *rf_helper = NULL;
847 guint reply_forward_type;
848 gboolean continue_download;
850 g_return_if_fail (MODEST_IS_WINDOW(win));
852 header_list = get_selected_headers (win);
856 /* Check that the messages have been previously downloaded */
857 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
858 if (!continue_download) {
859 g_object_unref (header_list);
864 modest_conf_get_int (modest_runtime_get_conf (),
865 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
867 /* We assume that we can only select messages of the
868 same folder and that we reply all of them from the
869 same account. In fact the interface currently only
870 allows single selection */
873 rf_helper = g_slice_new0 (ReplyForwardHelper);
874 rf_helper->reply_forward_type = reply_forward_type;
875 rf_helper->action = action;
876 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
877 if (!rf_helper->account_name)
878 rf_helper->account_name =
879 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
881 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
884 /* Get header and message. Do not free them here, the
885 reply_forward_cb must do it */
886 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
887 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
888 if (!msg || !header) {
890 g_object_unref (msg);
892 g_object_unref (header);
893 g_printerr ("modest: no message found\n");
896 reply_forward_cb (NULL, header, msg, rf_helper);
898 /* Retrieve messages */
899 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
901 modest_ui_actions_get_msgs_full_error_handler,
903 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
904 modest_mail_operation_get_msgs_full (mail_op,
908 free_reply_forward_helper);
911 g_object_unref(mail_op);
915 g_object_unref (header_list);
919 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
921 g_return_if_fail (MODEST_IS_WINDOW(win));
923 reply_forward (ACTION_REPLY, win);
927 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
929 g_return_if_fail (MODEST_IS_WINDOW(win));
931 reply_forward (ACTION_FORWARD, win);
935 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
937 g_return_if_fail (MODEST_IS_WINDOW(win));
939 reply_forward (ACTION_REPLY_TO_ALL, win);
943 modest_ui_actions_on_next (GtkAction *action,
944 ModestWindow *window)
946 if (MODEST_IS_MAIN_WINDOW (window)) {
947 GtkWidget *header_view;
949 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
950 MODEST_WIDGET_TYPE_HEADER_VIEW);
954 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
955 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
956 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
958 g_return_if_reached ();
963 modest_ui_actions_on_prev (GtkAction *action,
964 ModestWindow *window)
966 g_return_if_fail (MODEST_IS_WINDOW(window));
968 if (MODEST_IS_MAIN_WINDOW (window)) {
969 GtkWidget *header_view;
970 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
971 MODEST_WIDGET_TYPE_HEADER_VIEW);
975 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
976 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
977 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
979 g_return_if_reached ();
984 modest_ui_actions_on_sort (GtkAction *action,
985 ModestWindow *window)
987 g_return_if_fail (MODEST_IS_WINDOW(window));
989 if (MODEST_IS_MAIN_WINDOW (window)) {
990 GtkWidget *header_view;
991 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
992 MODEST_WIDGET_TYPE_HEADER_VIEW);
996 /* Show sorting dialog */
997 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1002 * This function performs the send & receive required actions. The
1003 * window is used to create the mail operation. Typically it should
1004 * always be the main window, but we pass it as argument in order to
1008 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1010 gchar *acc_name = NULL;
1011 ModestMailOperation *mail_op;
1013 /* If no account name was provided then get the current account, and if
1014 there is no current account then pick the default one: */
1015 if (!account_name) {
1016 acc_name = g_strdup (modest_window_get_active_account(win));
1018 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1020 g_printerr ("modest: cannot get default account\n");
1024 acc_name = g_strdup (account_name);
1027 /* Send & receive. */
1028 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1029 /* Receive and then send. The operation is tagged initially as
1030 a receive operation because the account update performs a
1031 receive and then a send. The operation changes its type
1032 internally, so the progress objects will receive the proper
1033 progress information */
1034 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1035 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1036 modest_mail_operation_update_account (mail_op, acc_name);
1037 g_object_unref (G_OBJECT (mail_op));
1044 * Refreshes all accounts. This function will be used by automatic
1048 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1050 GSList *account_names, *iter;
1052 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1055 iter = account_names;
1057 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1058 iter = g_slist_next (iter);
1061 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1062 g_slist_free (account_names);
1066 * Handler of the click on Send&Receive button in the main toolbar
1069 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1071 /* Check that at least one account exists: */
1072 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1073 TRUE /* enabled accounts only */);
1074 gboolean accounts_exist = account_names != NULL;
1075 g_slist_free (account_names);
1077 /* If not, allow the user to create an account before trying to send/receive. */
1078 if (!accounts_exist)
1079 modest_ui_actions_on_accounts (NULL, win);
1081 /* Refresh the active account */
1082 modest_ui_actions_do_send_receive (NULL, win);
1087 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1090 GtkWidget *header_view;
1092 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1094 header_view = modest_main_window_get_child_widget (main_window,
1095 MODEST_WIDGET_TYPE_HEADER_VIEW);
1099 conf = modest_runtime_get_conf ();
1101 /* what is saved/restored is depending on the style; thus; we save with
1102 * old style, then update the style, and restore for this new style
1104 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1106 if (modest_header_view_get_style
1107 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1108 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1109 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1111 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1112 MODEST_HEADER_VIEW_STYLE_DETAILS);
1114 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1115 MODEST_CONF_HEADER_VIEW_KEY);
1120 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1122 ModestMainWindow *main_window)
1124 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1126 /* If no header has been selected then exit */
1130 /* Update Main window title */
1131 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1132 const gchar *subject = tny_header_get_subject (header);
1133 if (subject && strcmp (subject, ""))
1134 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1136 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1141 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1143 ModestMainWindow *main_window)
1147 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1152 headers = tny_simple_list_new ();
1153 tny_list_prepend (headers, G_OBJECT (header));
1155 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1157 g_object_unref (headers);
1161 set_active_account_from_tny_account (TnyAccount *account,
1162 ModestWindow *window)
1164 const gchar *server_acc_name = tny_account_get_id (account);
1166 /* We need the TnyAccount provided by the
1167 account store because that is the one that
1168 knows the name of the Modest account */
1169 TnyAccount *modest_server_account = modest_server_account =
1170 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1173 const gchar *modest_acc_name =
1174 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1175 modest_window_set_active_account (window, modest_acc_name);
1176 g_object_unref (modest_server_account);
1180 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1181 TnyFolderStore *folder_store,
1183 ModestMainWindow *main_window)
1186 GtkWidget *header_view;
1188 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1190 header_view = modest_main_window_get_child_widget(main_window,
1191 MODEST_WIDGET_TYPE_HEADER_VIEW);
1195 conf = modest_runtime_get_conf ();
1197 if (TNY_IS_ACCOUNT (folder_store)) {
1198 /* Update active account */
1199 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1200 /* Show account details */
1201 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1202 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1203 //TODO: Set the virtual folder store as the "active account" somehow:
1204 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1206 if (TNY_IS_FOLDER (folder_store) && selected) {
1208 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1209 /* Update the active account */
1210 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1211 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1212 g_object_unref (account);
1215 /* Set folder on header view */
1216 modest_main_window_set_contents_style (main_window,
1217 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1218 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1219 TNY_FOLDER (folder_store));
1220 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1221 MODEST_CONF_HEADER_VIEW_KEY);
1223 /* Update the active account */
1224 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1225 /* Do not show folder */
1226 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1227 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1233 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1240 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1242 if (g_main_depth > 0)
1243 gdk_threads_enter ();
1244 online = tny_device_is_online (modest_runtime_get_device());
1247 /* already online -- the item is simply not there... */
1248 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1250 GTK_MESSAGE_WARNING,
1252 _("The %s you selected cannot be found"),
1254 gtk_dialog_run (GTK_DIALOG(dialog));
1256 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1260 GTK_RESPONSE_REJECT,
1262 GTK_RESPONSE_ACCEPT,
1264 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1265 "Do you want to get online?"), item);
1266 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1267 gtk_label_new (txt), FALSE, FALSE, 0);
1268 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1271 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1272 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1273 // modest_platform_connect_and_wait ();;
1276 gtk_widget_destroy (dialog);
1277 if (g_main_depth > 0)
1278 gdk_threads_leave ();
1282 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1285 /* g_message ("%s %s", __FUNCTION__, link); */
1290 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1293 modest_platform_activate_uri (link);
1297 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1300 modest_platform_show_uri_popup (link);
1304 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1307 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1311 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1312 const gchar *address,
1315 /* g_message ("%s %s", __FUNCTION__, address); */
1319 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1321 TnyTransportAccount *transport_account;
1322 ModestMailOperation *mail_operation;
1324 gchar *account_name, *from;
1325 ModestAccountMgr *account_mgr;
1327 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1329 data = modest_msg_edit_window_get_msg_data (edit_window);
1331 account_mgr = modest_runtime_get_account_mgr();
1332 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1334 account_name = modest_account_mgr_get_default_account (account_mgr);
1335 if (!account_name) {
1336 g_printerr ("modest: no account found\n");
1337 modest_msg_edit_window_free_msg_data (edit_window, data);
1341 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1342 (modest_runtime_get_account_store(),
1344 TNY_ACCOUNT_TYPE_TRANSPORT));
1345 if (!transport_account) {
1346 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1347 g_free (account_name);
1348 modest_msg_edit_window_free_msg_data (edit_window, data);
1351 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1353 /* Create the mail operation */
1354 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1355 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1357 modest_mail_operation_save_to_drafts (mail_operation,
1367 data->priority_flags);
1370 g_free (account_name);
1371 g_object_unref (G_OBJECT (transport_account));
1372 g_object_unref (G_OBJECT (mail_operation));
1374 modest_msg_edit_window_free_msg_data (edit_window, data);
1376 /* Save settings and close the window */
1377 gtk_widget_destroy (GTK_WIDGET (edit_window));
1380 /* For instance, when clicking the Send toolbar button when editing a message: */
1382 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1384 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1386 if (!modest_msg_edit_window_check_names (edit_window))
1389 /* FIXME: Code added just for testing. The final version will
1390 use the send queue provided by tinymail and some
1392 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1393 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1395 account_name = modest_account_mgr_get_default_account (account_mgr);
1397 if (!account_name) {
1398 g_printerr ("modest: no account found\n");
1402 /* Get the currently-active transport account for this modest account: */
1403 TnyTransportAccount *transport_account =
1404 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1405 (modest_runtime_get_account_store(),
1407 if (!transport_account) {
1408 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1409 g_free (account_name);
1413 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1415 /* Create the mail operation */
1416 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1417 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1419 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1420 modest_mail_operation_send_new_mail (mail_operation,
1430 data->priority_flags);
1434 g_free (account_name);
1435 g_object_unref (G_OBJECT (transport_account));
1436 g_object_unref (G_OBJECT (mail_operation));
1438 modest_msg_edit_window_free_msg_data (edit_window, data);
1440 /* Save settings and close the window: */
1441 gtk_widget_destroy (GTK_WIDGET (edit_window));
1445 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1446 ModestMsgEditWindow *window)
1448 ModestMsgEditFormatState *format_state = NULL;
1450 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1451 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1453 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1456 format_state = modest_msg_edit_window_get_format_state (window);
1457 g_return_if_fail (format_state != NULL);
1459 format_state->bold = gtk_toggle_action_get_active (action);
1460 modest_msg_edit_window_set_format_state (window, format_state);
1461 g_free (format_state);
1466 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1467 ModestMsgEditWindow *window)
1469 ModestMsgEditFormatState *format_state = NULL;
1471 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1472 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1474 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1477 format_state = modest_msg_edit_window_get_format_state (window);
1478 g_return_if_fail (format_state != NULL);
1480 format_state->italics = gtk_toggle_action_get_active (action);
1481 modest_msg_edit_window_set_format_state (window, format_state);
1482 g_free (format_state);
1487 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1488 ModestMsgEditWindow *window)
1490 ModestMsgEditFormatState *format_state = NULL;
1492 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1493 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1495 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1498 format_state = modest_msg_edit_window_get_format_state (window);
1499 g_return_if_fail (format_state != NULL);
1501 format_state->bullet = gtk_toggle_action_get_active (action);
1502 modest_msg_edit_window_set_format_state (window, format_state);
1503 g_free (format_state);
1508 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1509 GtkRadioAction *selected,
1510 ModestMsgEditWindow *window)
1512 ModestMsgEditFormatState *format_state = NULL;
1513 GtkJustification value;
1515 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1517 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1520 value = gtk_radio_action_get_current_value (selected);
1522 format_state = modest_msg_edit_window_get_format_state (window);
1523 g_return_if_fail (format_state != NULL);
1525 format_state->justification = value;
1526 modest_msg_edit_window_set_format_state (window, format_state);
1527 g_free (format_state);
1531 modest_ui_actions_on_select_editor_color (GtkAction *action,
1532 ModestMsgEditWindow *window)
1534 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1535 g_return_if_fail (GTK_IS_ACTION (action));
1537 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1540 modest_msg_edit_window_select_color (window);
1544 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1545 ModestMsgEditWindow *window)
1547 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1548 g_return_if_fail (GTK_IS_ACTION (action));
1550 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1553 modest_msg_edit_window_select_background_color (window);
1557 modest_ui_actions_on_insert_image (GtkAction *action,
1558 ModestMsgEditWindow *window)
1560 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1561 g_return_if_fail (GTK_IS_ACTION (action));
1563 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1566 modest_msg_edit_window_insert_image (window);
1570 modest_ui_actions_on_attach_file (GtkAction *action,
1571 ModestMsgEditWindow *window)
1573 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1574 g_return_if_fail (GTK_IS_ACTION (action));
1576 modest_msg_edit_window_attach_file (window);
1580 modest_ui_actions_on_remove_attachments (GtkAction *action,
1581 ModestMsgEditWindow *window)
1583 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1584 g_return_if_fail (GTK_IS_ACTION (action));
1586 modest_msg_edit_window_remove_attachments (window, NULL);
1590 * Shows a dialog with an entry that asks for some text. The returned
1591 * value must be freed by the caller. The dialog window title will be
1595 ask_for_folder_name (GtkWindow *parent_window,
1598 GtkWidget *dialog, *entry;
1599 gchar *folder_name = NULL;
1601 /* Ask for folder name */
1602 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1606 GTK_RESPONSE_REJECT,
1608 GTK_RESPONSE_ACCEPT,
1610 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1611 gtk_label_new(title),
1614 entry = gtk_entry_new_with_max_length (40);
1615 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1619 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1621 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1622 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1624 gtk_widget_destroy (dialog);
1630 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1632 TnyFolderStore *parent_folder;
1633 GtkWidget *folder_view;
1635 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1637 folder_view = modest_main_window_get_child_widget (main_window,
1638 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1642 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1644 if (parent_folder) {
1645 gboolean finished = FALSE;
1647 gchar *folder_name = NULL, *suggested_name = NULL;
1649 /* Run the new folder dialog */
1651 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1656 if (result == GTK_RESPONSE_REJECT) {
1659 ModestMailOperation *mail_op;
1660 TnyFolder *new_folder = NULL;
1662 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1663 G_OBJECT(main_window));
1664 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1666 new_folder = modest_mail_operation_create_folder (mail_op,
1668 (const gchar *) folder_name);
1670 g_object_unref (new_folder);
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_help (GtkAction *action,
2784 const gchar *help_id = NULL;
2786 if (MODEST_IS_MAIN_WINDOW (win)) {
2787 const gchar *action_name;
2788 action_name = gtk_action_get_name (action);
2790 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2791 !strcmp (action_name, "HeaderViewCSMHelp")) {
2792 GtkWidget *folder_view;
2793 TnyFolderStore *folder_store;
2794 /* Get selected folder */
2795 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2796 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2797 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2799 /* Switch help_id */
2800 if (TNY_IS_FOLDER (folder_store)) {
2801 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2802 case TNY_FOLDER_TYPE_NORMAL:
2803 help_id = "applications_email_userfolder";
2805 case TNY_FOLDER_TYPE_INBOX:
2806 help_id = "applications_email_inbox";
2808 case TNY_FOLDER_TYPE_OUTBOX:
2809 help_id = "applications_email_outbox";
2811 case TNY_FOLDER_TYPE_SENT:
2812 help_id = "applications_email_sent";
2814 case TNY_FOLDER_TYPE_DRAFTS:
2815 help_id = "applications_email_drafts";
2817 case TNY_FOLDER_TYPE_ARCHIVE:
2818 help_id = "applications_email_archive";
2825 help_id = "applications_email_mainview";
2827 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2828 help_id = "applications_email_viewer";
2829 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2830 help_id = "applications_email_editor";
2832 modest_platform_show_help (GTK_WINDOW (win), help_id);
2836 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2837 ModestWindow *window)
2839 ModestMailOperation *mail_op;
2843 headers = get_selected_headers (window);
2847 /* Create mail operation */
2848 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2850 modest_ui_actions_get_msgs_full_error_handler,
2852 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2853 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2856 g_object_unref (headers);
2857 g_object_unref (mail_op);
2861 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2862 ModestWindow *window)
2864 g_return_if_fail (MODEST_IS_WINDOW (window));
2867 modest_window_check_dimming_rules (window);
2871 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2872 ModestWindow *window)
2874 g_return_if_fail (MODEST_IS_WINDOW (window));
2877 modest_window_check_dimming_rules (window);
2881 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2882 ModestWindow *window)
2884 g_return_if_fail (MODEST_IS_WINDOW (window));
2887 modest_window_check_dimming_rules (window);
2891 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2892 ModestWindow *window)
2894 g_return_if_fail (MODEST_IS_WINDOW (window));
2897 modest_window_check_dimming_rules (window);
2901 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2902 ModestWindow *window)
2904 g_return_if_fail (MODEST_IS_WINDOW (window));
2907 modest_window_check_dimming_rules (window);