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>
36 #include <modest-runtime.h>
37 #include <modest-tny-folder.h>
38 #include <modest-tny-msg.h>
39 #include <modest-tny-account.h>
40 #include <modest-address-book.h>
42 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
47 #ifdef MODEST_PLATFORM_MAEMO
48 #include "maemo/modest-osso-state-saving.h"
49 #endif /* MODEST_PLATFORM_MAEMO */
51 #include "widgets/modest-ui-constants.h"
52 #include <widgets/modest-main-window.h>
53 #include <widgets/modest-msg-view-window.h>
54 #include <widgets/modest-account-view-window.h>
55 #include <widgets/modest-details-dialog.h>
56 #include <widgets/modest-attachments-view.h>
57 #include "widgets/modest-global-settings-dialog.h"
58 #include "modest-connection-specific-smtp-window.h"
59 #include "modest-account-mgr-helpers.h"
60 #include "modest-mail-operation.h"
61 #include "modest-text-utils.h"
63 #ifdef MODEST_HAVE_EASYSETUP
64 #include "easysetup/modest-easysetup-wizard.h"
65 #endif /* MODEST_HAVE_EASYSETUP */
67 #include <modest-widget-memory.h>
68 #include <tny-error.h>
69 #include <tny-simple-list.h>
70 #include <tny-msg-view.h>
71 #include <tny-device.h>
72 #include <tny-merge-folder.h>
74 typedef struct _GetMsgAsyncHelper {
76 ModestMailOperation *mail_op;
83 typedef enum _ReplyForwardAction {
89 typedef struct _ReplyForwardHelper {
90 guint reply_forward_type;
91 ReplyForwardAction action;
96 * The do_headers_action uses this kind of functions to perform some
97 * action to each member of a list of headers
99 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
102 do_headers_action (ModestWindow *win,
107 static void open_msg_cb (ModestMailOperation *mail_op,
112 static void reply_forward_cb (ModestMailOperation *mail_op,
117 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
119 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
122 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
125 const gchar *authors[] = {
126 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
129 about = gtk_about_dialog_new ();
130 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
131 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
132 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
133 _("Copyright (c) 2006, Nokia Corporation\n"
134 "All rights reserved."));
135 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
136 _("a modest e-mail client\n\n"
137 "design and implementation: Dirk-Jan C. Binnema\n"
138 "contributions from the fine people at KC and Ig\n"
139 "uses the tinymail email framework written by Philip van Hoof"));
140 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
141 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
143 gtk_dialog_run (GTK_DIALOG (about));
144 gtk_widget_destroy(about);
148 * Gets the list of currently selected messages. If the win is the
149 * main window, then it returns a newly allocated list of the headers
150 * selected in the header view. If win is the msg view window, then
151 * the value returned is a list with just a single header.
153 * The caller of this funcion must free the list.
156 get_selected_headers (ModestWindow *win)
158 if (MODEST_IS_MAIN_WINDOW(win)) {
159 GtkWidget *header_view;
161 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
162 MODEST_WIDGET_TYPE_HEADER_VIEW);
163 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
165 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
166 /* for MsgViewWindows, we simply return a list with one element */
168 TnyList *list = NULL;
170 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
171 if (header != NULL) {
172 list = tny_simple_list_new ();
173 tny_list_prepend (list, G_OBJECT(header));
174 g_object_unref (G_OBJECT(header));
184 headers_action_mark_as_read (TnyHeader *header,
188 TnyHeaderFlags flags;
190 g_return_if_fail (TNY_IS_HEADER(header));
192 flags = tny_header_get_flags (header);
193 if (flags & TNY_HEADER_FLAG_SEEN) return;
194 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
198 headers_action_mark_as_unread (TnyHeader *header,
202 TnyHeaderFlags flags;
204 g_return_if_fail (TNY_IS_HEADER(header));
206 flags = tny_header_get_flags (header);
207 if (flags & TNY_HEADER_FLAG_SEEN) {
208 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
214 headers_action_delete (TnyHeader *header,
218 ModestMailOperation *mail_op = NULL;
220 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
221 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
224 /* Always delete. TODO: Move to trash still not supported */
225 modest_mail_operation_remove_msg (mail_op, header, FALSE);
226 g_object_unref (G_OBJECT (mail_op));
230 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
232 TnyList *header_list = NULL;
233 TnyIterator *iter = NULL;
234 TnyHeader *header = NULL;
235 gchar *message = NULL;
239 g_return_if_fail (MODEST_IS_WINDOW(win));
241 header_list = get_selected_headers (win);
242 if (!header_list) return;
245 if (tny_list_get_length(header_list) > 1)
246 message = g_strdup(_("emev_nc_delete_messages"));
248 iter = tny_list_create_iterator (header_list);
249 header = TNY_HEADER (tny_iterator_get_current (iter));
250 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
251 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
254 /* Confirmation dialog */
255 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
259 if (response == GTK_RESPONSE_OK) {
260 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
262 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
266 /* Remove each header */
267 do_headers_action (win, headers_action_delete, NULL);
269 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
270 gtk_widget_destroy (GTK_WIDGET(win));
277 g_object_unref (header_list);
278 g_object_unref (iter);
283 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
285 #ifdef MODEST_PLATFORM_MAEMO
286 modest_osso_save_state();
287 #endif /* MODEST_PLATFORM_MAEMO */
293 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
295 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
296 gtk_widget_destroy (GTK_WIDGET (win));
297 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
299 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
300 } else if (MODEST_IS_WINDOW (win)) {
301 gtk_widget_destroy (GTK_WIDGET (win));
303 g_return_if_reached ();
308 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
310 GtkClipboard *clipboard = NULL;
311 gchar *selection = NULL;
313 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
314 selection = gtk_clipboard_wait_for_text (clipboard);
316 modest_address_book_add_address (selection);
321 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
323 /* This is currently only implemented for Maemo,
324 * because it requires a providers preset file which is not publically available.
326 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
327 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
328 TRUE /* enabled accounts only */);
329 gboolean accounts_exist = account_names != NULL;
330 g_slist_free (account_names);
332 if (!accounts_exist) {
333 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
334 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
335 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
336 gtk_dialog_run (GTK_DIALOG (wizard));
337 gtk_widget_destroy (GTK_WIDGET (wizard));
339 /* Show the list of accounts: */
340 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
341 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
342 gtk_dialog_run (account_win);
343 gtk_widget_destroy (GTK_WIDGET(account_win));
346 GtkWidget *dialog, *label;
348 /* Create the widgets */
350 dialog = gtk_dialog_new_with_buttons ("Message",
352 GTK_DIALOG_DESTROY_WITH_PARENT,
356 label = gtk_label_new ("Hello World!");
358 /* Ensure that the dialog box is destroyed when the user responds. */
360 g_signal_connect_swapped (dialog, "response",
361 G_CALLBACK (gtk_widget_destroy),
364 /* Add the label, and show everything we've added to the dialog. */
366 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
368 gtk_widget_show_all (dialog);
369 #endif /* MODEST_PLATFORM_MAEMO */
373 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
375 ModestWindow *main_window = MODEST_WINDOW (user_data);
377 /* Save any changes. */
378 modest_connection_specific_smtp_window_save_server_accounts (
379 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
380 modest_window_get_active_account (main_window));
381 gtk_widget_destroy (GTK_WIDGET (window));
385 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
387 /* This is currently only implemented for Maemo,
388 * because it requires an API (libconic) to detect different connection
391 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
393 /* Create the window if necessary: */
394 const gchar *active_account_name = modest_window_get_active_account (win);
396 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
397 * or show the default account?
398 * If we show the default account then the account name should be shown in
399 * the window when we show it. */
400 if (!active_account_name) {
401 g_warning ("%s: No account is active.", __FUNCTION__);
405 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
406 modest_connection_specific_smtp_window_fill_with_connections (
407 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
408 modest_runtime_get_account_mgr(),
409 active_account_name);
411 /* Show the window: */
412 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
413 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
414 gtk_widget_show (specific_window);
416 /* Save changes when the window is hidden: */
417 g_signal_connect (specific_window, "hide",
418 G_CALLBACK (on_smtp_servers_window_hide), win);
419 #endif /* MODEST_PLATFORM_MAEMO */
423 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
425 ModestWindow *msg_win;
427 TnyFolder *folder = NULL;
428 gchar *account_name = NULL;
429 gchar *from_str = NULL;
430 /* GError *err = NULL; */
431 TnyAccount *account = NULL;
432 ModestWindowMgr *mgr;
433 gchar *signature = NULL;
435 account_name = g_strdup(modest_window_get_active_account (win));
437 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
439 g_printerr ("modest: no account found\n");
443 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
445 TNY_ACCOUNT_TYPE_STORE);
447 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
451 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
453 g_printerr ("modest: failed get from string for '%s'\n", account_name);
457 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
458 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
459 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
460 MODEST_ACCOUNT_SIGNATURE, FALSE);
462 signature = g_strdup ("");
465 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
467 g_printerr ("modest: failed to create new msg\n");
471 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
473 g_printerr ("modest: failed to find Drafts folder\n");
477 /* tny_folder_add_msg (folder, msg, &err); */
479 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
481 /* g_error_free (err); */
485 /* Create and register edit window */
486 /* This is destroyed by TOOD. */
487 msg_win = modest_msg_edit_window_new (msg, account_name);
488 mgr = modest_runtime_get_window_mgr ();
489 modest_window_mgr_register_window (mgr, msg_win);
492 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
494 gtk_widget_show_all (GTK_WIDGET (msg_win));
497 g_free (account_name);
501 g_object_unref (G_OBJECT(account));
503 g_object_unref (G_OBJECT(msg));
505 g_object_unref (G_OBJECT(folder));
509 open_msg_cb (ModestMailOperation *mail_op,
514 ModestWindowMgr *mgr = NULL;
515 ModestWindow *parent_win = NULL;
516 ModestWindow *win = NULL;
517 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
518 gchar *account = NULL;
521 /* TODO: Show an error? (review the specs) */
525 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
526 folder = tny_header_get_folder (header);
528 /* Mark header as read */
529 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
532 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
534 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
536 /* Gets folder type (OUTBOX headers will be opened in edit window */
537 if (modest_tny_folder_is_local_folder (folder))
538 folder_type = modest_tny_folder_get_local_folder_type (folder);
540 /* If the header is in the drafts folder then open the editor,
541 else the message view window */
542 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
543 win = modest_msg_edit_window_new (msg, account);
545 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
546 GtkWidget *header_view;
547 GtkTreeSelection *sel;
548 GList *sel_list = NULL;
551 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
552 MODEST_WIDGET_TYPE_HEADER_VIEW);
554 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
555 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
557 if (sel_list != NULL) {
558 GtkTreeRowReference *row_reference;
560 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
561 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
562 g_list_free (sel_list);
564 win = modest_msg_view_window_new_with_header_model (msg,
568 gtk_tree_row_reference_free (row_reference);
570 win = modest_msg_view_window_new (msg, account);
573 win = modest_msg_view_window_new (msg, account);
577 /* Register and show new window */
579 mgr = modest_runtime_get_window_mgr ();
580 modest_window_mgr_register_window (mgr, win);
581 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
582 gtk_widget_show_all (GTK_WIDGET(win));
587 g_object_unref (msg);
588 g_object_unref (folder);
589 g_object_unref (header);
593 * This function is used by both modest_ui_actions_on_open and
594 * modest_ui_actions_on_header_activated. This way we always do the
595 * same when trying to open messages.
598 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
600 ModestWindowMgr *mgr;
602 ModestMailOperation *mail_op;
604 /* Look if we already have a message view for each header. If
605 true, then remove the header from the list of headers to
607 mgr = modest_runtime_get_window_mgr ();
608 iter = tny_list_create_iterator (headers);
609 while (!tny_iterator_is_done (iter)) {
610 ModestWindow *window;
613 header = TNY_HEADER (tny_iterator_get_current (iter));
614 window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
616 tny_list_remove (headers, G_OBJECT (header));
618 g_object_unref (header);
619 tny_iterator_next (iter);
622 /* Open each message */
623 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT (win));
624 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
625 modest_mail_operation_get_msgs_full (mail_op,
632 g_object_unref(mail_op);
636 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
641 headers = get_selected_headers (win);
646 _modest_ui_actions_open (headers, win);
648 g_object_unref(headers);
653 free_reply_forward_helper (gpointer data)
655 ReplyForwardHelper *helper;
657 helper = (ReplyForwardHelper *) data;
658 g_free (helper->account_name);
659 g_slice_free (ReplyForwardHelper, helper);
663 reply_forward_cb (ModestMailOperation *mail_op,
669 ReplyForwardHelper *rf_helper;
670 ModestWindow *msg_win;
671 ModestEditType edit_type;
674 TnyFolder *folder = NULL;
675 TnyAccount *account = NULL;
676 ModestWindowMgr *mgr;
677 gchar *signature = NULL;
679 g_return_if_fail (user_data != NULL);
680 rf_helper = (ReplyForwardHelper *) user_data;
682 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
683 rf_helper->account_name);
684 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
685 rf_helper->account_name,
686 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
687 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
688 rf_helper->account_name,
689 MODEST_ACCOUNT_SIGNATURE, FALSE);
692 /* Create reply mail */
693 switch (rf_helper->action) {
696 modest_tny_msg_create_reply_msg (msg, from, signature,
697 rf_helper->reply_forward_type,
698 MODEST_TNY_MSG_REPLY_MODE_SENDER);
700 case ACTION_REPLY_TO_ALL:
702 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
703 MODEST_TNY_MSG_REPLY_MODE_ALL);
704 edit_type = MODEST_EDIT_TYPE_REPLY;
708 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
709 edit_type = MODEST_EDIT_TYPE_FORWARD;
712 g_return_if_reached ();
719 g_printerr ("modest: failed to create message\n");
723 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
724 rf_helper->account_name,
725 TNY_ACCOUNT_TYPE_STORE);
727 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
731 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
733 g_printerr ("modest: failed to find Drafts folder\n");
737 tny_folder_add_msg (folder, msg, &err);
739 g_printerr ("modest: error adding msg to Drafts folder: %s",
745 /* Create and register the windows */
746 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
747 mgr = modest_runtime_get_window_mgr ();
748 modest_window_mgr_register_window (mgr, msg_win);
750 /* Show edit window */
751 gtk_widget_show_all (GTK_WIDGET (msg_win));
755 g_object_unref (G_OBJECT (new_msg));
757 g_object_unref (G_OBJECT (folder));
759 g_object_unref (G_OBJECT (account));
760 g_object_unref (msg);
761 g_object_unref (header);
765 * Checks a list of headers. If any of them are not currently
766 * downloaded (CACHED) then it asks the user for permission to
769 * Returns FALSE if the user does not want to download the
770 * messages. Returns TRUE if the user allowed the download or if all
771 * of them are currently downloaded
774 download_uncached_messages (TnyList *header_list, GtkWindow *win)
777 gboolean found, retval;
779 iter = tny_list_create_iterator (header_list);
781 while (!tny_iterator_is_done (iter) && !found) {
783 TnyHeaderFlags flags;
785 header = TNY_HEADER (tny_iterator_get_current (iter));
786 flags = tny_header_get_flags (header);
787 /* TODO: is this the right flag?, it seems that some
788 headers that have been previously downloaded do not
790 found = !(flags & TNY_HEADER_FLAG_CACHED);
791 g_object_unref (header);
792 tny_iterator_next (iter);
794 g_object_unref (iter);
796 /* Ask for user permission to download the messages */
799 GtkResponseType response;
801 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
802 _("mcen_nc_get_multi_msg_txt"));
803 if (response == GTK_RESPONSE_CANCEL)
811 * Common code for the reply and forward actions
814 reply_forward (ReplyForwardAction action, ModestWindow *win)
816 ModestMailOperation *mail_op = NULL;
817 TnyList *header_list = NULL;
818 ReplyForwardHelper *rf_helper = NULL;
819 guint reply_forward_type;
820 gboolean continue_download;
822 g_return_if_fail (MODEST_IS_WINDOW(win));
824 header_list = get_selected_headers (win);
828 /* Check that the messages have been previously downloaded */
829 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
830 if (!continue_download) {
831 g_object_unref (header_list);
836 modest_conf_get_int (modest_runtime_get_conf (),
837 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
839 /* We assume that we can only select messages of the
840 same folder and that we reply all of them from the
841 same account. In fact the interface currently only
842 allows single selection */
845 rf_helper = g_slice_new0 (ReplyForwardHelper);
846 rf_helper->reply_forward_type = reply_forward_type;
847 rf_helper->action = action;
848 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
849 if (!rf_helper->account_name)
850 rf_helper->account_name =
851 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
853 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
856 /* Get header and message. Do not free them here, the
857 reply_forward_cb must do it */
858 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
859 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
860 if (!msg || !header) {
862 g_object_unref (msg);
864 g_object_unref (header);
865 g_printerr ("modest: no message found\n");
868 reply_forward_cb (NULL, header, msg, rf_helper);
870 /* Retrieve messages */
871 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
872 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
873 modest_mail_operation_get_msgs_full (mail_op,
877 free_reply_forward_helper);
880 g_object_unref(mail_op);
884 g_object_unref (header_list);
888 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
890 g_return_if_fail (MODEST_IS_WINDOW(win));
892 reply_forward (ACTION_REPLY, win);
896 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
898 g_return_if_fail (MODEST_IS_WINDOW(win));
900 reply_forward (ACTION_FORWARD, win);
904 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
906 g_return_if_fail (MODEST_IS_WINDOW(win));
908 reply_forward (ACTION_REPLY_TO_ALL, win);
912 modest_ui_actions_on_next (GtkAction *action,
913 ModestWindow *window)
915 if (MODEST_IS_MAIN_WINDOW (window)) {
916 GtkWidget *header_view;
918 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
919 MODEST_WIDGET_TYPE_HEADER_VIEW);
923 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
924 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
925 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
927 g_return_if_reached ();
932 modest_ui_actions_on_prev (GtkAction *action,
933 ModestWindow *window)
935 g_return_if_fail (MODEST_IS_WINDOW(window));
937 if (MODEST_IS_MAIN_WINDOW (window)) {
938 GtkWidget *header_view;
939 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
940 MODEST_WIDGET_TYPE_HEADER_VIEW);
944 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
945 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
946 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
948 g_return_if_reached ();
953 modest_ui_actions_on_sort (GtkAction *action,
954 ModestWindow *window)
956 g_return_if_fail (MODEST_IS_WINDOW(window));
958 if (MODEST_IS_MAIN_WINDOW (window)) {
959 GtkWidget *header_view;
960 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
961 MODEST_WIDGET_TYPE_HEADER_VIEW);
965 /* Show sorting dialog */
966 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
971 * This function performs the send & receive required actions. The
972 * window is used to create the mail operation. Typically it should
973 * always be the main window, but we pass it as argument in order to
977 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
979 gchar *acc_name = NULL;
980 ModestMailOperation *mail_op;
982 /* If no account name was provided then get the current account, and if
983 there is no current account then pick the default one: */
985 acc_name = g_strdup (modest_window_get_active_account(win));
987 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
989 g_printerr ("modest: cannot get default account\n");
993 acc_name = g_strdup (account_name);
996 /* Send & receive. */
997 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
998 /* Receive and then send. The operation is tagged initially as
999 a receive operation because the account update performs a
1000 receive and then a send. The operation changes its type
1001 internally, so the progress objects will receive the proper
1002 progress information */
1003 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1004 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1005 modest_mail_operation_update_account (mail_op, acc_name);
1006 g_object_unref (G_OBJECT (mail_op));
1013 * Refreshes all accounts. This function will be used by automatic
1017 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1019 GSList *account_names, *iter;
1021 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1024 iter = account_names;
1026 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1027 iter = g_slist_next (iter);
1030 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1031 g_slist_free (account_names);
1035 * Handler of the click on Send&Receive button in the main toolbar
1038 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1040 /* Check that at least one account exists: */
1041 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1042 TRUE /* enabled accounts only */);
1043 gboolean accounts_exist = account_names != NULL;
1044 g_slist_free (account_names);
1046 /* If not, allow the user to create an account before trying to send/receive. */
1047 if (!accounts_exist)
1048 modest_ui_actions_on_accounts (NULL, win);
1050 /* Refresh the active account */
1051 modest_ui_actions_do_send_receive (NULL, win);
1056 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1059 GtkWidget *header_view;
1061 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1063 header_view = modest_main_window_get_child_widget (main_window,
1064 MODEST_WIDGET_TYPE_HEADER_VIEW);
1068 conf = modest_runtime_get_conf ();
1070 /* what is saved/restored is depending on the style; thus; we save with
1071 * old style, then update the style, and restore for this new style
1073 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1075 if (modest_header_view_get_style
1076 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1077 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1078 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1080 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1081 MODEST_HEADER_VIEW_STYLE_DETAILS);
1083 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1084 MODEST_CONF_HEADER_VIEW_KEY);
1089 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1091 ModestMainWindow *main_window)
1093 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1095 /* If no header has been selected then exit */
1099 /* Update Main window title */
1100 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1101 const gchar *subject = tny_header_get_subject (header);
1102 if (subject && strcmp (subject, ""))
1103 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1105 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1110 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1112 ModestMainWindow *main_window)
1116 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1121 headers = tny_simple_list_new ();
1122 tny_list_prepend (headers, G_OBJECT (header));
1124 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1126 g_object_unref (headers);
1130 set_active_account_from_tny_account (TnyAccount *account,
1131 ModestWindow *window)
1133 const gchar *server_acc_name = tny_account_get_id (account);
1135 /* We need the TnyAccount provided by the
1136 account store because that is the one that
1137 knows the name of the Modest account */
1138 TnyAccount *modest_server_account = modest_server_account =
1139 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1142 const gchar *modest_acc_name =
1143 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1144 modest_window_set_active_account (window, modest_acc_name);
1145 g_object_unref (modest_server_account);
1149 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1150 TnyFolderStore *folder_store,
1152 ModestMainWindow *main_window)
1155 GtkWidget *header_view;
1157 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1159 header_view = modest_main_window_get_child_widget(main_window,
1160 MODEST_WIDGET_TYPE_HEADER_VIEW);
1164 conf = modest_runtime_get_conf ();
1166 if (TNY_IS_ACCOUNT (folder_store)) {
1167 /* Update active account */
1168 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1169 /* Show account details */
1170 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1171 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1172 printf ("DEBUG: %s: folder store.\n", __FUNCTION__);
1173 //TODO: Set the virtual folder store as the "active account" somehow:
1174 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1176 if (TNY_IS_FOLDER (folder_store) && selected) {
1178 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1179 /* Update the active account */
1180 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1181 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1182 g_object_unref (account);
1185 /* Set folder on header view */
1186 modest_main_window_set_contents_style (main_window,
1187 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1188 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1189 TNY_FOLDER (folder_store));
1190 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1191 MODEST_CONF_HEADER_VIEW_KEY);
1193 /* Update the active account */
1194 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1195 /* Do not show folder */
1196 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1197 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1203 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1210 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1212 if (g_main_depth > 0)
1213 gdk_threads_enter ();
1214 online = tny_device_is_online (modest_runtime_get_device());
1217 /* already online -- the item is simply not there... */
1218 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1220 GTK_MESSAGE_WARNING,
1222 _("The %s you selected cannot be found"),
1224 gtk_dialog_run (GTK_DIALOG(dialog));
1226 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1230 GTK_RESPONSE_REJECT,
1232 GTK_RESPONSE_ACCEPT,
1234 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1235 "Do you want to get online?"), item);
1236 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1237 gtk_label_new (txt), FALSE, FALSE, 0);
1238 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1241 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1242 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1243 // modest_platform_connect_and_wait ();;
1246 gtk_widget_destroy (dialog);
1247 if (g_main_depth > 0)
1248 gdk_threads_leave ();
1252 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1255 /* g_message ("%s %s", __FUNCTION__, link); */
1260 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1263 modest_platform_activate_uri (link);
1267 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1270 modest_platform_show_uri_popup (link);
1274 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1277 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1281 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1282 const gchar *address,
1285 /* g_message ("%s %s", __FUNCTION__, address); */
1289 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1291 TnyTransportAccount *transport_account;
1292 ModestMailOperation *mail_operation;
1294 gchar *account_name, *from;
1295 ModestAccountMgr *account_mgr;
1297 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1299 data = modest_msg_edit_window_get_msg_data (edit_window);
1301 account_mgr = modest_runtime_get_account_mgr();
1302 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1304 account_name = modest_account_mgr_get_default_account (account_mgr);
1305 if (!account_name) {
1306 g_printerr ("modest: no account found\n");
1307 modest_msg_edit_window_free_msg_data (edit_window, data);
1311 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1312 (modest_runtime_get_account_store(),
1314 TNY_ACCOUNT_TYPE_TRANSPORT));
1315 if (!transport_account) {
1316 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1317 g_free (account_name);
1318 modest_msg_edit_window_free_msg_data (edit_window, data);
1321 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1323 /* Create the mail operation */
1324 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1325 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1327 modest_mail_operation_save_to_drafts (mail_operation,
1337 data->priority_flags);
1340 g_free (account_name);
1341 g_object_unref (G_OBJECT (transport_account));
1342 g_object_unref (G_OBJECT (mail_operation));
1344 modest_msg_edit_window_free_msg_data (edit_window, data);
1346 /* Save settings and close the window */
1347 gtk_widget_destroy (GTK_WIDGET (edit_window));
1350 /* For instance, when clicking the Send toolbar button when editing a message: */
1352 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1354 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1356 if (!modest_msg_edit_window_check_names (edit_window))
1359 /* FIXME: Code added just for testing. The final version will
1360 use the send queue provided by tinymail and some
1362 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1363 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1365 account_name = modest_account_mgr_get_default_account (account_mgr);
1367 if (!account_name) {
1368 g_printerr ("modest: no account found\n");
1372 /* Get the currently-active transport account for this modest account: */
1373 TnyTransportAccount *transport_account =
1374 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1375 (modest_runtime_get_account_store(),
1377 if (!transport_account) {
1378 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1379 g_free (account_name);
1383 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1385 /* Create the mail operation */
1386 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1387 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1389 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1390 modest_mail_operation_send_new_mail (mail_operation,
1400 data->priority_flags);
1404 g_free (account_name);
1405 g_object_unref (G_OBJECT (transport_account));
1406 g_object_unref (G_OBJECT (mail_operation));
1408 modest_msg_edit_window_free_msg_data (edit_window, data);
1410 /* Save settings and close the window: */
1411 gtk_widget_destroy (GTK_WIDGET (edit_window));
1415 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1416 ModestMsgEditWindow *window)
1418 ModestMsgEditFormatState *format_state = NULL;
1420 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1421 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1423 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1426 format_state = modest_msg_edit_window_get_format_state (window);
1427 g_return_if_fail (format_state != NULL);
1429 format_state->bold = gtk_toggle_action_get_active (action);
1430 modest_msg_edit_window_set_format_state (window, format_state);
1431 g_free (format_state);
1436 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1437 ModestMsgEditWindow *window)
1439 ModestMsgEditFormatState *format_state = NULL;
1441 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1442 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1444 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1447 format_state = modest_msg_edit_window_get_format_state (window);
1448 g_return_if_fail (format_state != NULL);
1450 format_state->italics = gtk_toggle_action_get_active (action);
1451 modest_msg_edit_window_set_format_state (window, format_state);
1452 g_free (format_state);
1457 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1458 ModestMsgEditWindow *window)
1460 ModestMsgEditFormatState *format_state = NULL;
1462 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1463 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1465 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1468 format_state = modest_msg_edit_window_get_format_state (window);
1469 g_return_if_fail (format_state != NULL);
1471 format_state->bullet = gtk_toggle_action_get_active (action);
1472 modest_msg_edit_window_set_format_state (window, format_state);
1473 g_free (format_state);
1478 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1479 GtkRadioAction *selected,
1480 ModestMsgEditWindow *window)
1482 ModestMsgEditFormatState *format_state = NULL;
1483 GtkJustification value;
1485 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1487 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1490 value = gtk_radio_action_get_current_value (selected);
1492 format_state = modest_msg_edit_window_get_format_state (window);
1493 g_return_if_fail (format_state != NULL);
1495 format_state->justification = value;
1496 modest_msg_edit_window_set_format_state (window, format_state);
1497 g_free (format_state);
1501 modest_ui_actions_on_select_editor_color (GtkAction *action,
1502 ModestMsgEditWindow *window)
1504 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1505 g_return_if_fail (GTK_IS_ACTION (action));
1507 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1510 modest_msg_edit_window_select_color (window);
1514 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1515 ModestMsgEditWindow *window)
1517 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1518 g_return_if_fail (GTK_IS_ACTION (action));
1520 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1523 modest_msg_edit_window_select_background_color (window);
1527 modest_ui_actions_on_insert_image (GtkAction *action,
1528 ModestMsgEditWindow *window)
1530 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1531 g_return_if_fail (GTK_IS_ACTION (action));
1533 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1536 modest_msg_edit_window_insert_image (window);
1540 modest_ui_actions_on_attach_file (GtkAction *action,
1541 ModestMsgEditWindow *window)
1543 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1544 g_return_if_fail (GTK_IS_ACTION (action));
1546 modest_msg_edit_window_attach_file (window);
1550 modest_ui_actions_on_remove_attachments (GtkAction *action,
1551 ModestMsgEditWindow *window)
1553 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1554 g_return_if_fail (GTK_IS_ACTION (action));
1556 modest_msg_edit_window_remove_attachments (window, NULL);
1560 * Shows a dialog with an entry that asks for some text. The returned
1561 * value must be freed by the caller. The dialog window title will be
1565 ask_for_folder_name (GtkWindow *parent_window,
1568 GtkWidget *dialog, *entry;
1569 gchar *folder_name = NULL;
1571 /* Ask for folder name */
1572 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1576 GTK_RESPONSE_REJECT,
1578 GTK_RESPONSE_ACCEPT,
1580 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1581 gtk_label_new(title),
1584 entry = gtk_entry_new_with_max_length (40);
1585 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1589 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1591 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1592 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1594 gtk_widget_destroy (dialog);
1600 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1602 TnyFolderStore *parent_folder;
1603 GtkWidget *folder_view;
1605 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1607 folder_view = modest_main_window_get_child_widget (main_window,
1608 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1612 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1614 if (parent_folder) {
1615 gboolean finished = FALSE;
1617 gchar *folder_name = NULL, *suggested_name = NULL;
1619 /* Run the new folder dialog */
1621 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1626 if (result == GTK_RESPONSE_REJECT) {
1629 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1630 TnyFolder *new_folder = NULL;
1632 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1635 new_folder = modest_mail_operation_create_folder (mail_op,
1637 (const gchar *) folder_name);
1639 g_object_unref (new_folder);
1643 /* /\* TODO: check error and follow proper actions *\/ */
1644 /* /\* suggested_name = X; *\/ */
1645 /* /\* Show error to the user *\/ */
1646 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1647 /* _("mail_in_ui_folder_create_error")); */
1649 g_object_unref (mail_op);
1651 g_free (folder_name);
1655 g_object_unref (parent_folder);
1660 modest_ui_actions_on_rename_folder (GtkAction *action,
1661 ModestMainWindow *main_window)
1663 TnyFolderStore *folder;
1664 GtkWidget *folder_view;
1665 GtkWidget *header_view;
1667 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1669 folder_view = modest_main_window_get_child_widget (main_window,
1670 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1674 header_view = modest_main_window_get_child_widget (main_window,
1675 MODEST_WIDGET_TYPE_HEADER_VIEW);
1680 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1682 if (folder && TNY_IS_FOLDER (folder)) {
1684 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1685 _("Please enter a new name for the folder"));
1687 if (folder_name != NULL && strlen (folder_name) > 0) {
1688 ModestMailOperation *mail_op;
1690 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1691 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1694 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1696 modest_mail_operation_rename_folder (mail_op,
1697 TNY_FOLDER (folder),
1698 (const gchar *) folder_name);
1700 g_object_unref (mail_op);
1701 g_free (folder_name);
1703 g_object_unref (folder);
1708 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1710 TnyFolderStore *folder;
1711 GtkWidget *folder_view;
1715 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1717 folder_view = modest_main_window_get_child_widget (main_window,
1718 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1722 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1724 /* Show an error if it's an account */
1725 if (!TNY_IS_FOLDER (folder)) {
1726 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1727 _("mail_in_ui_folder_delete_error"));
1732 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1733 tny_folder_get_name (TNY_FOLDER (folder)));
1734 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1735 (const gchar *) message);
1738 if (response == GTK_RESPONSE_OK) {
1739 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(main_window));
1741 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1743 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1745 /* Show error if happened */
1746 if (modest_mail_operation_get_error (mail_op))
1747 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1748 _("mail_in_ui_folder_delete_error"));
1750 g_object_unref (G_OBJECT (mail_op));
1753 g_object_unref (G_OBJECT (folder));
1757 modest_ui_actions_on_delete_folder (GtkAction *action,
1758 ModestMainWindow *main_window)
1760 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1762 delete_folder (main_window, FALSE);
1766 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1768 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1770 delete_folder (main_window, TRUE);
1774 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1775 const gchar* server_account_name,
1780 ModestMainWindow *main_window)
1782 g_return_if_fail(server_account_name);
1783 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1785 /* Initalize output parameters: */
1792 #ifdef MODEST_PLATFORM_MAEMO
1793 /* Maemo uses a different (awkward) button order,
1794 * It should probably just use gtk_alternative_dialog_button_order ().
1796 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1800 GTK_RESPONSE_ACCEPT,
1802 GTK_RESPONSE_REJECT,
1805 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1809 GTK_RESPONSE_REJECT,
1811 GTK_RESPONSE_ACCEPT,
1813 #endif /* MODEST_PLATFORM_MAEMO */
1815 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1817 gchar *server_name = modest_server_account_get_hostname (
1818 modest_runtime_get_account_mgr(), server_account_name);
1820 /* This causes a warning because the logical ID has no %s in it,
1821 * though the translation does, but there is not much we can do about that: */
1822 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1823 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1826 g_free (server_name);
1830 gchar *initial_username = modest_server_account_get_username (
1831 modest_runtime_get_account_mgr(), server_account_name);
1833 GtkWidget *entry_username = gtk_entry_new ();
1834 if (initial_username)
1835 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1836 /* Dim this if a connection has ever succeeded with this username,
1837 * as per the UI spec: */
1838 const gboolean username_known =
1839 modest_server_account_get_username_has_succeeded(
1840 modest_runtime_get_account_mgr(), server_account_name);
1841 gtk_widget_set_sensitive (entry_username, !username_known);
1843 #ifdef MODEST_PLATFORM_MAEMO
1844 /* Auto-capitalization is the default, so let's turn it off: */
1845 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1847 /* Create a size group to be used by all captions.
1848 * Note that HildonCaption does not create a default size group if we do not specify one.
1849 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1850 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1852 GtkWidget *caption = hildon_caption_new (sizegroup,
1853 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1854 gtk_widget_show (entry_username);
1855 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1856 FALSE, FALSE, MODEST_MARGIN_HALF);
1857 gtk_widget_show (caption);
1859 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1861 #endif /* MODEST_PLATFORM_MAEMO */
1864 GtkWidget *entry_password = gtk_entry_new ();
1865 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1866 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1868 #ifdef MODEST_PLATFORM_MAEMO
1869 /* Auto-capitalization is the default, so let's turn it off: */
1870 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1871 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1873 caption = hildon_caption_new (sizegroup,
1874 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1875 gtk_widget_show (entry_password);
1876 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1877 FALSE, FALSE, MODEST_MARGIN_HALF);
1878 gtk_widget_show (caption);
1879 g_object_unref (sizegroup);
1881 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1883 #endif /* MODEST_PLATFORM_MAEMO */
1885 /* This is not in the Maemo UI spec:
1886 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1887 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1891 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1893 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1895 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1897 modest_server_account_set_username (
1898 modest_runtime_get_account_mgr(), server_account_name,
1901 const gboolean username_was_changed =
1902 (strcmp (*username, initial_username) != 0);
1903 if (username_was_changed) {
1904 /* To actually use a changed username,
1905 * we must reset the connection, according to pvanhoof.
1906 * This _might_ be a sensible way to do that: */
1907 TnyDevice *device = modest_runtime_get_device();
1908 tny_device_force_offline (device);
1909 tny_device_force_online (device);
1914 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1916 /* We do not save the password in the configuration,
1917 * because this function is only called for passwords that should
1918 * not be remembered:
1919 modest_server_account_set_password (
1920 modest_runtime_get_account_mgr(), server_account_name,
1939 /* This is not in the Maemo UI spec:
1940 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1946 gtk_widget_destroy (dialog);
1948 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
1952 modest_ui_actions_on_cut (GtkAction *action,
1953 ModestWindow *window)
1955 GtkWidget *focused_widget;
1957 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1958 if (GTK_IS_EDITABLE (focused_widget)) {
1959 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1960 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1961 GtkTextBuffer *buffer;
1962 GtkClipboard *clipboard;
1964 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1965 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1966 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1971 modest_ui_actions_on_copy (GtkAction *action,
1972 ModestWindow *window)
1974 GtkClipboard *clipboard;
1975 GtkWidget *focused_widget;
1977 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1978 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1979 if (GTK_IS_LABEL (focused_widget)) {
1980 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1981 } else if (GTK_IS_EDITABLE (focused_widget)) {
1982 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1983 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1984 GtkTextBuffer *buffer;
1986 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1987 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1992 modest_ui_actions_on_undo (GtkAction *action,
1993 ModestWindow *window)
1995 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1996 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1998 g_return_if_reached ();
2003 modest_ui_actions_on_paste (GtkAction *action,
2004 ModestWindow *window)
2006 GtkWidget *focused_widget;
2008 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2009 if (GTK_IS_EDITABLE (focused_widget)) {
2010 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2011 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2012 GtkTextBuffer *buffer;
2013 GtkClipboard *clipboard;
2015 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2016 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2017 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2022 modest_ui_actions_on_select_all (GtkAction *action,
2023 ModestWindow *window)
2025 GtkWidget *focused_widget;
2027 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2028 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2029 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2030 } else if (GTK_IS_LABEL (focused_widget)) {
2031 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2032 } else if (GTK_IS_EDITABLE (focused_widget)) {
2033 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2034 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2035 GtkTextBuffer *buffer;
2036 GtkTextIter start, end;
2038 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2039 gtk_text_buffer_get_start_iter (buffer, &start);
2040 gtk_text_buffer_get_end_iter (buffer, &end);
2041 gtk_text_buffer_select_range (buffer, &start, &end);
2046 modest_ui_actions_on_mark_as_read (GtkAction *action,
2047 ModestWindow *window)
2049 g_return_if_fail (MODEST_IS_WINDOW(window));
2051 /* Mark each header as read */
2052 do_headers_action (window, headers_action_mark_as_read, NULL);
2056 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2057 ModestWindow *window)
2059 g_return_if_fail (MODEST_IS_WINDOW(window));
2061 /* Mark each header as read */
2062 do_headers_action (window, headers_action_mark_as_unread, NULL);
2066 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2067 GtkRadioAction *selected,
2068 ModestWindow *window)
2072 value = gtk_radio_action_get_current_value (selected);
2073 if (MODEST_IS_WINDOW (window)) {
2074 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2078 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2079 GtkRadioAction *selected,
2080 ModestWindow *window)
2082 TnyHeaderFlags flags;
2083 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2085 flags = gtk_radio_action_get_current_value (selected);
2086 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2089 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2090 GtkRadioAction *selected,
2091 ModestWindow *window)
2095 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2097 file_format = gtk_radio_action_get_current_value (selected);
2098 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2103 modest_ui_actions_on_zoom_plus (GtkAction *action,
2104 ModestWindow *window)
2106 g_return_if_fail (MODEST_IS_WINDOW (window));
2108 modest_window_zoom_plus (MODEST_WINDOW (window));
2112 modest_ui_actions_on_zoom_minus (GtkAction *action,
2113 ModestWindow *window)
2115 g_return_if_fail (MODEST_IS_WINDOW (window));
2117 modest_window_zoom_minus (MODEST_WINDOW (window));
2121 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2122 ModestWindow *window)
2124 ModestWindowMgr *mgr;
2125 gboolean fullscreen, active;
2126 g_return_if_fail (MODEST_IS_WINDOW (window));
2128 mgr = modest_runtime_get_window_mgr ();
2130 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2131 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2133 if (active != fullscreen) {
2134 modest_window_mgr_set_fullscreen_mode (mgr, active);
2135 gtk_window_present (GTK_WINDOW (window));
2140 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2141 ModestWindow *window)
2143 ModestWindowMgr *mgr;
2144 gboolean fullscreen;
2146 g_return_if_fail (MODEST_IS_WINDOW (window));
2148 mgr = modest_runtime_get_window_mgr ();
2149 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2150 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2152 gtk_window_present (GTK_WINDOW (window));
2156 * Used by modest_ui_actions_on_details to call do_headers_action
2159 headers_action_show_details (TnyHeader *header,
2160 ModestWindow *window,
2167 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2170 gtk_widget_show_all (dialog);
2171 gtk_dialog_run (GTK_DIALOG (dialog));
2173 gtk_widget_destroy (dialog);
2177 * Show the folder details in a ModestDetailsDialog widget
2180 show_folder_details (TnyFolder *folder,
2186 dialog = modest_details_dialog_new_with_folder (window, folder);
2189 gtk_widget_show_all (dialog);
2190 gtk_dialog_run (GTK_DIALOG (dialog));
2192 gtk_widget_destroy (dialog);
2196 * Show the header details in a ModestDetailsDialog widget
2199 modest_ui_actions_on_details (GtkAction *action,
2202 TnyList * headers_list;
2206 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2209 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2212 g_object_unref (msg);
2214 headers_list = get_selected_headers (win);
2218 iter = tny_list_create_iterator (headers_list);
2220 header = TNY_HEADER (tny_iterator_get_current (iter));
2221 headers_action_show_details (header, win, NULL);
2222 g_object_unref (header);
2224 g_object_unref (iter);
2225 g_object_unref (headers_list);
2227 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2228 GtkWidget *folder_view, *header_view;
2230 /* Check which widget has the focus */
2231 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2232 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2233 if (gtk_widget_is_focus (folder_view)) {
2236 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2238 /* Show only when it's a folder */
2239 if (!folder || !TNY_IS_FOLDER (folder))
2242 show_folder_details (folder, GTK_WINDOW (win));
2245 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2246 MODEST_WIDGET_TYPE_HEADER_VIEW);
2247 /* Show details of each header */
2248 do_headers_action (win, headers_action_show_details, header_view);
2254 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2255 ModestMsgEditWindow *window)
2257 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2259 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2263 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2264 ModestMsgEditWindow *window)
2266 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2268 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2272 modest_ui_actions_toggle_folders_view (GtkAction *action,
2273 ModestMainWindow *main_window)
2277 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2279 conf = modest_runtime_get_conf ();
2281 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2282 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2284 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2288 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2289 ModestWindow *window)
2291 gboolean active, fullscreen = FALSE;
2292 ModestWindowMgr *mgr;
2294 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2296 /* Check if we want to toggle the toolbar vuew in fullscreen
2298 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2299 "ViewShowToolbarFullScreen")) {
2303 /* Toggle toolbar */
2304 mgr = modest_runtime_get_window_mgr ();
2305 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2309 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2310 ModestMsgEditWindow *window)
2312 modest_msg_edit_window_select_font (window);
2316 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2317 const gchar *display_name,
2320 /* Do not change the application name if the widget has not
2321 the focus. This callback could be called even if the folder
2322 view has not the focus, because the handled signal could be
2323 emitted when the folder view is redrawn */
2324 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2326 gtk_window_set_title (window, display_name);
2328 gtk_window_set_title (window, " ");
2333 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2335 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2336 modest_msg_edit_window_select_contacts (window);
2340 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2342 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2343 modest_msg_edit_window_check_names (window);
2348 create_move_to_dialog (ModestWindow *win,
2349 GtkWidget *folder_view,
2350 GtkWidget **tree_view)
2352 GtkWidget *dialog, *scroll;
2354 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2356 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2358 GTK_RESPONSE_ACCEPT,
2360 GTK_RESPONSE_REJECT,
2363 /* Create scrolled window */
2364 scroll = gtk_scrolled_window_new (NULL, NULL);
2365 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2366 GTK_POLICY_AUTOMATIC,
2367 GTK_POLICY_AUTOMATIC);
2369 /* Create folder view */
2370 *tree_view = modest_folder_view_new (NULL);
2371 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2372 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2373 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2375 /* Add scroll to dialog */
2376 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2377 scroll, FALSE, FALSE, 0);
2379 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2385 * Returns TRUE if at least one of the headers of the list belongs to
2386 * a message that has been fully retrieved.
2389 has_retrieved_msgs (TnyList *list)
2392 gboolean found = FALSE;
2394 iter = tny_list_create_iterator (list);
2395 while (tny_iterator_is_done (iter) && !found) {
2397 TnyHeaderFlags flags;
2399 header = TNY_HEADER (tny_iterator_get_current (iter));
2400 flags = tny_header_get_flags (header);
2401 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2405 tny_iterator_next (iter);
2407 g_object_unref (iter);
2413 * Shows a confirmation dialog to the user when we're moving messages
2414 * from a remote server to the local storage. Returns the dialog
2415 * response. If it's other kind of movement the it always returns
2419 msgs_move_to_confirmation (GtkWindow *win,
2420 TnyFolder *dest_folder,
2423 gint response = GTK_RESPONSE_OK;
2425 /* If the destination is a local folder */
2426 if (modest_tny_folder_is_local_folder (dest_folder)) {
2427 TnyFolder *src_folder;
2431 /* Get source folder */
2432 iter = tny_list_create_iterator (headers);
2433 header = TNY_HEADER (tny_iterator_get_current (iter));
2434 src_folder = tny_header_get_folder (header);
2435 g_object_unref (header);
2436 g_object_unref (iter);
2438 /* If the source is a remote folder */
2439 if (!modest_tny_folder_is_local_folder (src_folder)) {
2440 const gchar *message;
2442 if (tny_list_get_length (headers) == 1)
2443 if (has_retrieved_msgs (headers))
2444 message = _("mcen_nc_move_retrieve");
2446 message = _("mcen_nc_move_header");
2448 if (has_retrieved_msgs (headers))
2449 message = _("mcen_nc_move_retrieves");
2451 message = _("mcen_nc_move_headers");
2453 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2454 (const gchar *) message);
2456 g_object_unref (src_folder);
2463 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2465 ModestMsgViewWindow *self = NULL;
2466 gboolean found = FALSE;
2468 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2469 self = MODEST_MSG_VIEW_WINDOW (object);
2471 found = modest_msg_view_window_select_first_message (self);
2472 g_return_if_fail (found);
2476 move_to_error_checking (const GObject *obj, gpointer user_data)
2478 ModestWindow *win = NULL;
2480 g_return_if_fail (MODEST_IS_WINDOW (obj));
2481 win = MODEST_WINDOW (obj);
2483 /* TODO: show error message */
2484 /* modest_platform_run_information_dialog (GTK_WINDOW (win), */
2485 /* _("mail_in_ui_folder_move_target_error")); */
2489 * UI handler for the "Move to" action when invoked from the
2493 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2494 ModestMainWindow *win)
2496 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2497 GtkWidget *header_view = NULL;
2499 TnyFolderStore *folder_store = NULL;
2500 ModestMailOperation *mail_op = NULL;
2502 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2504 /* Get the folder view */
2505 folder_view = modest_main_window_get_child_widget (win,
2506 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2508 /* Get header view */
2509 header_view = modest_main_window_get_child_widget (win,
2510 MODEST_WIDGET_TYPE_HEADER_VIEW);
2512 /* Create and run the dialog */
2513 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2514 result = gtk_dialog_run (GTK_DIALOG(dialog));
2515 g_object_ref (tree_view);
2517 /* We do this to save an indentation level ;-) */
2518 if (result != GTK_RESPONSE_ACCEPT)
2521 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2523 if (TNY_IS_ACCOUNT (folder_store))
2526 /* Get folder or messages to transfer */
2527 if (gtk_widget_is_focus (folder_view)) {
2528 TnyFolderStore *src_folder;
2529 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2531 /* Clean folder on header view before moving it */
2532 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2534 if (TNY_IS_FOLDER (src_folder)) {
2535 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2537 move_to_error_checking);
2538 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2541 modest_mail_operation_xfer_folder (mail_op,
2542 TNY_FOLDER (src_folder),
2545 g_object_unref (G_OBJECT (mail_op));
2550 g_object_unref (G_OBJECT (src_folder));
2552 if (gtk_widget_is_focus (header_view)) {
2556 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2558 /* Ask for user confirmation */
2559 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2560 TNY_FOLDER (folder_store),
2563 /* Transfer messages */
2564 if (response == GTK_RESPONSE_OK) {
2565 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2566 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2569 modest_mail_operation_xfer_msgs (mail_op,
2571 TNY_FOLDER (folder_store),
2575 g_object_unref (G_OBJECT (mail_op));
2577 g_object_unref (headers);
2580 g_object_unref (folder_store);
2583 gtk_widget_destroy (dialog);
2588 * UI handler for the "Move to" action when invoked from the
2589 * ModestMsgViewWindow
2592 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2593 ModestMsgViewWindow *win)
2595 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2597 ModestMainWindow *main_window;
2601 /* Get the folder view */
2602 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2603 folder_view = modest_main_window_get_child_widget (main_window,
2604 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2606 /* Create and run the dialog */
2607 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2608 result = gtk_dialog_run (GTK_DIALOG(dialog));
2609 g_object_ref (tree_view);
2611 if (result == GTK_RESPONSE_ACCEPT) {
2612 TnyFolderStore *folder_store;
2615 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2617 /* Create header list */
2618 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2619 headers = tny_simple_list_new ();
2620 tny_list_prepend (headers, G_OBJECT (header));
2621 g_object_unref (header);
2623 /* Ask user for confirmation. MSG-NOT404 */
2624 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2625 TNY_FOLDER (folder_store),
2628 /* Transfer current msg */
2629 if (response == GTK_RESPONSE_OK) {
2630 ModestMailOperation *mail_op;
2632 /* Create mail op */
2633 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2634 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2637 /* Transfer messages */
2638 modest_mail_operation_xfer_msgs (mail_op,
2640 TNY_FOLDER (folder_store),
2642 tranasfer_msgs_from_viewer_cb,
2644 g_object_unref (G_OBJECT (mail_op));
2646 g_object_unref (headers);
2647 g_object_unref (folder_store);
2649 gtk_widget_destroy (dialog);
2653 modest_ui_actions_on_move_to (GtkAction *action,
2656 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2657 MODEST_IS_MSG_VIEW_WINDOW (win));
2659 if (MODEST_IS_MAIN_WINDOW (win))
2660 modest_ui_actions_on_main_window_move_to (action,
2661 MODEST_MAIN_WINDOW (win));
2663 modest_ui_actions_on_msg_view_window_move_to (action,
2664 MODEST_MSG_VIEW_WINDOW (win));
2668 * Calls #HeadersFunc for each header already selected in the main
2669 * window or the message currently being shown in the msg view window
2672 do_headers_action (ModestWindow *win,
2676 TnyList *headers_list;
2680 headers_list = get_selected_headers (win);
2684 /* Call the function for each header */
2685 iter = tny_list_create_iterator (headers_list);
2686 while (!tny_iterator_is_done (iter)) {
2689 header = TNY_HEADER (tny_iterator_get_current (iter));
2690 func (header, win, user_data);
2691 g_object_unref (header);
2692 tny_iterator_next (iter);
2694 g_object_unref (iter);
2695 g_object_unref (headers_list);
2699 modest_ui_actions_view_attachment (GtkAction *action,
2700 ModestWindow *window)
2702 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2703 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2705 /* not supported window for this action */
2706 g_return_if_reached ();
2711 modest_ui_actions_save_attachments (GtkAction *action,
2712 ModestWindow *window)
2714 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2715 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2717 /* not supported window for this action */
2718 g_return_if_reached ();
2723 modest_ui_actions_remove_attachments (GtkAction *action,
2724 ModestWindow *window)
2726 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2727 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2729 /* not supported window for this action */
2730 g_return_if_reached ();
2735 modest_ui_actions_on_settings (GtkAction *action,
2740 dialog = modest_platform_get_global_settings_dialog ();
2741 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2742 gtk_widget_show (dialog);
2744 gtk_dialog_run (GTK_DIALOG (dialog));
2746 gtk_widget_destroy (dialog);
2750 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2751 ModestWindow *window)
2753 ModestMailOperation *mail_op;
2757 headers = get_selected_headers (window);
2761 /* Create mail operation */
2762 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT (window));
2763 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2764 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2767 g_object_unref (headers);
2768 g_object_unref (mail_op);