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 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1397 (modest_runtime_get_account_store(),
1399 TNY_ACCOUNT_TYPE_TRANSPORT));
1400 if (!transport_account) {
1401 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1402 g_free (account_name);
1403 modest_msg_edit_window_free_msg_data (edit_window, data);
1406 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1408 /* Create the mail operation */
1409 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1410 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1412 modest_mail_operation_save_to_drafts (mail_operation,
1422 data->priority_flags);
1425 g_free (account_name);
1426 g_object_unref (G_OBJECT (transport_account));
1427 g_object_unref (G_OBJECT (mail_operation));
1429 modest_msg_edit_window_free_msg_data (edit_window, data);
1431 /* Save settings and close the window */
1432 gtk_widget_destroy (GTK_WIDGET (edit_window));
1435 /* For instance, when clicking the Send toolbar button when editing a message: */
1437 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1439 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1441 if (!modest_msg_edit_window_check_names (edit_window))
1444 /* FIXME: Code added just for testing. The final version will
1445 use the send queue provided by tinymail and some
1447 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1448 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1450 account_name = modest_account_mgr_get_default_account (account_mgr);
1452 if (!account_name) {
1453 g_printerr ("modest: no account found\n");
1457 /* Get the currently-active transport account for this modest account: */
1458 TnyTransportAccount *transport_account =
1459 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1460 (modest_runtime_get_account_store(),
1462 if (!transport_account) {
1463 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1464 g_free (account_name);
1468 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1470 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1472 /* mail content checks and dialogs */
1473 if (data->subject == NULL || data->subject[0] == '\0') {
1474 GtkResponseType response;
1475 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1476 _("mcen_nc_subject_is_empty_send"));
1477 if (response == GTK_RESPONSE_CANCEL) {
1478 g_free (account_name);
1483 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1484 GtkResponseType response;
1485 gchar *note_message;
1486 gchar *note_subject = data->subject;
1487 if (note_subject == NULL || note_subject[0] == '\0')
1488 note_subject = _("mail_va_no_subject");
1489 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1490 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1492 g_free (note_message);
1493 if (response == GTK_RESPONSE_CANCEL) {
1494 g_free (account_name);
1499 /* Create the mail operation */
1500 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1501 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1503 modest_mail_operation_send_new_mail (mail_operation,
1513 data->priority_flags);
1517 g_free (account_name);
1518 g_object_unref (G_OBJECT (transport_account));
1519 g_object_unref (G_OBJECT (mail_operation));
1521 modest_msg_edit_window_free_msg_data (edit_window, data);
1523 /* Save settings and close the window: */
1524 gtk_widget_destroy (GTK_WIDGET (edit_window));
1528 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1529 ModestMsgEditWindow *window)
1531 ModestMsgEditFormatState *format_state = NULL;
1533 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1534 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1536 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1539 format_state = modest_msg_edit_window_get_format_state (window);
1540 g_return_if_fail (format_state != NULL);
1542 format_state->bold = gtk_toggle_action_get_active (action);
1543 modest_msg_edit_window_set_format_state (window, format_state);
1544 g_free (format_state);
1549 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1550 ModestMsgEditWindow *window)
1552 ModestMsgEditFormatState *format_state = NULL;
1554 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1555 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1557 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1560 format_state = modest_msg_edit_window_get_format_state (window);
1561 g_return_if_fail (format_state != NULL);
1563 format_state->italics = gtk_toggle_action_get_active (action);
1564 modest_msg_edit_window_set_format_state (window, format_state);
1565 g_free (format_state);
1570 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1571 ModestMsgEditWindow *window)
1573 ModestMsgEditFormatState *format_state = NULL;
1575 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1576 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1578 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1581 format_state = modest_msg_edit_window_get_format_state (window);
1582 g_return_if_fail (format_state != NULL);
1584 format_state->bullet = gtk_toggle_action_get_active (action);
1585 modest_msg_edit_window_set_format_state (window, format_state);
1586 g_free (format_state);
1591 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1592 GtkRadioAction *selected,
1593 ModestMsgEditWindow *window)
1595 ModestMsgEditFormatState *format_state = NULL;
1596 GtkJustification value;
1598 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1600 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1603 value = gtk_radio_action_get_current_value (selected);
1605 format_state = modest_msg_edit_window_get_format_state (window);
1606 g_return_if_fail (format_state != NULL);
1608 format_state->justification = value;
1609 modest_msg_edit_window_set_format_state (window, format_state);
1610 g_free (format_state);
1614 modest_ui_actions_on_select_editor_color (GtkAction *action,
1615 ModestMsgEditWindow *window)
1617 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1618 g_return_if_fail (GTK_IS_ACTION (action));
1620 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1623 modest_msg_edit_window_select_color (window);
1627 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1628 ModestMsgEditWindow *window)
1630 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1631 g_return_if_fail (GTK_IS_ACTION (action));
1633 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1636 modest_msg_edit_window_select_background_color (window);
1640 modest_ui_actions_on_insert_image (GtkAction *action,
1641 ModestMsgEditWindow *window)
1643 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1644 g_return_if_fail (GTK_IS_ACTION (action));
1646 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1649 modest_msg_edit_window_insert_image (window);
1653 modest_ui_actions_on_attach_file (GtkAction *action,
1654 ModestMsgEditWindow *window)
1656 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1657 g_return_if_fail (GTK_IS_ACTION (action));
1659 modest_msg_edit_window_attach_file (window);
1663 modest_ui_actions_on_remove_attachments (GtkAction *action,
1664 ModestMsgEditWindow *window)
1666 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1667 g_return_if_fail (GTK_IS_ACTION (action));
1669 modest_msg_edit_window_remove_attachments (window, NULL);
1673 * Shows a dialog with an entry that asks for some text. The returned
1674 * value must be freed by the caller. The dialog window title will be
1678 ask_for_folder_name (GtkWindow *parent_window,
1681 GtkWidget *dialog, *entry;
1682 gchar *folder_name = NULL;
1684 /* Ask for folder name */
1685 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1689 GTK_RESPONSE_REJECT,
1691 GTK_RESPONSE_ACCEPT,
1693 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1694 gtk_label_new(title),
1697 entry = gtk_entry_new_with_max_length (40);
1698 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1702 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1704 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1705 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1707 gtk_widget_destroy (dialog);
1713 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1715 TnyFolderStore *parent_folder;
1716 GtkWidget *folder_view;
1718 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1720 folder_view = modest_main_window_get_child_widget (main_window,
1721 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1725 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1727 if (parent_folder) {
1728 gboolean finished = FALSE;
1730 gchar *folder_name = NULL, *suggested_name = NULL;
1732 /* Run the new folder dialog */
1734 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1739 if (result == GTK_RESPONSE_REJECT) {
1742 ModestMailOperation *mail_op;
1743 TnyFolder *new_folder = NULL;
1745 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1746 G_OBJECT(main_window));
1747 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1749 new_folder = modest_mail_operation_create_folder (mail_op,
1751 (const gchar *) folder_name);
1753 g_object_unref (new_folder);
1756 g_object_unref (mail_op);
1758 g_free (folder_name);
1762 g_object_unref (parent_folder);
1767 modest_ui_actions_on_rename_folder (GtkAction *action,
1768 ModestMainWindow *main_window)
1770 TnyFolderStore *folder;
1771 GtkWidget *folder_view;
1772 GtkWidget *header_view;
1774 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1776 folder_view = modest_main_window_get_child_widget (main_window,
1777 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1781 header_view = modest_main_window_get_child_widget (main_window,
1782 MODEST_WIDGET_TYPE_HEADER_VIEW);
1787 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1789 if (folder && TNY_IS_FOLDER (folder)) {
1791 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1792 _("Please enter a new name for the folder"));
1794 if (folder_name != NULL && strlen (folder_name) > 0) {
1795 ModestMailOperation *mail_op;
1797 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1798 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1801 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1803 modest_mail_operation_rename_folder (mail_op,
1804 TNY_FOLDER (folder),
1805 (const gchar *) folder_name);
1807 g_object_unref (mail_op);
1808 g_free (folder_name);
1810 g_object_unref (folder);
1815 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1818 GObject *win = modest_mail_operation_get_source (mail_op);
1820 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1821 _("mail_in_ui_folder_delete_error"));
1825 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1827 TnyFolderStore *folder;
1828 GtkWidget *folder_view;
1832 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1834 folder_view = modest_main_window_get_child_widget (main_window,
1835 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1839 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1841 /* Show an error if it's an account */
1842 if (!TNY_IS_FOLDER (folder)) {
1843 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1844 _("mail_in_ui_folder_delete_error"));
1849 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1850 tny_folder_get_name (TNY_FOLDER (folder)));
1851 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1852 (const gchar *) message);
1855 if (response == GTK_RESPONSE_OK) {
1856 ModestMailOperation *mail_op =
1857 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1858 G_OBJECT(main_window),
1859 modest_ui_actions_delete_folder_error_handler,
1862 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1864 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1865 g_object_unref (G_OBJECT (mail_op));
1868 g_object_unref (G_OBJECT (folder));
1872 modest_ui_actions_on_delete_folder (GtkAction *action,
1873 ModestMainWindow *main_window)
1875 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1877 delete_folder (main_window, FALSE);
1881 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1883 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1885 delete_folder (main_window, TRUE);
1889 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1890 const gchar* server_account_name,
1895 ModestMainWindow *main_window)
1897 g_return_if_fail(server_account_name);
1898 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1900 /* Initalize output parameters: */
1907 #ifdef MODEST_PLATFORM_MAEMO
1908 /* Maemo uses a different (awkward) button order,
1909 * It should probably just use gtk_alternative_dialog_button_order ().
1911 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1915 GTK_RESPONSE_ACCEPT,
1917 GTK_RESPONSE_REJECT,
1920 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1924 GTK_RESPONSE_REJECT,
1926 GTK_RESPONSE_ACCEPT,
1928 #endif /* MODEST_PLATFORM_MAEMO */
1930 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1932 gchar *server_name = modest_server_account_get_hostname (
1933 modest_runtime_get_account_mgr(), server_account_name);
1935 /* This causes a warning because the logical ID has no %s in it,
1936 * though the translation does, but there is not much we can do about that: */
1937 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1938 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1941 g_free (server_name);
1945 gchar *initial_username = modest_server_account_get_username (
1946 modest_runtime_get_account_mgr(), server_account_name);
1948 GtkWidget *entry_username = gtk_entry_new ();
1949 if (initial_username)
1950 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1951 /* Dim this if a connection has ever succeeded with this username,
1952 * as per the UI spec: */
1953 const gboolean username_known =
1954 modest_server_account_get_username_has_succeeded(
1955 modest_runtime_get_account_mgr(), server_account_name);
1956 gtk_widget_set_sensitive (entry_username, !username_known);
1958 #ifdef MODEST_PLATFORM_MAEMO
1959 /* Auto-capitalization is the default, so let's turn it off: */
1960 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1962 /* Create a size group to be used by all captions.
1963 * Note that HildonCaption does not create a default size group if we do not specify one.
1964 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1965 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1967 GtkWidget *caption = hildon_caption_new (sizegroup,
1968 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1969 gtk_widget_show (entry_username);
1970 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1971 FALSE, FALSE, MODEST_MARGIN_HALF);
1972 gtk_widget_show (caption);
1974 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1976 #endif /* MODEST_PLATFORM_MAEMO */
1979 GtkWidget *entry_password = gtk_entry_new ();
1980 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1981 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1983 #ifdef MODEST_PLATFORM_MAEMO
1984 /* Auto-capitalization is the default, so let's turn it off: */
1985 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1986 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1988 caption = hildon_caption_new (sizegroup,
1989 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1990 gtk_widget_show (entry_password);
1991 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1992 FALSE, FALSE, MODEST_MARGIN_HALF);
1993 gtk_widget_show (caption);
1994 g_object_unref (sizegroup);
1996 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1998 #endif /* MODEST_PLATFORM_MAEMO */
2000 /* This is not in the Maemo UI spec:
2001 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2002 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2006 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2008 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2010 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2012 modest_server_account_set_username (
2013 modest_runtime_get_account_mgr(), server_account_name,
2016 const gboolean username_was_changed =
2017 (strcmp (*username, initial_username) != 0);
2018 if (username_was_changed) {
2019 /* To actually use a changed username,
2020 * we must reset the connection, according to pvanhoof.
2021 * This _might_ be a sensible way to do that: */
2022 TnyDevice *device = modest_runtime_get_device();
2023 tny_device_force_offline (device);
2024 tny_device_force_online (device);
2029 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2031 /* We do not save the password in the configuration,
2032 * because this function is only called for passwords that should
2033 * not be remembered:
2034 modest_server_account_set_password (
2035 modest_runtime_get_account_mgr(), server_account_name,
2054 /* This is not in the Maemo UI spec:
2055 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2061 gtk_widget_destroy (dialog);
2063 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2067 modest_ui_actions_on_cut (GtkAction *action,
2068 ModestWindow *window)
2070 GtkWidget *focused_widget;
2072 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2073 if (GTK_IS_EDITABLE (focused_widget)) {
2074 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2075 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2076 GtkTextBuffer *buffer;
2077 GtkClipboard *clipboard;
2079 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2080 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2081 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2086 modest_ui_actions_on_copy (GtkAction *action,
2087 ModestWindow *window)
2089 GtkClipboard *clipboard;
2090 GtkWidget *focused_widget;
2092 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2093 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2094 if (GTK_IS_LABEL (focused_widget)) {
2095 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2096 } else if (GTK_IS_EDITABLE (focused_widget)) {
2097 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2098 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2099 GtkTextBuffer *buffer;
2101 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2102 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2107 modest_ui_actions_on_undo (GtkAction *action,
2108 ModestWindow *window)
2110 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2111 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2113 g_return_if_reached ();
2118 modest_ui_actions_on_paste (GtkAction *action,
2119 ModestWindow *window)
2121 GtkWidget *focused_widget;
2123 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2124 if (GTK_IS_EDITABLE (focused_widget)) {
2125 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2126 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2127 GtkTextBuffer *buffer;
2128 GtkClipboard *clipboard;
2130 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2131 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2132 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2137 modest_ui_actions_on_select_all (GtkAction *action,
2138 ModestWindow *window)
2140 GtkWidget *focused_widget;
2142 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2143 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2144 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2145 } else if (GTK_IS_LABEL (focused_widget)) {
2146 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2147 } else if (GTK_IS_EDITABLE (focused_widget)) {
2148 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2149 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2150 GtkTextBuffer *buffer;
2151 GtkTextIter start, end;
2153 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2154 gtk_text_buffer_get_start_iter (buffer, &start);
2155 gtk_text_buffer_get_end_iter (buffer, &end);
2156 gtk_text_buffer_select_range (buffer, &start, &end);
2158 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2159 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2161 GtkTreeSelection *selection = NULL;
2163 /* Get header view */
2164 GtkWidget *header_view = focused_widget;
2165 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2166 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2167 MODEST_WIDGET_TYPE_HEADER_VIEW);
2169 /* Select all messages */
2170 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2171 gtk_tree_selection_select_all (selection);
2176 modest_ui_actions_on_mark_as_read (GtkAction *action,
2177 ModestWindow *window)
2179 g_return_if_fail (MODEST_IS_WINDOW(window));
2181 /* Mark each header as read */
2182 do_headers_action (window, headers_action_mark_as_read, NULL);
2186 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2187 ModestWindow *window)
2189 g_return_if_fail (MODEST_IS_WINDOW(window));
2191 /* Mark each header as read */
2192 do_headers_action (window, headers_action_mark_as_unread, NULL);
2196 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2197 GtkRadioAction *selected,
2198 ModestWindow *window)
2202 value = gtk_radio_action_get_current_value (selected);
2203 if (MODEST_IS_WINDOW (window)) {
2204 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2208 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2209 GtkRadioAction *selected,
2210 ModestWindow *window)
2212 TnyHeaderFlags flags;
2213 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2215 flags = gtk_radio_action_get_current_value (selected);
2216 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2219 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2220 GtkRadioAction *selected,
2221 ModestWindow *window)
2225 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2227 file_format = gtk_radio_action_get_current_value (selected);
2228 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2233 modest_ui_actions_on_zoom_plus (GtkAction *action,
2234 ModestWindow *window)
2236 g_return_if_fail (MODEST_IS_WINDOW (window));
2238 modest_window_zoom_plus (MODEST_WINDOW (window));
2242 modest_ui_actions_on_zoom_minus (GtkAction *action,
2243 ModestWindow *window)
2245 g_return_if_fail (MODEST_IS_WINDOW (window));
2247 modest_window_zoom_minus (MODEST_WINDOW (window));
2251 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2252 ModestWindow *window)
2254 ModestWindowMgr *mgr;
2255 gboolean fullscreen, active;
2256 g_return_if_fail (MODEST_IS_WINDOW (window));
2258 mgr = modest_runtime_get_window_mgr ();
2260 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2261 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2263 if (active != fullscreen) {
2264 modest_window_mgr_set_fullscreen_mode (mgr, active);
2265 gtk_window_present (GTK_WINDOW (window));
2270 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2271 ModestWindow *window)
2273 ModestWindowMgr *mgr;
2274 gboolean fullscreen;
2276 g_return_if_fail (MODEST_IS_WINDOW (window));
2278 mgr = modest_runtime_get_window_mgr ();
2279 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2280 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2282 gtk_window_present (GTK_WINDOW (window));
2286 * Used by modest_ui_actions_on_details to call do_headers_action
2289 headers_action_show_details (TnyHeader *header,
2290 ModestWindow *window,
2297 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2300 gtk_widget_show_all (dialog);
2301 gtk_dialog_run (GTK_DIALOG (dialog));
2303 gtk_widget_destroy (dialog);
2307 * Show the folder details in a ModestDetailsDialog widget
2310 show_folder_details (TnyFolder *folder,
2316 dialog = modest_details_dialog_new_with_folder (window, folder);
2319 gtk_widget_show_all (dialog);
2320 gtk_dialog_run (GTK_DIALOG (dialog));
2322 gtk_widget_destroy (dialog);
2326 * Show the header details in a ModestDetailsDialog widget
2329 modest_ui_actions_on_details (GtkAction *action,
2332 TnyList * headers_list;
2336 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2339 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2342 g_object_unref (msg);
2344 headers_list = get_selected_headers (win);
2348 iter = tny_list_create_iterator (headers_list);
2350 header = TNY_HEADER (tny_iterator_get_current (iter));
2351 headers_action_show_details (header, win, NULL);
2352 g_object_unref (header);
2354 g_object_unref (iter);
2355 g_object_unref (headers_list);
2357 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2358 GtkWidget *folder_view, *header_view;
2360 /* Check which widget has the focus */
2361 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2362 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2363 if (gtk_widget_is_focus (folder_view)) {
2366 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2368 /* Show only when it's a folder */
2369 if (!folder || !TNY_IS_FOLDER (folder))
2372 show_folder_details (folder, GTK_WINDOW (win));
2375 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2376 MODEST_WIDGET_TYPE_HEADER_VIEW);
2377 /* Show details of each header */
2378 do_headers_action (win, headers_action_show_details, header_view);
2384 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2385 ModestMsgEditWindow *window)
2387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2389 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2393 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2394 ModestMsgEditWindow *window)
2396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2398 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2402 modest_ui_actions_toggle_folders_view (GtkAction *action,
2403 ModestMainWindow *main_window)
2407 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2409 conf = modest_runtime_get_conf ();
2411 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2412 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2414 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2418 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2419 ModestWindow *window)
2421 gboolean active, fullscreen = FALSE;
2422 ModestWindowMgr *mgr;
2424 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2426 /* Check if we want to toggle the toolbar vuew in fullscreen
2428 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2429 "ViewShowToolbarFullScreen")) {
2433 /* Toggle toolbar */
2434 mgr = modest_runtime_get_window_mgr ();
2435 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2439 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2440 ModestMsgEditWindow *window)
2442 modest_msg_edit_window_select_font (window);
2446 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2447 const gchar *display_name,
2450 /* Do not change the application name if the widget has not
2451 the focus. This callback could be called even if the folder
2452 view has not the focus, because the handled signal could be
2453 emitted when the folder view is redrawn */
2454 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2456 gtk_window_set_title (window, display_name);
2458 gtk_window_set_title (window, " ");
2463 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2465 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2466 modest_msg_edit_window_select_contacts (window);
2470 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2472 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2473 modest_msg_edit_window_check_names (window);
2478 create_move_to_dialog (ModestWindow *win,
2479 GtkWidget *folder_view,
2480 GtkWidget **tree_view)
2482 GtkWidget *dialog, *scroll;
2484 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2486 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2488 GTK_RESPONSE_ACCEPT,
2490 GTK_RESPONSE_REJECT,
2493 /* Create scrolled window */
2494 scroll = gtk_scrolled_window_new (NULL, NULL);
2495 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2496 GTK_POLICY_AUTOMATIC,
2497 GTK_POLICY_AUTOMATIC);
2499 /* Create folder view */
2500 *tree_view = modest_folder_view_new (NULL);
2501 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2502 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2503 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2505 /* Add scroll to dialog */
2506 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2507 scroll, FALSE, FALSE, 0);
2509 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2515 * Returns TRUE if at least one of the headers of the list belongs to
2516 * a message that has been fully retrieved.
2519 has_retrieved_msgs (TnyList *list)
2522 gboolean found = FALSE;
2524 iter = tny_list_create_iterator (list);
2525 while (tny_iterator_is_done (iter) && !found) {
2527 TnyHeaderFlags flags;
2529 header = TNY_HEADER (tny_iterator_get_current (iter));
2530 flags = tny_header_get_flags (header);
2531 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2535 tny_iterator_next (iter);
2537 g_object_unref (iter);
2543 * Shows a confirmation dialog to the user when we're moving messages
2544 * from a remote server to the local storage. Returns the dialog
2545 * response. If it's other kind of movement the it always returns
2549 msgs_move_to_confirmation (GtkWindow *win,
2550 TnyFolder *dest_folder,
2553 gint response = GTK_RESPONSE_OK;
2555 /* If the destination is a local folder */
2556 if (modest_tny_folder_is_local_folder (dest_folder)) {
2557 TnyFolder *src_folder;
2561 /* Get source folder */
2562 iter = tny_list_create_iterator (headers);
2563 header = TNY_HEADER (tny_iterator_get_current (iter));
2564 src_folder = tny_header_get_folder (header);
2565 g_object_unref (header);
2566 g_object_unref (iter);
2568 /* If the source is a remote folder */
2569 if (!modest_tny_folder_is_local_folder (src_folder)) {
2570 const gchar *message;
2572 if (tny_list_get_length (headers) == 1)
2573 if (has_retrieved_msgs (headers))
2574 message = _("mcen_nc_move_retrieve");
2576 message = _("mcen_nc_move_header");
2578 if (has_retrieved_msgs (headers))
2579 message = _("mcen_nc_move_retrieves");
2581 message = _("mcen_nc_move_headers");
2583 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2584 (const gchar *) message);
2586 g_object_unref (src_folder);
2593 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2595 ModestMsgViewWindow *self = NULL;
2596 gboolean found = FALSE;
2598 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2599 self = MODEST_MSG_VIEW_WINDOW (object);
2601 found = modest_msg_view_window_select_first_message (self);
2602 g_return_if_fail (found);
2606 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2609 GObject *win = modest_mail_operation_get_source (mail_op);
2611 /* TODO: show error message */
2612 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2613 _("mail_in_ui_folder_move_target_error"));
2617 * UI handler for the "Move to" action when invoked from the
2621 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2622 ModestMainWindow *win)
2624 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2625 GtkWidget *header_view = NULL;
2627 TnyFolderStore *folder_store = NULL;
2628 ModestMailOperation *mail_op = NULL;
2630 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2632 /* Get the folder view */
2633 folder_view = modest_main_window_get_child_widget (win,
2634 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2636 /* Get header view */
2637 header_view = modest_main_window_get_child_widget (win,
2638 MODEST_WIDGET_TYPE_HEADER_VIEW);
2640 /* Create and run the dialog */
2641 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2642 result = gtk_dialog_run (GTK_DIALOG(dialog));
2643 g_object_ref (tree_view);
2645 /* We do this to save an indentation level ;-) */
2646 if (result != GTK_RESPONSE_ACCEPT)
2649 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2651 if (TNY_IS_ACCOUNT (folder_store))
2654 /* Get folder or messages to transfer */
2655 if (gtk_widget_is_focus (folder_view)) {
2656 TnyFolderStore *src_folder;
2657 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2659 /* Clean folder on header view before moving it */
2660 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2662 if (TNY_IS_FOLDER (src_folder)) {
2664 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2666 modest_ui_actions_move_folder_error_handler,
2668 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2670 modest_mail_operation_xfer_folder (mail_op,
2671 TNY_FOLDER (src_folder),
2674 /* Unref mail operation */
2675 g_object_unref (G_OBJECT (mail_op));
2679 g_object_unref (G_OBJECT (src_folder));
2681 if (gtk_widget_is_focus (header_view)) {
2685 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2687 /* Ask for user confirmation */
2688 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2689 TNY_FOLDER (folder_store),
2692 /* Transfer messages */
2693 if (response == GTK_RESPONSE_OK) {
2694 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2695 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2698 modest_mail_operation_xfer_msgs (mail_op,
2700 TNY_FOLDER (folder_store),
2705 g_object_unref (G_OBJECT (mail_op));
2707 g_object_unref (headers);
2710 g_object_unref (folder_store);
2712 gtk_widget_destroy (dialog);
2717 * UI handler for the "Move to" action when invoked from the
2718 * ModestMsgViewWindow
2721 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2722 ModestMsgViewWindow *win)
2724 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2726 ModestMainWindow *main_window;
2730 /* Get the folder view */
2731 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2732 folder_view = modest_main_window_get_child_widget (main_window,
2733 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2735 /* Create and run the dialog */
2736 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2737 result = gtk_dialog_run (GTK_DIALOG(dialog));
2738 g_object_ref (tree_view);
2740 if (result == GTK_RESPONSE_ACCEPT) {
2741 TnyFolderStore *folder_store;
2744 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2746 /* Create header list */
2747 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2748 headers = tny_simple_list_new ();
2749 tny_list_prepend (headers, G_OBJECT (header));
2750 g_object_unref (header);
2752 /* Ask user for confirmation. MSG-NOT404 */
2753 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2754 TNY_FOLDER (folder_store),
2757 /* Transfer current msg */
2758 if (response == GTK_RESPONSE_OK) {
2759 ModestMailOperation *mail_op;
2761 /* Create mail op */
2762 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2763 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2766 /* Transfer messages */
2767 modest_mail_operation_xfer_msgs (mail_op,
2769 TNY_FOLDER (folder_store),
2771 tranasfer_msgs_from_viewer_cb,
2773 g_object_unref (G_OBJECT (mail_op));
2775 g_object_unref (headers);
2776 g_object_unref (folder_store);
2778 gtk_widget_destroy (dialog);
2782 modest_ui_actions_on_move_to (GtkAction *action,
2785 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2786 MODEST_IS_MSG_VIEW_WINDOW (win));
2788 if (MODEST_IS_MAIN_WINDOW (win))
2789 modest_ui_actions_on_main_window_move_to (action,
2790 MODEST_MAIN_WINDOW (win));
2792 modest_ui_actions_on_msg_view_window_move_to (action,
2793 MODEST_MSG_VIEW_WINDOW (win));
2797 * Calls #HeadersFunc for each header already selected in the main
2798 * window or the message currently being shown in the msg view window
2801 do_headers_action (ModestWindow *win,
2805 TnyList *headers_list;
2809 headers_list = get_selected_headers (win);
2813 /* Call the function for each header */
2814 iter = tny_list_create_iterator (headers_list);
2815 while (!tny_iterator_is_done (iter)) {
2818 header = TNY_HEADER (tny_iterator_get_current (iter));
2819 func (header, win, user_data);
2820 g_object_unref (header);
2821 tny_iterator_next (iter);
2823 g_object_unref (iter);
2824 g_object_unref (headers_list);
2828 modest_ui_actions_view_attachment (GtkAction *action,
2829 ModestWindow *window)
2831 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2832 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2834 /* not supported window for this action */
2835 g_return_if_reached ();
2840 modest_ui_actions_save_attachments (GtkAction *action,
2841 ModestWindow *window)
2843 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2844 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2846 /* not supported window for this action */
2847 g_return_if_reached ();
2852 modest_ui_actions_remove_attachments (GtkAction *action,
2853 ModestWindow *window)
2855 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2856 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2858 /* not supported window for this action */
2859 g_return_if_reached ();
2864 modest_ui_actions_on_settings (GtkAction *action,
2869 dialog = modest_platform_get_global_settings_dialog ();
2870 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2871 gtk_widget_show (dialog);
2873 gtk_dialog_run (GTK_DIALOG (dialog));
2875 gtk_widget_destroy (dialog);
2879 modest_ui_actions_on_help (GtkAction *action,
2882 const gchar *help_id = NULL;
2884 if (MODEST_IS_MAIN_WINDOW (win)) {
2885 const gchar *action_name;
2886 action_name = gtk_action_get_name (action);
2888 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2889 !strcmp (action_name, "HeaderViewCSMHelp")) {
2890 GtkWidget *folder_view;
2891 TnyFolderStore *folder_store;
2892 /* Get selected folder */
2893 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2894 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2895 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2897 /* Switch help_id */
2898 if (TNY_IS_FOLDER (folder_store)) {
2899 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2900 case TNY_FOLDER_TYPE_NORMAL:
2901 help_id = "applications_email_userfolder";
2903 case TNY_FOLDER_TYPE_INBOX:
2904 help_id = "applications_email_inbox";
2906 case TNY_FOLDER_TYPE_OUTBOX:
2907 help_id = "applications_email_outbox";
2909 case TNY_FOLDER_TYPE_SENT:
2910 help_id = "applications_email_sent";
2912 case TNY_FOLDER_TYPE_DRAFTS:
2913 help_id = "applications_email_drafts";
2915 case TNY_FOLDER_TYPE_ARCHIVE:
2916 help_id = "applications_email_archive";
2923 help_id = "applications_email_mainview";
2925 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2926 help_id = "applications_email_viewer";
2927 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2928 help_id = "applications_email_editor";
2930 modest_platform_show_help (GTK_WINDOW (win), help_id);
2934 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2935 ModestWindow *window)
2937 ModestMailOperation *mail_op;
2941 headers = get_selected_headers (window);
2945 /* Create mail operation */
2946 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2948 modest_ui_actions_get_msgs_full_error_handler,
2950 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2951 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2954 g_object_unref (headers);
2955 g_object_unref (mail_op);
2959 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2960 ModestWindow *window)
2962 g_return_if_fail (MODEST_IS_WINDOW (window));
2965 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2969 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2970 ModestWindow *window)
2972 g_return_if_fail (MODEST_IS_WINDOW (window));
2975 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2979 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2980 ModestWindow *window)
2982 g_return_if_fail (MODEST_IS_WINDOW (window));
2985 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2989 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2990 ModestWindow *window)
2992 g_return_if_fail (MODEST_IS_WINDOW (window));
2995 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2999 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3000 ModestWindow *window)
3002 g_return_if_fail (MODEST_IS_WINDOW (window));
3005 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3009 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3011 g_return_if_fail (MODEST_IS_WINDOW (window));
3014 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");