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);
1236 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1237 //TODO: Set the virtual folder store as the "active account" somehow:
1238 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1240 if (TNY_IS_FOLDER (folder_store) && selected) {
1242 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1243 /* Update the active account */
1244 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1245 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1246 g_object_unref (account);
1249 /* Set folder on header view */
1250 modest_main_window_set_contents_style (main_window,
1251 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1252 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1253 TNY_FOLDER (folder_store));
1254 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1255 MODEST_CONF_HEADER_VIEW_KEY);
1257 /* Update the active account */
1258 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1259 /* Do not show folder */
1260 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1261 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1265 /* Update toolbar dimming state */
1266 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1270 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1277 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1279 if (g_main_depth > 0)
1280 gdk_threads_enter ();
1281 online = tny_device_is_online (modest_runtime_get_device());
1284 /* already online -- the item is simply not there... */
1285 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1287 GTK_MESSAGE_WARNING,
1289 _("The %s you selected cannot be found"),
1291 gtk_dialog_run (GTK_DIALOG(dialog));
1293 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1297 GTK_RESPONSE_REJECT,
1299 GTK_RESPONSE_ACCEPT,
1301 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1302 "Do you want to get online?"), item);
1303 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1304 gtk_label_new (txt), FALSE, FALSE, 0);
1305 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1308 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1309 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1310 // modest_platform_connect_and_wait ();;
1313 gtk_widget_destroy (dialog);
1314 if (g_main_depth > 0)
1315 gdk_threads_leave ();
1319 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1322 /* g_message ("%s %s", __FUNCTION__, link); */
1327 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1330 modest_platform_activate_uri (link);
1334 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1337 modest_platform_show_uri_popup (link);
1341 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1344 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1348 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1349 const gchar *address,
1352 /* g_message ("%s %s", __FUNCTION__, address); */
1356 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1358 TnyTransportAccount *transport_account;
1359 ModestMailOperation *mail_operation;
1361 gchar *account_name, *from;
1362 ModestAccountMgr *account_mgr;
1364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1366 data = modest_msg_edit_window_get_msg_data (edit_window);
1368 account_mgr = modest_runtime_get_account_mgr();
1369 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1371 account_name = modest_account_mgr_get_default_account (account_mgr);
1372 if (!account_name) {
1373 g_printerr ("modest: no account found\n");
1374 modest_msg_edit_window_free_msg_data (edit_window, data);
1378 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1379 account_name = g_strdup (data->account_name);
1383 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1384 (modest_runtime_get_account_store(),
1386 TNY_ACCOUNT_TYPE_TRANSPORT));
1387 if (!transport_account) {
1388 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1389 g_free (account_name);
1390 modest_msg_edit_window_free_msg_data (edit_window, data);
1393 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1395 /* Create the mail operation */
1396 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1397 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1399 modest_mail_operation_save_to_drafts (mail_operation,
1410 data->priority_flags);
1413 g_free (account_name);
1414 g_object_unref (G_OBJECT (transport_account));
1415 g_object_unref (G_OBJECT (mail_operation));
1417 modest_msg_edit_window_free_msg_data (edit_window, data);
1419 /* Save settings and close the window */
1420 gtk_widget_destroy (GTK_WIDGET (edit_window));
1423 /* For instance, when clicking the Send toolbar button when editing a message: */
1425 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1427 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1429 if (!modest_msg_edit_window_check_names (edit_window))
1432 /* FIXME: Code added just for testing. The final version will
1433 use the send queue provided by tinymail and some
1435 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1436 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1438 account_name = modest_account_mgr_get_default_account (account_mgr);
1440 if (!account_name) {
1441 g_printerr ("modest: no account found\n");
1444 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1446 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1447 account_name = g_strdup (data->account_name);
1450 /* Get the currently-active transport account for this modest account: */
1451 TnyTransportAccount *transport_account =
1452 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1453 (modest_runtime_get_account_store(),
1455 if (!transport_account) {
1456 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1457 g_free (account_name);
1458 modest_msg_edit_window_free_msg_data (edit_window, data);
1462 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1464 /* mail content checks and dialogs */
1465 if (data->subject == NULL || data->subject[0] == '\0') {
1466 GtkResponseType response;
1467 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1468 _("mcen_nc_subject_is_empty_send"));
1469 if (response == GTK_RESPONSE_CANCEL) {
1470 g_free (account_name);
1475 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1476 GtkResponseType response;
1477 gchar *note_message;
1478 gchar *note_subject = data->subject;
1479 if (note_subject == NULL || note_subject[0] == '\0')
1480 note_subject = _("mail_va_no_subject");
1481 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1482 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1484 g_free (note_message);
1485 if (response == GTK_RESPONSE_CANCEL) {
1486 g_free (account_name);
1491 /* Create the mail operation */
1492 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1493 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1495 modest_mail_operation_send_new_mail (mail_operation,
1506 data->priority_flags);
1510 g_free (account_name);
1511 g_object_unref (G_OBJECT (transport_account));
1512 g_object_unref (G_OBJECT (mail_operation));
1514 modest_msg_edit_window_free_msg_data (edit_window, data);
1516 /* Save settings and close the window: */
1517 gtk_widget_destroy (GTK_WIDGET (edit_window));
1521 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1522 ModestMsgEditWindow *window)
1524 ModestMsgEditFormatState *format_state = NULL;
1526 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1527 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1529 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1532 format_state = modest_msg_edit_window_get_format_state (window);
1533 g_return_if_fail (format_state != NULL);
1535 format_state->bold = gtk_toggle_action_get_active (action);
1536 modest_msg_edit_window_set_format_state (window, format_state);
1537 g_free (format_state);
1542 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1543 ModestMsgEditWindow *window)
1545 ModestMsgEditFormatState *format_state = NULL;
1547 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1548 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1550 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1553 format_state = modest_msg_edit_window_get_format_state (window);
1554 g_return_if_fail (format_state != NULL);
1556 format_state->italics = gtk_toggle_action_get_active (action);
1557 modest_msg_edit_window_set_format_state (window, format_state);
1558 g_free (format_state);
1563 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1564 ModestMsgEditWindow *window)
1566 ModestMsgEditFormatState *format_state = NULL;
1568 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1569 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1571 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1574 format_state = modest_msg_edit_window_get_format_state (window);
1575 g_return_if_fail (format_state != NULL);
1577 format_state->bullet = gtk_toggle_action_get_active (action);
1578 modest_msg_edit_window_set_format_state (window, format_state);
1579 g_free (format_state);
1584 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1585 GtkRadioAction *selected,
1586 ModestMsgEditWindow *window)
1588 ModestMsgEditFormatState *format_state = NULL;
1589 GtkJustification value;
1591 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1593 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1596 value = gtk_radio_action_get_current_value (selected);
1598 format_state = modest_msg_edit_window_get_format_state (window);
1599 g_return_if_fail (format_state != NULL);
1601 format_state->justification = value;
1602 modest_msg_edit_window_set_format_state (window, format_state);
1603 g_free (format_state);
1607 modest_ui_actions_on_select_editor_color (GtkAction *action,
1608 ModestMsgEditWindow *window)
1610 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1611 g_return_if_fail (GTK_IS_ACTION (action));
1613 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1616 modest_msg_edit_window_select_color (window);
1620 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1621 ModestMsgEditWindow *window)
1623 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1624 g_return_if_fail (GTK_IS_ACTION (action));
1626 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1629 modest_msg_edit_window_select_background_color (window);
1633 modest_ui_actions_on_insert_image (GtkAction *action,
1634 ModestMsgEditWindow *window)
1636 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1637 g_return_if_fail (GTK_IS_ACTION (action));
1639 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1642 modest_msg_edit_window_insert_image (window);
1646 modest_ui_actions_on_attach_file (GtkAction *action,
1647 ModestMsgEditWindow *window)
1649 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1650 g_return_if_fail (GTK_IS_ACTION (action));
1652 modest_msg_edit_window_attach_file (window);
1656 modest_ui_actions_on_remove_attachments (GtkAction *action,
1657 ModestMsgEditWindow *window)
1659 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1660 g_return_if_fail (GTK_IS_ACTION (action));
1662 modest_msg_edit_window_remove_attachments (window, NULL);
1666 * Shows a dialog with an entry that asks for some text. The returned
1667 * value must be freed by the caller. The dialog window title will be
1671 ask_for_folder_name (GtkWindow *parent_window,
1674 GtkWidget *dialog, *entry;
1675 gchar *folder_name = NULL;
1677 /* Ask for folder name */
1678 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1682 GTK_RESPONSE_REJECT,
1684 GTK_RESPONSE_ACCEPT,
1686 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1687 gtk_label_new(title),
1690 entry = gtk_entry_new_with_max_length (40);
1691 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1695 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1697 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1698 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1700 gtk_widget_destroy (dialog);
1706 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1708 TnyFolderStore *parent_folder;
1709 GtkWidget *folder_view;
1711 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1713 folder_view = modest_main_window_get_child_widget (main_window,
1714 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1718 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1720 if (parent_folder) {
1721 gboolean finished = FALSE;
1723 gchar *folder_name = NULL, *suggested_name = NULL;
1725 /* Run the new folder dialog */
1727 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1732 if (result == GTK_RESPONSE_REJECT) {
1735 ModestMailOperation *mail_op;
1736 TnyFolder *new_folder = NULL;
1738 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1739 G_OBJECT(main_window));
1740 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1742 new_folder = modest_mail_operation_create_folder (mail_op,
1744 (const gchar *) folder_name);
1746 g_object_unref (new_folder);
1749 g_object_unref (mail_op);
1751 g_free (folder_name);
1755 g_object_unref (parent_folder);
1760 modest_ui_actions_on_rename_folder (GtkAction *action,
1761 ModestMainWindow *main_window)
1763 TnyFolderStore *folder;
1764 GtkWidget *folder_view;
1765 GtkWidget *header_view;
1767 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1769 folder_view = modest_main_window_get_child_widget (main_window,
1770 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1774 header_view = modest_main_window_get_child_widget (main_window,
1775 MODEST_WIDGET_TYPE_HEADER_VIEW);
1780 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1782 if (folder && TNY_IS_FOLDER (folder)) {
1784 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1785 _("Please enter a new name for the folder"));
1787 if (folder_name != NULL && strlen (folder_name) > 0) {
1788 ModestMailOperation *mail_op;
1790 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1791 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1794 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1796 modest_mail_operation_rename_folder (mail_op,
1797 TNY_FOLDER (folder),
1798 (const gchar *) folder_name);
1800 g_object_unref (mail_op);
1801 g_free (folder_name);
1803 g_object_unref (folder);
1808 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1811 GObject *win = modest_mail_operation_get_source (mail_op);
1813 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1814 _("mail_in_ui_folder_delete_error"));
1818 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1820 TnyFolderStore *folder;
1821 GtkWidget *folder_view;
1825 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1827 folder_view = modest_main_window_get_child_widget (main_window,
1828 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1832 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1834 /* Show an error if it's an account */
1835 if (!TNY_IS_FOLDER (folder)) {
1836 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1837 _("mail_in_ui_folder_delete_error"));
1842 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1843 tny_folder_get_name (TNY_FOLDER (folder)));
1844 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1845 (const gchar *) message);
1848 if (response == GTK_RESPONSE_OK) {
1849 ModestMailOperation *mail_op =
1850 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1851 G_OBJECT(main_window),
1852 modest_ui_actions_delete_folder_error_handler,
1855 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1857 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1858 g_object_unref (G_OBJECT (mail_op));
1861 g_object_unref (G_OBJECT (folder));
1865 modest_ui_actions_on_delete_folder (GtkAction *action,
1866 ModestMainWindow *main_window)
1868 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1870 delete_folder (main_window, FALSE);
1874 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1876 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1878 delete_folder (main_window, TRUE);
1882 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1883 const gchar* server_account_name,
1888 ModestMainWindow *main_window)
1890 g_return_if_fail(server_account_name);
1891 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1893 /* Initalize output parameters: */
1900 #ifdef MODEST_PLATFORM_MAEMO
1901 /* Maemo uses a different (awkward) button order,
1902 * It should probably just use gtk_alternative_dialog_button_order ().
1904 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1908 GTK_RESPONSE_ACCEPT,
1910 GTK_RESPONSE_REJECT,
1913 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1917 GTK_RESPONSE_REJECT,
1919 GTK_RESPONSE_ACCEPT,
1921 #endif /* MODEST_PLATFORM_MAEMO */
1923 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1925 gchar *server_name = modest_server_account_get_hostname (
1926 modest_runtime_get_account_mgr(), server_account_name);
1928 /* This causes a warning because the logical ID has no %s in it,
1929 * though the translation does, but there is not much we can do about that: */
1930 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1931 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1934 g_free (server_name);
1938 gchar *initial_username = modest_server_account_get_username (
1939 modest_runtime_get_account_mgr(), server_account_name);
1941 GtkWidget *entry_username = gtk_entry_new ();
1942 if (initial_username)
1943 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1944 /* Dim this if a connection has ever succeeded with this username,
1945 * as per the UI spec: */
1946 const gboolean username_known =
1947 modest_server_account_get_username_has_succeeded(
1948 modest_runtime_get_account_mgr(), server_account_name);
1949 gtk_widget_set_sensitive (entry_username, !username_known);
1951 #ifdef MODEST_PLATFORM_MAEMO
1952 /* Auto-capitalization is the default, so let's turn it off: */
1953 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1955 /* Create a size group to be used by all captions.
1956 * Note that HildonCaption does not create a default size group if we do not specify one.
1957 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1958 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1960 GtkWidget *caption = hildon_caption_new (sizegroup,
1961 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1962 gtk_widget_show (entry_username);
1963 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1964 FALSE, FALSE, MODEST_MARGIN_HALF);
1965 gtk_widget_show (caption);
1967 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1969 #endif /* MODEST_PLATFORM_MAEMO */
1972 GtkWidget *entry_password = gtk_entry_new ();
1973 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1974 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1976 #ifdef MODEST_PLATFORM_MAEMO
1977 /* Auto-capitalization is the default, so let's turn it off: */
1978 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1979 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1981 caption = hildon_caption_new (sizegroup,
1982 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1983 gtk_widget_show (entry_password);
1984 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1985 FALSE, FALSE, MODEST_MARGIN_HALF);
1986 gtk_widget_show (caption);
1987 g_object_unref (sizegroup);
1989 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1991 #endif /* MODEST_PLATFORM_MAEMO */
1993 /* This is not in the Maemo UI spec:
1994 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1995 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1999 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2001 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2003 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2005 modest_server_account_set_username (
2006 modest_runtime_get_account_mgr(), server_account_name,
2009 const gboolean username_was_changed =
2010 (strcmp (*username, initial_username) != 0);
2011 if (username_was_changed) {
2012 /* To actually use a changed username,
2013 * we must reset the connection, according to pvanhoof.
2014 * This _might_ be a sensible way to do that: */
2015 TnyDevice *device = modest_runtime_get_device();
2016 tny_device_force_offline (device);
2017 tny_device_force_online (device);
2022 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2024 /* We do not save the password in the configuration,
2025 * because this function is only called for passwords that should
2026 * not be remembered:
2027 modest_server_account_set_password (
2028 modest_runtime_get_account_mgr(), server_account_name,
2047 /* This is not in the Maemo UI spec:
2048 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2054 gtk_widget_destroy (dialog);
2056 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2060 modest_ui_actions_on_cut (GtkAction *action,
2061 ModestWindow *window)
2063 GtkWidget *focused_widget;
2065 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2066 if (GTK_IS_EDITABLE (focused_widget)) {
2067 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2068 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2069 GtkTextBuffer *buffer;
2070 GtkClipboard *clipboard;
2072 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2073 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2074 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2079 modest_ui_actions_on_copy (GtkAction *action,
2080 ModestWindow *window)
2082 GtkClipboard *clipboard;
2083 GtkWidget *focused_widget;
2085 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2086 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2087 if (GTK_IS_LABEL (focused_widget)) {
2088 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2089 } else if (GTK_IS_EDITABLE (focused_widget)) {
2090 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2091 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2092 GtkTextBuffer *buffer;
2094 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2095 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2100 modest_ui_actions_on_undo (GtkAction *action,
2101 ModestWindow *window)
2103 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2104 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2106 g_return_if_reached ();
2111 modest_ui_actions_on_paste (GtkAction *action,
2112 ModestWindow *window)
2114 GtkWidget *focused_widget;
2116 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2117 if (GTK_IS_EDITABLE (focused_widget)) {
2118 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2119 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2120 GtkTextBuffer *buffer;
2121 GtkClipboard *clipboard;
2123 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2124 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2125 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2130 modest_ui_actions_on_select_all (GtkAction *action,
2131 ModestWindow *window)
2133 GtkWidget *focused_widget;
2135 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2136 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2137 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2138 } else if (GTK_IS_LABEL (focused_widget)) {
2139 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2140 } else if (GTK_IS_EDITABLE (focused_widget)) {
2141 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2142 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2143 GtkTextBuffer *buffer;
2144 GtkTextIter start, end;
2146 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2147 gtk_text_buffer_get_start_iter (buffer, &start);
2148 gtk_text_buffer_get_end_iter (buffer, &end);
2149 gtk_text_buffer_select_range (buffer, &start, &end);
2151 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2152 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2154 GtkTreeSelection *selection = NULL;
2156 /* Get header view */
2157 GtkWidget *header_view = focused_widget;
2158 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2159 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2160 MODEST_WIDGET_TYPE_HEADER_VIEW);
2162 /* Select all messages */
2163 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2164 gtk_tree_selection_select_all (selection);
2169 modest_ui_actions_on_mark_as_read (GtkAction *action,
2170 ModestWindow *window)
2172 g_return_if_fail (MODEST_IS_WINDOW(window));
2174 /* Mark each header as read */
2175 do_headers_action (window, headers_action_mark_as_read, NULL);
2179 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2180 ModestWindow *window)
2182 g_return_if_fail (MODEST_IS_WINDOW(window));
2184 /* Mark each header as read */
2185 do_headers_action (window, headers_action_mark_as_unread, NULL);
2189 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2190 GtkRadioAction *selected,
2191 ModestWindow *window)
2195 value = gtk_radio_action_get_current_value (selected);
2196 if (MODEST_IS_WINDOW (window)) {
2197 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2201 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2202 GtkRadioAction *selected,
2203 ModestWindow *window)
2205 TnyHeaderFlags flags;
2206 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2208 flags = gtk_radio_action_get_current_value (selected);
2209 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2212 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2213 GtkRadioAction *selected,
2214 ModestWindow *window)
2218 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2220 file_format = gtk_radio_action_get_current_value (selected);
2221 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2226 modest_ui_actions_on_zoom_plus (GtkAction *action,
2227 ModestWindow *window)
2229 g_return_if_fail (MODEST_IS_WINDOW (window));
2231 modest_window_zoom_plus (MODEST_WINDOW (window));
2235 modest_ui_actions_on_zoom_minus (GtkAction *action,
2236 ModestWindow *window)
2238 g_return_if_fail (MODEST_IS_WINDOW (window));
2240 modest_window_zoom_minus (MODEST_WINDOW (window));
2244 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2245 ModestWindow *window)
2247 ModestWindowMgr *mgr;
2248 gboolean fullscreen, active;
2249 g_return_if_fail (MODEST_IS_WINDOW (window));
2251 mgr = modest_runtime_get_window_mgr ();
2253 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2254 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2256 if (active != fullscreen) {
2257 modest_window_mgr_set_fullscreen_mode (mgr, active);
2258 gtk_window_present (GTK_WINDOW (window));
2263 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2264 ModestWindow *window)
2266 ModestWindowMgr *mgr;
2267 gboolean fullscreen;
2269 g_return_if_fail (MODEST_IS_WINDOW (window));
2271 mgr = modest_runtime_get_window_mgr ();
2272 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2273 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2275 gtk_window_present (GTK_WINDOW (window));
2279 * Used by modest_ui_actions_on_details to call do_headers_action
2282 headers_action_show_details (TnyHeader *header,
2283 ModestWindow *window,
2290 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2293 gtk_widget_show_all (dialog);
2294 gtk_dialog_run (GTK_DIALOG (dialog));
2296 gtk_widget_destroy (dialog);
2300 * Show the folder details in a ModestDetailsDialog widget
2303 show_folder_details (TnyFolder *folder,
2309 dialog = modest_details_dialog_new_with_folder (window, folder);
2312 gtk_widget_show_all (dialog);
2313 gtk_dialog_run (GTK_DIALOG (dialog));
2315 gtk_widget_destroy (dialog);
2319 * Show the header details in a ModestDetailsDialog widget
2322 modest_ui_actions_on_details (GtkAction *action,
2325 TnyList * headers_list;
2329 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2332 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2335 g_object_unref (msg);
2337 headers_list = get_selected_headers (win);
2341 iter = tny_list_create_iterator (headers_list);
2343 header = TNY_HEADER (tny_iterator_get_current (iter));
2344 headers_action_show_details (header, win, NULL);
2345 g_object_unref (header);
2347 g_object_unref (iter);
2348 g_object_unref (headers_list);
2350 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2351 GtkWidget *folder_view, *header_view;
2353 /* Check which widget has the focus */
2354 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2355 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2356 if (gtk_widget_is_focus (folder_view)) {
2359 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2361 /* Show only when it's a folder */
2362 if (!folder || !TNY_IS_FOLDER (folder))
2365 show_folder_details (folder, GTK_WINDOW (win));
2368 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2369 MODEST_WIDGET_TYPE_HEADER_VIEW);
2370 /* Show details of each header */
2371 do_headers_action (win, headers_action_show_details, header_view);
2377 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2378 ModestMsgEditWindow *window)
2380 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2382 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2386 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2387 ModestMsgEditWindow *window)
2389 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2391 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2395 modest_ui_actions_toggle_folders_view (GtkAction *action,
2396 ModestMainWindow *main_window)
2400 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2402 conf = modest_runtime_get_conf ();
2404 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2405 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2407 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2411 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2412 ModestWindow *window)
2414 gboolean active, fullscreen = FALSE;
2415 ModestWindowMgr *mgr;
2417 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2419 /* Check if we want to toggle the toolbar vuew in fullscreen
2421 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2422 "ViewShowToolbarFullScreen")) {
2426 /* Toggle toolbar */
2427 mgr = modest_runtime_get_window_mgr ();
2428 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2432 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2433 ModestMsgEditWindow *window)
2435 modest_msg_edit_window_select_font (window);
2439 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2440 const gchar *display_name,
2443 /* Do not change the application name if the widget has not
2444 the focus. This callback could be called even if the folder
2445 view has not the focus, because the handled signal could be
2446 emitted when the folder view is redrawn */
2447 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2449 gtk_window_set_title (window, display_name);
2451 gtk_window_set_title (window, " ");
2456 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2458 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2459 modest_msg_edit_window_select_contacts (window);
2463 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2465 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2466 modest_msg_edit_window_check_names (window);
2471 create_move_to_dialog (ModestWindow *win,
2472 GtkWidget *folder_view,
2473 GtkWidget **tree_view)
2475 GtkWidget *dialog, *scroll;
2477 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2479 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2481 GTK_RESPONSE_ACCEPT,
2483 GTK_RESPONSE_REJECT,
2486 /* Create scrolled window */
2487 scroll = gtk_scrolled_window_new (NULL, NULL);
2488 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2489 GTK_POLICY_AUTOMATIC,
2490 GTK_POLICY_AUTOMATIC);
2492 /* Create folder view */
2493 *tree_view = modest_folder_view_new (NULL);
2494 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2495 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2496 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2498 /* Add scroll to dialog */
2499 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2500 scroll, FALSE, FALSE, 0);
2502 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2508 * Returns TRUE if at least one of the headers of the list belongs to
2509 * a message that has been fully retrieved.
2512 has_retrieved_msgs (TnyList *list)
2515 gboolean found = FALSE;
2517 iter = tny_list_create_iterator (list);
2518 while (tny_iterator_is_done (iter) && !found) {
2520 TnyHeaderFlags flags;
2522 header = TNY_HEADER (tny_iterator_get_current (iter));
2523 flags = tny_header_get_flags (header);
2524 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2528 tny_iterator_next (iter);
2530 g_object_unref (iter);
2536 * Shows a confirmation dialog to the user when we're moving messages
2537 * from a remote server to the local storage. Returns the dialog
2538 * response. If it's other kind of movement the it always returns
2542 msgs_move_to_confirmation (GtkWindow *win,
2543 TnyFolder *dest_folder,
2546 gint response = GTK_RESPONSE_OK;
2548 /* If the destination is a local folder */
2549 if (modest_tny_folder_is_local_folder (dest_folder)) {
2550 TnyFolder *src_folder;
2554 /* Get source folder */
2555 iter = tny_list_create_iterator (headers);
2556 header = TNY_HEADER (tny_iterator_get_current (iter));
2557 src_folder = tny_header_get_folder (header);
2558 g_object_unref (header);
2559 g_object_unref (iter);
2561 /* If the source is a remote folder */
2562 if (!modest_tny_folder_is_local_folder (src_folder)) {
2563 const gchar *message;
2565 if (tny_list_get_length (headers) == 1)
2566 if (has_retrieved_msgs (headers))
2567 message = _("mcen_nc_move_retrieve");
2569 message = _("mcen_nc_move_header");
2571 if (has_retrieved_msgs (headers))
2572 message = _("mcen_nc_move_retrieves");
2574 message = _("mcen_nc_move_headers");
2576 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2577 (const gchar *) message);
2579 g_object_unref (src_folder);
2586 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2588 ModestMsgViewWindow *self = NULL;
2589 gboolean found = FALSE;
2591 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2592 self = MODEST_MSG_VIEW_WINDOW (object);
2594 found = modest_msg_view_window_select_first_message (self);
2595 g_return_if_fail (found);
2599 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2602 GObject *win = modest_mail_operation_get_source (mail_op);
2604 /* TODO: show error message */
2605 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2606 _("mail_in_ui_folder_move_target_error"));
2610 * UI handler for the "Move to" action when invoked from the
2614 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2615 ModestMainWindow *win)
2617 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2618 GtkWidget *header_view = NULL;
2620 TnyFolderStore *folder_store = NULL;
2621 ModestMailOperation *mail_op = NULL;
2623 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2625 /* Get the folder view */
2626 folder_view = modest_main_window_get_child_widget (win,
2627 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2629 /* Get header view */
2630 header_view = modest_main_window_get_child_widget (win,
2631 MODEST_WIDGET_TYPE_HEADER_VIEW);
2633 /* Create and run the dialog */
2634 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2635 result = gtk_dialog_run (GTK_DIALOG(dialog));
2636 g_object_ref (tree_view);
2638 /* We do this to save an indentation level ;-) */
2639 if (result != GTK_RESPONSE_ACCEPT)
2642 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2644 if (TNY_IS_ACCOUNT (folder_store))
2647 /* Get folder or messages to transfer */
2648 if (gtk_widget_is_focus (folder_view)) {
2649 TnyFolderStore *src_folder;
2650 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2652 /* Clean folder on header view before moving it */
2653 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2655 if (TNY_IS_FOLDER (src_folder)) {
2657 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2659 modest_ui_actions_move_folder_error_handler,
2661 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2663 modest_mail_operation_xfer_folder (mail_op,
2664 TNY_FOLDER (src_folder),
2667 /* Unref mail operation */
2668 g_object_unref (G_OBJECT (mail_op));
2672 g_object_unref (G_OBJECT (src_folder));
2674 if (gtk_widget_is_focus (header_view)) {
2678 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2680 /* Ask for user confirmation */
2681 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2682 TNY_FOLDER (folder_store),
2685 /* Transfer messages */
2686 if (response == GTK_RESPONSE_OK) {
2687 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2688 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2691 modest_mail_operation_xfer_msgs (mail_op,
2693 TNY_FOLDER (folder_store),
2698 g_object_unref (G_OBJECT (mail_op));
2700 g_object_unref (headers);
2703 g_object_unref (folder_store);
2705 gtk_widget_destroy (dialog);
2710 * UI handler for the "Move to" action when invoked from the
2711 * ModestMsgViewWindow
2714 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2715 ModestMsgViewWindow *win)
2717 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2719 ModestMainWindow *main_window;
2723 /* Get the folder view */
2724 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2725 folder_view = modest_main_window_get_child_widget (main_window,
2726 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2728 /* Create and run the dialog */
2729 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2730 result = gtk_dialog_run (GTK_DIALOG(dialog));
2731 g_object_ref (tree_view);
2733 if (result == GTK_RESPONSE_ACCEPT) {
2734 TnyFolderStore *folder_store;
2737 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2739 /* Create header list */
2740 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2741 headers = tny_simple_list_new ();
2742 tny_list_prepend (headers, G_OBJECT (header));
2743 g_object_unref (header);
2745 /* Ask user for confirmation. MSG-NOT404 */
2746 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2747 TNY_FOLDER (folder_store),
2750 /* Transfer current msg */
2751 if (response == GTK_RESPONSE_OK) {
2752 ModestMailOperation *mail_op;
2754 /* Create mail op */
2755 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2756 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2759 /* Transfer messages */
2760 modest_mail_operation_xfer_msgs (mail_op,
2762 TNY_FOLDER (folder_store),
2764 tranasfer_msgs_from_viewer_cb,
2766 g_object_unref (G_OBJECT (mail_op));
2768 g_object_unref (headers);
2769 g_object_unref (folder_store);
2771 gtk_widget_destroy (dialog);
2775 modest_ui_actions_on_move_to (GtkAction *action,
2778 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2779 MODEST_IS_MSG_VIEW_WINDOW (win));
2781 if (MODEST_IS_MAIN_WINDOW (win))
2782 modest_ui_actions_on_main_window_move_to (action,
2783 MODEST_MAIN_WINDOW (win));
2785 modest_ui_actions_on_msg_view_window_move_to (action,
2786 MODEST_MSG_VIEW_WINDOW (win));
2790 * Calls #HeadersFunc for each header already selected in the main
2791 * window or the message currently being shown in the msg view window
2794 do_headers_action (ModestWindow *win,
2798 TnyList *headers_list;
2802 headers_list = get_selected_headers (win);
2806 /* Call the function for each header */
2807 iter = tny_list_create_iterator (headers_list);
2808 while (!tny_iterator_is_done (iter)) {
2811 header = TNY_HEADER (tny_iterator_get_current (iter));
2812 func (header, win, user_data);
2813 g_object_unref (header);
2814 tny_iterator_next (iter);
2816 g_object_unref (iter);
2817 g_object_unref (headers_list);
2821 modest_ui_actions_view_attachment (GtkAction *action,
2822 ModestWindow *window)
2824 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2825 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2827 /* not supported window for this action */
2828 g_return_if_reached ();
2833 modest_ui_actions_save_attachments (GtkAction *action,
2834 ModestWindow *window)
2836 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2837 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2839 /* not supported window for this action */
2840 g_return_if_reached ();
2845 modest_ui_actions_remove_attachments (GtkAction *action,
2846 ModestWindow *window)
2848 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2849 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2851 /* not supported window for this action */
2852 g_return_if_reached ();
2857 modest_ui_actions_on_settings (GtkAction *action,
2862 dialog = modest_platform_get_global_settings_dialog ();
2863 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2864 gtk_widget_show (dialog);
2866 gtk_dialog_run (GTK_DIALOG (dialog));
2868 gtk_widget_destroy (dialog);
2872 modest_ui_actions_on_help (GtkAction *action,
2875 const gchar *help_id = NULL;
2877 if (MODEST_IS_MAIN_WINDOW (win)) {
2878 const gchar *action_name;
2879 action_name = gtk_action_get_name (action);
2881 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2882 !strcmp (action_name, "HeaderViewCSMHelp")) {
2883 GtkWidget *folder_view;
2884 TnyFolderStore *folder_store;
2885 /* Get selected folder */
2886 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2887 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2888 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2890 /* Switch help_id */
2891 if (TNY_IS_FOLDER (folder_store)) {
2892 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2893 case TNY_FOLDER_TYPE_NORMAL:
2894 help_id = "applications_email_userfolder";
2896 case TNY_FOLDER_TYPE_INBOX:
2897 help_id = "applications_email_inbox";
2899 case TNY_FOLDER_TYPE_OUTBOX:
2900 help_id = "applications_email_outbox";
2902 case TNY_FOLDER_TYPE_SENT:
2903 help_id = "applications_email_sent";
2905 case TNY_FOLDER_TYPE_DRAFTS:
2906 help_id = "applications_email_drafts";
2908 case TNY_FOLDER_TYPE_ARCHIVE:
2909 help_id = "applications_email_archive";
2916 help_id = "applications_email_mainview";
2918 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2919 help_id = "applications_email_viewer";
2920 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2921 help_id = "applications_email_editor";
2923 modest_platform_show_help (GTK_WINDOW (win), help_id);
2927 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2928 ModestWindow *window)
2930 ModestMailOperation *mail_op;
2934 headers = get_selected_headers (window);
2938 /* Create mail operation */
2939 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2941 modest_ui_actions_get_msgs_full_error_handler,
2943 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2944 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2947 g_object_unref (headers);
2948 g_object_unref (mail_op);
2952 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2953 ModestWindow *window)
2955 g_return_if_fail (MODEST_IS_WINDOW (window));
2958 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2962 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2963 ModestWindow *window)
2965 g_return_if_fail (MODEST_IS_WINDOW (window));
2968 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2972 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2973 ModestWindow *window)
2975 g_return_if_fail (MODEST_IS_WINDOW (window));
2978 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2982 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2983 ModestWindow *window)
2985 g_return_if_fail (MODEST_IS_WINDOW (window));
2988 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2992 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2993 ModestWindow *window)
2995 g_return_if_fail (MODEST_IS_WINDOW (window));
2998 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3002 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3004 g_return_if_fail (MODEST_IS_WINDOW (window));
3007 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");