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, *blank_and_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);
499 blank_and_signature = g_strconcat ("\n", signature, NULL);
502 blank_and_signature = g_strdup ("");
505 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
507 g_printerr ("modest: failed to create new msg\n");
511 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
513 g_printerr ("modest: failed to find Drafts folder\n");
517 /* tny_folder_add_msg (folder, msg, &err); */
519 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
521 /* g_error_free (err); */
525 /* Create and register edit window */
526 /* This is destroyed by TOOD. */
527 msg_win = modest_msg_edit_window_new (msg, account_name);
528 mgr = modest_runtime_get_window_mgr ();
529 modest_window_mgr_register_window (mgr, msg_win);
532 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
534 gtk_widget_show_all (GTK_WIDGET (msg_win));
537 g_free (account_name);
539 g_free (blank_and_signature);
541 g_object_unref (G_OBJECT(account));
543 g_object_unref (G_OBJECT(msg));
545 g_object_unref (G_OBJECT(folder));
549 open_msg_cb (ModestMailOperation *mail_op,
554 ModestWindowMgr *mgr = NULL;
555 ModestWindow *parent_win = NULL;
556 ModestWindow *win = NULL;
557 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
558 gchar *account = NULL;
561 /* TODO: Show an error? (review the specs) */
565 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
566 folder = tny_header_get_folder (header);
568 /* Mark header as read */
569 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
572 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
574 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
576 /* Gets folder type (OUTBOX headers will be opened in edit window */
577 if (modest_tny_folder_is_local_folder (folder))
578 folder_type = modest_tny_folder_get_local_folder_type (folder);
580 /* If the header is in the drafts folder then open the editor,
581 else the message view window */
582 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
583 win = modest_msg_edit_window_new (msg, account);
585 gchar *uid = modest_tny_folder_get_header_unique_id (header);
587 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
588 GtkWidget *header_view;
589 GtkTreeSelection *sel;
590 GList *sel_list = NULL;
593 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
594 MODEST_WIDGET_TYPE_HEADER_VIEW);
596 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
597 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
599 if (sel_list != NULL) {
600 GtkTreeRowReference *row_reference;
602 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
603 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
604 g_list_free (sel_list);
606 win = modest_msg_view_window_new_with_header_model (msg,
611 gtk_tree_row_reference_free (row_reference);
613 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
616 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
621 /* Register and show new window */
623 mgr = modest_runtime_get_window_mgr ();
624 modest_window_mgr_register_window (mgr, win);
625 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
626 gtk_widget_show_all (GTK_WIDGET(win));
631 g_object_unref (msg);
632 g_object_unref (folder);
633 g_object_unref (header);
637 * This function is the error handler of the
638 * modest_mail_operation_get_msgs_full operation
641 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
646 error = modest_mail_operation_get_error (mail_op);
647 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
648 GObject *win = modest_mail_operation_get_source (mail_op);
650 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
656 * This function is used by both modest_ui_actions_on_open and
657 * modest_ui_actions_on_header_activated. This way we always do the
658 * same when trying to open messages.
661 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
663 ModestWindowMgr *mgr;
665 ModestMailOperation *mail_op;
667 /* Look if we already have a message view for each header. If
668 true, then remove the header from the list of headers to
670 mgr = modest_runtime_get_window_mgr ();
671 iter = tny_list_create_iterator (headers);
672 while (!tny_iterator_is_done (iter)) {
673 ModestWindow *window;
676 header = TNY_HEADER (tny_iterator_get_current (iter));
677 window = modest_window_mgr_find_window_by_header (mgr, header);
679 /* Do not open again the message and present
680 the window to the user */
681 tny_list_remove (headers, G_OBJECT (header));
682 gtk_window_present (GTK_WINDOW (window));
685 g_object_unref (header);
686 tny_iterator_next (iter);
689 /* Open each message */
690 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
692 modest_ui_actions_get_msgs_full_error_handler,
694 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
695 modest_mail_operation_get_msgs_full (mail_op,
702 g_object_unref(mail_op);
706 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
711 headers = get_selected_headers (win);
716 _modest_ui_actions_open (headers, win);
718 g_object_unref(headers);
723 free_reply_forward_helper (gpointer data)
725 ReplyForwardHelper *helper;
727 helper = (ReplyForwardHelper *) data;
728 g_free (helper->account_name);
729 g_slice_free (ReplyForwardHelper, helper);
733 reply_forward_cb (ModestMailOperation *mail_op,
739 ReplyForwardHelper *rf_helper;
740 ModestWindow *msg_win;
741 ModestEditType edit_type;
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 /* Create and register the windows */
800 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
801 mgr = modest_runtime_get_window_mgr ();
802 modest_window_mgr_register_window (mgr, msg_win);
804 if (rf_helper->parent_window != NULL) {
807 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
808 modest_window_set_zoom (msg_win, parent_zoom);
811 /* Show edit window */
812 gtk_widget_show_all (GTK_WIDGET (msg_win));
816 g_object_unref (G_OBJECT (new_msg));
818 g_object_unref (G_OBJECT (account));
819 g_object_unref (msg);
820 g_object_unref (header);
824 * Checks a list of headers. If any of them are not currently
825 * downloaded (CACHED) then it asks the user for permission to
828 * Returns FALSE if the user does not want to download the
829 * messages. Returns TRUE if the user allowed the download or if all
830 * of them are currently downloaded
833 download_uncached_messages (TnyList *header_list, GtkWindow *win)
836 gboolean found, retval;
838 iter = tny_list_create_iterator (header_list);
840 while (!tny_iterator_is_done (iter) && !found) {
842 TnyHeaderFlags flags;
844 header = TNY_HEADER (tny_iterator_get_current (iter));
845 flags = tny_header_get_flags (header);
846 /* TODO: is this the right flag?, it seems that some
847 headers that have been previously downloaded do not
849 found = !(flags & TNY_HEADER_FLAG_CACHED);
850 g_object_unref (header);
851 tny_iterator_next (iter);
853 g_object_unref (iter);
855 /* Ask for user permission to download the messages */
858 GtkResponseType response;
860 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
861 _("mcen_nc_get_multi_msg_txt"));
862 if (response == GTK_RESPONSE_CANCEL)
870 * Common code for the reply and forward actions
873 reply_forward (ReplyForwardAction action, ModestWindow *win)
875 ModestMailOperation *mail_op = NULL;
876 TnyList *header_list = NULL;
877 ReplyForwardHelper *rf_helper = NULL;
878 guint reply_forward_type;
879 gboolean continue_download;
881 g_return_if_fail (MODEST_IS_WINDOW(win));
883 header_list = get_selected_headers (win);
887 /* Check that the messages have been previously downloaded */
888 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
889 if (!continue_download) {
890 g_object_unref (header_list);
895 modest_conf_get_int (modest_runtime_get_conf (),
896 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
898 /* We assume that we can only select messages of the
899 same folder and that we reply all of them from the
900 same account. In fact the interface currently only
901 allows single selection */
904 rf_helper = g_slice_new0 (ReplyForwardHelper);
905 rf_helper->reply_forward_type = reply_forward_type;
906 rf_helper->action = action;
907 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
908 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
909 rf_helper->parent_window = GTK_WIDGET (win);
910 if (!rf_helper->account_name)
911 rf_helper->account_name =
912 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
914 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
917 /* Get header and message. Do not free them here, the
918 reply_forward_cb must do it */
919 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
920 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
921 if (!msg || !header) {
923 g_object_unref (msg);
925 g_object_unref (header);
926 g_printerr ("modest: no message found\n");
929 reply_forward_cb (NULL, header, msg, rf_helper);
931 /* Retrieve messages */
932 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
934 modest_ui_actions_get_msgs_full_error_handler,
936 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
937 modest_mail_operation_get_msgs_full (mail_op,
941 free_reply_forward_helper);
944 g_object_unref(mail_op);
948 g_object_unref (header_list);
952 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
954 g_return_if_fail (MODEST_IS_WINDOW(win));
956 reply_forward (ACTION_REPLY, win);
960 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
962 g_return_if_fail (MODEST_IS_WINDOW(win));
964 reply_forward (ACTION_FORWARD, win);
968 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
970 g_return_if_fail (MODEST_IS_WINDOW(win));
972 reply_forward (ACTION_REPLY_TO_ALL, win);
976 modest_ui_actions_on_next (GtkAction *action,
977 ModestWindow *window)
979 if (MODEST_IS_MAIN_WINDOW (window)) {
980 GtkWidget *header_view;
982 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
983 MODEST_WIDGET_TYPE_HEADER_VIEW);
987 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
988 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
989 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
991 g_return_if_reached ();
996 modest_ui_actions_on_prev (GtkAction *action,
997 ModestWindow *window)
999 g_return_if_fail (MODEST_IS_WINDOW(window));
1001 if (MODEST_IS_MAIN_WINDOW (window)) {
1002 GtkWidget *header_view;
1003 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1004 MODEST_WIDGET_TYPE_HEADER_VIEW);
1008 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1009 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1010 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1012 g_return_if_reached ();
1017 modest_ui_actions_on_sort (GtkAction *action,
1018 ModestWindow *window)
1020 g_return_if_fail (MODEST_IS_WINDOW(window));
1022 if (MODEST_IS_MAIN_WINDOW (window)) {
1023 GtkWidget *header_view;
1024 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1025 MODEST_WIDGET_TYPE_HEADER_VIEW);
1029 /* Show sorting dialog */
1030 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1035 * This function performs the send & receive required actions. The
1036 * window is used to create the mail operation. Typically it should
1037 * always be the main window, but we pass it as argument in order to
1041 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1043 gchar *acc_name = NULL;
1044 ModestMailOperation *mail_op;
1046 /* If no account name was provided then get the current account, and if
1047 there is no current account then pick the default one: */
1048 if (!account_name) {
1049 acc_name = g_strdup (modest_window_get_active_account(win));
1051 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1053 g_printerr ("modest: cannot get default account\n");
1057 acc_name = g_strdup (account_name);
1060 /* Send & receive. */
1061 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1062 /* Receive and then send. The operation is tagged initially as
1063 a receive operation because the account update performs a
1064 receive and then a send. The operation changes its type
1065 internally, so the progress objects will receive the proper
1066 progress information */
1067 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1068 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1069 modest_mail_operation_update_account (mail_op, acc_name);
1070 g_object_unref (G_OBJECT (mail_op));
1077 * Refreshes all accounts. This function will be used by automatic
1081 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1083 GSList *account_names, *iter;
1085 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1088 iter = account_names;
1090 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1091 iter = g_slist_next (iter);
1094 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1095 g_slist_free (account_names);
1099 * Handler of the click on Send&Receive button in the main toolbar
1102 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1104 /* Check that at least one account exists: */
1105 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1106 TRUE /* enabled accounts only */);
1107 gboolean accounts_exist = account_names != NULL;
1108 g_slist_free (account_names);
1110 /* If not, allow the user to create an account before trying to send/receive. */
1111 if (!accounts_exist)
1112 modest_ui_actions_on_accounts (NULL, win);
1114 /* Refresh the active account */
1115 modest_ui_actions_do_send_receive (NULL, win);
1120 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1123 GtkWidget *header_view;
1125 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1127 header_view = modest_main_window_get_child_widget (main_window,
1128 MODEST_WIDGET_TYPE_HEADER_VIEW);
1132 conf = modest_runtime_get_conf ();
1134 /* what is saved/restored is depending on the style; thus; we save with
1135 * old style, then update the style, and restore for this new style
1137 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1139 if (modest_header_view_get_style
1140 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1141 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1142 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1144 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1145 MODEST_HEADER_VIEW_STYLE_DETAILS);
1147 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1148 MODEST_CONF_HEADER_VIEW_KEY);
1153 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1155 ModestMainWindow *main_window)
1157 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1159 /* If no header has been selected then exit */
1163 /* Update Main window title */
1164 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1165 const gchar *subject = tny_header_get_subject (header);
1166 if (subject && strcmp (subject, ""))
1167 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1169 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1172 /* Update toolbar dimming state */
1173 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1177 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1179 ModestMainWindow *main_window)
1183 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1188 headers = tny_simple_list_new ();
1189 tny_list_prepend (headers, G_OBJECT (header));
1191 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1193 g_object_unref (headers);
1197 set_active_account_from_tny_account (TnyAccount *account,
1198 ModestWindow *window)
1200 const gchar *server_acc_name = tny_account_get_id (account);
1202 /* We need the TnyAccount provided by the
1203 account store because that is the one that
1204 knows the name of the Modest account */
1205 TnyAccount *modest_server_account = modest_server_account =
1206 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1209 const gchar *modest_acc_name =
1210 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1211 modest_window_set_active_account (window, modest_acc_name);
1212 g_object_unref (modest_server_account);
1216 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1217 TnyFolderStore *folder_store,
1219 ModestMainWindow *main_window)
1222 GtkWidget *header_view;
1224 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1226 header_view = modest_main_window_get_child_widget(main_window,
1227 MODEST_WIDGET_TYPE_HEADER_VIEW);
1231 conf = modest_runtime_get_conf ();
1233 if (TNY_IS_ACCOUNT (folder_store)) {
1234 /* Update active account */
1235 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1236 /* Show account details */
1237 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1239 if (TNY_IS_FOLDER (folder_store) && selected) {
1241 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1242 /* Update the active account */
1243 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1244 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1245 g_object_unref (account);
1248 /* Set folder on header view */
1249 modest_main_window_set_contents_style (main_window,
1250 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1251 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1252 TNY_FOLDER (folder_store));
1253 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1254 MODEST_CONF_HEADER_VIEW_KEY);
1256 /* Update the active account */
1257 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1258 /* Do not show folder */
1259 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1260 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1264 /* Update toolbar dimming state */
1265 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1269 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1276 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1278 if (g_main_depth > 0)
1279 gdk_threads_enter ();
1280 online = tny_device_is_online (modest_runtime_get_device());
1283 /* already online -- the item is simply not there... */
1284 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1286 GTK_MESSAGE_WARNING,
1288 _("The %s you selected cannot be found"),
1290 gtk_dialog_run (GTK_DIALOG(dialog));
1292 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1296 GTK_RESPONSE_REJECT,
1298 GTK_RESPONSE_ACCEPT,
1300 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1301 "Do you want to get online?"), item);
1302 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1303 gtk_label_new (txt), FALSE, FALSE, 0);
1304 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1307 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1308 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1309 // modest_platform_connect_and_wait ();;
1312 gtk_widget_destroy (dialog);
1313 if (g_main_depth > 0)
1314 gdk_threads_leave ();
1318 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1321 /* g_message ("%s %s", __FUNCTION__, link); */
1326 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1329 modest_platform_activate_uri (link);
1333 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1336 modest_platform_show_uri_popup (link);
1340 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1343 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1347 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1348 const gchar *address,
1351 /* g_message ("%s %s", __FUNCTION__, address); */
1355 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1357 TnyTransportAccount *transport_account;
1358 ModestMailOperation *mail_operation;
1360 gchar *account_name, *from;
1361 ModestAccountMgr *account_mgr;
1363 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1365 data = modest_msg_edit_window_get_msg_data (edit_window);
1367 account_mgr = modest_runtime_get_account_mgr();
1368 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1370 account_name = modest_account_mgr_get_default_account (account_mgr);
1371 if (!account_name) {
1372 g_printerr ("modest: no account found\n");
1373 modest_msg_edit_window_free_msg_data (edit_window, data);
1377 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1378 account_name = g_strdup (data->account_name);
1382 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1383 (modest_runtime_get_account_store(),
1385 TNY_ACCOUNT_TYPE_TRANSPORT));
1386 if (!transport_account) {
1387 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1388 g_free (account_name);
1389 modest_msg_edit_window_free_msg_data (edit_window, data);
1392 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1394 /* Create the mail operation */
1395 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1396 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1398 modest_mail_operation_save_to_drafts (mail_operation,
1409 data->priority_flags);
1412 g_free (account_name);
1413 g_object_unref (G_OBJECT (transport_account));
1414 g_object_unref (G_OBJECT (mail_operation));
1416 modest_msg_edit_window_free_msg_data (edit_window, data);
1418 /* Save settings and close the window */
1419 gtk_widget_destroy (GTK_WIDGET (edit_window));
1422 /* For instance, when clicking the Send toolbar button when editing a message: */
1424 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1426 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1428 if (!modest_msg_edit_window_check_names (edit_window))
1431 /* FIXME: Code added just for testing. The final version will
1432 use the send queue provided by tinymail and some
1434 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1435 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1437 account_name = modest_account_mgr_get_default_account (account_mgr);
1439 if (!account_name) {
1440 g_printerr ("modest: no account found\n");
1443 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1445 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1446 account_name = g_strdup (data->account_name);
1449 /* Get the currently-active transport account for this modest account: */
1450 TnyTransportAccount *transport_account =
1451 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1452 (modest_runtime_get_account_store(),
1454 if (!transport_account) {
1455 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1456 g_free (account_name);
1457 modest_msg_edit_window_free_msg_data (edit_window, data);
1461 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1463 /* mail content checks and dialogs */
1464 if (data->subject == NULL || data->subject[0] == '\0') {
1465 GtkResponseType response;
1466 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1467 _("mcen_nc_subject_is_empty_send"));
1468 if (response == GTK_RESPONSE_CANCEL) {
1469 g_free (account_name);
1474 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1475 GtkResponseType response;
1476 gchar *note_message;
1477 gchar *note_subject = data->subject;
1478 if (note_subject == NULL || note_subject[0] == '\0')
1479 note_subject = _("mail_va_no_subject");
1480 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1481 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1483 g_free (note_message);
1484 if (response == GTK_RESPONSE_CANCEL) {
1485 g_free (account_name);
1490 /* Create the mail operation */
1491 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1492 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1494 modest_mail_operation_send_new_mail (mail_operation,
1505 data->priority_flags);
1509 g_free (account_name);
1510 g_object_unref (G_OBJECT (transport_account));
1511 g_object_unref (G_OBJECT (mail_operation));
1513 modest_msg_edit_window_free_msg_data (edit_window, data);
1515 /* Save settings and close the window: */
1516 gtk_widget_destroy (GTK_WIDGET (edit_window));
1520 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1521 ModestMsgEditWindow *window)
1523 ModestMsgEditFormatState *format_state = NULL;
1525 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1526 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1528 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1531 format_state = modest_msg_edit_window_get_format_state (window);
1532 g_return_if_fail (format_state != NULL);
1534 format_state->bold = gtk_toggle_action_get_active (action);
1535 modest_msg_edit_window_set_format_state (window, format_state);
1536 g_free (format_state);
1541 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1542 ModestMsgEditWindow *window)
1544 ModestMsgEditFormatState *format_state = NULL;
1546 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1547 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1549 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1552 format_state = modest_msg_edit_window_get_format_state (window);
1553 g_return_if_fail (format_state != NULL);
1555 format_state->italics = gtk_toggle_action_get_active (action);
1556 modest_msg_edit_window_set_format_state (window, format_state);
1557 g_free (format_state);
1562 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1563 ModestMsgEditWindow *window)
1565 ModestMsgEditFormatState *format_state = NULL;
1567 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1568 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1570 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1573 format_state = modest_msg_edit_window_get_format_state (window);
1574 g_return_if_fail (format_state != NULL);
1576 format_state->bullet = gtk_toggle_action_get_active (action);
1577 modest_msg_edit_window_set_format_state (window, format_state);
1578 g_free (format_state);
1583 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1584 GtkRadioAction *selected,
1585 ModestMsgEditWindow *window)
1587 ModestMsgEditFormatState *format_state = NULL;
1588 GtkJustification value;
1590 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1592 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1595 value = gtk_radio_action_get_current_value (selected);
1597 format_state = modest_msg_edit_window_get_format_state (window);
1598 g_return_if_fail (format_state != NULL);
1600 format_state->justification = value;
1601 modest_msg_edit_window_set_format_state (window, format_state);
1602 g_free (format_state);
1606 modest_ui_actions_on_select_editor_color (GtkAction *action,
1607 ModestMsgEditWindow *window)
1609 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1610 g_return_if_fail (GTK_IS_ACTION (action));
1612 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1615 modest_msg_edit_window_select_color (window);
1619 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1620 ModestMsgEditWindow *window)
1622 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1623 g_return_if_fail (GTK_IS_ACTION (action));
1625 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1628 modest_msg_edit_window_select_background_color (window);
1632 modest_ui_actions_on_insert_image (GtkAction *action,
1633 ModestMsgEditWindow *window)
1635 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1636 g_return_if_fail (GTK_IS_ACTION (action));
1638 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1641 modest_msg_edit_window_insert_image (window);
1645 modest_ui_actions_on_attach_file (GtkAction *action,
1646 ModestMsgEditWindow *window)
1648 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1649 g_return_if_fail (GTK_IS_ACTION (action));
1651 modest_msg_edit_window_attach_file (window);
1655 modest_ui_actions_on_remove_attachments (GtkAction *action,
1656 ModestMsgEditWindow *window)
1658 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1659 g_return_if_fail (GTK_IS_ACTION (action));
1661 modest_msg_edit_window_remove_attachments (window, NULL);
1665 * Shows a dialog with an entry that asks for some text. The returned
1666 * value must be freed by the caller. The dialog window title will be
1670 ask_for_folder_name (GtkWindow *parent_window,
1673 GtkWidget *dialog, *entry;
1674 gchar *folder_name = NULL;
1676 /* Ask for folder name */
1677 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1681 GTK_RESPONSE_REJECT,
1683 GTK_RESPONSE_ACCEPT,
1685 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1686 gtk_label_new(title),
1689 entry = gtk_entry_new_with_max_length (40);
1690 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1694 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1696 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1697 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1699 gtk_widget_destroy (dialog);
1705 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1707 TnyFolderStore *parent_folder;
1708 GtkWidget *folder_view;
1710 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1712 folder_view = modest_main_window_get_child_widget (main_window,
1713 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1717 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1719 if (parent_folder) {
1720 gboolean finished = FALSE;
1722 gchar *folder_name = NULL, *suggested_name = NULL;
1724 /* Run the new folder dialog */
1726 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1731 if (result == GTK_RESPONSE_REJECT) {
1734 ModestMailOperation *mail_op;
1735 TnyFolder *new_folder = NULL;
1737 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1738 G_OBJECT(main_window));
1739 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1741 new_folder = modest_mail_operation_create_folder (mail_op,
1743 (const gchar *) folder_name);
1745 g_object_unref (new_folder);
1748 g_object_unref (mail_op);
1750 g_free (folder_name);
1754 g_object_unref (parent_folder);
1759 modest_ui_actions_on_rename_folder (GtkAction *action,
1760 ModestMainWindow *main_window)
1762 TnyFolderStore *folder;
1763 GtkWidget *folder_view;
1764 GtkWidget *header_view;
1766 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1768 folder_view = modest_main_window_get_child_widget (main_window,
1769 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1773 header_view = modest_main_window_get_child_widget (main_window,
1774 MODEST_WIDGET_TYPE_HEADER_VIEW);
1779 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1781 if (folder && TNY_IS_FOLDER (folder)) {
1783 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1784 _("Please enter a new name for the folder"));
1786 if (folder_name != NULL && strlen (folder_name) > 0) {
1787 ModestMailOperation *mail_op;
1789 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1790 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1793 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1795 modest_mail_operation_rename_folder (mail_op,
1796 TNY_FOLDER (folder),
1797 (const gchar *) folder_name);
1799 g_object_unref (mail_op);
1800 g_free (folder_name);
1802 g_object_unref (folder);
1807 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1810 GObject *win = modest_mail_operation_get_source (mail_op);
1812 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1813 _("mail_in_ui_folder_delete_error"));
1817 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1819 TnyFolderStore *folder;
1820 GtkWidget *folder_view;
1824 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1826 folder_view = modest_main_window_get_child_widget (main_window,
1827 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1831 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1833 /* Show an error if it's an account */
1834 if (!TNY_IS_FOLDER (folder)) {
1835 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1836 _("mail_in_ui_folder_delete_error"));
1841 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1842 tny_folder_get_name (TNY_FOLDER (folder)));
1843 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1844 (const gchar *) message);
1847 if (response == GTK_RESPONSE_OK) {
1848 ModestMailOperation *mail_op =
1849 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1850 G_OBJECT(main_window),
1851 modest_ui_actions_delete_folder_error_handler,
1854 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1856 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1857 g_object_unref (G_OBJECT (mail_op));
1860 g_object_unref (G_OBJECT (folder));
1864 modest_ui_actions_on_delete_folder (GtkAction *action,
1865 ModestMainWindow *main_window)
1867 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1869 delete_folder (main_window, FALSE);
1873 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1875 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1877 delete_folder (main_window, TRUE);
1881 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1882 const gchar* server_account_name,
1887 ModestMainWindow *main_window)
1889 g_return_if_fail(server_account_name);
1890 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1892 /* Initalize output parameters: */
1899 #ifdef MODEST_PLATFORM_MAEMO
1900 /* Maemo uses a different (awkward) button order,
1901 * It should probably just use gtk_alternative_dialog_button_order ().
1903 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1907 GTK_RESPONSE_ACCEPT,
1909 GTK_RESPONSE_REJECT,
1912 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1916 GTK_RESPONSE_REJECT,
1918 GTK_RESPONSE_ACCEPT,
1920 #endif /* MODEST_PLATFORM_MAEMO */
1922 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1924 gchar *server_name = modest_server_account_get_hostname (
1925 modest_runtime_get_account_mgr(), server_account_name);
1927 /* This causes a warning because the logical ID has no %s in it,
1928 * though the translation does, but there is not much we can do about that: */
1929 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1930 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1933 g_free (server_name);
1937 gchar *initial_username = modest_server_account_get_username (
1938 modest_runtime_get_account_mgr(), server_account_name);
1940 GtkWidget *entry_username = gtk_entry_new ();
1941 if (initial_username)
1942 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1943 /* Dim this if a connection has ever succeeded with this username,
1944 * as per the UI spec: */
1945 const gboolean username_known =
1946 modest_server_account_get_username_has_succeeded(
1947 modest_runtime_get_account_mgr(), server_account_name);
1948 gtk_widget_set_sensitive (entry_username, !username_known);
1950 #ifdef MODEST_PLATFORM_MAEMO
1951 /* Auto-capitalization is the default, so let's turn it off: */
1952 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1954 /* Create a size group to be used by all captions.
1955 * Note that HildonCaption does not create a default size group if we do not specify one.
1956 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1957 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1959 GtkWidget *caption = hildon_caption_new (sizegroup,
1960 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1961 gtk_widget_show (entry_username);
1962 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1963 FALSE, FALSE, MODEST_MARGIN_HALF);
1964 gtk_widget_show (caption);
1966 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1968 #endif /* MODEST_PLATFORM_MAEMO */
1971 GtkWidget *entry_password = gtk_entry_new ();
1972 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1973 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1975 #ifdef MODEST_PLATFORM_MAEMO
1976 /* Auto-capitalization is the default, so let's turn it off: */
1977 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1978 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1980 caption = hildon_caption_new (sizegroup,
1981 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1982 gtk_widget_show (entry_password);
1983 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1984 FALSE, FALSE, MODEST_MARGIN_HALF);
1985 gtk_widget_show (caption);
1986 g_object_unref (sizegroup);
1988 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1990 #endif /* MODEST_PLATFORM_MAEMO */
1992 /* This is not in the Maemo UI spec:
1993 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1994 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1998 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2000 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2002 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2004 modest_server_account_set_username (
2005 modest_runtime_get_account_mgr(), server_account_name,
2008 const gboolean username_was_changed =
2009 (strcmp (*username, initial_username) != 0);
2010 if (username_was_changed) {
2011 /* To actually use a changed username,
2012 * we must reset the connection, according to pvanhoof.
2013 * This _might_ be a sensible way to do that: */
2014 TnyDevice *device = modest_runtime_get_device();
2015 tny_device_force_offline (device);
2016 tny_device_force_online (device);
2021 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2023 /* We do not save the password in the configuration,
2024 * because this function is only called for passwords that should
2025 * not be remembered:
2026 modest_server_account_set_password (
2027 modest_runtime_get_account_mgr(), server_account_name,
2046 /* This is not in the Maemo UI spec:
2047 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2053 gtk_widget_destroy (dialog);
2055 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2059 modest_ui_actions_on_cut (GtkAction *action,
2060 ModestWindow *window)
2062 GtkWidget *focused_widget;
2064 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2065 if (GTK_IS_EDITABLE (focused_widget)) {
2066 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2067 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2068 GtkTextBuffer *buffer;
2069 GtkClipboard *clipboard;
2071 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2072 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2073 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2078 modest_ui_actions_on_copy (GtkAction *action,
2079 ModestWindow *window)
2081 GtkClipboard *clipboard;
2082 GtkWidget *focused_widget;
2084 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2085 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2086 if (GTK_IS_LABEL (focused_widget)) {
2087 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2088 } else if (GTK_IS_EDITABLE (focused_widget)) {
2089 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2090 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2091 GtkTextBuffer *buffer;
2093 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2094 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2099 modest_ui_actions_on_undo (GtkAction *action,
2100 ModestWindow *window)
2102 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2103 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2105 g_return_if_reached ();
2110 modest_ui_actions_on_paste (GtkAction *action,
2111 ModestWindow *window)
2113 GtkWidget *focused_widget;
2115 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2116 if (GTK_IS_EDITABLE (focused_widget)) {
2117 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2118 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2119 GtkTextBuffer *buffer;
2120 GtkClipboard *clipboard;
2122 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2123 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2124 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2129 modest_ui_actions_on_select_all (GtkAction *action,
2130 ModestWindow *window)
2132 GtkWidget *focused_widget;
2134 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2135 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2136 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2137 } else if (GTK_IS_LABEL (focused_widget)) {
2138 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2139 } else if (GTK_IS_EDITABLE (focused_widget)) {
2140 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2141 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2142 GtkTextBuffer *buffer;
2143 GtkTextIter start, end;
2145 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2146 gtk_text_buffer_get_start_iter (buffer, &start);
2147 gtk_text_buffer_get_end_iter (buffer, &end);
2148 gtk_text_buffer_select_range (buffer, &start, &end);
2150 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2151 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2153 GtkTreeSelection *selection = NULL;
2155 /* Get header view */
2156 GtkWidget *header_view = focused_widget;
2157 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2158 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2159 MODEST_WIDGET_TYPE_HEADER_VIEW);
2161 /* Select all messages */
2162 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2163 gtk_tree_selection_select_all (selection);
2168 modest_ui_actions_on_mark_as_read (GtkAction *action,
2169 ModestWindow *window)
2171 g_return_if_fail (MODEST_IS_WINDOW(window));
2173 /* Mark each header as read */
2174 do_headers_action (window, headers_action_mark_as_read, NULL);
2178 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2179 ModestWindow *window)
2181 g_return_if_fail (MODEST_IS_WINDOW(window));
2183 /* Mark each header as read */
2184 do_headers_action (window, headers_action_mark_as_unread, NULL);
2188 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2189 GtkRadioAction *selected,
2190 ModestWindow *window)
2194 value = gtk_radio_action_get_current_value (selected);
2195 if (MODEST_IS_WINDOW (window)) {
2196 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2200 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2201 GtkRadioAction *selected,
2202 ModestWindow *window)
2204 TnyHeaderFlags flags;
2205 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2207 flags = gtk_radio_action_get_current_value (selected);
2208 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2211 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2212 GtkRadioAction *selected,
2213 ModestWindow *window)
2217 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2219 file_format = gtk_radio_action_get_current_value (selected);
2220 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2225 modest_ui_actions_on_zoom_plus (GtkAction *action,
2226 ModestWindow *window)
2228 g_return_if_fail (MODEST_IS_WINDOW (window));
2230 modest_window_zoom_plus (MODEST_WINDOW (window));
2234 modest_ui_actions_on_zoom_minus (GtkAction *action,
2235 ModestWindow *window)
2237 g_return_if_fail (MODEST_IS_WINDOW (window));
2239 modest_window_zoom_minus (MODEST_WINDOW (window));
2243 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2244 ModestWindow *window)
2246 ModestWindowMgr *mgr;
2247 gboolean fullscreen, active;
2248 g_return_if_fail (MODEST_IS_WINDOW (window));
2250 mgr = modest_runtime_get_window_mgr ();
2252 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2253 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2255 if (active != fullscreen) {
2256 modest_window_mgr_set_fullscreen_mode (mgr, active);
2257 gtk_window_present (GTK_WINDOW (window));
2262 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2263 ModestWindow *window)
2265 ModestWindowMgr *mgr;
2266 gboolean fullscreen;
2268 g_return_if_fail (MODEST_IS_WINDOW (window));
2270 mgr = modest_runtime_get_window_mgr ();
2271 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2272 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2274 gtk_window_present (GTK_WINDOW (window));
2278 * Used by modest_ui_actions_on_details to call do_headers_action
2281 headers_action_show_details (TnyHeader *header,
2282 ModestWindow *window,
2289 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2292 gtk_widget_show_all (dialog);
2293 gtk_dialog_run (GTK_DIALOG (dialog));
2295 gtk_widget_destroy (dialog);
2299 * Show the folder details in a ModestDetailsDialog widget
2302 show_folder_details (TnyFolder *folder,
2308 dialog = modest_details_dialog_new_with_folder (window, folder);
2311 gtk_widget_show_all (dialog);
2312 gtk_dialog_run (GTK_DIALOG (dialog));
2314 gtk_widget_destroy (dialog);
2318 * Show the header details in a ModestDetailsDialog widget
2321 modest_ui_actions_on_details (GtkAction *action,
2324 TnyList * headers_list;
2328 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2331 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2334 g_object_unref (msg);
2336 headers_list = get_selected_headers (win);
2340 iter = tny_list_create_iterator (headers_list);
2342 header = TNY_HEADER (tny_iterator_get_current (iter));
2343 headers_action_show_details (header, win, NULL);
2344 g_object_unref (header);
2346 g_object_unref (iter);
2347 g_object_unref (headers_list);
2349 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2350 GtkWidget *folder_view, *header_view;
2352 /* Check which widget has the focus */
2353 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2354 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2355 if (gtk_widget_is_focus (folder_view)) {
2358 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2360 /* Show only when it's a folder */
2361 if (!folder || !TNY_IS_FOLDER (folder))
2364 show_folder_details (folder, GTK_WINDOW (win));
2367 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2368 MODEST_WIDGET_TYPE_HEADER_VIEW);
2369 /* Show details of each header */
2370 do_headers_action (win, headers_action_show_details, header_view);
2376 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2377 ModestMsgEditWindow *window)
2379 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2381 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2385 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2386 ModestMsgEditWindow *window)
2388 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2390 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2394 modest_ui_actions_toggle_folders_view (GtkAction *action,
2395 ModestMainWindow *main_window)
2399 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2401 conf = modest_runtime_get_conf ();
2403 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2404 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2406 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2410 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2411 ModestWindow *window)
2413 gboolean active, fullscreen = FALSE;
2414 ModestWindowMgr *mgr;
2416 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2418 /* Check if we want to toggle the toolbar vuew in fullscreen
2420 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2421 "ViewShowToolbarFullScreen")) {
2425 /* Toggle toolbar */
2426 mgr = modest_runtime_get_window_mgr ();
2427 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2431 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2432 ModestMsgEditWindow *window)
2434 modest_msg_edit_window_select_font (window);
2438 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2439 const gchar *display_name,
2442 /* Do not change the application name if the widget has not
2443 the focus. This callback could be called even if the folder
2444 view has not the focus, because the handled signal could be
2445 emitted when the folder view is redrawn */
2446 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2448 gtk_window_set_title (window, display_name);
2450 gtk_window_set_title (window, " ");
2455 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2457 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2458 modest_msg_edit_window_select_contacts (window);
2462 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2464 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2465 modest_msg_edit_window_check_names (window);
2470 create_move_to_dialog (ModestWindow *win,
2471 GtkWidget *folder_view,
2472 GtkWidget **tree_view)
2474 GtkWidget *dialog, *scroll;
2476 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2478 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2480 GTK_RESPONSE_ACCEPT,
2482 GTK_RESPONSE_REJECT,
2485 /* Create scrolled window */
2486 scroll = gtk_scrolled_window_new (NULL, NULL);
2487 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2488 GTK_POLICY_AUTOMATIC,
2489 GTK_POLICY_AUTOMATIC);
2491 /* Create folder view */
2492 *tree_view = modest_folder_view_new (NULL);
2493 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2494 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2495 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2497 /* Add scroll to dialog */
2498 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2499 scroll, FALSE, FALSE, 0);
2501 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2507 * Returns TRUE if at least one of the headers of the list belongs to
2508 * a message that has been fully retrieved.
2511 has_retrieved_msgs (TnyList *list)
2514 gboolean found = FALSE;
2516 iter = tny_list_create_iterator (list);
2517 while (tny_iterator_is_done (iter) && !found) {
2519 TnyHeaderFlags flags;
2521 header = TNY_HEADER (tny_iterator_get_current (iter));
2522 flags = tny_header_get_flags (header);
2523 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2527 tny_iterator_next (iter);
2529 g_object_unref (iter);
2535 * Shows a confirmation dialog to the user when we're moving messages
2536 * from a remote server to the local storage. Returns the dialog
2537 * response. If it's other kind of movement the it always returns
2541 msgs_move_to_confirmation (GtkWindow *win,
2542 TnyFolder *dest_folder,
2545 gint response = GTK_RESPONSE_OK;
2547 /* If the destination is a local folder */
2548 if (modest_tny_folder_is_local_folder (dest_folder)) {
2549 TnyFolder *src_folder;
2553 /* Get source folder */
2554 iter = tny_list_create_iterator (headers);
2555 header = TNY_HEADER (tny_iterator_get_current (iter));
2556 src_folder = tny_header_get_folder (header);
2557 g_object_unref (header);
2558 g_object_unref (iter);
2560 /* If the source is a remote folder */
2561 if (!modest_tny_folder_is_local_folder (src_folder)) {
2562 const gchar *message;
2564 if (tny_list_get_length (headers) == 1)
2565 if (has_retrieved_msgs (headers))
2566 message = _("mcen_nc_move_retrieve");
2568 message = _("mcen_nc_move_header");
2570 if (has_retrieved_msgs (headers))
2571 message = _("mcen_nc_move_retrieves");
2573 message = _("mcen_nc_move_headers");
2575 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2576 (const gchar *) message);
2578 g_object_unref (src_folder);
2585 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2587 ModestMsgViewWindow *self = NULL;
2588 gboolean found = FALSE;
2590 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2591 self = MODEST_MSG_VIEW_WINDOW (object);
2593 found = modest_msg_view_window_select_first_message (self);
2594 g_return_if_fail (found);
2598 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2601 GObject *win = modest_mail_operation_get_source (mail_op);
2603 /* TODO: show error message */
2604 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2605 _("mail_in_ui_folder_move_target_error"));
2609 * UI handler for the "Move to" action when invoked from the
2613 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2614 ModestMainWindow *win)
2616 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2617 GtkWidget *header_view = NULL;
2619 TnyFolderStore *folder_store = NULL;
2620 ModestMailOperation *mail_op = NULL;
2622 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2624 /* Get the folder view */
2625 folder_view = modest_main_window_get_child_widget (win,
2626 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2628 /* Get header view */
2629 header_view = modest_main_window_get_child_widget (win,
2630 MODEST_WIDGET_TYPE_HEADER_VIEW);
2632 /* Create and run the dialog */
2633 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2634 result = gtk_dialog_run (GTK_DIALOG(dialog));
2635 g_object_ref (tree_view);
2637 /* We do this to save an indentation level ;-) */
2638 if (result != GTK_RESPONSE_ACCEPT)
2641 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2643 if (TNY_IS_ACCOUNT (folder_store))
2646 /* Get folder or messages to transfer */
2647 if (gtk_widget_is_focus (folder_view)) {
2648 TnyFolderStore *src_folder;
2649 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2651 /* Clean folder on header view before moving it */
2652 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2654 if (TNY_IS_FOLDER (src_folder)) {
2656 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2658 modest_ui_actions_move_folder_error_handler,
2660 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2662 modest_mail_operation_xfer_folder (mail_op,
2663 TNY_FOLDER (src_folder),
2666 /* Unref mail operation */
2667 g_object_unref (G_OBJECT (mail_op));
2671 g_object_unref (G_OBJECT (src_folder));
2673 if (gtk_widget_is_focus (header_view)) {
2677 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2679 /* Ask for user confirmation */
2680 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2681 TNY_FOLDER (folder_store),
2684 /* Transfer messages */
2685 if (response == GTK_RESPONSE_OK) {
2686 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2687 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2690 modest_mail_operation_xfer_msgs (mail_op,
2692 TNY_FOLDER (folder_store),
2697 g_object_unref (G_OBJECT (mail_op));
2699 g_object_unref (headers);
2702 g_object_unref (folder_store);
2704 gtk_widget_destroy (dialog);
2709 * UI handler for the "Move to" action when invoked from the
2710 * ModestMsgViewWindow
2713 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2714 ModestMsgViewWindow *win)
2716 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2718 ModestMainWindow *main_window;
2722 /* Get the folder view */
2723 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2724 folder_view = modest_main_window_get_child_widget (main_window,
2725 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2727 /* Create and run the dialog */
2728 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2729 result = gtk_dialog_run (GTK_DIALOG(dialog));
2730 g_object_ref (tree_view);
2732 if (result == GTK_RESPONSE_ACCEPT) {
2733 TnyFolderStore *folder_store;
2736 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2738 /* Create header list */
2739 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2740 headers = tny_simple_list_new ();
2741 tny_list_prepend (headers, G_OBJECT (header));
2742 g_object_unref (header);
2744 /* Ask user for confirmation. MSG-NOT404 */
2745 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2746 TNY_FOLDER (folder_store),
2749 /* Transfer current msg */
2750 if (response == GTK_RESPONSE_OK) {
2751 ModestMailOperation *mail_op;
2753 /* Create mail op */
2754 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2755 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2758 /* Transfer messages */
2759 modest_mail_operation_xfer_msgs (mail_op,
2761 TNY_FOLDER (folder_store),
2763 tranasfer_msgs_from_viewer_cb,
2765 g_object_unref (G_OBJECT (mail_op));
2767 g_object_unref (headers);
2768 g_object_unref (folder_store);
2770 gtk_widget_destroy (dialog);
2774 modest_ui_actions_on_move_to (GtkAction *action,
2777 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2778 MODEST_IS_MSG_VIEW_WINDOW (win));
2780 if (MODEST_IS_MAIN_WINDOW (win))
2781 modest_ui_actions_on_main_window_move_to (action,
2782 MODEST_MAIN_WINDOW (win));
2784 modest_ui_actions_on_msg_view_window_move_to (action,
2785 MODEST_MSG_VIEW_WINDOW (win));
2789 * Calls #HeadersFunc for each header already selected in the main
2790 * window or the message currently being shown in the msg view window
2793 do_headers_action (ModestWindow *win,
2797 TnyList *headers_list;
2801 headers_list = get_selected_headers (win);
2805 /* Call the function for each header */
2806 iter = tny_list_create_iterator (headers_list);
2807 while (!tny_iterator_is_done (iter)) {
2810 header = TNY_HEADER (tny_iterator_get_current (iter));
2811 func (header, win, user_data);
2812 g_object_unref (header);
2813 tny_iterator_next (iter);
2815 g_object_unref (iter);
2816 g_object_unref (headers_list);
2820 modest_ui_actions_view_attachment (GtkAction *action,
2821 ModestWindow *window)
2823 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2824 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2826 /* not supported window for this action */
2827 g_return_if_reached ();
2832 modest_ui_actions_save_attachments (GtkAction *action,
2833 ModestWindow *window)
2835 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2836 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2838 /* not supported window for this action */
2839 g_return_if_reached ();
2844 modest_ui_actions_remove_attachments (GtkAction *action,
2845 ModestWindow *window)
2847 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2848 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2850 /* not supported window for this action */
2851 g_return_if_reached ();
2856 modest_ui_actions_on_settings (GtkAction *action,
2861 dialog = modest_platform_get_global_settings_dialog ();
2862 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2863 gtk_widget_show (dialog);
2865 gtk_dialog_run (GTK_DIALOG (dialog));
2867 gtk_widget_destroy (dialog);
2871 modest_ui_actions_on_help (GtkAction *action,
2874 const gchar *help_id = NULL;
2876 if (MODEST_IS_MAIN_WINDOW (win)) {
2877 const gchar *action_name;
2878 action_name = gtk_action_get_name (action);
2880 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2881 !strcmp (action_name, "HeaderViewCSMHelp")) {
2882 GtkWidget *folder_view;
2883 TnyFolderStore *folder_store;
2884 /* Get selected folder */
2885 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2886 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2887 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2889 /* Switch help_id */
2890 if (TNY_IS_FOLDER (folder_store)) {
2891 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2892 case TNY_FOLDER_TYPE_NORMAL:
2893 help_id = "applications_email_userfolder";
2895 case TNY_FOLDER_TYPE_INBOX:
2896 help_id = "applications_email_inbox";
2898 case TNY_FOLDER_TYPE_OUTBOX:
2899 help_id = "applications_email_outbox";
2901 case TNY_FOLDER_TYPE_SENT:
2902 help_id = "applications_email_sent";
2904 case TNY_FOLDER_TYPE_DRAFTS:
2905 help_id = "applications_email_drafts";
2907 case TNY_FOLDER_TYPE_ARCHIVE:
2908 help_id = "applications_email_archive";
2915 help_id = "applications_email_mainview";
2917 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2918 help_id = "applications_email_viewer";
2919 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2920 help_id = "applications_email_editor";
2922 modest_platform_show_help (GTK_WINDOW (win), help_id);
2926 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2927 ModestWindow *window)
2929 ModestMailOperation *mail_op;
2933 headers = get_selected_headers (window);
2937 /* Create mail operation */
2938 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2940 modest_ui_actions_get_msgs_full_error_handler,
2942 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2943 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2946 g_object_unref (headers);
2947 g_object_unref (mail_op);
2951 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2952 ModestWindow *window)
2954 g_return_if_fail (MODEST_IS_WINDOW (window));
2957 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2961 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2962 ModestWindow *window)
2964 g_return_if_fail (MODEST_IS_WINDOW (window));
2967 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2971 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2972 ModestWindow *window)
2974 g_return_if_fail (MODEST_IS_WINDOW (window));
2977 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2981 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2982 ModestWindow *window)
2984 g_return_if_fail (MODEST_IS_WINDOW (window));
2987 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2991 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2992 ModestWindow *window)
2994 g_return_if_fail (MODEST_IS_WINDOW (window));
2997 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3001 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3003 g_return_if_fail (MODEST_IS_WINDOW (window));
3006 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3010 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3012 g_return_if_fail (MODEST_IS_WINDOW (window));
3014 modest_platform_show_search_messages (GTK_WINDOW (window));