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>
41 #include "modest-error.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 the error handler of the
594 * modest_mail_operation_get_msgs_full operation
597 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
602 error = modest_mail_operation_get_error (mail_op);
603 if (error->code == MODEST_MAIL_OPERATION_ERROR_SIZE_LIMIT) {
604 modest_platform_run_information_dialog (GTK_WINDOW (modest_mail_operation_get_source (mail_op)),
610 * This function is used by both modest_ui_actions_on_open and
611 * modest_ui_actions_on_header_activated. This way we always do the
612 * same when trying to open messages.
615 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
617 ModestWindowMgr *mgr;
619 ModestMailOperation *mail_op;
621 /* Look if we already have a message view for each header. If
622 true, then remove the header from the list of headers to
624 mgr = modest_runtime_get_window_mgr ();
625 iter = tny_list_create_iterator (headers);
626 while (!tny_iterator_is_done (iter)) {
627 ModestWindow *window;
630 header = TNY_HEADER (tny_iterator_get_current (iter));
631 window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
633 tny_list_remove (headers, G_OBJECT (header));
635 g_object_unref (header);
636 tny_iterator_next (iter);
639 /* Open each message */
640 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
642 modest_ui_actions_get_msgs_full_error_handler,
644 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
645 modest_mail_operation_get_msgs_full (mail_op,
652 g_object_unref(mail_op);
656 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
661 headers = get_selected_headers (win);
666 _modest_ui_actions_open (headers, win);
668 g_object_unref(headers);
673 free_reply_forward_helper (gpointer data)
675 ReplyForwardHelper *helper;
677 helper = (ReplyForwardHelper *) data;
678 g_free (helper->account_name);
679 g_slice_free (ReplyForwardHelper, helper);
683 reply_forward_cb (ModestMailOperation *mail_op,
689 ReplyForwardHelper *rf_helper;
690 ModestWindow *msg_win;
691 ModestEditType edit_type;
694 TnyFolder *folder = NULL;
695 TnyAccount *account = NULL;
696 ModestWindowMgr *mgr;
697 gchar *signature = NULL;
699 g_return_if_fail (user_data != NULL);
700 rf_helper = (ReplyForwardHelper *) user_data;
702 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
703 rf_helper->account_name);
704 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
705 rf_helper->account_name,
706 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
707 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
708 rf_helper->account_name,
709 MODEST_ACCOUNT_SIGNATURE, FALSE);
712 /* Create reply mail */
713 switch (rf_helper->action) {
716 modest_tny_msg_create_reply_msg (msg, from, signature,
717 rf_helper->reply_forward_type,
718 MODEST_TNY_MSG_REPLY_MODE_SENDER);
720 case ACTION_REPLY_TO_ALL:
722 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
723 MODEST_TNY_MSG_REPLY_MODE_ALL);
724 edit_type = MODEST_EDIT_TYPE_REPLY;
728 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
729 edit_type = MODEST_EDIT_TYPE_FORWARD;
732 g_return_if_reached ();
739 g_printerr ("modest: failed to create message\n");
743 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
744 rf_helper->account_name,
745 TNY_ACCOUNT_TYPE_STORE);
747 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
751 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
753 g_printerr ("modest: failed to find Drafts folder\n");
757 tny_folder_add_msg (folder, msg, &err);
759 g_printerr ("modest: error adding msg to Drafts folder: %s",
765 /* Create and register the windows */
766 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
767 mgr = modest_runtime_get_window_mgr ();
768 modest_window_mgr_register_window (mgr, msg_win);
770 /* Show edit window */
771 gtk_widget_show_all (GTK_WIDGET (msg_win));
775 g_object_unref (G_OBJECT (new_msg));
777 g_object_unref (G_OBJECT (folder));
779 g_object_unref (G_OBJECT (account));
780 g_object_unref (msg);
781 g_object_unref (header);
785 * Checks a list of headers. If any of them are not currently
786 * downloaded (CACHED) then it asks the user for permission to
789 * Returns FALSE if the user does not want to download the
790 * messages. Returns TRUE if the user allowed the download or if all
791 * of them are currently downloaded
794 download_uncached_messages (TnyList *header_list, GtkWindow *win)
797 gboolean found, retval;
799 iter = tny_list_create_iterator (header_list);
801 while (!tny_iterator_is_done (iter) && !found) {
803 TnyHeaderFlags flags;
805 header = TNY_HEADER (tny_iterator_get_current (iter));
806 flags = tny_header_get_flags (header);
807 /* TODO: is this the right flag?, it seems that some
808 headers that have been previously downloaded do not
810 found = !(flags & TNY_HEADER_FLAG_CACHED);
811 g_object_unref (header);
812 tny_iterator_next (iter);
814 g_object_unref (iter);
816 /* Ask for user permission to download the messages */
819 GtkResponseType response;
821 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
822 _("mcen_nc_get_multi_msg_txt"));
823 if (response == GTK_RESPONSE_CANCEL)
831 * Common code for the reply and forward actions
834 reply_forward (ReplyForwardAction action, ModestWindow *win)
836 ModestMailOperation *mail_op = NULL;
837 TnyList *header_list = NULL;
838 ReplyForwardHelper *rf_helper = NULL;
839 guint reply_forward_type;
840 gboolean continue_download;
842 g_return_if_fail (MODEST_IS_WINDOW(win));
844 header_list = get_selected_headers (win);
848 /* Check that the messages have been previously downloaded */
849 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
850 if (!continue_download) {
851 g_object_unref (header_list);
856 modest_conf_get_int (modest_runtime_get_conf (),
857 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
859 /* We assume that we can only select messages of the
860 same folder and that we reply all of them from the
861 same account. In fact the interface currently only
862 allows single selection */
865 rf_helper = g_slice_new0 (ReplyForwardHelper);
866 rf_helper->reply_forward_type = reply_forward_type;
867 rf_helper->action = action;
868 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
869 if (!rf_helper->account_name)
870 rf_helper->account_name =
871 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
873 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
876 /* Get header and message. Do not free them here, the
877 reply_forward_cb must do it */
878 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
879 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
880 if (!msg || !header) {
882 g_object_unref (msg);
884 g_object_unref (header);
885 g_printerr ("modest: no message found\n");
888 reply_forward_cb (NULL, header, msg, rf_helper);
890 /* Retrieve messages */
891 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
893 modest_ui_actions_get_msgs_full_error_handler,
895 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
896 modest_mail_operation_get_msgs_full (mail_op,
900 free_reply_forward_helper);
903 g_object_unref(mail_op);
907 g_object_unref (header_list);
911 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
913 g_return_if_fail (MODEST_IS_WINDOW(win));
915 reply_forward (ACTION_REPLY, win);
919 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
921 g_return_if_fail (MODEST_IS_WINDOW(win));
923 reply_forward (ACTION_FORWARD, win);
927 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
929 g_return_if_fail (MODEST_IS_WINDOW(win));
931 reply_forward (ACTION_REPLY_TO_ALL, win);
935 modest_ui_actions_on_next (GtkAction *action,
936 ModestWindow *window)
938 if (MODEST_IS_MAIN_WINDOW (window)) {
939 GtkWidget *header_view;
941 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
942 MODEST_WIDGET_TYPE_HEADER_VIEW);
946 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
947 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
948 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
950 g_return_if_reached ();
955 modest_ui_actions_on_prev (GtkAction *action,
956 ModestWindow *window)
958 g_return_if_fail (MODEST_IS_WINDOW(window));
960 if (MODEST_IS_MAIN_WINDOW (window)) {
961 GtkWidget *header_view;
962 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
963 MODEST_WIDGET_TYPE_HEADER_VIEW);
967 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
968 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
969 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
971 g_return_if_reached ();
976 modest_ui_actions_on_sort (GtkAction *action,
977 ModestWindow *window)
979 g_return_if_fail (MODEST_IS_WINDOW(window));
981 if (MODEST_IS_MAIN_WINDOW (window)) {
982 GtkWidget *header_view;
983 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
984 MODEST_WIDGET_TYPE_HEADER_VIEW);
988 /* Show sorting dialog */
989 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
994 * This function performs the send & receive required actions. The
995 * window is used to create the mail operation. Typically it should
996 * always be the main window, but we pass it as argument in order to
1000 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1002 gchar *acc_name = NULL;
1003 ModestMailOperation *mail_op;
1005 /* If no account name was provided then get the current account, and if
1006 there is no current account then pick the default one: */
1007 if (!account_name) {
1008 acc_name = g_strdup (modest_window_get_active_account(win));
1010 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1012 g_printerr ("modest: cannot get default account\n");
1016 acc_name = g_strdup (account_name);
1019 /* Send & receive. */
1020 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1021 /* Receive and then send. The operation is tagged initially as
1022 a receive operation because the account update performs a
1023 receive and then a send. The operation changes its type
1024 internally, so the progress objects will receive the proper
1025 progress information */
1026 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1028 modest_mail_operation_update_account (mail_op, acc_name);
1029 g_object_unref (G_OBJECT (mail_op));
1036 * Refreshes all accounts. This function will be used by automatic
1040 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1042 GSList *account_names, *iter;
1044 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1047 iter = account_names;
1049 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1050 iter = g_slist_next (iter);
1053 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1054 g_slist_free (account_names);
1058 * Handler of the click on Send&Receive button in the main toolbar
1061 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1063 /* Check that at least one account exists: */
1064 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1065 TRUE /* enabled accounts only */);
1066 gboolean accounts_exist = account_names != NULL;
1067 g_slist_free (account_names);
1069 /* If not, allow the user to create an account before trying to send/receive. */
1070 if (!accounts_exist)
1071 modest_ui_actions_on_accounts (NULL, win);
1073 /* Refresh the active account */
1074 modest_ui_actions_do_send_receive (NULL, win);
1079 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1082 GtkWidget *header_view;
1084 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1086 header_view = modest_main_window_get_child_widget (main_window,
1087 MODEST_WIDGET_TYPE_HEADER_VIEW);
1091 conf = modest_runtime_get_conf ();
1093 /* what is saved/restored is depending on the style; thus; we save with
1094 * old style, then update the style, and restore for this new style
1096 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1098 if (modest_header_view_get_style
1099 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1100 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1101 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1103 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1104 MODEST_HEADER_VIEW_STYLE_DETAILS);
1106 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1107 MODEST_CONF_HEADER_VIEW_KEY);
1112 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1114 ModestMainWindow *main_window)
1116 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1118 /* If no header has been selected then exit */
1122 /* Update Main window title */
1123 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1124 const gchar *subject = tny_header_get_subject (header);
1125 if (subject && strcmp (subject, ""))
1126 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1128 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1133 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1135 ModestMainWindow *main_window)
1139 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1144 headers = tny_simple_list_new ();
1145 tny_list_prepend (headers, G_OBJECT (header));
1147 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1149 g_object_unref (headers);
1153 set_active_account_from_tny_account (TnyAccount *account,
1154 ModestWindow *window)
1156 const gchar *server_acc_name = tny_account_get_id (account);
1158 /* We need the TnyAccount provided by the
1159 account store because that is the one that
1160 knows the name of the Modest account */
1161 TnyAccount *modest_server_account = modest_server_account =
1162 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1165 const gchar *modest_acc_name =
1166 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1167 modest_window_set_active_account (window, modest_acc_name);
1168 g_object_unref (modest_server_account);
1172 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1173 TnyFolderStore *folder_store,
1175 ModestMainWindow *main_window)
1178 GtkWidget *header_view;
1180 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1182 header_view = modest_main_window_get_child_widget(main_window,
1183 MODEST_WIDGET_TYPE_HEADER_VIEW);
1187 conf = modest_runtime_get_conf ();
1189 if (TNY_IS_ACCOUNT (folder_store)) {
1190 /* Update active account */
1191 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1192 /* Show account details */
1193 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1194 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1195 //TODO: Set the virtual folder store as the "active account" somehow:
1196 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1198 if (TNY_IS_FOLDER (folder_store) && selected) {
1200 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1201 /* Update the active account */
1202 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1203 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1204 g_object_unref (account);
1207 /* Set folder on header view */
1208 modest_main_window_set_contents_style (main_window,
1209 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1210 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1211 TNY_FOLDER (folder_store));
1212 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1213 MODEST_CONF_HEADER_VIEW_KEY);
1215 /* Update the active account */
1216 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1217 /* Do not show folder */
1218 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1219 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1225 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1232 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1234 if (g_main_depth > 0)
1235 gdk_threads_enter ();
1236 online = tny_device_is_online (modest_runtime_get_device());
1239 /* already online -- the item is simply not there... */
1240 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1242 GTK_MESSAGE_WARNING,
1244 _("The %s you selected cannot be found"),
1246 gtk_dialog_run (GTK_DIALOG(dialog));
1248 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1252 GTK_RESPONSE_REJECT,
1254 GTK_RESPONSE_ACCEPT,
1256 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1257 "Do you want to get online?"), item);
1258 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1259 gtk_label_new (txt), FALSE, FALSE, 0);
1260 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1263 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1264 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1265 // modest_platform_connect_and_wait ();;
1268 gtk_widget_destroy (dialog);
1269 if (g_main_depth > 0)
1270 gdk_threads_leave ();
1274 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1277 /* g_message ("%s %s", __FUNCTION__, link); */
1282 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1285 modest_platform_activate_uri (link);
1289 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1292 modest_platform_show_uri_popup (link);
1296 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1299 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1303 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1304 const gchar *address,
1307 /* g_message ("%s %s", __FUNCTION__, address); */
1311 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1313 TnyTransportAccount *transport_account;
1314 ModestMailOperation *mail_operation;
1316 gchar *account_name, *from;
1317 ModestAccountMgr *account_mgr;
1319 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1321 data = modest_msg_edit_window_get_msg_data (edit_window);
1323 account_mgr = modest_runtime_get_account_mgr();
1324 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1326 account_name = modest_account_mgr_get_default_account (account_mgr);
1327 if (!account_name) {
1328 g_printerr ("modest: no account found\n");
1329 modest_msg_edit_window_free_msg_data (edit_window, data);
1333 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1334 (modest_runtime_get_account_store(),
1336 TNY_ACCOUNT_TYPE_TRANSPORT));
1337 if (!transport_account) {
1338 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1339 g_free (account_name);
1340 modest_msg_edit_window_free_msg_data (edit_window, data);
1343 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1345 /* Create the mail operation */
1346 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1347 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1349 modest_mail_operation_save_to_drafts (mail_operation,
1359 data->priority_flags);
1362 g_free (account_name);
1363 g_object_unref (G_OBJECT (transport_account));
1364 g_object_unref (G_OBJECT (mail_operation));
1366 modest_msg_edit_window_free_msg_data (edit_window, data);
1368 /* Save settings and close the window */
1369 gtk_widget_destroy (GTK_WIDGET (edit_window));
1372 /* For instance, when clicking the Send toolbar button when editing a message: */
1374 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1376 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1378 if (!modest_msg_edit_window_check_names (edit_window))
1381 /* FIXME: Code added just for testing. The final version will
1382 use the send queue provided by tinymail and some
1384 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1385 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1387 account_name = modest_account_mgr_get_default_account (account_mgr);
1389 if (!account_name) {
1390 g_printerr ("modest: no account found\n");
1394 /* Get the currently-active transport account for this modest account: */
1395 TnyTransportAccount *transport_account =
1396 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1397 (modest_runtime_get_account_store(),
1399 if (!transport_account) {
1400 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1401 g_free (account_name);
1405 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1407 /* Create the mail operation */
1408 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1409 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1411 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1412 modest_mail_operation_send_new_mail (mail_operation,
1422 data->priority_flags);
1426 g_free (account_name);
1427 g_object_unref (G_OBJECT (transport_account));
1428 g_object_unref (G_OBJECT (mail_operation));
1430 modest_msg_edit_window_free_msg_data (edit_window, data);
1432 /* Save settings and close the window: */
1433 gtk_widget_destroy (GTK_WIDGET (edit_window));
1437 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1438 ModestMsgEditWindow *window)
1440 ModestMsgEditFormatState *format_state = NULL;
1442 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1443 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1445 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1448 format_state = modest_msg_edit_window_get_format_state (window);
1449 g_return_if_fail (format_state != NULL);
1451 format_state->bold = gtk_toggle_action_get_active (action);
1452 modest_msg_edit_window_set_format_state (window, format_state);
1453 g_free (format_state);
1458 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1459 ModestMsgEditWindow *window)
1461 ModestMsgEditFormatState *format_state = NULL;
1463 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1464 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1466 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1469 format_state = modest_msg_edit_window_get_format_state (window);
1470 g_return_if_fail (format_state != NULL);
1472 format_state->italics = gtk_toggle_action_get_active (action);
1473 modest_msg_edit_window_set_format_state (window, format_state);
1474 g_free (format_state);
1479 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1480 ModestMsgEditWindow *window)
1482 ModestMsgEditFormatState *format_state = NULL;
1484 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1485 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1487 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1490 format_state = modest_msg_edit_window_get_format_state (window);
1491 g_return_if_fail (format_state != NULL);
1493 format_state->bullet = gtk_toggle_action_get_active (action);
1494 modest_msg_edit_window_set_format_state (window, format_state);
1495 g_free (format_state);
1500 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1501 GtkRadioAction *selected,
1502 ModestMsgEditWindow *window)
1504 ModestMsgEditFormatState *format_state = NULL;
1505 GtkJustification value;
1507 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1509 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1512 value = gtk_radio_action_get_current_value (selected);
1514 format_state = modest_msg_edit_window_get_format_state (window);
1515 g_return_if_fail (format_state != NULL);
1517 format_state->justification = value;
1518 modest_msg_edit_window_set_format_state (window, format_state);
1519 g_free (format_state);
1523 modest_ui_actions_on_select_editor_color (GtkAction *action,
1524 ModestMsgEditWindow *window)
1526 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1527 g_return_if_fail (GTK_IS_ACTION (action));
1529 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1532 modest_msg_edit_window_select_color (window);
1536 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1537 ModestMsgEditWindow *window)
1539 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1540 g_return_if_fail (GTK_IS_ACTION (action));
1542 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1545 modest_msg_edit_window_select_background_color (window);
1549 modest_ui_actions_on_insert_image (GtkAction *action,
1550 ModestMsgEditWindow *window)
1552 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1553 g_return_if_fail (GTK_IS_ACTION (action));
1555 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1558 modest_msg_edit_window_insert_image (window);
1562 modest_ui_actions_on_attach_file (GtkAction *action,
1563 ModestMsgEditWindow *window)
1565 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1566 g_return_if_fail (GTK_IS_ACTION (action));
1568 modest_msg_edit_window_attach_file (window);
1572 modest_ui_actions_on_remove_attachments (GtkAction *action,
1573 ModestMsgEditWindow *window)
1575 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1576 g_return_if_fail (GTK_IS_ACTION (action));
1578 modest_msg_edit_window_remove_attachments (window, NULL);
1582 * Shows a dialog with an entry that asks for some text. The returned
1583 * value must be freed by the caller. The dialog window title will be
1587 ask_for_folder_name (GtkWindow *parent_window,
1590 GtkWidget *dialog, *entry;
1591 gchar *folder_name = NULL;
1593 /* Ask for folder name */
1594 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1598 GTK_RESPONSE_REJECT,
1600 GTK_RESPONSE_ACCEPT,
1602 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1603 gtk_label_new(title),
1606 entry = gtk_entry_new_with_max_length (40);
1607 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1611 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1613 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1614 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1616 gtk_widget_destroy (dialog);
1622 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1624 TnyFolderStore *parent_folder;
1625 GtkWidget *folder_view;
1627 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1629 folder_view = modest_main_window_get_child_widget (main_window,
1630 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1634 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1636 if (parent_folder) {
1637 gboolean finished = FALSE;
1639 gchar *folder_name = NULL, *suggested_name = NULL;
1641 /* Run the new folder dialog */
1643 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1648 if (result == GTK_RESPONSE_REJECT) {
1651 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1652 TnyFolder *new_folder = NULL;
1654 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1657 new_folder = modest_mail_operation_create_folder (mail_op,
1659 (const gchar *) folder_name);
1661 g_object_unref (new_folder);
1665 /* /\* TODO: check error and follow proper actions *\/ */
1666 /* /\* suggested_name = X; *\/ */
1667 /* /\* Show error to the user *\/ */
1668 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1669 /* _("mail_in_ui_folder_create_error")); */
1671 g_object_unref (mail_op);
1673 g_free (folder_name);
1677 g_object_unref (parent_folder);
1682 modest_ui_actions_on_rename_folder (GtkAction *action,
1683 ModestMainWindow *main_window)
1685 TnyFolderStore *folder;
1686 GtkWidget *folder_view;
1687 GtkWidget *header_view;
1689 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1691 folder_view = modest_main_window_get_child_widget (main_window,
1692 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1696 header_view = modest_main_window_get_child_widget (main_window,
1697 MODEST_WIDGET_TYPE_HEADER_VIEW);
1702 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1704 if (folder && TNY_IS_FOLDER (folder)) {
1706 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1707 _("Please enter a new name for the folder"));
1709 if (folder_name != NULL && strlen (folder_name) > 0) {
1710 ModestMailOperation *mail_op;
1712 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1713 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1716 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1718 modest_mail_operation_rename_folder (mail_op,
1719 TNY_FOLDER (folder),
1720 (const gchar *) folder_name);
1722 g_object_unref (mail_op);
1723 g_free (folder_name);
1725 g_object_unref (folder);
1730 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1732 TnyFolderStore *folder;
1733 GtkWidget *folder_view;
1737 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1739 folder_view = modest_main_window_get_child_widget (main_window,
1740 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1744 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1746 /* Show an error if it's an account */
1747 if (!TNY_IS_FOLDER (folder)) {
1748 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1749 _("mail_in_ui_folder_delete_error"));
1754 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1755 tny_folder_get_name (TNY_FOLDER (folder)));
1756 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1757 (const gchar *) message);
1760 if (response == GTK_RESPONSE_OK) {
1761 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(main_window));
1763 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1765 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1767 /* Show error if happened */
1768 if (modest_mail_operation_get_error (mail_op))
1769 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1770 _("mail_in_ui_folder_delete_error"));
1772 g_object_unref (G_OBJECT (mail_op));
1775 g_object_unref (G_OBJECT (folder));
1779 modest_ui_actions_on_delete_folder (GtkAction *action,
1780 ModestMainWindow *main_window)
1782 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1784 delete_folder (main_window, FALSE);
1788 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1790 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1792 delete_folder (main_window, TRUE);
1796 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1797 const gchar* server_account_name,
1802 ModestMainWindow *main_window)
1804 g_return_if_fail(server_account_name);
1805 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1807 /* Initalize output parameters: */
1814 #ifdef MODEST_PLATFORM_MAEMO
1815 /* Maemo uses a different (awkward) button order,
1816 * It should probably just use gtk_alternative_dialog_button_order ().
1818 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1822 GTK_RESPONSE_ACCEPT,
1824 GTK_RESPONSE_REJECT,
1827 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1831 GTK_RESPONSE_REJECT,
1833 GTK_RESPONSE_ACCEPT,
1835 #endif /* MODEST_PLATFORM_MAEMO */
1837 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1839 gchar *server_name = modest_server_account_get_hostname (
1840 modest_runtime_get_account_mgr(), server_account_name);
1842 /* This causes a warning because the logical ID has no %s in it,
1843 * though the translation does, but there is not much we can do about that: */
1844 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1845 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1848 g_free (server_name);
1852 gchar *initial_username = modest_server_account_get_username (
1853 modest_runtime_get_account_mgr(), server_account_name);
1855 GtkWidget *entry_username = gtk_entry_new ();
1856 if (initial_username)
1857 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1858 /* Dim this if a connection has ever succeeded with this username,
1859 * as per the UI spec: */
1860 const gboolean username_known =
1861 modest_server_account_get_username_has_succeeded(
1862 modest_runtime_get_account_mgr(), server_account_name);
1863 gtk_widget_set_sensitive (entry_username, !username_known);
1865 #ifdef MODEST_PLATFORM_MAEMO
1866 /* Auto-capitalization is the default, so let's turn it off: */
1867 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1869 /* Create a size group to be used by all captions.
1870 * Note that HildonCaption does not create a default size group if we do not specify one.
1871 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1872 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1874 GtkWidget *caption = hildon_caption_new (sizegroup,
1875 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1876 gtk_widget_show (entry_username);
1877 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1878 FALSE, FALSE, MODEST_MARGIN_HALF);
1879 gtk_widget_show (caption);
1881 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1883 #endif /* MODEST_PLATFORM_MAEMO */
1886 GtkWidget *entry_password = gtk_entry_new ();
1887 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1888 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1890 #ifdef MODEST_PLATFORM_MAEMO
1891 /* Auto-capitalization is the default, so let's turn it off: */
1892 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1893 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1895 caption = hildon_caption_new (sizegroup,
1896 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1897 gtk_widget_show (entry_password);
1898 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1899 FALSE, FALSE, MODEST_MARGIN_HALF);
1900 gtk_widget_show (caption);
1901 g_object_unref (sizegroup);
1903 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1905 #endif /* MODEST_PLATFORM_MAEMO */
1907 /* This is not in the Maemo UI spec:
1908 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1909 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1913 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1915 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1917 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1919 modest_server_account_set_username (
1920 modest_runtime_get_account_mgr(), server_account_name,
1923 const gboolean username_was_changed =
1924 (strcmp (*username, initial_username) != 0);
1925 if (username_was_changed) {
1926 /* To actually use a changed username,
1927 * we must reset the connection, according to pvanhoof.
1928 * This _might_ be a sensible way to do that: */
1929 TnyDevice *device = modest_runtime_get_device();
1930 tny_device_force_offline (device);
1931 tny_device_force_online (device);
1936 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1938 /* We do not save the password in the configuration,
1939 * because this function is only called for passwords that should
1940 * not be remembered:
1941 modest_server_account_set_password (
1942 modest_runtime_get_account_mgr(), server_account_name,
1961 /* This is not in the Maemo UI spec:
1962 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1968 gtk_widget_destroy (dialog);
1970 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
1974 modest_ui_actions_on_cut (GtkAction *action,
1975 ModestWindow *window)
1977 GtkWidget *focused_widget;
1979 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1980 if (GTK_IS_EDITABLE (focused_widget)) {
1981 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1982 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1983 GtkTextBuffer *buffer;
1984 GtkClipboard *clipboard;
1986 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1987 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1988 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1993 modest_ui_actions_on_copy (GtkAction *action,
1994 ModestWindow *window)
1996 GtkClipboard *clipboard;
1997 GtkWidget *focused_widget;
1999 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2000 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2001 if (GTK_IS_LABEL (focused_widget)) {
2002 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2003 } else if (GTK_IS_EDITABLE (focused_widget)) {
2004 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2005 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2006 GtkTextBuffer *buffer;
2008 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2009 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2014 modest_ui_actions_on_undo (GtkAction *action,
2015 ModestWindow *window)
2017 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2018 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2020 g_return_if_reached ();
2025 modest_ui_actions_on_paste (GtkAction *action,
2026 ModestWindow *window)
2028 GtkWidget *focused_widget;
2030 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2031 if (GTK_IS_EDITABLE (focused_widget)) {
2032 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2033 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2034 GtkTextBuffer *buffer;
2035 GtkClipboard *clipboard;
2037 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2038 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2039 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2044 modest_ui_actions_on_select_all (GtkAction *action,
2045 ModestWindow *window)
2047 GtkWidget *focused_widget;
2049 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2050 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2051 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2052 } else if (GTK_IS_LABEL (focused_widget)) {
2053 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2054 } else if (GTK_IS_EDITABLE (focused_widget)) {
2055 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2056 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2057 GtkTextBuffer *buffer;
2058 GtkTextIter start, end;
2060 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2061 gtk_text_buffer_get_start_iter (buffer, &start);
2062 gtk_text_buffer_get_end_iter (buffer, &end);
2063 gtk_text_buffer_select_range (buffer, &start, &end);
2068 modest_ui_actions_on_mark_as_read (GtkAction *action,
2069 ModestWindow *window)
2071 g_return_if_fail (MODEST_IS_WINDOW(window));
2073 /* Mark each header as read */
2074 do_headers_action (window, headers_action_mark_as_read, NULL);
2078 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2079 ModestWindow *window)
2081 g_return_if_fail (MODEST_IS_WINDOW(window));
2083 /* Mark each header as read */
2084 do_headers_action (window, headers_action_mark_as_unread, NULL);
2088 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2089 GtkRadioAction *selected,
2090 ModestWindow *window)
2094 value = gtk_radio_action_get_current_value (selected);
2095 if (MODEST_IS_WINDOW (window)) {
2096 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2100 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2101 GtkRadioAction *selected,
2102 ModestWindow *window)
2104 TnyHeaderFlags flags;
2105 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2107 flags = gtk_radio_action_get_current_value (selected);
2108 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2111 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2112 GtkRadioAction *selected,
2113 ModestWindow *window)
2117 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2119 file_format = gtk_radio_action_get_current_value (selected);
2120 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2125 modest_ui_actions_on_zoom_plus (GtkAction *action,
2126 ModestWindow *window)
2128 g_return_if_fail (MODEST_IS_WINDOW (window));
2130 modest_window_zoom_plus (MODEST_WINDOW (window));
2134 modest_ui_actions_on_zoom_minus (GtkAction *action,
2135 ModestWindow *window)
2137 g_return_if_fail (MODEST_IS_WINDOW (window));
2139 modest_window_zoom_minus (MODEST_WINDOW (window));
2143 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2144 ModestWindow *window)
2146 ModestWindowMgr *mgr;
2147 gboolean fullscreen, active;
2148 g_return_if_fail (MODEST_IS_WINDOW (window));
2150 mgr = modest_runtime_get_window_mgr ();
2152 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2153 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2155 if (active != fullscreen) {
2156 modest_window_mgr_set_fullscreen_mode (mgr, active);
2157 gtk_window_present (GTK_WINDOW (window));
2162 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2163 ModestWindow *window)
2165 ModestWindowMgr *mgr;
2166 gboolean fullscreen;
2168 g_return_if_fail (MODEST_IS_WINDOW (window));
2170 mgr = modest_runtime_get_window_mgr ();
2171 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2172 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2174 gtk_window_present (GTK_WINDOW (window));
2178 * Used by modest_ui_actions_on_details to call do_headers_action
2181 headers_action_show_details (TnyHeader *header,
2182 ModestWindow *window,
2189 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2192 gtk_widget_show_all (dialog);
2193 gtk_dialog_run (GTK_DIALOG (dialog));
2195 gtk_widget_destroy (dialog);
2199 * Show the folder details in a ModestDetailsDialog widget
2202 show_folder_details (TnyFolder *folder,
2208 dialog = modest_details_dialog_new_with_folder (window, folder);
2211 gtk_widget_show_all (dialog);
2212 gtk_dialog_run (GTK_DIALOG (dialog));
2214 gtk_widget_destroy (dialog);
2218 * Show the header details in a ModestDetailsDialog widget
2221 modest_ui_actions_on_details (GtkAction *action,
2224 TnyList * headers_list;
2228 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2231 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2234 g_object_unref (msg);
2236 headers_list = get_selected_headers (win);
2240 iter = tny_list_create_iterator (headers_list);
2242 header = TNY_HEADER (tny_iterator_get_current (iter));
2243 headers_action_show_details (header, win, NULL);
2244 g_object_unref (header);
2246 g_object_unref (iter);
2247 g_object_unref (headers_list);
2249 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2250 GtkWidget *folder_view, *header_view;
2252 /* Check which widget has the focus */
2253 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2254 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2255 if (gtk_widget_is_focus (folder_view)) {
2258 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2260 /* Show only when it's a folder */
2261 if (!folder || !TNY_IS_FOLDER (folder))
2264 show_folder_details (folder, GTK_WINDOW (win));
2267 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2268 MODEST_WIDGET_TYPE_HEADER_VIEW);
2269 /* Show details of each header */
2270 do_headers_action (win, headers_action_show_details, header_view);
2276 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2277 ModestMsgEditWindow *window)
2279 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2281 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2285 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2286 ModestMsgEditWindow *window)
2288 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2290 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2294 modest_ui_actions_toggle_folders_view (GtkAction *action,
2295 ModestMainWindow *main_window)
2299 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2301 conf = modest_runtime_get_conf ();
2303 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2304 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2306 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2310 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2311 ModestWindow *window)
2313 gboolean active, fullscreen = FALSE;
2314 ModestWindowMgr *mgr;
2316 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2318 /* Check if we want to toggle the toolbar vuew in fullscreen
2320 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2321 "ViewShowToolbarFullScreen")) {
2325 /* Toggle toolbar */
2326 mgr = modest_runtime_get_window_mgr ();
2327 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2331 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2332 ModestMsgEditWindow *window)
2334 modest_msg_edit_window_select_font (window);
2338 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2339 const gchar *display_name,
2342 /* Do not change the application name if the widget has not
2343 the focus. This callback could be called even if the folder
2344 view has not the focus, because the handled signal could be
2345 emitted when the folder view is redrawn */
2346 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2348 gtk_window_set_title (window, display_name);
2350 gtk_window_set_title (window, " ");
2355 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2357 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2358 modest_msg_edit_window_select_contacts (window);
2362 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2365 modest_msg_edit_window_check_names (window);
2370 create_move_to_dialog (ModestWindow *win,
2371 GtkWidget *folder_view,
2372 GtkWidget **tree_view)
2374 GtkWidget *dialog, *scroll;
2376 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2378 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2380 GTK_RESPONSE_ACCEPT,
2382 GTK_RESPONSE_REJECT,
2385 /* Create scrolled window */
2386 scroll = gtk_scrolled_window_new (NULL, NULL);
2387 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2388 GTK_POLICY_AUTOMATIC,
2389 GTK_POLICY_AUTOMATIC);
2391 /* Create folder view */
2392 *tree_view = modest_folder_view_new (NULL);
2393 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2394 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2395 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2397 /* Add scroll to dialog */
2398 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2399 scroll, FALSE, FALSE, 0);
2401 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2407 * Returns TRUE if at least one of the headers of the list belongs to
2408 * a message that has been fully retrieved.
2411 has_retrieved_msgs (TnyList *list)
2414 gboolean found = FALSE;
2416 iter = tny_list_create_iterator (list);
2417 while (tny_iterator_is_done (iter) && !found) {
2419 TnyHeaderFlags flags;
2421 header = TNY_HEADER (tny_iterator_get_current (iter));
2422 flags = tny_header_get_flags (header);
2423 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2427 tny_iterator_next (iter);
2429 g_object_unref (iter);
2435 * Shows a confirmation dialog to the user when we're moving messages
2436 * from a remote server to the local storage. Returns the dialog
2437 * response. If it's other kind of movement the it always returns
2441 msgs_move_to_confirmation (GtkWindow *win,
2442 TnyFolder *dest_folder,
2445 gint response = GTK_RESPONSE_OK;
2447 /* If the destination is a local folder */
2448 if (modest_tny_folder_is_local_folder (dest_folder)) {
2449 TnyFolder *src_folder;
2453 /* Get source folder */
2454 iter = tny_list_create_iterator (headers);
2455 header = TNY_HEADER (tny_iterator_get_current (iter));
2456 src_folder = tny_header_get_folder (header);
2457 g_object_unref (header);
2458 g_object_unref (iter);
2460 /* If the source is a remote folder */
2461 if (!modest_tny_folder_is_local_folder (src_folder)) {
2462 const gchar *message;
2464 if (tny_list_get_length (headers) == 1)
2465 if (has_retrieved_msgs (headers))
2466 message = _("mcen_nc_move_retrieve");
2468 message = _("mcen_nc_move_header");
2470 if (has_retrieved_msgs (headers))
2471 message = _("mcen_nc_move_retrieves");
2473 message = _("mcen_nc_move_headers");
2475 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2476 (const gchar *) message);
2478 g_object_unref (src_folder);
2485 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2487 ModestMsgViewWindow *self = NULL;
2488 gboolean found = FALSE;
2490 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2491 self = MODEST_MSG_VIEW_WINDOW (object);
2493 found = modest_msg_view_window_select_first_message (self);
2494 g_return_if_fail (found);
2498 move_to_error_checking (const GObject *obj, gpointer user_data)
2500 ModestWindow *win = NULL;
2502 g_return_if_fail (MODEST_IS_WINDOW (obj));
2503 win = MODEST_WINDOW (obj);
2505 /* TODO: show error message */
2506 modest_platform_run_information_dialog (GTK_WINDOW (win),
2507 _("mail_in_ui_folder_move_target_error"));
2511 * UI handler for the "Move to" action when invoked from the
2515 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2516 ModestMainWindow *win)
2518 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2519 GtkWidget *header_view = NULL;
2521 TnyFolderStore *folder_store = NULL;
2522 ModestMailOperation *mail_op = NULL;
2523 ModestMailOperationStatus status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
2525 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2527 /* Get the folder view */
2528 folder_view = modest_main_window_get_child_widget (win,
2529 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2531 /* Get header view */
2532 header_view = modest_main_window_get_child_widget (win,
2533 MODEST_WIDGET_TYPE_HEADER_VIEW);
2535 /* Create and run the dialog */
2536 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2537 result = gtk_dialog_run (GTK_DIALOG(dialog));
2538 g_object_ref (tree_view);
2540 /* We do this to save an indentation level ;-) */
2541 if (result != GTK_RESPONSE_ACCEPT)
2544 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2546 if (TNY_IS_ACCOUNT (folder_store))
2549 /* Get folder or messages to transfer */
2550 if (gtk_widget_is_focus (folder_view)) {
2551 TnyFolderStore *src_folder;
2552 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2554 /* Clean folder on header view before moving it */
2555 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2557 if (TNY_IS_FOLDER (src_folder)) {
2558 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2560 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2563 modest_mail_operation_xfer_folder (mail_op,
2564 TNY_FOLDER (src_folder),
2567 /* Get status and unref mail operation */
2568 status = modest_mail_operation_get_status (mail_op);
2569 g_object_unref (G_OBJECT (mail_op));
2573 g_object_unref (G_OBJECT (src_folder));
2575 if (gtk_widget_is_focus (header_view)) {
2579 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2581 /* Ask for user confirmation */
2582 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2583 TNY_FOLDER (folder_store),
2586 /* Transfer messages */
2587 if (response == GTK_RESPONSE_OK) {
2588 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2589 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2592 modest_mail_operation_xfer_msgs (mail_op,
2594 TNY_FOLDER (folder_store),
2599 /* Get status and unref mail operation */
2600 status = modest_mail_operation_get_status (mail_op);
2601 g_object_unref (G_OBJECT (mail_op));
2603 g_object_unref (headers);
2606 g_object_unref (folder_store);
2609 if (status != MODEST_MAIL_OPERATION_STATUS_SUCCESS)
2610 move_to_error_checking (G_OBJECT(win), NULL);
2612 gtk_widget_destroy (dialog);
2617 * UI handler for the "Move to" action when invoked from the
2618 * ModestMsgViewWindow
2621 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2622 ModestMsgViewWindow *win)
2624 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2626 ModestMainWindow *main_window;
2630 /* Get the folder view */
2631 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2632 folder_view = modest_main_window_get_child_widget (main_window,
2633 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2635 /* Create and run the dialog */
2636 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2637 result = gtk_dialog_run (GTK_DIALOG(dialog));
2638 g_object_ref (tree_view);
2640 if (result == GTK_RESPONSE_ACCEPT) {
2641 TnyFolderStore *folder_store;
2644 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2646 /* Create header list */
2647 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2648 headers = tny_simple_list_new ();
2649 tny_list_prepend (headers, G_OBJECT (header));
2650 g_object_unref (header);
2652 /* Ask user for confirmation. MSG-NOT404 */
2653 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2654 TNY_FOLDER (folder_store),
2657 /* Transfer current msg */
2658 if (response == GTK_RESPONSE_OK) {
2659 ModestMailOperation *mail_op;
2661 /* Create mail op */
2662 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2663 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2666 /* Transfer messages */
2667 modest_mail_operation_xfer_msgs (mail_op,
2669 TNY_FOLDER (folder_store),
2671 tranasfer_msgs_from_viewer_cb,
2673 g_object_unref (G_OBJECT (mail_op));
2675 g_object_unref (headers);
2676 g_object_unref (folder_store);
2678 gtk_widget_destroy (dialog);
2682 modest_ui_actions_on_move_to (GtkAction *action,
2685 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2686 MODEST_IS_MSG_VIEW_WINDOW (win));
2688 if (MODEST_IS_MAIN_WINDOW (win))
2689 modest_ui_actions_on_main_window_move_to (action,
2690 MODEST_MAIN_WINDOW (win));
2692 modest_ui_actions_on_msg_view_window_move_to (action,
2693 MODEST_MSG_VIEW_WINDOW (win));
2697 * Calls #HeadersFunc for each header already selected in the main
2698 * window or the message currently being shown in the msg view window
2701 do_headers_action (ModestWindow *win,
2705 TnyList *headers_list;
2709 headers_list = get_selected_headers (win);
2713 /* Call the function for each header */
2714 iter = tny_list_create_iterator (headers_list);
2715 while (!tny_iterator_is_done (iter)) {
2718 header = TNY_HEADER (tny_iterator_get_current (iter));
2719 func (header, win, user_data);
2720 g_object_unref (header);
2721 tny_iterator_next (iter);
2723 g_object_unref (iter);
2724 g_object_unref (headers_list);
2728 modest_ui_actions_view_attachment (GtkAction *action,
2729 ModestWindow *window)
2731 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2732 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2734 /* not supported window for this action */
2735 g_return_if_reached ();
2740 modest_ui_actions_save_attachments (GtkAction *action,
2741 ModestWindow *window)
2743 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2744 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2746 /* not supported window for this action */
2747 g_return_if_reached ();
2752 modest_ui_actions_remove_attachments (GtkAction *action,
2753 ModestWindow *window)
2755 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2756 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2758 /* not supported window for this action */
2759 g_return_if_reached ();
2764 modest_ui_actions_on_settings (GtkAction *action,
2769 dialog = modest_platform_get_global_settings_dialog ();
2770 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2771 gtk_widget_show (dialog);
2773 gtk_dialog_run (GTK_DIALOG (dialog));
2775 gtk_widget_destroy (dialog);
2779 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2780 ModestWindow *window)
2782 ModestMailOperation *mail_op;
2786 headers = get_selected_headers (window);
2790 /* Create mail operation */
2791 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2793 modest_ui_actions_get_msgs_full_error_handler,
2795 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2796 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2799 g_object_unref (headers);
2800 g_object_unref (mail_op);
2804 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2805 ModestWindow *window)
2807 g_return_if_fail (MODEST_IS_WINDOW (window));
2810 modest_window_check_dimming_rules (window);