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;
742 TnyFolder *folder = NULL;
743 TnyAccount *account = NULL;
744 ModestWindowMgr *mgr;
745 gchar *signature = NULL;
747 g_return_if_fail (user_data != NULL);
748 rf_helper = (ReplyForwardHelper *) user_data;
750 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
751 rf_helper->account_name);
752 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
753 rf_helper->account_name,
754 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
755 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
756 rf_helper->account_name,
757 MODEST_ACCOUNT_SIGNATURE, FALSE);
760 /* Create reply mail */
761 switch (rf_helper->action) {
764 modest_tny_msg_create_reply_msg (msg, from, signature,
765 rf_helper->reply_forward_type,
766 MODEST_TNY_MSG_REPLY_MODE_SENDER);
768 case ACTION_REPLY_TO_ALL:
770 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
771 MODEST_TNY_MSG_REPLY_MODE_ALL);
772 edit_type = MODEST_EDIT_TYPE_REPLY;
776 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
777 edit_type = MODEST_EDIT_TYPE_FORWARD;
780 g_return_if_reached ();
787 g_printerr ("modest: failed to create message\n");
791 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
792 rf_helper->account_name,
793 TNY_ACCOUNT_TYPE_STORE);
795 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
799 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
801 g_printerr ("modest: failed to find Drafts folder\n");
805 tny_folder_add_msg (folder, msg, &err);
807 g_printerr ("modest: error adding msg to Drafts folder: %s",
813 /* Create and register the windows */
814 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
815 mgr = modest_runtime_get_window_mgr ();
816 modest_window_mgr_register_window (mgr, msg_win);
818 if (rf_helper->parent_window != NULL) {
821 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
822 modest_window_set_zoom (msg_win, parent_zoom);
825 /* Show edit window */
826 gtk_widget_show_all (GTK_WIDGET (msg_win));
830 g_object_unref (G_OBJECT (new_msg));
832 g_object_unref (G_OBJECT (folder));
834 g_object_unref (G_OBJECT (account));
835 g_object_unref (msg);
836 g_object_unref (header);
840 * Checks a list of headers. If any of them are not currently
841 * downloaded (CACHED) then it asks the user for permission to
844 * Returns FALSE if the user does not want to download the
845 * messages. Returns TRUE if the user allowed the download or if all
846 * of them are currently downloaded
849 download_uncached_messages (TnyList *header_list, GtkWindow *win)
852 gboolean found, retval;
854 iter = tny_list_create_iterator (header_list);
856 while (!tny_iterator_is_done (iter) && !found) {
858 TnyHeaderFlags flags;
860 header = TNY_HEADER (tny_iterator_get_current (iter));
861 flags = tny_header_get_flags (header);
862 /* TODO: is this the right flag?, it seems that some
863 headers that have been previously downloaded do not
865 found = !(flags & TNY_HEADER_FLAG_CACHED);
866 g_object_unref (header);
867 tny_iterator_next (iter);
869 g_object_unref (iter);
871 /* Ask for user permission to download the messages */
874 GtkResponseType response;
876 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
877 _("mcen_nc_get_multi_msg_txt"));
878 if (response == GTK_RESPONSE_CANCEL)
886 * Common code for the reply and forward actions
889 reply_forward (ReplyForwardAction action, ModestWindow *win)
891 ModestMailOperation *mail_op = NULL;
892 TnyList *header_list = NULL;
893 ReplyForwardHelper *rf_helper = NULL;
894 guint reply_forward_type;
895 gboolean continue_download;
897 g_return_if_fail (MODEST_IS_WINDOW(win));
899 header_list = get_selected_headers (win);
903 /* Check that the messages have been previously downloaded */
904 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
905 if (!continue_download) {
906 g_object_unref (header_list);
911 modest_conf_get_int (modest_runtime_get_conf (),
912 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
914 /* We assume that we can only select messages of the
915 same folder and that we reply all of them from the
916 same account. In fact the interface currently only
917 allows single selection */
920 rf_helper = g_slice_new0 (ReplyForwardHelper);
921 rf_helper->reply_forward_type = reply_forward_type;
922 rf_helper->action = action;
923 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
924 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
925 rf_helper->parent_window = GTK_WIDGET (win);
926 if (!rf_helper->account_name)
927 rf_helper->account_name =
928 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
930 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
933 /* Get header and message. Do not free them here, the
934 reply_forward_cb must do it */
935 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
936 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
937 if (!msg || !header) {
939 g_object_unref (msg);
941 g_object_unref (header);
942 g_printerr ("modest: no message found\n");
945 reply_forward_cb (NULL, header, msg, rf_helper);
947 /* Retrieve messages */
948 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
950 modest_ui_actions_get_msgs_full_error_handler,
952 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
953 modest_mail_operation_get_msgs_full (mail_op,
957 free_reply_forward_helper);
960 g_object_unref(mail_op);
964 g_object_unref (header_list);
968 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
970 g_return_if_fail (MODEST_IS_WINDOW(win));
972 reply_forward (ACTION_REPLY, win);
976 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
978 g_return_if_fail (MODEST_IS_WINDOW(win));
980 reply_forward (ACTION_FORWARD, win);
984 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
986 g_return_if_fail (MODEST_IS_WINDOW(win));
988 reply_forward (ACTION_REPLY_TO_ALL, win);
992 modest_ui_actions_on_next (GtkAction *action,
993 ModestWindow *window)
995 if (MODEST_IS_MAIN_WINDOW (window)) {
996 GtkWidget *header_view;
998 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
999 MODEST_WIDGET_TYPE_HEADER_VIEW);
1003 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1004 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1005 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1007 g_return_if_reached ();
1012 modest_ui_actions_on_prev (GtkAction *action,
1013 ModestWindow *window)
1015 g_return_if_fail (MODEST_IS_WINDOW(window));
1017 if (MODEST_IS_MAIN_WINDOW (window)) {
1018 GtkWidget *header_view;
1019 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1020 MODEST_WIDGET_TYPE_HEADER_VIEW);
1024 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1025 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1026 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1028 g_return_if_reached ();
1033 modest_ui_actions_on_sort (GtkAction *action,
1034 ModestWindow *window)
1036 g_return_if_fail (MODEST_IS_WINDOW(window));
1038 if (MODEST_IS_MAIN_WINDOW (window)) {
1039 GtkWidget *header_view;
1040 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1041 MODEST_WIDGET_TYPE_HEADER_VIEW);
1045 /* Show sorting dialog */
1046 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1051 * This function performs the send & receive required actions. The
1052 * window is used to create the mail operation. Typically it should
1053 * always be the main window, but we pass it as argument in order to
1057 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1059 gchar *acc_name = NULL;
1060 ModestMailOperation *mail_op;
1062 /* If no account name was provided then get the current account, and if
1063 there is no current account then pick the default one: */
1064 if (!account_name) {
1065 acc_name = g_strdup (modest_window_get_active_account(win));
1067 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1069 g_printerr ("modest: cannot get default account\n");
1073 acc_name = g_strdup (account_name);
1076 /* Send & receive. */
1077 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1078 /* Receive and then send. The operation is tagged initially as
1079 a receive operation because the account update performs a
1080 receive and then a send. The operation changes its type
1081 internally, so the progress objects will receive the proper
1082 progress information */
1083 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1084 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1085 modest_mail_operation_update_account (mail_op, acc_name);
1086 g_object_unref (G_OBJECT (mail_op));
1093 * Refreshes all accounts. This function will be used by automatic
1097 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1099 GSList *account_names, *iter;
1101 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1104 iter = account_names;
1106 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1107 iter = g_slist_next (iter);
1110 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1111 g_slist_free (account_names);
1115 * Handler of the click on Send&Receive button in the main toolbar
1118 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1120 /* Check that at least one account exists: */
1121 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1122 TRUE /* enabled accounts only */);
1123 gboolean accounts_exist = account_names != NULL;
1124 g_slist_free (account_names);
1126 /* If not, allow the user to create an account before trying to send/receive. */
1127 if (!accounts_exist)
1128 modest_ui_actions_on_accounts (NULL, win);
1130 /* Refresh the active account */
1131 modest_ui_actions_do_send_receive (NULL, win);
1136 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1139 GtkWidget *header_view;
1141 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1143 header_view = modest_main_window_get_child_widget (main_window,
1144 MODEST_WIDGET_TYPE_HEADER_VIEW);
1148 conf = modest_runtime_get_conf ();
1150 /* what is saved/restored is depending on the style; thus; we save with
1151 * old style, then update the style, and restore for this new style
1153 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1155 if (modest_header_view_get_style
1156 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1157 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1158 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1160 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1161 MODEST_HEADER_VIEW_STYLE_DETAILS);
1163 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1164 MODEST_CONF_HEADER_VIEW_KEY);
1169 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1171 ModestMainWindow *main_window)
1173 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1175 /* If no header has been selected then exit */
1179 /* Update Main window title */
1180 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1181 const gchar *subject = tny_header_get_subject (header);
1182 if (subject && strcmp (subject, ""))
1183 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1185 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1188 /* Update toolbar dimming state */
1189 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1193 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1195 ModestMainWindow *main_window)
1199 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1204 headers = tny_simple_list_new ();
1205 tny_list_prepend (headers, G_OBJECT (header));
1207 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1209 g_object_unref (headers);
1213 set_active_account_from_tny_account (TnyAccount *account,
1214 ModestWindow *window)
1216 const gchar *server_acc_name = tny_account_get_id (account);
1218 /* We need the TnyAccount provided by the
1219 account store because that is the one that
1220 knows the name of the Modest account */
1221 TnyAccount *modest_server_account = modest_server_account =
1222 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1225 const gchar *modest_acc_name =
1226 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1227 modest_window_set_active_account (window, modest_acc_name);
1228 g_object_unref (modest_server_account);
1232 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1233 TnyFolderStore *folder_store,
1235 ModestMainWindow *main_window)
1238 GtkWidget *header_view;
1240 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1242 header_view = modest_main_window_get_child_widget(main_window,
1243 MODEST_WIDGET_TYPE_HEADER_VIEW);
1247 conf = modest_runtime_get_conf ();
1249 if (TNY_IS_ACCOUNT (folder_store)) {
1250 /* Update active account */
1251 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1252 /* Show account details */
1253 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1254 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1255 //TODO: Set the virtual folder store as the "active account" somehow:
1256 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1258 if (TNY_IS_FOLDER (folder_store) && selected) {
1260 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1261 /* Update the active account */
1262 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1263 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1264 g_object_unref (account);
1267 /* Set folder on header view */
1268 modest_main_window_set_contents_style (main_window,
1269 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1270 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1271 TNY_FOLDER (folder_store));
1272 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1273 MODEST_CONF_HEADER_VIEW_KEY);
1275 /* Update the active account */
1276 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1277 /* Do not show folder */
1278 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1279 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1283 /* Update toolbar dimming state */
1284 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1288 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1295 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1297 if (g_main_depth > 0)
1298 gdk_threads_enter ();
1299 online = tny_device_is_online (modest_runtime_get_device());
1302 /* already online -- the item is simply not there... */
1303 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1305 GTK_MESSAGE_WARNING,
1307 _("The %s you selected cannot be found"),
1309 gtk_dialog_run (GTK_DIALOG(dialog));
1311 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1315 GTK_RESPONSE_REJECT,
1317 GTK_RESPONSE_ACCEPT,
1319 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1320 "Do you want to get online?"), item);
1321 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1322 gtk_label_new (txt), FALSE, FALSE, 0);
1323 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1326 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1327 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1328 // modest_platform_connect_and_wait ();;
1331 gtk_widget_destroy (dialog);
1332 if (g_main_depth > 0)
1333 gdk_threads_leave ();
1337 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1340 /* g_message ("%s %s", __FUNCTION__, link); */
1345 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1348 modest_platform_activate_uri (link);
1352 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1355 modest_platform_show_uri_popup (link);
1359 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1362 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1366 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1367 const gchar *address,
1370 /* g_message ("%s %s", __FUNCTION__, address); */
1374 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1376 TnyTransportAccount *transport_account;
1377 ModestMailOperation *mail_operation;
1379 gchar *account_name, *from;
1380 ModestAccountMgr *account_mgr;
1382 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1384 data = modest_msg_edit_window_get_msg_data (edit_window);
1386 account_mgr = modest_runtime_get_account_mgr();
1387 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1389 account_name = modest_account_mgr_get_default_account (account_mgr);
1390 if (!account_name) {
1391 g_printerr ("modest: no account found\n");
1392 modest_msg_edit_window_free_msg_data (edit_window, data);
1396 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1397 account_name = g_strdup (data->account_name);
1401 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1402 (modest_runtime_get_account_store(),
1404 TNY_ACCOUNT_TYPE_TRANSPORT));
1405 if (!transport_account) {
1406 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1407 g_free (account_name);
1408 modest_msg_edit_window_free_msg_data (edit_window, data);
1411 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1413 /* Create the mail operation */
1414 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1415 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1417 modest_mail_operation_save_to_drafts (mail_operation,
1428 data->priority_flags);
1431 g_free (account_name);
1432 g_object_unref (G_OBJECT (transport_account));
1433 g_object_unref (G_OBJECT (mail_operation));
1435 modest_msg_edit_window_free_msg_data (edit_window, data);
1437 /* Save settings and close the window */
1438 gtk_widget_destroy (GTK_WIDGET (edit_window));
1441 /* For instance, when clicking the Send toolbar button when editing a message: */
1443 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1445 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1447 if (!modest_msg_edit_window_check_names (edit_window))
1450 /* FIXME: Code added just for testing. The final version will
1451 use the send queue provided by tinymail and some
1453 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1454 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1456 account_name = modest_account_mgr_get_default_account (account_mgr);
1458 if (!account_name) {
1459 g_printerr ("modest: no account found\n");
1462 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1464 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1465 account_name = g_strdup (data->account_name);
1468 /* Get the currently-active transport account for this modest account: */
1469 TnyTransportAccount *transport_account =
1470 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1471 (modest_runtime_get_account_store(),
1473 if (!transport_account) {
1474 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1475 g_free (account_name);
1476 modest_msg_edit_window_free_msg_data (edit_window, data);
1480 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1482 /* mail content checks and dialogs */
1483 if (data->subject == NULL || data->subject[0] == '\0') {
1484 GtkResponseType response;
1485 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1486 _("mcen_nc_subject_is_empty_send"));
1487 if (response == GTK_RESPONSE_CANCEL) {
1488 g_free (account_name);
1493 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1494 GtkResponseType response;
1495 gchar *note_message;
1496 gchar *note_subject = data->subject;
1497 if (note_subject == NULL || note_subject[0] == '\0')
1498 note_subject = _("mail_va_no_subject");
1499 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1500 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1502 g_free (note_message);
1503 if (response == GTK_RESPONSE_CANCEL) {
1504 g_free (account_name);
1509 /* Create the mail operation */
1510 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1511 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1513 modest_mail_operation_send_new_mail (mail_operation,
1524 data->priority_flags);
1528 g_free (account_name);
1529 g_object_unref (G_OBJECT (transport_account));
1530 g_object_unref (G_OBJECT (mail_operation));
1532 modest_msg_edit_window_free_msg_data (edit_window, data);
1534 /* Save settings and close the window: */
1535 gtk_widget_destroy (GTK_WIDGET (edit_window));
1539 modest_ui_actions_on_toggle_bold (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->bold = 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_italics (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->italics = 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_toggle_bullets (GtkToggleAction *action,
1582 ModestMsgEditWindow *window)
1584 ModestMsgEditFormatState *format_state = NULL;
1586 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1587 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1589 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1592 format_state = modest_msg_edit_window_get_format_state (window);
1593 g_return_if_fail (format_state != NULL);
1595 format_state->bullet = gtk_toggle_action_get_active (action);
1596 modest_msg_edit_window_set_format_state (window, format_state);
1597 g_free (format_state);
1602 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1603 GtkRadioAction *selected,
1604 ModestMsgEditWindow *window)
1606 ModestMsgEditFormatState *format_state = NULL;
1607 GtkJustification value;
1609 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1611 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1614 value = gtk_radio_action_get_current_value (selected);
1616 format_state = modest_msg_edit_window_get_format_state (window);
1617 g_return_if_fail (format_state != NULL);
1619 format_state->justification = value;
1620 modest_msg_edit_window_set_format_state (window, format_state);
1621 g_free (format_state);
1625 modest_ui_actions_on_select_editor_color (GtkAction *action,
1626 ModestMsgEditWindow *window)
1628 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1629 g_return_if_fail (GTK_IS_ACTION (action));
1631 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1634 modest_msg_edit_window_select_color (window);
1638 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1639 ModestMsgEditWindow *window)
1641 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1642 g_return_if_fail (GTK_IS_ACTION (action));
1644 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1647 modest_msg_edit_window_select_background_color (window);
1651 modest_ui_actions_on_insert_image (GtkAction *action,
1652 ModestMsgEditWindow *window)
1654 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1655 g_return_if_fail (GTK_IS_ACTION (action));
1657 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1660 modest_msg_edit_window_insert_image (window);
1664 modest_ui_actions_on_attach_file (GtkAction *action,
1665 ModestMsgEditWindow *window)
1667 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1668 g_return_if_fail (GTK_IS_ACTION (action));
1670 modest_msg_edit_window_attach_file (window);
1674 modest_ui_actions_on_remove_attachments (GtkAction *action,
1675 ModestMsgEditWindow *window)
1677 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1678 g_return_if_fail (GTK_IS_ACTION (action));
1680 modest_msg_edit_window_remove_attachments (window, NULL);
1684 * Shows a dialog with an entry that asks for some text. The returned
1685 * value must be freed by the caller. The dialog window title will be
1689 ask_for_folder_name (GtkWindow *parent_window,
1692 GtkWidget *dialog, *entry;
1693 gchar *folder_name = NULL;
1695 /* Ask for folder name */
1696 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1700 GTK_RESPONSE_REJECT,
1702 GTK_RESPONSE_ACCEPT,
1704 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1705 gtk_label_new(title),
1708 entry = gtk_entry_new_with_max_length (40);
1709 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1713 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1715 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1716 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1718 gtk_widget_destroy (dialog);
1724 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1726 TnyFolderStore *parent_folder;
1727 GtkWidget *folder_view;
1729 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1731 folder_view = modest_main_window_get_child_widget (main_window,
1732 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1736 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1738 if (parent_folder) {
1739 gboolean finished = FALSE;
1741 gchar *folder_name = NULL, *suggested_name = NULL;
1743 /* Run the new folder dialog */
1745 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1750 if (result == GTK_RESPONSE_REJECT) {
1753 ModestMailOperation *mail_op;
1754 TnyFolder *new_folder = NULL;
1756 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1757 G_OBJECT(main_window));
1758 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1760 new_folder = modest_mail_operation_create_folder (mail_op,
1762 (const gchar *) folder_name);
1764 g_object_unref (new_folder);
1767 g_object_unref (mail_op);
1769 g_free (folder_name);
1773 g_object_unref (parent_folder);
1778 modest_ui_actions_on_rename_folder (GtkAction *action,
1779 ModestMainWindow *main_window)
1781 TnyFolderStore *folder;
1782 GtkWidget *folder_view;
1783 GtkWidget *header_view;
1785 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1787 folder_view = modest_main_window_get_child_widget (main_window,
1788 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1792 header_view = modest_main_window_get_child_widget (main_window,
1793 MODEST_WIDGET_TYPE_HEADER_VIEW);
1798 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1800 if (folder && TNY_IS_FOLDER (folder)) {
1802 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1803 _("Please enter a new name for the folder"));
1805 if (folder_name != NULL && strlen (folder_name) > 0) {
1806 ModestMailOperation *mail_op;
1808 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1809 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1812 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1814 modest_mail_operation_rename_folder (mail_op,
1815 TNY_FOLDER (folder),
1816 (const gchar *) folder_name);
1818 g_object_unref (mail_op);
1819 g_free (folder_name);
1821 g_object_unref (folder);
1826 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1829 GObject *win = modest_mail_operation_get_source (mail_op);
1831 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1832 _("mail_in_ui_folder_delete_error"));
1836 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1838 TnyFolderStore *folder;
1839 GtkWidget *folder_view;
1843 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1845 folder_view = modest_main_window_get_child_widget (main_window,
1846 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1850 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1852 /* Show an error if it's an account */
1853 if (!TNY_IS_FOLDER (folder)) {
1854 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1855 _("mail_in_ui_folder_delete_error"));
1860 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1861 tny_folder_get_name (TNY_FOLDER (folder)));
1862 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1863 (const gchar *) message);
1866 if (response == GTK_RESPONSE_OK) {
1867 ModestMailOperation *mail_op =
1868 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1869 G_OBJECT(main_window),
1870 modest_ui_actions_delete_folder_error_handler,
1873 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1875 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1876 g_object_unref (G_OBJECT (mail_op));
1879 g_object_unref (G_OBJECT (folder));
1883 modest_ui_actions_on_delete_folder (GtkAction *action,
1884 ModestMainWindow *main_window)
1886 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1888 delete_folder (main_window, FALSE);
1892 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1894 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1896 delete_folder (main_window, TRUE);
1900 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1901 const gchar* server_account_name,
1906 ModestMainWindow *main_window)
1908 g_return_if_fail(server_account_name);
1909 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1911 /* Initalize output parameters: */
1918 #ifdef MODEST_PLATFORM_MAEMO
1919 /* Maemo uses a different (awkward) button order,
1920 * It should probably just use gtk_alternative_dialog_button_order ().
1922 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1926 GTK_RESPONSE_ACCEPT,
1928 GTK_RESPONSE_REJECT,
1931 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1935 GTK_RESPONSE_REJECT,
1937 GTK_RESPONSE_ACCEPT,
1939 #endif /* MODEST_PLATFORM_MAEMO */
1941 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1943 gchar *server_name = modest_server_account_get_hostname (
1944 modest_runtime_get_account_mgr(), server_account_name);
1946 /* This causes a warning because the logical ID has no %s in it,
1947 * though the translation does, but there is not much we can do about that: */
1948 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1949 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1952 g_free (server_name);
1956 gchar *initial_username = modest_server_account_get_username (
1957 modest_runtime_get_account_mgr(), server_account_name);
1959 GtkWidget *entry_username = gtk_entry_new ();
1960 if (initial_username)
1961 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1962 /* Dim this if a connection has ever succeeded with this username,
1963 * as per the UI spec: */
1964 const gboolean username_known =
1965 modest_server_account_get_username_has_succeeded(
1966 modest_runtime_get_account_mgr(), server_account_name);
1967 gtk_widget_set_sensitive (entry_username, !username_known);
1969 #ifdef MODEST_PLATFORM_MAEMO
1970 /* Auto-capitalization is the default, so let's turn it off: */
1971 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1973 /* Create a size group to be used by all captions.
1974 * Note that HildonCaption does not create a default size group if we do not specify one.
1975 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1976 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1978 GtkWidget *caption = hildon_caption_new (sizegroup,
1979 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1980 gtk_widget_show (entry_username);
1981 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1982 FALSE, FALSE, MODEST_MARGIN_HALF);
1983 gtk_widget_show (caption);
1985 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1987 #endif /* MODEST_PLATFORM_MAEMO */
1990 GtkWidget *entry_password = gtk_entry_new ();
1991 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1992 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1994 #ifdef MODEST_PLATFORM_MAEMO
1995 /* Auto-capitalization is the default, so let's turn it off: */
1996 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1997 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1999 caption = hildon_caption_new (sizegroup,
2000 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2001 gtk_widget_show (entry_password);
2002 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2003 FALSE, FALSE, MODEST_MARGIN_HALF);
2004 gtk_widget_show (caption);
2005 g_object_unref (sizegroup);
2007 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2009 #endif /* MODEST_PLATFORM_MAEMO */
2011 /* This is not in the Maemo UI spec:
2012 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2013 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2017 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2019 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2021 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2023 modest_server_account_set_username (
2024 modest_runtime_get_account_mgr(), server_account_name,
2027 const gboolean username_was_changed =
2028 (strcmp (*username, initial_username) != 0);
2029 if (username_was_changed) {
2030 /* To actually use a changed username,
2031 * we must reset the connection, according to pvanhoof.
2032 * This _might_ be a sensible way to do that: */
2033 TnyDevice *device = modest_runtime_get_device();
2034 tny_device_force_offline (device);
2035 tny_device_force_online (device);
2040 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2042 /* We do not save the password in the configuration,
2043 * because this function is only called for passwords that should
2044 * not be remembered:
2045 modest_server_account_set_password (
2046 modest_runtime_get_account_mgr(), server_account_name,
2065 /* This is not in the Maemo UI spec:
2066 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2072 gtk_widget_destroy (dialog);
2074 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2078 modest_ui_actions_on_cut (GtkAction *action,
2079 ModestWindow *window)
2081 GtkWidget *focused_widget;
2083 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2084 if (GTK_IS_EDITABLE (focused_widget)) {
2085 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2086 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2087 GtkTextBuffer *buffer;
2088 GtkClipboard *clipboard;
2090 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2091 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2092 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2097 modest_ui_actions_on_copy (GtkAction *action,
2098 ModestWindow *window)
2100 GtkClipboard *clipboard;
2101 GtkWidget *focused_widget;
2103 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2104 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2105 if (GTK_IS_LABEL (focused_widget)) {
2106 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2107 } else if (GTK_IS_EDITABLE (focused_widget)) {
2108 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2109 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2110 GtkTextBuffer *buffer;
2112 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2113 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2118 modest_ui_actions_on_undo (GtkAction *action,
2119 ModestWindow *window)
2121 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2122 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2124 g_return_if_reached ();
2129 modest_ui_actions_on_paste (GtkAction *action,
2130 ModestWindow *window)
2132 GtkWidget *focused_widget;
2134 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2135 if (GTK_IS_EDITABLE (focused_widget)) {
2136 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2137 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2138 GtkTextBuffer *buffer;
2139 GtkClipboard *clipboard;
2141 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2142 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2143 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2148 modest_ui_actions_on_select_all (GtkAction *action,
2149 ModestWindow *window)
2151 GtkWidget *focused_widget;
2153 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2154 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2155 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2156 } else if (GTK_IS_LABEL (focused_widget)) {
2157 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2158 } else if (GTK_IS_EDITABLE (focused_widget)) {
2159 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2160 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2161 GtkTextBuffer *buffer;
2162 GtkTextIter start, end;
2164 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2165 gtk_text_buffer_get_start_iter (buffer, &start);
2166 gtk_text_buffer_get_end_iter (buffer, &end);
2167 gtk_text_buffer_select_range (buffer, &start, &end);
2169 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2170 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2172 GtkTreeSelection *selection = NULL;
2174 /* Get header view */
2175 GtkWidget *header_view = focused_widget;
2176 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2177 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2178 MODEST_WIDGET_TYPE_HEADER_VIEW);
2180 /* Select all messages */
2181 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2182 gtk_tree_selection_select_all (selection);
2187 modest_ui_actions_on_mark_as_read (GtkAction *action,
2188 ModestWindow *window)
2190 g_return_if_fail (MODEST_IS_WINDOW(window));
2192 /* Mark each header as read */
2193 do_headers_action (window, headers_action_mark_as_read, NULL);
2197 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2198 ModestWindow *window)
2200 g_return_if_fail (MODEST_IS_WINDOW(window));
2202 /* Mark each header as read */
2203 do_headers_action (window, headers_action_mark_as_unread, NULL);
2207 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2208 GtkRadioAction *selected,
2209 ModestWindow *window)
2213 value = gtk_radio_action_get_current_value (selected);
2214 if (MODEST_IS_WINDOW (window)) {
2215 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2219 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2220 GtkRadioAction *selected,
2221 ModestWindow *window)
2223 TnyHeaderFlags flags;
2224 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2226 flags = gtk_radio_action_get_current_value (selected);
2227 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2230 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2231 GtkRadioAction *selected,
2232 ModestWindow *window)
2236 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2238 file_format = gtk_radio_action_get_current_value (selected);
2239 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2244 modest_ui_actions_on_zoom_plus (GtkAction *action,
2245 ModestWindow *window)
2247 g_return_if_fail (MODEST_IS_WINDOW (window));
2249 modest_window_zoom_plus (MODEST_WINDOW (window));
2253 modest_ui_actions_on_zoom_minus (GtkAction *action,
2254 ModestWindow *window)
2256 g_return_if_fail (MODEST_IS_WINDOW (window));
2258 modest_window_zoom_minus (MODEST_WINDOW (window));
2262 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2263 ModestWindow *window)
2265 ModestWindowMgr *mgr;
2266 gboolean fullscreen, active;
2267 g_return_if_fail (MODEST_IS_WINDOW (window));
2269 mgr = modest_runtime_get_window_mgr ();
2271 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2272 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2274 if (active != fullscreen) {
2275 modest_window_mgr_set_fullscreen_mode (mgr, active);
2276 gtk_window_present (GTK_WINDOW (window));
2281 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2282 ModestWindow *window)
2284 ModestWindowMgr *mgr;
2285 gboolean fullscreen;
2287 g_return_if_fail (MODEST_IS_WINDOW (window));
2289 mgr = modest_runtime_get_window_mgr ();
2290 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2291 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2293 gtk_window_present (GTK_WINDOW (window));
2297 * Used by modest_ui_actions_on_details to call do_headers_action
2300 headers_action_show_details (TnyHeader *header,
2301 ModestWindow *window,
2308 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2311 gtk_widget_show_all (dialog);
2312 gtk_dialog_run (GTK_DIALOG (dialog));
2314 gtk_widget_destroy (dialog);
2318 * Show the folder details in a ModestDetailsDialog widget
2321 show_folder_details (TnyFolder *folder,
2327 dialog = modest_details_dialog_new_with_folder (window, folder);
2330 gtk_widget_show_all (dialog);
2331 gtk_dialog_run (GTK_DIALOG (dialog));
2333 gtk_widget_destroy (dialog);
2337 * Show the header details in a ModestDetailsDialog widget
2340 modest_ui_actions_on_details (GtkAction *action,
2343 TnyList * headers_list;
2347 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2350 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2353 g_object_unref (msg);
2355 headers_list = get_selected_headers (win);
2359 iter = tny_list_create_iterator (headers_list);
2361 header = TNY_HEADER (tny_iterator_get_current (iter));
2362 headers_action_show_details (header, win, NULL);
2363 g_object_unref (header);
2365 g_object_unref (iter);
2366 g_object_unref (headers_list);
2368 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2369 GtkWidget *folder_view, *header_view;
2371 /* Check which widget has the focus */
2372 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2373 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2374 if (gtk_widget_is_focus (folder_view)) {
2377 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2379 /* Show only when it's a folder */
2380 if (!folder || !TNY_IS_FOLDER (folder))
2383 show_folder_details (folder, GTK_WINDOW (win));
2386 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2387 MODEST_WIDGET_TYPE_HEADER_VIEW);
2388 /* Show details of each header */
2389 do_headers_action (win, headers_action_show_details, header_view);
2395 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2396 ModestMsgEditWindow *window)
2398 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2400 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2404 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2405 ModestMsgEditWindow *window)
2407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2409 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2413 modest_ui_actions_toggle_folders_view (GtkAction *action,
2414 ModestMainWindow *main_window)
2418 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2420 conf = modest_runtime_get_conf ();
2422 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2423 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2425 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2429 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2430 ModestWindow *window)
2432 gboolean active, fullscreen = FALSE;
2433 ModestWindowMgr *mgr;
2435 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2437 /* Check if we want to toggle the toolbar vuew in fullscreen
2439 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2440 "ViewShowToolbarFullScreen")) {
2444 /* Toggle toolbar */
2445 mgr = modest_runtime_get_window_mgr ();
2446 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2450 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2451 ModestMsgEditWindow *window)
2453 modest_msg_edit_window_select_font (window);
2457 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2458 const gchar *display_name,
2461 /* Do not change the application name if the widget has not
2462 the focus. This callback could be called even if the folder
2463 view has not the focus, because the handled signal could be
2464 emitted when the folder view is redrawn */
2465 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2467 gtk_window_set_title (window, display_name);
2469 gtk_window_set_title (window, " ");
2474 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2476 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2477 modest_msg_edit_window_select_contacts (window);
2481 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2483 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2484 modest_msg_edit_window_check_names (window);
2489 create_move_to_dialog (ModestWindow *win,
2490 GtkWidget *folder_view,
2491 GtkWidget **tree_view)
2493 GtkWidget *dialog, *scroll;
2495 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2497 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2499 GTK_RESPONSE_ACCEPT,
2501 GTK_RESPONSE_REJECT,
2504 /* Create scrolled window */
2505 scroll = gtk_scrolled_window_new (NULL, NULL);
2506 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2507 GTK_POLICY_AUTOMATIC,
2508 GTK_POLICY_AUTOMATIC);
2510 /* Create folder view */
2511 *tree_view = modest_folder_view_new (NULL);
2512 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2513 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2514 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2516 /* Add scroll to dialog */
2517 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2518 scroll, FALSE, FALSE, 0);
2520 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2526 * Returns TRUE if at least one of the headers of the list belongs to
2527 * a message that has been fully retrieved.
2530 has_retrieved_msgs (TnyList *list)
2533 gboolean found = FALSE;
2535 iter = tny_list_create_iterator (list);
2536 while (tny_iterator_is_done (iter) && !found) {
2538 TnyHeaderFlags flags;
2540 header = TNY_HEADER (tny_iterator_get_current (iter));
2541 flags = tny_header_get_flags (header);
2542 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2546 tny_iterator_next (iter);
2548 g_object_unref (iter);
2554 * Shows a confirmation dialog to the user when we're moving messages
2555 * from a remote server to the local storage. Returns the dialog
2556 * response. If it's other kind of movement the it always returns
2560 msgs_move_to_confirmation (GtkWindow *win,
2561 TnyFolder *dest_folder,
2564 gint response = GTK_RESPONSE_OK;
2566 /* If the destination is a local folder */
2567 if (modest_tny_folder_is_local_folder (dest_folder)) {
2568 TnyFolder *src_folder;
2572 /* Get source folder */
2573 iter = tny_list_create_iterator (headers);
2574 header = TNY_HEADER (tny_iterator_get_current (iter));
2575 src_folder = tny_header_get_folder (header);
2576 g_object_unref (header);
2577 g_object_unref (iter);
2579 /* If the source is a remote folder */
2580 if (!modest_tny_folder_is_local_folder (src_folder)) {
2581 const gchar *message;
2583 if (tny_list_get_length (headers) == 1)
2584 if (has_retrieved_msgs (headers))
2585 message = _("mcen_nc_move_retrieve");
2587 message = _("mcen_nc_move_header");
2589 if (has_retrieved_msgs (headers))
2590 message = _("mcen_nc_move_retrieves");
2592 message = _("mcen_nc_move_headers");
2594 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2595 (const gchar *) message);
2597 g_object_unref (src_folder);
2604 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2606 ModestMsgViewWindow *self = NULL;
2607 gboolean found = FALSE;
2609 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2610 self = MODEST_MSG_VIEW_WINDOW (object);
2612 found = modest_msg_view_window_select_first_message (self);
2613 g_return_if_fail (found);
2617 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2620 GObject *win = modest_mail_operation_get_source (mail_op);
2622 /* TODO: show error message */
2623 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2624 _("mail_in_ui_folder_move_target_error"));
2628 * UI handler for the "Move to" action when invoked from the
2632 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2633 ModestMainWindow *win)
2635 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2636 GtkWidget *header_view = NULL;
2638 TnyFolderStore *folder_store = NULL;
2639 ModestMailOperation *mail_op = NULL;
2641 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2643 /* Get the folder view */
2644 folder_view = modest_main_window_get_child_widget (win,
2645 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2647 /* Get header view */
2648 header_view = modest_main_window_get_child_widget (win,
2649 MODEST_WIDGET_TYPE_HEADER_VIEW);
2651 /* Create and run the dialog */
2652 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2653 result = gtk_dialog_run (GTK_DIALOG(dialog));
2654 g_object_ref (tree_view);
2656 /* We do this to save an indentation level ;-) */
2657 if (result != GTK_RESPONSE_ACCEPT)
2660 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2662 if (TNY_IS_ACCOUNT (folder_store))
2665 /* Get folder or messages to transfer */
2666 if (gtk_widget_is_focus (folder_view)) {
2667 TnyFolderStore *src_folder;
2668 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2670 /* Clean folder on header view before moving it */
2671 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2673 if (TNY_IS_FOLDER (src_folder)) {
2675 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2677 modest_ui_actions_move_folder_error_handler,
2679 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2681 modest_mail_operation_xfer_folder (mail_op,
2682 TNY_FOLDER (src_folder),
2685 /* Unref mail operation */
2686 g_object_unref (G_OBJECT (mail_op));
2690 g_object_unref (G_OBJECT (src_folder));
2692 if (gtk_widget_is_focus (header_view)) {
2696 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2698 /* Ask for user confirmation */
2699 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2700 TNY_FOLDER (folder_store),
2703 /* Transfer messages */
2704 if (response == GTK_RESPONSE_OK) {
2705 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2706 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2709 modest_mail_operation_xfer_msgs (mail_op,
2711 TNY_FOLDER (folder_store),
2716 g_object_unref (G_OBJECT (mail_op));
2718 g_object_unref (headers);
2721 g_object_unref (folder_store);
2723 gtk_widget_destroy (dialog);
2728 * UI handler for the "Move to" action when invoked from the
2729 * ModestMsgViewWindow
2732 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2733 ModestMsgViewWindow *win)
2735 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2737 ModestMainWindow *main_window;
2741 /* Get the folder view */
2742 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2743 folder_view = modest_main_window_get_child_widget (main_window,
2744 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2746 /* Create and run the dialog */
2747 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2748 result = gtk_dialog_run (GTK_DIALOG(dialog));
2749 g_object_ref (tree_view);
2751 if (result == GTK_RESPONSE_ACCEPT) {
2752 TnyFolderStore *folder_store;
2755 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2757 /* Create header list */
2758 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2759 headers = tny_simple_list_new ();
2760 tny_list_prepend (headers, G_OBJECT (header));
2761 g_object_unref (header);
2763 /* Ask user for confirmation. MSG-NOT404 */
2764 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2765 TNY_FOLDER (folder_store),
2768 /* Transfer current msg */
2769 if (response == GTK_RESPONSE_OK) {
2770 ModestMailOperation *mail_op;
2772 /* Create mail op */
2773 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2774 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2777 /* Transfer messages */
2778 modest_mail_operation_xfer_msgs (mail_op,
2780 TNY_FOLDER (folder_store),
2782 tranasfer_msgs_from_viewer_cb,
2784 g_object_unref (G_OBJECT (mail_op));
2786 g_object_unref (headers);
2787 g_object_unref (folder_store);
2789 gtk_widget_destroy (dialog);
2793 modest_ui_actions_on_move_to (GtkAction *action,
2796 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2797 MODEST_IS_MSG_VIEW_WINDOW (win));
2799 if (MODEST_IS_MAIN_WINDOW (win))
2800 modest_ui_actions_on_main_window_move_to (action,
2801 MODEST_MAIN_WINDOW (win));
2803 modest_ui_actions_on_msg_view_window_move_to (action,
2804 MODEST_MSG_VIEW_WINDOW (win));
2808 * Calls #HeadersFunc for each header already selected in the main
2809 * window or the message currently being shown in the msg view window
2812 do_headers_action (ModestWindow *win,
2816 TnyList *headers_list;
2820 headers_list = get_selected_headers (win);
2824 /* Call the function for each header */
2825 iter = tny_list_create_iterator (headers_list);
2826 while (!tny_iterator_is_done (iter)) {
2829 header = TNY_HEADER (tny_iterator_get_current (iter));
2830 func (header, win, user_data);
2831 g_object_unref (header);
2832 tny_iterator_next (iter);
2834 g_object_unref (iter);
2835 g_object_unref (headers_list);
2839 modest_ui_actions_view_attachment (GtkAction *action,
2840 ModestWindow *window)
2842 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2843 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2845 /* not supported window for this action */
2846 g_return_if_reached ();
2851 modest_ui_actions_save_attachments (GtkAction *action,
2852 ModestWindow *window)
2854 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2855 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2857 /* not supported window for this action */
2858 g_return_if_reached ();
2863 modest_ui_actions_remove_attachments (GtkAction *action,
2864 ModestWindow *window)
2866 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2867 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2869 /* not supported window for this action */
2870 g_return_if_reached ();
2875 modest_ui_actions_on_settings (GtkAction *action,
2880 dialog = modest_platform_get_global_settings_dialog ();
2881 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2882 gtk_widget_show (dialog);
2884 gtk_dialog_run (GTK_DIALOG (dialog));
2886 gtk_widget_destroy (dialog);
2890 modest_ui_actions_on_help (GtkAction *action,
2893 const gchar *help_id = NULL;
2895 if (MODEST_IS_MAIN_WINDOW (win)) {
2896 const gchar *action_name;
2897 action_name = gtk_action_get_name (action);
2899 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2900 !strcmp (action_name, "HeaderViewCSMHelp")) {
2901 GtkWidget *folder_view;
2902 TnyFolderStore *folder_store;
2903 /* Get selected folder */
2904 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2905 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2906 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2908 /* Switch help_id */
2909 if (TNY_IS_FOLDER (folder_store)) {
2910 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2911 case TNY_FOLDER_TYPE_NORMAL:
2912 help_id = "applications_email_userfolder";
2914 case TNY_FOLDER_TYPE_INBOX:
2915 help_id = "applications_email_inbox";
2917 case TNY_FOLDER_TYPE_OUTBOX:
2918 help_id = "applications_email_outbox";
2920 case TNY_FOLDER_TYPE_SENT:
2921 help_id = "applications_email_sent";
2923 case TNY_FOLDER_TYPE_DRAFTS:
2924 help_id = "applications_email_drafts";
2926 case TNY_FOLDER_TYPE_ARCHIVE:
2927 help_id = "applications_email_archive";
2934 help_id = "applications_email_mainview";
2936 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2937 help_id = "applications_email_viewer";
2938 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2939 help_id = "applications_email_editor";
2941 modest_platform_show_help (GTK_WINDOW (win), help_id);
2945 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2946 ModestWindow *window)
2948 ModestMailOperation *mail_op;
2952 headers = get_selected_headers (window);
2956 /* Create mail operation */
2957 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2959 modest_ui_actions_get_msgs_full_error_handler,
2961 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2962 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2965 g_object_unref (headers);
2966 g_object_unref (mail_op);
2970 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2971 ModestWindow *window)
2973 g_return_if_fail (MODEST_IS_WINDOW (window));
2976 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2980 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2981 ModestWindow *window)
2983 g_return_if_fail (MODEST_IS_WINDOW (window));
2986 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2990 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2991 ModestWindow *window)
2993 g_return_if_fail (MODEST_IS_WINDOW (window));
2996 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3000 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3001 ModestWindow *window)
3003 g_return_if_fail (MODEST_IS_WINDOW (window));
3006 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3010 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3011 ModestWindow *window)
3013 g_return_if_fail (MODEST_IS_WINDOW (window));
3016 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3020 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3022 g_return_if_fail (MODEST_IS_WINDOW (window));
3025 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");