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_MESSAGE_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 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1417 /* mail content checks and dialogs */
1418 if (data->subject == NULL || data->subject[0] == '\0') {
1419 GtkResponseType response;
1420 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1421 _("mcen_nc_subject_is_empty_send"));
1422 if (response == GTK_RESPONSE_CANCEL) {
1423 g_free (account_name);
1428 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1429 GtkResponseType response;
1430 gchar *note_message;
1431 gchar *note_subject = data->subject;
1432 if (note_subject == NULL || note_subject[0] == '\0')
1433 note_subject = _("mail_va_no_subject");
1434 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1435 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1437 g_free (note_message);
1438 if (response == GTK_RESPONSE_CANCEL) {
1439 g_free (account_name);
1444 /* Create the mail operation */
1445 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1446 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1448 modest_mail_operation_send_new_mail (mail_operation,
1458 data->priority_flags);
1462 g_free (account_name);
1463 g_object_unref (G_OBJECT (transport_account));
1464 g_object_unref (G_OBJECT (mail_operation));
1466 modest_msg_edit_window_free_msg_data (edit_window, data);
1468 /* Save settings and close the window: */
1469 gtk_widget_destroy (GTK_WIDGET (edit_window));
1473 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1474 ModestMsgEditWindow *window)
1476 ModestMsgEditFormatState *format_state = NULL;
1478 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1479 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1481 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1484 format_state = modest_msg_edit_window_get_format_state (window);
1485 g_return_if_fail (format_state != NULL);
1487 format_state->bold = gtk_toggle_action_get_active (action);
1488 modest_msg_edit_window_set_format_state (window, format_state);
1489 g_free (format_state);
1494 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1495 ModestMsgEditWindow *window)
1497 ModestMsgEditFormatState *format_state = NULL;
1499 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1500 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1502 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1505 format_state = modest_msg_edit_window_get_format_state (window);
1506 g_return_if_fail (format_state != NULL);
1508 format_state->italics = gtk_toggle_action_get_active (action);
1509 modest_msg_edit_window_set_format_state (window, format_state);
1510 g_free (format_state);
1515 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1516 ModestMsgEditWindow *window)
1518 ModestMsgEditFormatState *format_state = NULL;
1520 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1521 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1523 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1526 format_state = modest_msg_edit_window_get_format_state (window);
1527 g_return_if_fail (format_state != NULL);
1529 format_state->bullet = gtk_toggle_action_get_active (action);
1530 modest_msg_edit_window_set_format_state (window, format_state);
1531 g_free (format_state);
1536 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1537 GtkRadioAction *selected,
1538 ModestMsgEditWindow *window)
1540 ModestMsgEditFormatState *format_state = NULL;
1541 GtkJustification value;
1543 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1545 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1548 value = gtk_radio_action_get_current_value (selected);
1550 format_state = modest_msg_edit_window_get_format_state (window);
1551 g_return_if_fail (format_state != NULL);
1553 format_state->justification = value;
1554 modest_msg_edit_window_set_format_state (window, format_state);
1555 g_free (format_state);
1559 modest_ui_actions_on_select_editor_color (GtkAction *action,
1560 ModestMsgEditWindow *window)
1562 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1563 g_return_if_fail (GTK_IS_ACTION (action));
1565 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1568 modest_msg_edit_window_select_color (window);
1572 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1573 ModestMsgEditWindow *window)
1575 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1576 g_return_if_fail (GTK_IS_ACTION (action));
1578 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1581 modest_msg_edit_window_select_background_color (window);
1585 modest_ui_actions_on_insert_image (GtkAction *action,
1586 ModestMsgEditWindow *window)
1588 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1589 g_return_if_fail (GTK_IS_ACTION (action));
1591 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1594 modest_msg_edit_window_insert_image (window);
1598 modest_ui_actions_on_attach_file (GtkAction *action,
1599 ModestMsgEditWindow *window)
1601 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1602 g_return_if_fail (GTK_IS_ACTION (action));
1604 modest_msg_edit_window_attach_file (window);
1608 modest_ui_actions_on_remove_attachments (GtkAction *action,
1609 ModestMsgEditWindow *window)
1611 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1612 g_return_if_fail (GTK_IS_ACTION (action));
1614 modest_msg_edit_window_remove_attachments (window, NULL);
1618 * Shows a dialog with an entry that asks for some text. The returned
1619 * value must be freed by the caller. The dialog window title will be
1623 ask_for_folder_name (GtkWindow *parent_window,
1626 GtkWidget *dialog, *entry;
1627 gchar *folder_name = NULL;
1629 /* Ask for folder name */
1630 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1634 GTK_RESPONSE_REJECT,
1636 GTK_RESPONSE_ACCEPT,
1638 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1639 gtk_label_new(title),
1642 entry = gtk_entry_new_with_max_length (40);
1643 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1647 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1649 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1650 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1652 gtk_widget_destroy (dialog);
1658 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1660 TnyFolderStore *parent_folder;
1661 GtkWidget *folder_view;
1663 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1665 folder_view = modest_main_window_get_child_widget (main_window,
1666 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1670 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1672 if (parent_folder) {
1673 gboolean finished = FALSE;
1675 gchar *folder_name = NULL, *suggested_name = NULL;
1677 /* Run the new folder dialog */
1679 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1684 if (result == GTK_RESPONSE_REJECT) {
1687 ModestMailOperation *mail_op;
1688 TnyFolder *new_folder = NULL;
1690 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1691 G_OBJECT(main_window));
1692 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1694 new_folder = modest_mail_operation_create_folder (mail_op,
1696 (const gchar *) folder_name);
1698 g_object_unref (new_folder);
1701 g_object_unref (mail_op);
1703 g_free (folder_name);
1707 g_object_unref (parent_folder);
1712 modest_ui_actions_on_rename_folder (GtkAction *action,
1713 ModestMainWindow *main_window)
1715 TnyFolderStore *folder;
1716 GtkWidget *folder_view;
1717 GtkWidget *header_view;
1719 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1721 folder_view = modest_main_window_get_child_widget (main_window,
1722 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1726 header_view = modest_main_window_get_child_widget (main_window,
1727 MODEST_WIDGET_TYPE_HEADER_VIEW);
1732 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1734 if (folder && TNY_IS_FOLDER (folder)) {
1736 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1737 _("Please enter a new name for the folder"));
1739 if (folder_name != NULL && strlen (folder_name) > 0) {
1740 ModestMailOperation *mail_op;
1742 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1743 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1746 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1748 modest_mail_operation_rename_folder (mail_op,
1749 TNY_FOLDER (folder),
1750 (const gchar *) folder_name);
1752 g_object_unref (mail_op);
1753 g_free (folder_name);
1755 g_object_unref (folder);
1760 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1763 GObject *win = modest_mail_operation_get_source (mail_op);
1765 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1766 _("mail_in_ui_folder_delete_error"));
1770 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1772 TnyFolderStore *folder;
1773 GtkWidget *folder_view;
1777 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1779 folder_view = modest_main_window_get_child_widget (main_window,
1780 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1784 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1786 /* Show an error if it's an account */
1787 if (!TNY_IS_FOLDER (folder)) {
1788 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1789 _("mail_in_ui_folder_delete_error"));
1794 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1795 tny_folder_get_name (TNY_FOLDER (folder)));
1796 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1797 (const gchar *) message);
1800 if (response == GTK_RESPONSE_OK) {
1801 ModestMailOperation *mail_op =
1802 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1803 G_OBJECT(main_window),
1804 modest_ui_actions_delete_folder_error_handler,
1807 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1809 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1810 g_object_unref (G_OBJECT (mail_op));
1813 g_object_unref (G_OBJECT (folder));
1817 modest_ui_actions_on_delete_folder (GtkAction *action,
1818 ModestMainWindow *main_window)
1820 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1822 delete_folder (main_window, FALSE);
1826 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1828 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1830 delete_folder (main_window, TRUE);
1834 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1835 const gchar* server_account_name,
1840 ModestMainWindow *main_window)
1842 g_return_if_fail(server_account_name);
1843 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1845 /* Initalize output parameters: */
1852 #ifdef MODEST_PLATFORM_MAEMO
1853 /* Maemo uses a different (awkward) button order,
1854 * It should probably just use gtk_alternative_dialog_button_order ().
1856 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1860 GTK_RESPONSE_ACCEPT,
1862 GTK_RESPONSE_REJECT,
1865 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1869 GTK_RESPONSE_REJECT,
1871 GTK_RESPONSE_ACCEPT,
1873 #endif /* MODEST_PLATFORM_MAEMO */
1875 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1877 gchar *server_name = modest_server_account_get_hostname (
1878 modest_runtime_get_account_mgr(), server_account_name);
1880 /* This causes a warning because the logical ID has no %s in it,
1881 * though the translation does, but there is not much we can do about that: */
1882 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1883 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1886 g_free (server_name);
1890 gchar *initial_username = modest_server_account_get_username (
1891 modest_runtime_get_account_mgr(), server_account_name);
1893 GtkWidget *entry_username = gtk_entry_new ();
1894 if (initial_username)
1895 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1896 /* Dim this if a connection has ever succeeded with this username,
1897 * as per the UI spec: */
1898 const gboolean username_known =
1899 modest_server_account_get_username_has_succeeded(
1900 modest_runtime_get_account_mgr(), server_account_name);
1901 gtk_widget_set_sensitive (entry_username, !username_known);
1903 #ifdef MODEST_PLATFORM_MAEMO
1904 /* Auto-capitalization is the default, so let's turn it off: */
1905 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1907 /* Create a size group to be used by all captions.
1908 * Note that HildonCaption does not create a default size group if we do not specify one.
1909 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1910 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1912 GtkWidget *caption = hildon_caption_new (sizegroup,
1913 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1914 gtk_widget_show (entry_username);
1915 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1916 FALSE, FALSE, MODEST_MARGIN_HALF);
1917 gtk_widget_show (caption);
1919 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1921 #endif /* MODEST_PLATFORM_MAEMO */
1924 GtkWidget *entry_password = gtk_entry_new ();
1925 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1926 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1928 #ifdef MODEST_PLATFORM_MAEMO
1929 /* Auto-capitalization is the default, so let's turn it off: */
1930 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1931 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1933 caption = hildon_caption_new (sizegroup,
1934 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1935 gtk_widget_show (entry_password);
1936 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1937 FALSE, FALSE, MODEST_MARGIN_HALF);
1938 gtk_widget_show (caption);
1939 g_object_unref (sizegroup);
1941 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1943 #endif /* MODEST_PLATFORM_MAEMO */
1945 /* This is not in the Maemo UI spec:
1946 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1947 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1951 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1953 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1955 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1957 modest_server_account_set_username (
1958 modest_runtime_get_account_mgr(), server_account_name,
1961 const gboolean username_was_changed =
1962 (strcmp (*username, initial_username) != 0);
1963 if (username_was_changed) {
1964 /* To actually use a changed username,
1965 * we must reset the connection, according to pvanhoof.
1966 * This _might_ be a sensible way to do that: */
1967 TnyDevice *device = modest_runtime_get_device();
1968 tny_device_force_offline (device);
1969 tny_device_force_online (device);
1974 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1976 /* We do not save the password in the configuration,
1977 * because this function is only called for passwords that should
1978 * not be remembered:
1979 modest_server_account_set_password (
1980 modest_runtime_get_account_mgr(), server_account_name,
1999 /* This is not in the Maemo UI spec:
2000 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2006 gtk_widget_destroy (dialog);
2008 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2012 modest_ui_actions_on_cut (GtkAction *action,
2013 ModestWindow *window)
2015 GtkWidget *focused_widget;
2017 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2018 if (GTK_IS_EDITABLE (focused_widget)) {
2019 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2020 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2021 GtkTextBuffer *buffer;
2022 GtkClipboard *clipboard;
2024 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2025 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2026 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2031 modest_ui_actions_on_copy (GtkAction *action,
2032 ModestWindow *window)
2034 GtkClipboard *clipboard;
2035 GtkWidget *focused_widget;
2037 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2038 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2039 if (GTK_IS_LABEL (focused_widget)) {
2040 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2041 } else if (GTK_IS_EDITABLE (focused_widget)) {
2042 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2043 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2044 GtkTextBuffer *buffer;
2046 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2047 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2052 modest_ui_actions_on_undo (GtkAction *action,
2053 ModestWindow *window)
2055 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2056 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2058 g_return_if_reached ();
2063 modest_ui_actions_on_paste (GtkAction *action,
2064 ModestWindow *window)
2066 GtkWidget *focused_widget;
2068 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2069 if (GTK_IS_EDITABLE (focused_widget)) {
2070 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2071 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2072 GtkTextBuffer *buffer;
2073 GtkClipboard *clipboard;
2075 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2076 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2077 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2082 modest_ui_actions_on_select_all (GtkAction *action,
2083 ModestWindow *window)
2085 GtkWidget *focused_widget;
2087 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2088 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2089 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2090 } else if (GTK_IS_LABEL (focused_widget)) {
2091 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2092 } else if (GTK_IS_EDITABLE (focused_widget)) {
2093 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2094 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2095 GtkTextBuffer *buffer;
2096 GtkTextIter start, end;
2098 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2099 gtk_text_buffer_get_start_iter (buffer, &start);
2100 gtk_text_buffer_get_end_iter (buffer, &end);
2101 gtk_text_buffer_select_range (buffer, &start, &end);
2106 modest_ui_actions_on_mark_as_read (GtkAction *action,
2107 ModestWindow *window)
2109 g_return_if_fail (MODEST_IS_WINDOW(window));
2111 /* Mark each header as read */
2112 do_headers_action (window, headers_action_mark_as_read, NULL);
2116 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2117 ModestWindow *window)
2119 g_return_if_fail (MODEST_IS_WINDOW(window));
2121 /* Mark each header as read */
2122 do_headers_action (window, headers_action_mark_as_unread, NULL);
2126 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2127 GtkRadioAction *selected,
2128 ModestWindow *window)
2132 value = gtk_radio_action_get_current_value (selected);
2133 if (MODEST_IS_WINDOW (window)) {
2134 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2138 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2139 GtkRadioAction *selected,
2140 ModestWindow *window)
2142 TnyHeaderFlags flags;
2143 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2145 flags = gtk_radio_action_get_current_value (selected);
2146 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2149 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2150 GtkRadioAction *selected,
2151 ModestWindow *window)
2155 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2157 file_format = gtk_radio_action_get_current_value (selected);
2158 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2163 modest_ui_actions_on_zoom_plus (GtkAction *action,
2164 ModestWindow *window)
2166 g_return_if_fail (MODEST_IS_WINDOW (window));
2168 modest_window_zoom_plus (MODEST_WINDOW (window));
2172 modest_ui_actions_on_zoom_minus (GtkAction *action,
2173 ModestWindow *window)
2175 g_return_if_fail (MODEST_IS_WINDOW (window));
2177 modest_window_zoom_minus (MODEST_WINDOW (window));
2181 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2182 ModestWindow *window)
2184 ModestWindowMgr *mgr;
2185 gboolean fullscreen, active;
2186 g_return_if_fail (MODEST_IS_WINDOW (window));
2188 mgr = modest_runtime_get_window_mgr ();
2190 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2191 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2193 if (active != fullscreen) {
2194 modest_window_mgr_set_fullscreen_mode (mgr, active);
2195 gtk_window_present (GTK_WINDOW (window));
2200 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2201 ModestWindow *window)
2203 ModestWindowMgr *mgr;
2204 gboolean fullscreen;
2206 g_return_if_fail (MODEST_IS_WINDOW (window));
2208 mgr = modest_runtime_get_window_mgr ();
2209 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2210 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2212 gtk_window_present (GTK_WINDOW (window));
2216 * Used by modest_ui_actions_on_details to call do_headers_action
2219 headers_action_show_details (TnyHeader *header,
2220 ModestWindow *window,
2227 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2230 gtk_widget_show_all (dialog);
2231 gtk_dialog_run (GTK_DIALOG (dialog));
2233 gtk_widget_destroy (dialog);
2237 * Show the folder details in a ModestDetailsDialog widget
2240 show_folder_details (TnyFolder *folder,
2246 dialog = modest_details_dialog_new_with_folder (window, folder);
2249 gtk_widget_show_all (dialog);
2250 gtk_dialog_run (GTK_DIALOG (dialog));
2252 gtk_widget_destroy (dialog);
2256 * Show the header details in a ModestDetailsDialog widget
2259 modest_ui_actions_on_details (GtkAction *action,
2262 TnyList * headers_list;
2266 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2269 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2272 g_object_unref (msg);
2274 headers_list = get_selected_headers (win);
2278 iter = tny_list_create_iterator (headers_list);
2280 header = TNY_HEADER (tny_iterator_get_current (iter));
2281 headers_action_show_details (header, win, NULL);
2282 g_object_unref (header);
2284 g_object_unref (iter);
2285 g_object_unref (headers_list);
2287 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2288 GtkWidget *folder_view, *header_view;
2290 /* Check which widget has the focus */
2291 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2292 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2293 if (gtk_widget_is_focus (folder_view)) {
2296 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2298 /* Show only when it's a folder */
2299 if (!folder || !TNY_IS_FOLDER (folder))
2302 show_folder_details (folder, GTK_WINDOW (win));
2305 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2306 MODEST_WIDGET_TYPE_HEADER_VIEW);
2307 /* Show details of each header */
2308 do_headers_action (win, headers_action_show_details, header_view);
2314 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2315 ModestMsgEditWindow *window)
2317 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2319 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2323 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2324 ModestMsgEditWindow *window)
2326 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2328 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2332 modest_ui_actions_toggle_folders_view (GtkAction *action,
2333 ModestMainWindow *main_window)
2337 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2339 conf = modest_runtime_get_conf ();
2341 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2342 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2344 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2348 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2349 ModestWindow *window)
2351 gboolean active, fullscreen = FALSE;
2352 ModestWindowMgr *mgr;
2354 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2356 /* Check if we want to toggle the toolbar vuew in fullscreen
2358 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2359 "ViewShowToolbarFullScreen")) {
2363 /* Toggle toolbar */
2364 mgr = modest_runtime_get_window_mgr ();
2365 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2369 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2370 ModestMsgEditWindow *window)
2372 modest_msg_edit_window_select_font (window);
2376 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2377 const gchar *display_name,
2380 /* Do not change the application name if the widget has not
2381 the focus. This callback could be called even if the folder
2382 view has not the focus, because the handled signal could be
2383 emitted when the folder view is redrawn */
2384 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2386 gtk_window_set_title (window, display_name);
2388 gtk_window_set_title (window, " ");
2393 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2395 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2396 modest_msg_edit_window_select_contacts (window);
2400 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2402 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2403 modest_msg_edit_window_check_names (window);
2408 create_move_to_dialog (ModestWindow *win,
2409 GtkWidget *folder_view,
2410 GtkWidget **tree_view)
2412 GtkWidget *dialog, *scroll;
2414 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2416 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2418 GTK_RESPONSE_ACCEPT,
2420 GTK_RESPONSE_REJECT,
2423 /* Create scrolled window */
2424 scroll = gtk_scrolled_window_new (NULL, NULL);
2425 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2426 GTK_POLICY_AUTOMATIC,
2427 GTK_POLICY_AUTOMATIC);
2429 /* Create folder view */
2430 *tree_view = modest_folder_view_new (NULL);
2431 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2432 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2433 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2435 /* Add scroll to dialog */
2436 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2437 scroll, FALSE, FALSE, 0);
2439 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2445 * Returns TRUE if at least one of the headers of the list belongs to
2446 * a message that has been fully retrieved.
2449 has_retrieved_msgs (TnyList *list)
2452 gboolean found = FALSE;
2454 iter = tny_list_create_iterator (list);
2455 while (tny_iterator_is_done (iter) && !found) {
2457 TnyHeaderFlags flags;
2459 header = TNY_HEADER (tny_iterator_get_current (iter));
2460 flags = tny_header_get_flags (header);
2461 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2465 tny_iterator_next (iter);
2467 g_object_unref (iter);
2473 * Shows a confirmation dialog to the user when we're moving messages
2474 * from a remote server to the local storage. Returns the dialog
2475 * response. If it's other kind of movement the it always returns
2479 msgs_move_to_confirmation (GtkWindow *win,
2480 TnyFolder *dest_folder,
2483 gint response = GTK_RESPONSE_OK;
2485 /* If the destination is a local folder */
2486 if (modest_tny_folder_is_local_folder (dest_folder)) {
2487 TnyFolder *src_folder;
2491 /* Get source folder */
2492 iter = tny_list_create_iterator (headers);
2493 header = TNY_HEADER (tny_iterator_get_current (iter));
2494 src_folder = tny_header_get_folder (header);
2495 g_object_unref (header);
2496 g_object_unref (iter);
2498 /* If the source is a remote folder */
2499 if (!modest_tny_folder_is_local_folder (src_folder)) {
2500 const gchar *message;
2502 if (tny_list_get_length (headers) == 1)
2503 if (has_retrieved_msgs (headers))
2504 message = _("mcen_nc_move_retrieve");
2506 message = _("mcen_nc_move_header");
2508 if (has_retrieved_msgs (headers))
2509 message = _("mcen_nc_move_retrieves");
2511 message = _("mcen_nc_move_headers");
2513 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2514 (const gchar *) message);
2516 g_object_unref (src_folder);
2523 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2525 ModestMsgViewWindow *self = NULL;
2526 gboolean found = FALSE;
2528 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2529 self = MODEST_MSG_VIEW_WINDOW (object);
2531 found = modest_msg_view_window_select_first_message (self);
2532 g_return_if_fail (found);
2536 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2539 GObject *win = modest_mail_operation_get_source (mail_op);
2541 /* TODO: show error message */
2542 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2543 _("mail_in_ui_folder_move_target_error"));
2547 * UI handler for the "Move to" action when invoked from the
2551 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2552 ModestMainWindow *win)
2554 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2555 GtkWidget *header_view = NULL;
2557 TnyFolderStore *folder_store = NULL;
2558 ModestMailOperation *mail_op = NULL;
2560 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2562 /* Get the folder view */
2563 folder_view = modest_main_window_get_child_widget (win,
2564 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2566 /* Get header view */
2567 header_view = modest_main_window_get_child_widget (win,
2568 MODEST_WIDGET_TYPE_HEADER_VIEW);
2570 /* Create and run the dialog */
2571 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2572 result = gtk_dialog_run (GTK_DIALOG(dialog));
2573 g_object_ref (tree_view);
2575 /* We do this to save an indentation level ;-) */
2576 if (result != GTK_RESPONSE_ACCEPT)
2579 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2581 if (TNY_IS_ACCOUNT (folder_store))
2584 /* Get folder or messages to transfer */
2585 if (gtk_widget_is_focus (folder_view)) {
2586 TnyFolderStore *src_folder;
2587 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2589 /* Clean folder on header view before moving it */
2590 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2592 if (TNY_IS_FOLDER (src_folder)) {
2594 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2596 modest_ui_actions_move_folder_error_handler,
2598 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2600 modest_mail_operation_xfer_folder (mail_op,
2601 TNY_FOLDER (src_folder),
2604 /* Unref mail operation */
2605 g_object_unref (G_OBJECT (mail_op));
2609 g_object_unref (G_OBJECT (src_folder));
2611 if (gtk_widget_is_focus (header_view)) {
2615 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2617 /* Ask for user confirmation */
2618 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2619 TNY_FOLDER (folder_store),
2622 /* Transfer messages */
2623 if (response == GTK_RESPONSE_OK) {
2624 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2625 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2628 modest_mail_operation_xfer_msgs (mail_op,
2630 TNY_FOLDER (folder_store),
2635 g_object_unref (G_OBJECT (mail_op));
2637 g_object_unref (headers);
2640 g_object_unref (folder_store);
2642 gtk_widget_destroy (dialog);
2647 * UI handler for the "Move to" action when invoked from the
2648 * ModestMsgViewWindow
2651 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2652 ModestMsgViewWindow *win)
2654 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2656 ModestMainWindow *main_window;
2660 /* Get the folder view */
2661 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2662 folder_view = modest_main_window_get_child_widget (main_window,
2663 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2665 /* Create and run the dialog */
2666 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2667 result = gtk_dialog_run (GTK_DIALOG(dialog));
2668 g_object_ref (tree_view);
2670 if (result == GTK_RESPONSE_ACCEPT) {
2671 TnyFolderStore *folder_store;
2674 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2676 /* Create header list */
2677 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2678 headers = tny_simple_list_new ();
2679 tny_list_prepend (headers, G_OBJECT (header));
2680 g_object_unref (header);
2682 /* Ask user for confirmation. MSG-NOT404 */
2683 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2684 TNY_FOLDER (folder_store),
2687 /* Transfer current msg */
2688 if (response == GTK_RESPONSE_OK) {
2689 ModestMailOperation *mail_op;
2691 /* Create mail op */
2692 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2693 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2696 /* Transfer messages */
2697 modest_mail_operation_xfer_msgs (mail_op,
2699 TNY_FOLDER (folder_store),
2701 tranasfer_msgs_from_viewer_cb,
2703 g_object_unref (G_OBJECT (mail_op));
2705 g_object_unref (headers);
2706 g_object_unref (folder_store);
2708 gtk_widget_destroy (dialog);
2712 modest_ui_actions_on_move_to (GtkAction *action,
2715 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2716 MODEST_IS_MSG_VIEW_WINDOW (win));
2718 if (MODEST_IS_MAIN_WINDOW (win))
2719 modest_ui_actions_on_main_window_move_to (action,
2720 MODEST_MAIN_WINDOW (win));
2722 modest_ui_actions_on_msg_view_window_move_to (action,
2723 MODEST_MSG_VIEW_WINDOW (win));
2727 * Calls #HeadersFunc for each header already selected in the main
2728 * window or the message currently being shown in the msg view window
2731 do_headers_action (ModestWindow *win,
2735 TnyList *headers_list;
2739 headers_list = get_selected_headers (win);
2743 /* Call the function for each header */
2744 iter = tny_list_create_iterator (headers_list);
2745 while (!tny_iterator_is_done (iter)) {
2748 header = TNY_HEADER (tny_iterator_get_current (iter));
2749 func (header, win, user_data);
2750 g_object_unref (header);
2751 tny_iterator_next (iter);
2753 g_object_unref (iter);
2754 g_object_unref (headers_list);
2758 modest_ui_actions_view_attachment (GtkAction *action,
2759 ModestWindow *window)
2761 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2762 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2764 /* not supported window for this action */
2765 g_return_if_reached ();
2770 modest_ui_actions_save_attachments (GtkAction *action,
2771 ModestWindow *window)
2773 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2774 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2776 /* not supported window for this action */
2777 g_return_if_reached ();
2782 modest_ui_actions_remove_attachments (GtkAction *action,
2783 ModestWindow *window)
2785 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2786 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2788 /* not supported window for this action */
2789 g_return_if_reached ();
2794 modest_ui_actions_on_settings (GtkAction *action,
2799 dialog = modest_platform_get_global_settings_dialog ();
2800 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2801 gtk_widget_show (dialog);
2803 gtk_dialog_run (GTK_DIALOG (dialog));
2805 gtk_widget_destroy (dialog);
2809 modest_ui_actions_on_help (GtkAction *action,
2812 const gchar *help_id = NULL;
2814 if (MODEST_IS_MAIN_WINDOW (win)) {
2815 const gchar *action_name;
2816 action_name = gtk_action_get_name (action);
2818 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2819 !strcmp (action_name, "HeaderViewCSMHelp")) {
2820 GtkWidget *folder_view;
2821 TnyFolderStore *folder_store;
2822 /* Get selected folder */
2823 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2824 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2825 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2827 /* Switch help_id */
2828 if (TNY_IS_FOLDER (folder_store)) {
2829 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2830 case TNY_FOLDER_TYPE_NORMAL:
2831 help_id = "applications_email_userfolder";
2833 case TNY_FOLDER_TYPE_INBOX:
2834 help_id = "applications_email_inbox";
2836 case TNY_FOLDER_TYPE_OUTBOX:
2837 help_id = "applications_email_outbox";
2839 case TNY_FOLDER_TYPE_SENT:
2840 help_id = "applications_email_sent";
2842 case TNY_FOLDER_TYPE_DRAFTS:
2843 help_id = "applications_email_drafts";
2845 case TNY_FOLDER_TYPE_ARCHIVE:
2846 help_id = "applications_email_archive";
2853 help_id = "applications_email_mainview";
2855 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2856 help_id = "applications_email_viewer";
2857 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2858 help_id = "applications_email_editor";
2860 modest_platform_show_help (GTK_WINDOW (win), help_id);
2864 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2865 ModestWindow *window)
2867 ModestMailOperation *mail_op;
2871 headers = get_selected_headers (window);
2875 /* Create mail operation */
2876 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2878 modest_ui_actions_get_msgs_full_error_handler,
2880 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2881 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2884 g_object_unref (headers);
2885 g_object_unref (mail_op);
2889 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2890 ModestWindow *window)
2892 g_return_if_fail (MODEST_IS_WINDOW (window));
2895 modest_window_check_dimming_rules (window);
2899 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2900 ModestWindow *window)
2902 g_return_if_fail (MODEST_IS_WINDOW (window));
2905 modest_window_check_dimming_rules (window);
2909 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2910 ModestWindow *window)
2912 g_return_if_fail (MODEST_IS_WINDOW (window));
2915 modest_window_check_dimming_rules (window);
2919 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2920 ModestWindow *window)
2922 g_return_if_fail (MODEST_IS_WINDOW (window));
2925 modest_window_check_dimming_rules (window);
2929 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2930 ModestWindow *window)
2932 g_return_if_fail (MODEST_IS_WINDOW (window));
2935 modest_window_check_dimming_rules (window);