1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
48 #ifdef MODEST_PLATFORM_MAEMO
49 #include "maemo/modest-osso-state-saving.h"
50 #endif /* MODEST_PLATFORM_MAEMO */
52 #include "widgets/modest-ui-constants.h"
53 #include <widgets/modest-main-window.h>
54 #include <widgets/modest-msg-view-window.h>
55 #include <widgets/modest-account-view-window.h>
56 #include <widgets/modest-details-dialog.h>
57 #include <widgets/modest-attachments-view.h>
58 #include "widgets/modest-global-settings-dialog.h"
59 #include "modest-connection-specific-smtp-window.h"
60 #include "modest-account-mgr-helpers.h"
61 #include "modest-mail-operation.h"
62 #include "modest-text-utils.h"
64 #ifdef MODEST_HAVE_EASYSETUP
65 #include "easysetup/modest-easysetup-wizard.h"
66 #endif /* MODEST_HAVE_EASYSETUP */
68 #include <modest-widget-memory.h>
69 #include <tny-error.h>
70 #include <tny-simple-list.h>
71 #include <tny-msg-view.h>
72 #include <tny-device.h>
73 #include <tny-merge-folder.h>
75 typedef struct _GetMsgAsyncHelper {
77 ModestMailOperation *mail_op;
84 typedef enum _ReplyForwardAction {
90 typedef struct _ReplyForwardHelper {
91 guint reply_forward_type;
92 ReplyForwardAction action;
94 GtkWidget *parent_window;
98 * The do_headers_action uses this kind of functions to perform some
99 * action to each member of a list of headers
101 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
104 do_headers_action (ModestWindow *win,
109 static void open_msg_cb (ModestMailOperation *mail_op,
114 static void reply_forward_cb (ModestMailOperation *mail_op,
119 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
121 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
124 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
127 const gchar *authors[] = {
128 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
131 about = gtk_about_dialog_new ();
132 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
133 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
134 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
135 _("Copyright (c) 2006, Nokia Corporation\n"
136 "All rights reserved."));
137 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
138 _("a modest e-mail client\n\n"
139 "design and implementation: Dirk-Jan C. Binnema\n"
140 "contributions from the fine people at KC and Ig\n"
141 "uses the tinymail email framework written by Philip van Hoof"));
142 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
143 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
145 gtk_dialog_run (GTK_DIALOG (about));
146 gtk_widget_destroy(about);
150 * Gets the list of currently selected messages. If the win is the
151 * main window, then it returns a newly allocated list of the headers
152 * selected in the header view. If win is the msg view window, then
153 * the value returned is a list with just a single header.
155 * The caller of this funcion must free the list.
158 get_selected_headers (ModestWindow *win)
160 if (MODEST_IS_MAIN_WINDOW(win)) {
161 GtkWidget *header_view;
163 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
164 MODEST_WIDGET_TYPE_HEADER_VIEW);
165 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
167 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
168 /* for MsgViewWindows, we simply return a list with one element */
170 TnyList *list = NULL;
172 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
173 if (header != NULL) {
174 list = tny_simple_list_new ();
175 tny_list_prepend (list, G_OBJECT(header));
176 g_object_unref (G_OBJECT(header));
186 headers_action_mark_as_read (TnyHeader *header,
190 TnyHeaderFlags flags;
192 g_return_if_fail (TNY_IS_HEADER(header));
194 flags = tny_header_get_flags (header);
195 if (flags & TNY_HEADER_FLAG_SEEN) return;
196 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
200 headers_action_mark_as_unread (TnyHeader *header,
204 TnyHeaderFlags flags;
206 g_return_if_fail (TNY_IS_HEADER(header));
208 flags = tny_header_get_flags (header);
209 if (flags & TNY_HEADER_FLAG_SEEN) {
210 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
216 headers_action_delete (TnyHeader *header,
220 ModestMailOperation *mail_op = NULL;
222 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
223 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
226 /* Always delete. TODO: Move to trash still not supported */
227 modest_mail_operation_remove_msg (mail_op, header, FALSE);
228 g_object_unref (G_OBJECT (mail_op));
232 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
234 TnyList *header_list = NULL;
235 TnyIterator *iter = NULL;
236 TnyHeader *header = NULL;
237 gchar *message = NULL;
241 ModestWindowMgr *mgr;
243 g_return_if_fail (MODEST_IS_WINDOW(win));
245 header_list = get_selected_headers (win);
246 if (!header_list) return;
248 /* Check if any of the headers is already opened */
249 iter = tny_list_create_iterator (header_list);
251 mgr = modest_runtime_get_window_mgr ();
252 while (!tny_iterator_is_done (iter) && !found) {
253 header = TNY_HEADER (tny_iterator_get_current (iter));
254 if (modest_window_mgr_find_window_by_header (mgr, header))
256 g_object_unref (header);
257 tny_iterator_next (iter);
259 g_object_unref (iter);
264 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
265 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
267 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
271 g_object_unref (header_list);
276 if (tny_list_get_length(header_list) > 1)
277 message = g_strdup(_("emev_nc_delete_messages"));
279 iter = tny_list_create_iterator (header_list);
280 header = TNY_HEADER (tny_iterator_get_current (iter));
281 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
282 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
283 g_object_unref (header);
284 g_object_unref (iter);
287 /* Confirmation dialog */
288 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
292 if (response == GTK_RESPONSE_OK) {
293 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
295 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
299 /* Remove each header */
300 do_headers_action (win, headers_action_delete, NULL);
302 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
303 gtk_widget_destroy (GTK_WIDGET(win));
310 g_object_unref (header_list);
315 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
317 #ifdef MODEST_PLATFORM_MAEMO
318 modest_osso_save_state();
319 #endif /* MODEST_PLATFORM_MAEMO */
325 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
327 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
328 gtk_widget_destroy (GTK_WIDGET (win));
329 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
331 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
332 } else if (MODEST_IS_WINDOW (win)) {
333 gtk_widget_destroy (GTK_WIDGET (win));
335 g_return_if_reached ();
340 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
342 GtkClipboard *clipboard = NULL;
343 gchar *selection = NULL;
345 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
346 selection = gtk_clipboard_wait_for_text (clipboard);
348 /* Question: why is the clipboard being used here?
349 * It doesn't really make a lot of sense. */
353 modest_address_book_add_address (selection);
359 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
361 /* This is currently only implemented for Maemo,
362 * because it requires a providers preset file which is not publically available.
364 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
365 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
366 TRUE /* enabled accounts only */);
367 gboolean accounts_exist = account_names != NULL;
368 g_slist_free (account_names);
370 if (!accounts_exist) {
371 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
372 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
373 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
374 gtk_dialog_run (GTK_DIALOG (wizard));
375 gtk_widget_destroy (GTK_WIDGET (wizard));
377 /* Show the list of accounts: */
378 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
379 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
380 gtk_dialog_run (account_win);
381 gtk_widget_destroy (GTK_WIDGET(account_win));
384 GtkWidget *dialog, *label;
386 /* Create the widgets */
388 dialog = gtk_dialog_new_with_buttons ("Message",
390 GTK_DIALOG_DESTROY_WITH_PARENT,
394 label = gtk_label_new ("Hello World!");
396 /* Ensure that the dialog box is destroyed when the user responds. */
398 g_signal_connect_swapped (dialog, "response",
399 G_CALLBACK (gtk_widget_destroy),
402 /* Add the label, and show everything we've added to the dialog. */
404 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
406 gtk_widget_show_all (dialog);
407 #endif /* MODEST_PLATFORM_MAEMO */
411 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
413 ModestWindow *main_window = MODEST_WINDOW (user_data);
415 /* Save any changes. */
416 modest_connection_specific_smtp_window_save_server_accounts (
417 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
418 modest_window_get_active_account (main_window));
419 gtk_widget_destroy (GTK_WIDGET (window));
423 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
425 /* This is currently only implemented for Maemo,
426 * because it requires an API (libconic) to detect different connection
429 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
431 /* Create the window if necessary: */
432 const gchar *active_account_name = modest_window_get_active_account (win);
434 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
435 * or show the default account?
436 * If we show the default account then the account name should be shown in
437 * the window when we show it. */
438 if (!active_account_name) {
439 g_warning ("%s: No account is active.", __FUNCTION__);
443 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
444 modest_connection_specific_smtp_window_fill_with_connections (
445 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
446 modest_runtime_get_account_mgr(),
447 active_account_name);
449 /* Show the window: */
450 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
451 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
452 gtk_widget_show (specific_window);
454 /* Save changes when the window is hidden: */
455 g_signal_connect (specific_window, "hide",
456 G_CALLBACK (on_smtp_servers_window_hide), win);
457 #endif /* MODEST_PLATFORM_MAEMO */
461 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
463 ModestWindow *msg_win;
465 TnyFolder *folder = NULL;
466 gchar *account_name = NULL;
467 gchar *from_str = NULL;
468 /* GError *err = NULL; */
469 TnyAccount *account = NULL;
470 ModestWindowMgr *mgr;
471 gchar *signature = NULL;
473 account_name = g_strdup(modest_window_get_active_account (win));
475 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
477 g_printerr ("modest: no account found\n");
481 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
483 TNY_ACCOUNT_TYPE_STORE);
485 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
489 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
491 g_printerr ("modest: failed get from string for '%s'\n", account_name);
495 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
496 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
497 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
498 MODEST_ACCOUNT_SIGNATURE, FALSE);
500 signature = g_strdup ("");
503 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
505 g_printerr ("modest: failed to create new msg\n");
509 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
511 g_printerr ("modest: failed to find Drafts folder\n");
515 /* tny_folder_add_msg (folder, msg, &err); */
517 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
519 /* g_error_free (err); */
523 /* Create and register edit window */
524 /* This is destroyed by TOOD. */
525 msg_win = modest_msg_edit_window_new (msg, account_name);
526 mgr = modest_runtime_get_window_mgr ();
527 modest_window_mgr_register_window (mgr, msg_win);
530 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
532 gtk_widget_show_all (GTK_WIDGET (msg_win));
535 g_free (account_name);
539 g_object_unref (G_OBJECT(account));
541 g_object_unref (G_OBJECT(msg));
543 g_object_unref (G_OBJECT(folder));
547 open_msg_cb (ModestMailOperation *mail_op,
552 ModestWindowMgr *mgr = NULL;
553 ModestWindow *parent_win = NULL;
554 ModestWindow *win = NULL;
555 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
556 gchar *account = NULL;
559 /* TODO: Show an error? (review the specs) */
563 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
564 folder = tny_header_get_folder (header);
566 /* Mark header as read */
567 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
570 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
572 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
574 /* Gets folder type (OUTBOX headers will be opened in edit window */
575 if (modest_tny_folder_is_local_folder (folder))
576 folder_type = modest_tny_folder_get_local_folder_type (folder);
578 /* If the header is in the drafts folder then open the editor,
579 else the message view window */
580 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
581 win = modest_msg_edit_window_new (msg, account);
583 gchar *uid = modest_tny_folder_get_header_unique_id (header);
585 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
586 GtkWidget *header_view;
587 GtkTreeSelection *sel;
588 GList *sel_list = NULL;
591 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
592 MODEST_WIDGET_TYPE_HEADER_VIEW);
594 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
595 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
597 if (sel_list != NULL) {
598 GtkTreeRowReference *row_reference;
600 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
601 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
602 g_list_free (sel_list);
604 win = modest_msg_view_window_new_with_header_model (msg,
609 gtk_tree_row_reference_free (row_reference);
611 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
614 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
619 /* Register and show new window */
621 mgr = modest_runtime_get_window_mgr ();
622 modest_window_mgr_register_window (mgr, win);
623 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
624 gtk_widget_show_all (GTK_WIDGET(win));
629 g_object_unref (msg);
630 g_object_unref (folder);
631 g_object_unref (header);
635 * This function is the error handler of the
636 * modest_mail_operation_get_msgs_full operation
639 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
644 error = modest_mail_operation_get_error (mail_op);
645 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
646 GObject *win = modest_mail_operation_get_source (mail_op);
648 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
654 * This function is used by both modest_ui_actions_on_open and
655 * modest_ui_actions_on_header_activated. This way we always do the
656 * same when trying to open messages.
659 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
661 ModestWindowMgr *mgr;
663 ModestMailOperation *mail_op;
665 /* Look if we already have a message view for each header. If
666 true, then remove the header from the list of headers to
668 mgr = modest_runtime_get_window_mgr ();
669 iter = tny_list_create_iterator (headers);
670 while (!tny_iterator_is_done (iter)) {
671 ModestWindow *window;
674 header = TNY_HEADER (tny_iterator_get_current (iter));
675 window = modest_window_mgr_find_window_by_header (mgr, header);
677 /* Do not open again the message and present
678 the window to the user */
679 tny_list_remove (headers, G_OBJECT (header));
680 gtk_window_present (GTK_WINDOW (window));
683 g_object_unref (header);
684 tny_iterator_next (iter);
687 /* Open each message */
688 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
690 modest_ui_actions_get_msgs_full_error_handler,
692 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
693 modest_mail_operation_get_msgs_full (mail_op,
700 g_object_unref(mail_op);
704 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
709 headers = get_selected_headers (win);
714 _modest_ui_actions_open (headers, win);
716 g_object_unref(headers);
721 free_reply_forward_helper (gpointer data)
723 ReplyForwardHelper *helper;
725 helper = (ReplyForwardHelper *) data;
726 g_free (helper->account_name);
727 g_slice_free (ReplyForwardHelper, helper);
731 reply_forward_cb (ModestMailOperation *mail_op,
737 ReplyForwardHelper *rf_helper;
738 ModestWindow *msg_win;
739 ModestEditType edit_type;
741 TnyAccount *account = NULL;
742 ModestWindowMgr *mgr;
743 gchar *signature = NULL;
745 g_return_if_fail (user_data != NULL);
746 rf_helper = (ReplyForwardHelper *) user_data;
748 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
749 rf_helper->account_name);
750 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
751 rf_helper->account_name,
752 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
753 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
754 rf_helper->account_name,
755 MODEST_ACCOUNT_SIGNATURE, FALSE);
758 /* Create reply mail */
759 switch (rf_helper->action) {
762 modest_tny_msg_create_reply_msg (msg, from, signature,
763 rf_helper->reply_forward_type,
764 MODEST_TNY_MSG_REPLY_MODE_SENDER);
766 case ACTION_REPLY_TO_ALL:
768 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
769 MODEST_TNY_MSG_REPLY_MODE_ALL);
770 edit_type = MODEST_EDIT_TYPE_REPLY;
774 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
775 edit_type = MODEST_EDIT_TYPE_FORWARD;
778 g_return_if_reached ();
785 g_printerr ("modest: failed to create message\n");
789 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
790 rf_helper->account_name,
791 TNY_ACCOUNT_TYPE_STORE);
793 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
797 /* Create and register the windows */
798 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
799 mgr = modest_runtime_get_window_mgr ();
800 modest_window_mgr_register_window (mgr, msg_win);
802 if (rf_helper->parent_window != NULL) {
805 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
806 modest_window_set_zoom (msg_win, parent_zoom);
809 /* Show edit window */
810 gtk_widget_show_all (GTK_WIDGET (msg_win));
814 g_object_unref (G_OBJECT (new_msg));
816 g_object_unref (G_OBJECT (account));
817 g_object_unref (msg);
818 g_object_unref (header);
822 * Checks a list of headers. If any of them are not currently
823 * downloaded (CACHED) then it asks the user for permission to
826 * Returns FALSE if the user does not want to download the
827 * messages. Returns TRUE if the user allowed the download or if all
828 * of them are currently downloaded
831 download_uncached_messages (TnyList *header_list, GtkWindow *win)
834 gboolean found, retval;
836 iter = tny_list_create_iterator (header_list);
838 while (!tny_iterator_is_done (iter) && !found) {
840 TnyHeaderFlags flags;
842 header = TNY_HEADER (tny_iterator_get_current (iter));
843 flags = tny_header_get_flags (header);
844 /* TODO: is this the right flag?, it seems that some
845 headers that have been previously downloaded do not
847 found = !(flags & TNY_HEADER_FLAG_CACHED);
848 g_object_unref (header);
849 tny_iterator_next (iter);
851 g_object_unref (iter);
853 /* Ask for user permission to download the messages */
856 GtkResponseType response;
858 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
859 _("mcen_nc_get_multi_msg_txt"));
860 if (response == GTK_RESPONSE_CANCEL)
868 * Common code for the reply and forward actions
871 reply_forward (ReplyForwardAction action, ModestWindow *win)
873 ModestMailOperation *mail_op = NULL;
874 TnyList *header_list = NULL;
875 ReplyForwardHelper *rf_helper = NULL;
876 guint reply_forward_type;
877 gboolean continue_download;
879 g_return_if_fail (MODEST_IS_WINDOW(win));
881 header_list = get_selected_headers (win);
885 /* Check that the messages have been previously downloaded */
886 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
887 if (!continue_download) {
888 g_object_unref (header_list);
893 modest_conf_get_int (modest_runtime_get_conf (),
894 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
896 /* We assume that we can only select messages of the
897 same folder and that we reply all of them from the
898 same account. In fact the interface currently only
899 allows single selection */
902 rf_helper = g_slice_new0 (ReplyForwardHelper);
903 rf_helper->reply_forward_type = reply_forward_type;
904 rf_helper->action = action;
905 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
906 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
907 rf_helper->parent_window = GTK_WIDGET (win);
908 if (!rf_helper->account_name)
909 rf_helper->account_name =
910 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
912 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
915 /* Get header and message. Do not free them here, the
916 reply_forward_cb must do it */
917 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
918 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
919 if (!msg || !header) {
921 g_object_unref (msg);
923 g_object_unref (header);
924 g_printerr ("modest: no message found\n");
927 reply_forward_cb (NULL, header, msg, rf_helper);
929 /* Retrieve messages */
930 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
932 modest_ui_actions_get_msgs_full_error_handler,
934 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
935 modest_mail_operation_get_msgs_full (mail_op,
939 free_reply_forward_helper);
942 g_object_unref(mail_op);
946 g_object_unref (header_list);
950 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
952 g_return_if_fail (MODEST_IS_WINDOW(win));
954 reply_forward (ACTION_REPLY, win);
958 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
960 g_return_if_fail (MODEST_IS_WINDOW(win));
962 reply_forward (ACTION_FORWARD, win);
966 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
968 g_return_if_fail (MODEST_IS_WINDOW(win));
970 reply_forward (ACTION_REPLY_TO_ALL, win);
974 modest_ui_actions_on_next (GtkAction *action,
975 ModestWindow *window)
977 if (MODEST_IS_MAIN_WINDOW (window)) {
978 GtkWidget *header_view;
980 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
981 MODEST_WIDGET_TYPE_HEADER_VIEW);
985 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
986 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
987 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
989 g_return_if_reached ();
994 modest_ui_actions_on_prev (GtkAction *action,
995 ModestWindow *window)
997 g_return_if_fail (MODEST_IS_WINDOW(window));
999 if (MODEST_IS_MAIN_WINDOW (window)) {
1000 GtkWidget *header_view;
1001 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1002 MODEST_WIDGET_TYPE_HEADER_VIEW);
1006 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1007 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1008 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1010 g_return_if_reached ();
1015 modest_ui_actions_on_sort (GtkAction *action,
1016 ModestWindow *window)
1018 g_return_if_fail (MODEST_IS_WINDOW(window));
1020 if (MODEST_IS_MAIN_WINDOW (window)) {
1021 GtkWidget *header_view;
1022 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1023 MODEST_WIDGET_TYPE_HEADER_VIEW);
1027 /* Show sorting dialog */
1028 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1033 * This function performs the send & receive required actions. The
1034 * window is used to create the mail operation. Typically it should
1035 * always be the main window, but we pass it as argument in order to
1039 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1041 gchar *acc_name = NULL;
1042 ModestMailOperation *mail_op;
1044 /* If no account name was provided then get the current account, and if
1045 there is no current account then pick the default one: */
1046 if (!account_name) {
1047 acc_name = g_strdup (modest_window_get_active_account(win));
1049 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1051 g_printerr ("modest: cannot get default account\n");
1055 acc_name = g_strdup (account_name);
1058 /* Send & receive. */
1059 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1060 /* Receive and then send. The operation is tagged initially as
1061 a receive operation because the account update performs a
1062 receive and then a send. The operation changes its type
1063 internally, so the progress objects will receive the proper
1064 progress information */
1065 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1066 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1067 modest_mail_operation_update_account (mail_op, acc_name);
1068 g_object_unref (G_OBJECT (mail_op));
1075 * Refreshes all accounts. This function will be used by automatic
1079 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1081 GSList *account_names, *iter;
1083 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1086 iter = account_names;
1088 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1089 iter = g_slist_next (iter);
1092 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1093 g_slist_free (account_names);
1097 * Handler of the click on Send&Receive button in the main toolbar
1100 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1102 /* Check that at least one account exists: */
1103 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1104 TRUE /* enabled accounts only */);
1105 gboolean accounts_exist = account_names != NULL;
1106 g_slist_free (account_names);
1108 /* If not, allow the user to create an account before trying to send/receive. */
1109 if (!accounts_exist)
1110 modest_ui_actions_on_accounts (NULL, win);
1112 /* Refresh the active account */
1113 modest_ui_actions_do_send_receive (NULL, win);
1118 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1121 GtkWidget *header_view;
1123 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1125 header_view = modest_main_window_get_child_widget (main_window,
1126 MODEST_WIDGET_TYPE_HEADER_VIEW);
1130 conf = modest_runtime_get_conf ();
1132 /* what is saved/restored is depending on the style; thus; we save with
1133 * old style, then update the style, and restore for this new style
1135 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1137 if (modest_header_view_get_style
1138 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1139 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1140 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1142 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1143 MODEST_HEADER_VIEW_STYLE_DETAILS);
1145 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1146 MODEST_CONF_HEADER_VIEW_KEY);
1151 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1153 ModestMainWindow *main_window)
1155 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1157 /* If no header has been selected then exit */
1161 /* Update Main window title */
1162 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1163 const gchar *subject = tny_header_get_subject (header);
1164 if (subject && strcmp (subject, ""))
1165 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1167 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1170 /* Update toolbar dimming state */
1171 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1175 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1177 ModestMainWindow *main_window)
1181 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1186 headers = tny_simple_list_new ();
1187 tny_list_prepend (headers, G_OBJECT (header));
1189 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1191 g_object_unref (headers);
1195 set_active_account_from_tny_account (TnyAccount *account,
1196 ModestWindow *window)
1198 const gchar *server_acc_name = tny_account_get_id (account);
1200 /* We need the TnyAccount provided by the
1201 account store because that is the one that
1202 knows the name of the Modest account */
1203 TnyAccount *modest_server_account = modest_server_account =
1204 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1207 const gchar *modest_acc_name =
1208 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1209 modest_window_set_active_account (window, modest_acc_name);
1210 g_object_unref (modest_server_account);
1214 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1215 TnyFolderStore *folder_store,
1217 ModestMainWindow *main_window)
1220 GtkWidget *header_view;
1222 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1224 header_view = modest_main_window_get_child_widget(main_window,
1225 MODEST_WIDGET_TYPE_HEADER_VIEW);
1229 conf = modest_runtime_get_conf ();
1231 if (TNY_IS_ACCOUNT (folder_store)) {
1232 /* Update active account */
1233 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1234 /* Show account details */
1235 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1237 if (TNY_IS_FOLDER (folder_store) && selected) {
1239 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1240 /* Update the active account */
1241 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1242 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1243 g_object_unref (account);
1246 /* Set folder on header view */
1247 modest_main_window_set_contents_style (main_window,
1248 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1249 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1250 TNY_FOLDER (folder_store));
1251 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1252 MODEST_CONF_HEADER_VIEW_KEY);
1254 /* Update the active account */
1255 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1256 /* Do not show folder */
1257 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1258 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1262 /* Update toolbar dimming state */
1263 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1267 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1274 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1276 if (g_main_depth > 0)
1277 gdk_threads_enter ();
1278 online = tny_device_is_online (modest_runtime_get_device());
1281 /* already online -- the item is simply not there... */
1282 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1284 GTK_MESSAGE_WARNING,
1286 _("The %s you selected cannot be found"),
1288 gtk_dialog_run (GTK_DIALOG(dialog));
1290 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1294 GTK_RESPONSE_REJECT,
1296 GTK_RESPONSE_ACCEPT,
1298 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1299 "Do you want to get online?"), item);
1300 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1301 gtk_label_new (txt), FALSE, FALSE, 0);
1302 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1305 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1306 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1307 // modest_platform_connect_and_wait ();;
1310 gtk_widget_destroy (dialog);
1311 if (g_main_depth > 0)
1312 gdk_threads_leave ();
1316 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1319 /* g_message ("%s %s", __FUNCTION__, link); */
1324 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1327 modest_platform_activate_uri (link);
1331 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1334 modest_platform_show_uri_popup (link);
1338 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1341 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1345 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1346 const gchar *address,
1349 /* g_message ("%s %s", __FUNCTION__, address); */
1353 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1355 TnyTransportAccount *transport_account;
1356 ModestMailOperation *mail_operation;
1358 gchar *account_name, *from;
1359 ModestAccountMgr *account_mgr;
1361 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1363 data = modest_msg_edit_window_get_msg_data (edit_window);
1365 account_mgr = modest_runtime_get_account_mgr();
1366 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1368 account_name = modest_account_mgr_get_default_account (account_mgr);
1369 if (!account_name) {
1370 g_printerr ("modest: no account found\n");
1371 modest_msg_edit_window_free_msg_data (edit_window, data);
1375 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1376 account_name = g_strdup (data->account_name);
1380 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1381 (modest_runtime_get_account_store(),
1383 TNY_ACCOUNT_TYPE_TRANSPORT));
1384 if (!transport_account) {
1385 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1386 g_free (account_name);
1387 modest_msg_edit_window_free_msg_data (edit_window, data);
1390 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1392 /* Create the mail operation */
1393 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1394 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1396 modest_mail_operation_save_to_drafts (mail_operation,
1407 data->priority_flags);
1410 g_free (account_name);
1411 g_object_unref (G_OBJECT (transport_account));
1412 g_object_unref (G_OBJECT (mail_operation));
1414 modest_msg_edit_window_free_msg_data (edit_window, data);
1416 /* Save settings and close the window */
1417 gtk_widget_destroy (GTK_WIDGET (edit_window));
1420 /* For instance, when clicking the Send toolbar button when editing a message: */
1422 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1424 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1426 if (!modest_msg_edit_window_check_names (edit_window))
1429 /* FIXME: Code added just for testing. The final version will
1430 use the send queue provided by tinymail and some
1432 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1433 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1435 account_name = modest_account_mgr_get_default_account (account_mgr);
1437 if (!account_name) {
1438 g_printerr ("modest: no account found\n");
1441 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1443 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1444 account_name = g_strdup (data->account_name);
1447 /* Get the currently-active transport account for this modest account: */
1448 TnyTransportAccount *transport_account =
1449 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1450 (modest_runtime_get_account_store(),
1452 if (!transport_account) {
1453 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1454 g_free (account_name);
1455 modest_msg_edit_window_free_msg_data (edit_window, data);
1459 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1461 /* mail content checks and dialogs */
1462 if (data->subject == NULL || data->subject[0] == '\0') {
1463 GtkResponseType response;
1464 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1465 _("mcen_nc_subject_is_empty_send"));
1466 if (response == GTK_RESPONSE_CANCEL) {
1467 g_free (account_name);
1472 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1473 GtkResponseType response;
1474 gchar *note_message;
1475 gchar *note_subject = data->subject;
1476 if (note_subject == NULL || note_subject[0] == '\0')
1477 note_subject = _("mail_va_no_subject");
1478 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1479 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1481 g_free (note_message);
1482 if (response == GTK_RESPONSE_CANCEL) {
1483 g_free (account_name);
1488 /* Create the mail operation */
1489 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1490 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1492 modest_mail_operation_send_new_mail (mail_operation,
1503 data->priority_flags);
1507 g_free (account_name);
1508 g_object_unref (G_OBJECT (transport_account));
1509 g_object_unref (G_OBJECT (mail_operation));
1511 modest_msg_edit_window_free_msg_data (edit_window, data);
1513 /* Save settings and close the window: */
1514 gtk_widget_destroy (GTK_WIDGET (edit_window));
1518 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1519 ModestMsgEditWindow *window)
1521 ModestMsgEditFormatState *format_state = NULL;
1523 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1524 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1526 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1529 format_state = modest_msg_edit_window_get_format_state (window);
1530 g_return_if_fail (format_state != NULL);
1532 format_state->bold = gtk_toggle_action_get_active (action);
1533 modest_msg_edit_window_set_format_state (window, format_state);
1534 g_free (format_state);
1539 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1540 ModestMsgEditWindow *window)
1542 ModestMsgEditFormatState *format_state = NULL;
1544 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1545 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1547 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1550 format_state = modest_msg_edit_window_get_format_state (window);
1551 g_return_if_fail (format_state != NULL);
1553 format_state->italics = gtk_toggle_action_get_active (action);
1554 modest_msg_edit_window_set_format_state (window, format_state);
1555 g_free (format_state);
1560 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1561 ModestMsgEditWindow *window)
1563 ModestMsgEditFormatState *format_state = NULL;
1565 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1566 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1568 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1571 format_state = modest_msg_edit_window_get_format_state (window);
1572 g_return_if_fail (format_state != NULL);
1574 format_state->bullet = gtk_toggle_action_get_active (action);
1575 modest_msg_edit_window_set_format_state (window, format_state);
1576 g_free (format_state);
1581 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1582 GtkRadioAction *selected,
1583 ModestMsgEditWindow *window)
1585 ModestMsgEditFormatState *format_state = NULL;
1586 GtkJustification value;
1588 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1590 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1593 value = gtk_radio_action_get_current_value (selected);
1595 format_state = modest_msg_edit_window_get_format_state (window);
1596 g_return_if_fail (format_state != NULL);
1598 format_state->justification = value;
1599 modest_msg_edit_window_set_format_state (window, format_state);
1600 g_free (format_state);
1604 modest_ui_actions_on_select_editor_color (GtkAction *action,
1605 ModestMsgEditWindow *window)
1607 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1608 g_return_if_fail (GTK_IS_ACTION (action));
1610 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1613 modest_msg_edit_window_select_color (window);
1617 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1618 ModestMsgEditWindow *window)
1620 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1621 g_return_if_fail (GTK_IS_ACTION (action));
1623 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1626 modest_msg_edit_window_select_background_color (window);
1630 modest_ui_actions_on_insert_image (GtkAction *action,
1631 ModestMsgEditWindow *window)
1633 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1634 g_return_if_fail (GTK_IS_ACTION (action));
1636 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1639 modest_msg_edit_window_insert_image (window);
1643 modest_ui_actions_on_attach_file (GtkAction *action,
1644 ModestMsgEditWindow *window)
1646 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1647 g_return_if_fail (GTK_IS_ACTION (action));
1649 modest_msg_edit_window_attach_file (window);
1653 modest_ui_actions_on_remove_attachments (GtkAction *action,
1654 ModestMsgEditWindow *window)
1656 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1657 g_return_if_fail (GTK_IS_ACTION (action));
1659 modest_msg_edit_window_remove_attachments (window, NULL);
1663 * Shows a dialog with an entry that asks for some text. The returned
1664 * value must be freed by the caller. The dialog window title will be
1668 ask_for_folder_name (GtkWindow *parent_window,
1671 GtkWidget *dialog, *entry;
1672 gchar *folder_name = NULL;
1674 /* Ask for folder name */
1675 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1679 GTK_RESPONSE_REJECT,
1681 GTK_RESPONSE_ACCEPT,
1683 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1684 gtk_label_new(title),
1687 entry = gtk_entry_new_with_max_length (40);
1688 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1692 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1694 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1695 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1697 gtk_widget_destroy (dialog);
1703 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1705 TnyFolderStore *parent_folder;
1706 GtkWidget *folder_view;
1708 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1710 folder_view = modest_main_window_get_child_widget (main_window,
1711 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1715 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1717 if (parent_folder) {
1718 gboolean finished = FALSE;
1720 gchar *folder_name = NULL, *suggested_name = NULL;
1722 /* Run the new folder dialog */
1724 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1729 if (result == GTK_RESPONSE_REJECT) {
1732 ModestMailOperation *mail_op;
1733 TnyFolder *new_folder = NULL;
1735 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1736 G_OBJECT(main_window));
1737 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1739 new_folder = modest_mail_operation_create_folder (mail_op,
1741 (const gchar *) folder_name);
1743 g_object_unref (new_folder);
1746 g_object_unref (mail_op);
1748 g_free (folder_name);
1752 g_object_unref (parent_folder);
1757 modest_ui_actions_on_rename_folder (GtkAction *action,
1758 ModestMainWindow *main_window)
1760 TnyFolderStore *folder;
1761 GtkWidget *folder_view;
1762 GtkWidget *header_view;
1764 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1766 folder_view = modest_main_window_get_child_widget (main_window,
1767 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1771 header_view = modest_main_window_get_child_widget (main_window,
1772 MODEST_WIDGET_TYPE_HEADER_VIEW);
1777 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1779 if (folder && TNY_IS_FOLDER (folder)) {
1781 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1782 _("Please enter a new name for the folder"));
1784 if (folder_name != NULL && strlen (folder_name) > 0) {
1785 ModestMailOperation *mail_op;
1787 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1788 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1791 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1793 modest_mail_operation_rename_folder (mail_op,
1794 TNY_FOLDER (folder),
1795 (const gchar *) folder_name);
1797 g_object_unref (mail_op);
1798 g_free (folder_name);
1800 g_object_unref (folder);
1805 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1808 GObject *win = modest_mail_operation_get_source (mail_op);
1810 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1811 _("mail_in_ui_folder_delete_error"));
1815 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1817 TnyFolderStore *folder;
1818 GtkWidget *folder_view;
1822 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1824 folder_view = modest_main_window_get_child_widget (main_window,
1825 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1829 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1831 /* Show an error if it's an account */
1832 if (!TNY_IS_FOLDER (folder)) {
1833 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1834 _("mail_in_ui_folder_delete_error"));
1839 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1840 tny_folder_get_name (TNY_FOLDER (folder)));
1841 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1842 (const gchar *) message);
1845 if (response == GTK_RESPONSE_OK) {
1846 ModestMailOperation *mail_op =
1847 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1848 G_OBJECT(main_window),
1849 modest_ui_actions_delete_folder_error_handler,
1852 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1854 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1855 g_object_unref (G_OBJECT (mail_op));
1858 g_object_unref (G_OBJECT (folder));
1862 modest_ui_actions_on_delete_folder (GtkAction *action,
1863 ModestMainWindow *main_window)
1865 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1867 delete_folder (main_window, FALSE);
1871 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1873 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1875 delete_folder (main_window, TRUE);
1879 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1880 const gchar* server_account_name,
1885 ModestMainWindow *main_window)
1887 g_return_if_fail(server_account_name);
1888 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1890 /* Initalize output parameters: */
1897 #ifdef MODEST_PLATFORM_MAEMO
1898 /* Maemo uses a different (awkward) button order,
1899 * It should probably just use gtk_alternative_dialog_button_order ().
1901 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1905 GTK_RESPONSE_ACCEPT,
1907 GTK_RESPONSE_REJECT,
1910 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1914 GTK_RESPONSE_REJECT,
1916 GTK_RESPONSE_ACCEPT,
1918 #endif /* MODEST_PLATFORM_MAEMO */
1920 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1922 gchar *server_name = modest_server_account_get_hostname (
1923 modest_runtime_get_account_mgr(), server_account_name);
1925 /* This causes a warning because the logical ID has no %s in it,
1926 * though the translation does, but there is not much we can do about that: */
1927 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1928 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1931 g_free (server_name);
1935 gchar *initial_username = modest_server_account_get_username (
1936 modest_runtime_get_account_mgr(), server_account_name);
1938 GtkWidget *entry_username = gtk_entry_new ();
1939 if (initial_username)
1940 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1941 /* Dim this if a connection has ever succeeded with this username,
1942 * as per the UI spec: */
1943 const gboolean username_known =
1944 modest_server_account_get_username_has_succeeded(
1945 modest_runtime_get_account_mgr(), server_account_name);
1946 gtk_widget_set_sensitive (entry_username, !username_known);
1948 #ifdef MODEST_PLATFORM_MAEMO
1949 /* Auto-capitalization is the default, so let's turn it off: */
1950 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1952 /* Create a size group to be used by all captions.
1953 * Note that HildonCaption does not create a default size group if we do not specify one.
1954 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1955 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1957 GtkWidget *caption = hildon_caption_new (sizegroup,
1958 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1959 gtk_widget_show (entry_username);
1960 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1961 FALSE, FALSE, MODEST_MARGIN_HALF);
1962 gtk_widget_show (caption);
1964 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1966 #endif /* MODEST_PLATFORM_MAEMO */
1969 GtkWidget *entry_password = gtk_entry_new ();
1970 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1971 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1973 #ifdef MODEST_PLATFORM_MAEMO
1974 /* Auto-capitalization is the default, so let's turn it off: */
1975 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1976 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1978 caption = hildon_caption_new (sizegroup,
1979 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1980 gtk_widget_show (entry_password);
1981 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1982 FALSE, FALSE, MODEST_MARGIN_HALF);
1983 gtk_widget_show (caption);
1984 g_object_unref (sizegroup);
1986 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1988 #endif /* MODEST_PLATFORM_MAEMO */
1990 /* This is not in the Maemo UI spec:
1991 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1992 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1996 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1998 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2000 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2002 modest_server_account_set_username (
2003 modest_runtime_get_account_mgr(), server_account_name,
2006 const gboolean username_was_changed =
2007 (strcmp (*username, initial_username) != 0);
2008 if (username_was_changed) {
2009 /* To actually use a changed username,
2010 * we must reset the connection, according to pvanhoof.
2011 * This _might_ be a sensible way to do that: */
2012 TnyDevice *device = modest_runtime_get_device();
2013 tny_device_force_offline (device);
2014 tny_device_force_online (device);
2019 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2021 /* We do not save the password in the configuration,
2022 * because this function is only called for passwords that should
2023 * not be remembered:
2024 modest_server_account_set_password (
2025 modest_runtime_get_account_mgr(), server_account_name,
2044 /* This is not in the Maemo UI spec:
2045 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2051 gtk_widget_destroy (dialog);
2053 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2057 modest_ui_actions_on_cut (GtkAction *action,
2058 ModestWindow *window)
2060 GtkWidget *focused_widget;
2062 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2063 if (GTK_IS_EDITABLE (focused_widget)) {
2064 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2065 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2066 GtkTextBuffer *buffer;
2067 GtkClipboard *clipboard;
2069 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2070 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2071 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2076 modest_ui_actions_on_copy (GtkAction *action,
2077 ModestWindow *window)
2079 GtkClipboard *clipboard;
2080 GtkWidget *focused_widget;
2082 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2083 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2084 if (GTK_IS_LABEL (focused_widget)) {
2085 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2086 } else if (GTK_IS_EDITABLE (focused_widget)) {
2087 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2088 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2089 GtkTextBuffer *buffer;
2091 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2092 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2097 modest_ui_actions_on_undo (GtkAction *action,
2098 ModestWindow *window)
2100 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2101 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2103 g_return_if_reached ();
2108 modest_ui_actions_on_paste (GtkAction *action,
2109 ModestWindow *window)
2111 GtkWidget *focused_widget;
2113 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2114 if (GTK_IS_EDITABLE (focused_widget)) {
2115 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2116 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2117 GtkTextBuffer *buffer;
2118 GtkClipboard *clipboard;
2120 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2121 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2122 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2127 modest_ui_actions_on_select_all (GtkAction *action,
2128 ModestWindow *window)
2130 GtkWidget *focused_widget;
2132 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2133 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2134 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2135 } else if (GTK_IS_LABEL (focused_widget)) {
2136 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2137 } else if (GTK_IS_EDITABLE (focused_widget)) {
2138 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2139 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2140 GtkTextBuffer *buffer;
2141 GtkTextIter start, end;
2143 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2144 gtk_text_buffer_get_start_iter (buffer, &start);
2145 gtk_text_buffer_get_end_iter (buffer, &end);
2146 gtk_text_buffer_select_range (buffer, &start, &end);
2148 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2149 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2151 GtkTreeSelection *selection = NULL;
2153 /* Get header view */
2154 GtkWidget *header_view = focused_widget;
2155 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2156 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2157 MODEST_WIDGET_TYPE_HEADER_VIEW);
2159 /* Select all messages */
2160 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2161 gtk_tree_selection_select_all (selection);
2166 modest_ui_actions_on_mark_as_read (GtkAction *action,
2167 ModestWindow *window)
2169 g_return_if_fail (MODEST_IS_WINDOW(window));
2171 /* Mark each header as read */
2172 do_headers_action (window, headers_action_mark_as_read, NULL);
2176 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2177 ModestWindow *window)
2179 g_return_if_fail (MODEST_IS_WINDOW(window));
2181 /* Mark each header as read */
2182 do_headers_action (window, headers_action_mark_as_unread, NULL);
2186 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2187 GtkRadioAction *selected,
2188 ModestWindow *window)
2192 value = gtk_radio_action_get_current_value (selected);
2193 if (MODEST_IS_WINDOW (window)) {
2194 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2198 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2199 GtkRadioAction *selected,
2200 ModestWindow *window)
2202 TnyHeaderFlags flags;
2203 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2205 flags = gtk_radio_action_get_current_value (selected);
2206 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2209 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2210 GtkRadioAction *selected,
2211 ModestWindow *window)
2215 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2217 file_format = gtk_radio_action_get_current_value (selected);
2218 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2223 modest_ui_actions_on_zoom_plus (GtkAction *action,
2224 ModestWindow *window)
2226 g_return_if_fail (MODEST_IS_WINDOW (window));
2228 modest_window_zoom_plus (MODEST_WINDOW (window));
2232 modest_ui_actions_on_zoom_minus (GtkAction *action,
2233 ModestWindow *window)
2235 g_return_if_fail (MODEST_IS_WINDOW (window));
2237 modest_window_zoom_minus (MODEST_WINDOW (window));
2241 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2242 ModestWindow *window)
2244 ModestWindowMgr *mgr;
2245 gboolean fullscreen, active;
2246 g_return_if_fail (MODEST_IS_WINDOW (window));
2248 mgr = modest_runtime_get_window_mgr ();
2250 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2251 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2253 if (active != fullscreen) {
2254 modest_window_mgr_set_fullscreen_mode (mgr, active);
2255 gtk_window_present (GTK_WINDOW (window));
2260 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2261 ModestWindow *window)
2263 ModestWindowMgr *mgr;
2264 gboolean fullscreen;
2266 g_return_if_fail (MODEST_IS_WINDOW (window));
2268 mgr = modest_runtime_get_window_mgr ();
2269 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2270 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2272 gtk_window_present (GTK_WINDOW (window));
2276 * Used by modest_ui_actions_on_details to call do_headers_action
2279 headers_action_show_details (TnyHeader *header,
2280 ModestWindow *window,
2287 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2290 gtk_widget_show_all (dialog);
2291 gtk_dialog_run (GTK_DIALOG (dialog));
2293 gtk_widget_destroy (dialog);
2297 * Show the folder details in a ModestDetailsDialog widget
2300 show_folder_details (TnyFolder *folder,
2306 dialog = modest_details_dialog_new_with_folder (window, folder);
2309 gtk_widget_show_all (dialog);
2310 gtk_dialog_run (GTK_DIALOG (dialog));
2312 gtk_widget_destroy (dialog);
2316 * Show the header details in a ModestDetailsDialog widget
2319 modest_ui_actions_on_details (GtkAction *action,
2322 TnyList * headers_list;
2326 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2329 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2332 g_object_unref (msg);
2334 headers_list = get_selected_headers (win);
2338 iter = tny_list_create_iterator (headers_list);
2340 header = TNY_HEADER (tny_iterator_get_current (iter));
2341 headers_action_show_details (header, win, NULL);
2342 g_object_unref (header);
2344 g_object_unref (iter);
2345 g_object_unref (headers_list);
2347 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2348 GtkWidget *folder_view, *header_view;
2350 /* Check which widget has the focus */
2351 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2352 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2353 if (gtk_widget_is_focus (folder_view)) {
2356 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2358 /* Show only when it's a folder */
2359 if (!folder || !TNY_IS_FOLDER (folder))
2362 show_folder_details (folder, GTK_WINDOW (win));
2365 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2366 MODEST_WIDGET_TYPE_HEADER_VIEW);
2367 /* Show details of each header */
2368 do_headers_action (win, headers_action_show_details, header_view);
2374 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2375 ModestMsgEditWindow *window)
2377 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2379 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2383 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2384 ModestMsgEditWindow *window)
2386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2388 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2392 modest_ui_actions_toggle_folders_view (GtkAction *action,
2393 ModestMainWindow *main_window)
2397 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2399 conf = modest_runtime_get_conf ();
2401 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2402 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2404 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2408 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2409 ModestWindow *window)
2411 gboolean active, fullscreen = FALSE;
2412 ModestWindowMgr *mgr;
2414 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2416 /* Check if we want to toggle the toolbar vuew in fullscreen
2418 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2419 "ViewShowToolbarFullScreen")) {
2423 /* Toggle toolbar */
2424 mgr = modest_runtime_get_window_mgr ();
2425 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2429 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2430 ModestMsgEditWindow *window)
2432 modest_msg_edit_window_select_font (window);
2436 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2437 const gchar *display_name,
2440 /* Do not change the application name if the widget has not
2441 the focus. This callback could be called even if the folder
2442 view has not the focus, because the handled signal could be
2443 emitted when the folder view is redrawn */
2444 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2446 gtk_window_set_title (window, display_name);
2448 gtk_window_set_title (window, " ");
2453 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2455 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2456 modest_msg_edit_window_select_contacts (window);
2460 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2462 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2463 modest_msg_edit_window_check_names (window);
2468 create_move_to_dialog (ModestWindow *win,
2469 GtkWidget *folder_view,
2470 GtkWidget **tree_view)
2472 GtkWidget *dialog, *scroll;
2474 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2476 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2478 GTK_RESPONSE_ACCEPT,
2480 GTK_RESPONSE_REJECT,
2483 /* Create scrolled window */
2484 scroll = gtk_scrolled_window_new (NULL, NULL);
2485 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2486 GTK_POLICY_AUTOMATIC,
2487 GTK_POLICY_AUTOMATIC);
2489 /* Create folder view */
2490 *tree_view = modest_folder_view_new (NULL);
2491 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2492 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2493 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2495 /* Add scroll to dialog */
2496 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2497 scroll, FALSE, FALSE, 0);
2499 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2505 * Returns TRUE if at least one of the headers of the list belongs to
2506 * a message that has been fully retrieved.
2509 has_retrieved_msgs (TnyList *list)
2512 gboolean found = FALSE;
2514 iter = tny_list_create_iterator (list);
2515 while (tny_iterator_is_done (iter) && !found) {
2517 TnyHeaderFlags flags;
2519 header = TNY_HEADER (tny_iterator_get_current (iter));
2520 flags = tny_header_get_flags (header);
2521 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2525 tny_iterator_next (iter);
2527 g_object_unref (iter);
2533 * Shows a confirmation dialog to the user when we're moving messages
2534 * from a remote server to the local storage. Returns the dialog
2535 * response. If it's other kind of movement the it always returns
2539 msgs_move_to_confirmation (GtkWindow *win,
2540 TnyFolder *dest_folder,
2543 gint response = GTK_RESPONSE_OK;
2545 /* If the destination is a local folder */
2546 if (modest_tny_folder_is_local_folder (dest_folder)) {
2547 TnyFolder *src_folder;
2551 /* Get source folder */
2552 iter = tny_list_create_iterator (headers);
2553 header = TNY_HEADER (tny_iterator_get_current (iter));
2554 src_folder = tny_header_get_folder (header);
2555 g_object_unref (header);
2556 g_object_unref (iter);
2558 /* If the source is a remote folder */
2559 if (!modest_tny_folder_is_local_folder (src_folder)) {
2560 const gchar *message;
2562 if (tny_list_get_length (headers) == 1)
2563 if (has_retrieved_msgs (headers))
2564 message = _("mcen_nc_move_retrieve");
2566 message = _("mcen_nc_move_header");
2568 if (has_retrieved_msgs (headers))
2569 message = _("mcen_nc_move_retrieves");
2571 message = _("mcen_nc_move_headers");
2573 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2574 (const gchar *) message);
2576 g_object_unref (src_folder);
2583 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2585 ModestMsgViewWindow *self = NULL;
2586 gboolean found = FALSE;
2588 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2589 self = MODEST_MSG_VIEW_WINDOW (object);
2591 found = modest_msg_view_window_select_first_message (self);
2592 g_return_if_fail (found);
2596 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2599 GObject *win = modest_mail_operation_get_source (mail_op);
2601 /* TODO: show error message */
2602 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2603 _("mail_in_ui_folder_move_target_error"));
2607 * UI handler for the "Move to" action when invoked from the
2611 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2612 ModestMainWindow *win)
2614 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2615 GtkWidget *header_view = NULL;
2617 TnyFolderStore *folder_store = NULL;
2618 ModestMailOperation *mail_op = NULL;
2620 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2622 /* Get the folder view */
2623 folder_view = modest_main_window_get_child_widget (win,
2624 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2626 /* Get header view */
2627 header_view = modest_main_window_get_child_widget (win,
2628 MODEST_WIDGET_TYPE_HEADER_VIEW);
2630 /* Create and run the dialog */
2631 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2632 result = gtk_dialog_run (GTK_DIALOG(dialog));
2633 g_object_ref (tree_view);
2635 /* We do this to save an indentation level ;-) */
2636 if (result != GTK_RESPONSE_ACCEPT)
2639 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2641 if (TNY_IS_ACCOUNT (folder_store))
2644 /* Get folder or messages to transfer */
2645 if (gtk_widget_is_focus (folder_view)) {
2646 TnyFolderStore *src_folder;
2647 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2649 /* Clean folder on header view before moving it */
2650 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2652 if (TNY_IS_FOLDER (src_folder)) {
2654 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2656 modest_ui_actions_move_folder_error_handler,
2658 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2660 modest_mail_operation_xfer_folder (mail_op,
2661 TNY_FOLDER (src_folder),
2664 /* Unref mail operation */
2665 g_object_unref (G_OBJECT (mail_op));
2669 g_object_unref (G_OBJECT (src_folder));
2671 if (gtk_widget_is_focus (header_view)) {
2675 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2677 /* Ask for user confirmation */
2678 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2679 TNY_FOLDER (folder_store),
2682 /* Transfer messages */
2683 if (response == GTK_RESPONSE_OK) {
2684 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2685 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2688 modest_mail_operation_xfer_msgs (mail_op,
2690 TNY_FOLDER (folder_store),
2695 g_object_unref (G_OBJECT (mail_op));
2697 g_object_unref (headers);
2700 g_object_unref (folder_store);
2702 gtk_widget_destroy (dialog);
2707 * UI handler for the "Move to" action when invoked from the
2708 * ModestMsgViewWindow
2711 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2712 ModestMsgViewWindow *win)
2714 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2716 ModestMainWindow *main_window;
2720 /* Get the folder view */
2721 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2722 folder_view = modest_main_window_get_child_widget (main_window,
2723 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2725 /* Create and run the dialog */
2726 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2727 result = gtk_dialog_run (GTK_DIALOG(dialog));
2728 g_object_ref (tree_view);
2730 if (result == GTK_RESPONSE_ACCEPT) {
2731 TnyFolderStore *folder_store;
2734 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2736 /* Create header list */
2737 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2738 headers = tny_simple_list_new ();
2739 tny_list_prepend (headers, G_OBJECT (header));
2740 g_object_unref (header);
2742 /* Ask user for confirmation. MSG-NOT404 */
2743 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2744 TNY_FOLDER (folder_store),
2747 /* Transfer current msg */
2748 if (response == GTK_RESPONSE_OK) {
2749 ModestMailOperation *mail_op;
2751 /* Create mail op */
2752 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2753 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2756 /* Transfer messages */
2757 modest_mail_operation_xfer_msgs (mail_op,
2759 TNY_FOLDER (folder_store),
2761 tranasfer_msgs_from_viewer_cb,
2763 g_object_unref (G_OBJECT (mail_op));
2765 g_object_unref (headers);
2766 g_object_unref (folder_store);
2768 gtk_widget_destroy (dialog);
2772 modest_ui_actions_on_move_to (GtkAction *action,
2775 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2776 MODEST_IS_MSG_VIEW_WINDOW (win));
2778 if (MODEST_IS_MAIN_WINDOW (win))
2779 modest_ui_actions_on_main_window_move_to (action,
2780 MODEST_MAIN_WINDOW (win));
2782 modest_ui_actions_on_msg_view_window_move_to (action,
2783 MODEST_MSG_VIEW_WINDOW (win));
2787 * Calls #HeadersFunc for each header already selected in the main
2788 * window or the message currently being shown in the msg view window
2791 do_headers_action (ModestWindow *win,
2795 TnyList *headers_list;
2799 headers_list = get_selected_headers (win);
2803 /* Call the function for each header */
2804 iter = tny_list_create_iterator (headers_list);
2805 while (!tny_iterator_is_done (iter)) {
2808 header = TNY_HEADER (tny_iterator_get_current (iter));
2809 func (header, win, user_data);
2810 g_object_unref (header);
2811 tny_iterator_next (iter);
2813 g_object_unref (iter);
2814 g_object_unref (headers_list);
2818 modest_ui_actions_view_attachment (GtkAction *action,
2819 ModestWindow *window)
2821 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2822 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2824 /* not supported window for this action */
2825 g_return_if_reached ();
2830 modest_ui_actions_save_attachments (GtkAction *action,
2831 ModestWindow *window)
2833 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2834 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2836 /* not supported window for this action */
2837 g_return_if_reached ();
2842 modest_ui_actions_remove_attachments (GtkAction *action,
2843 ModestWindow *window)
2845 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2846 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2848 /* not supported window for this action */
2849 g_return_if_reached ();
2854 modest_ui_actions_on_settings (GtkAction *action,
2859 dialog = modest_platform_get_global_settings_dialog ();
2860 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2861 gtk_widget_show (dialog);
2863 gtk_dialog_run (GTK_DIALOG (dialog));
2865 gtk_widget_destroy (dialog);
2869 modest_ui_actions_on_help (GtkAction *action,
2872 const gchar *help_id = NULL;
2874 if (MODEST_IS_MAIN_WINDOW (win)) {
2875 const gchar *action_name;
2876 action_name = gtk_action_get_name (action);
2878 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2879 !strcmp (action_name, "HeaderViewCSMHelp")) {
2880 GtkWidget *folder_view;
2881 TnyFolderStore *folder_store;
2882 /* Get selected folder */
2883 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2884 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2885 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2887 /* Switch help_id */
2888 if (TNY_IS_FOLDER (folder_store)) {
2889 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2890 case TNY_FOLDER_TYPE_NORMAL:
2891 help_id = "applications_email_userfolder";
2893 case TNY_FOLDER_TYPE_INBOX:
2894 help_id = "applications_email_inbox";
2896 case TNY_FOLDER_TYPE_OUTBOX:
2897 help_id = "applications_email_outbox";
2899 case TNY_FOLDER_TYPE_SENT:
2900 help_id = "applications_email_sent";
2902 case TNY_FOLDER_TYPE_DRAFTS:
2903 help_id = "applications_email_drafts";
2905 case TNY_FOLDER_TYPE_ARCHIVE:
2906 help_id = "applications_email_archive";
2913 help_id = "applications_email_mainview";
2915 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2916 help_id = "applications_email_viewer";
2917 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2918 help_id = "applications_email_editor";
2920 modest_platform_show_help (GTK_WINDOW (win), help_id);
2924 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2925 ModestWindow *window)
2927 ModestMailOperation *mail_op;
2931 headers = get_selected_headers (window);
2935 /* Create mail operation */
2936 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2938 modest_ui_actions_get_msgs_full_error_handler,
2940 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2941 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2944 g_object_unref (headers);
2945 g_object_unref (mail_op);
2949 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2950 ModestWindow *window)
2952 g_return_if_fail (MODEST_IS_WINDOW (window));
2955 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2959 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2960 ModestWindow *window)
2962 g_return_if_fail (MODEST_IS_WINDOW (window));
2965 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2969 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2970 ModestWindow *window)
2972 g_return_if_fail (MODEST_IS_WINDOW (window));
2975 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2979 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2980 ModestWindow *window)
2982 g_return_if_fail (MODEST_IS_WINDOW (window));
2985 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2989 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2990 ModestWindow *window)
2992 g_return_if_fail (MODEST_IS_WINDOW (window));
2995 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2999 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3001 g_return_if_fail (MODEST_IS_WINDOW (window));
3004 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3008 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3010 g_return_if_fail (MODEST_IS_WINDOW (window));
3012 modest_platform_show_search_messages (GTK_WINDOW (window));