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 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
395 modest_connection_specific_smtp_window_fill_with_connections (
396 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
397 modest_runtime_get_account_mgr(),
398 modest_window_get_active_account (win));
400 /* Show the window: */
401 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
402 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
403 gtk_widget_show (specific_window);
405 /* Save changes when the window is hidden: */
406 g_signal_connect (specific_window, "hide",
407 G_CALLBACK (on_smtp_servers_window_hide), win);
408 #endif /* MODEST_PLATFORM_MAEMO */
412 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
414 ModestWindow *msg_win;
416 TnyFolder *folder = NULL;
417 gchar *account_name = NULL;
418 gchar *from_str = NULL;
419 /* GError *err = NULL; */
420 TnyAccount *account = NULL;
421 ModestWindowMgr *mgr;
422 gchar *signature = NULL;
424 account_name = g_strdup(modest_window_get_active_account (win));
426 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
428 g_printerr ("modest: no account found\n");
432 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
434 TNY_ACCOUNT_TYPE_STORE);
436 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
440 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
442 g_printerr ("modest: failed get from string for '%s'\n", account_name);
446 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
447 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
448 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
449 MODEST_ACCOUNT_SIGNATURE, FALSE);
451 signature = g_strdup ("");
454 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
456 g_printerr ("modest: failed to create new msg\n");
460 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
462 g_printerr ("modest: failed to find Drafts folder\n");
466 /* tny_folder_add_msg (folder, msg, &err); */
468 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
470 /* g_error_free (err); */
474 /* Create and register edit window */
475 /* This is destroyed by TOOD. */
476 msg_win = modest_msg_edit_window_new (msg, account_name);
477 mgr = modest_runtime_get_window_mgr ();
478 modest_window_mgr_register_window (mgr, msg_win);
481 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
483 gtk_widget_show_all (GTK_WIDGET (msg_win));
486 g_free (account_name);
490 g_object_unref (G_OBJECT(account));
492 g_object_unref (G_OBJECT(msg));
494 g_object_unref (G_OBJECT(folder));
498 open_msg_cb (ModestMailOperation *mail_op,
503 ModestWindowMgr *mgr = NULL;
504 ModestWindow *parent_win = NULL;
505 ModestWindow *win = NULL;
506 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
507 gchar *account = NULL;
510 /* TODO: Show an error? (review the specs) */
514 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
515 folder = tny_header_get_folder (header);
517 /* Mark header as read */
518 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
521 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
523 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
525 /* Gets folder type (OUTBOX headers will be opened in edit window */
526 if (modest_tny_folder_is_local_folder (folder))
527 folder_type = modest_tny_folder_get_local_folder_type (folder);
529 /* If the header is in the drafts folder then open the editor,
530 else the message view window */
531 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
532 win = modest_msg_edit_window_new (msg, account);
534 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
535 GtkWidget *header_view;
536 GtkTreeSelection *sel;
537 GList *sel_list = NULL;
540 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
541 MODEST_WIDGET_TYPE_HEADER_VIEW);
543 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
544 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
546 if (sel_list != NULL) {
547 GtkTreeRowReference *row_reference;
549 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
550 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
551 g_list_free (sel_list);
553 win = modest_msg_view_window_new_with_header_model (msg,
557 gtk_tree_row_reference_free (row_reference);
559 win = modest_msg_view_window_new (msg, account);
562 win = modest_msg_view_window_new (msg, account);
566 /* Register and show new window */
568 mgr = modest_runtime_get_window_mgr ();
569 modest_window_mgr_register_window (mgr, win);
570 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
571 gtk_widget_show_all (GTK_WIDGET(win));
576 g_object_unref (msg);
577 g_object_unref (folder);
578 g_object_unref (header);
582 * This function is used by both modest_ui_actions_on_open and
583 * modest_ui_actions_on_header_activated. This way we always do the
584 * same when trying to open messages.
587 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
589 ModestWindowMgr *mgr;
591 ModestMailOperation *mail_op;
593 /* Look if we already have a message view for each header. If
594 true, then remove the header from the list of headers to
596 mgr = modest_runtime_get_window_mgr ();
597 iter = tny_list_create_iterator (headers);
598 while (!tny_iterator_is_done (iter)) {
599 ModestWindow *window;
602 header = TNY_HEADER (tny_iterator_get_current (iter));
603 window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
605 tny_list_remove (headers, G_OBJECT (header));
607 g_object_unref (header);
608 tny_iterator_next (iter);
611 /* Open each message */
612 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT (win));
613 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
614 modest_mail_operation_get_msgs_full (mail_op,
621 g_object_unref(mail_op);
625 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
630 headers = get_selected_headers (win);
635 _modest_ui_actions_open (headers, win);
637 g_object_unref(headers);
642 free_reply_forward_helper (gpointer data)
644 ReplyForwardHelper *helper;
646 helper = (ReplyForwardHelper *) data;
647 g_free (helper->account_name);
648 g_slice_free (ReplyForwardHelper, helper);
652 reply_forward_cb (ModestMailOperation *mail_op,
658 ReplyForwardHelper *rf_helper;
659 ModestWindow *msg_win;
660 ModestEditType edit_type;
663 TnyFolder *folder = NULL;
664 TnyAccount *account = NULL;
665 ModestWindowMgr *mgr;
666 gchar *signature = NULL;
668 g_return_if_fail (user_data != NULL);
669 rf_helper = (ReplyForwardHelper *) user_data;
671 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
672 rf_helper->account_name);
673 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
674 rf_helper->account_name,
675 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
676 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
677 rf_helper->account_name,
678 MODEST_ACCOUNT_SIGNATURE, FALSE);
681 /* Create reply mail */
682 switch (rf_helper->action) {
685 modest_tny_msg_create_reply_msg (msg, from, signature,
686 rf_helper->reply_forward_type,
687 MODEST_TNY_MSG_REPLY_MODE_SENDER);
689 case ACTION_REPLY_TO_ALL:
691 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
692 MODEST_TNY_MSG_REPLY_MODE_ALL);
693 edit_type = MODEST_EDIT_TYPE_REPLY;
697 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
698 edit_type = MODEST_EDIT_TYPE_FORWARD;
701 g_return_if_reached ();
708 g_printerr ("modest: failed to create message\n");
712 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
713 rf_helper->account_name,
714 TNY_ACCOUNT_TYPE_STORE);
716 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
720 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
722 g_printerr ("modest: failed to find Drafts folder\n");
726 tny_folder_add_msg (folder, msg, &err);
728 g_printerr ("modest: error adding msg to Drafts folder: %s",
734 /* Create and register the windows */
735 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
736 mgr = modest_runtime_get_window_mgr ();
737 modest_window_mgr_register_window (mgr, msg_win);
739 /* Show edit window */
740 gtk_widget_show_all (GTK_WIDGET (msg_win));
744 g_object_unref (G_OBJECT (new_msg));
746 g_object_unref (G_OBJECT (folder));
748 g_object_unref (G_OBJECT (account));
749 g_object_unref (msg);
750 g_object_unref (header);
754 * Checks a list of headers. If any of them are not currently
755 * downloaded (CACHED) then it asks the user for permission to
758 * Returns FALSE if the user does not want to download the
759 * messages. Returns TRUE if the user allowed the download or if all
760 * of them are currently downloaded
763 download_uncached_messages (TnyList *header_list, GtkWindow *win)
766 gboolean found, retval;
768 iter = tny_list_create_iterator (header_list);
770 while (!tny_iterator_is_done (iter) && !found) {
772 TnyHeaderFlags flags;
774 header = TNY_HEADER (tny_iterator_get_current (iter));
775 flags = tny_header_get_flags (header);
776 found = !(flags & TNY_HEADER_FLAG_CACHED);
777 g_object_unref (header);
778 tny_iterator_next (iter);
780 g_object_unref (iter);
782 /* Ask for user permission to download the messages */
785 GtkResponseType response;
787 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
788 _("mcen_nc_get_multi_msg_txt"));
789 if (response == GTK_RESPONSE_CANCEL)
797 * Common code for the reply and forward actions
800 reply_forward (ReplyForwardAction action, ModestWindow *win)
802 ModestMailOperation *mail_op = NULL;
803 TnyList *header_list = NULL;
804 ReplyForwardHelper *rf_helper = NULL;
805 guint reply_forward_type;
806 gboolean continue_download;
808 g_return_if_fail (MODEST_IS_WINDOW(win));
810 header_list = get_selected_headers (win);
814 /* Check that the messages have been previously downloaded */
815 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
816 if (!continue_download) {
817 g_object_unref (header_list);
822 modest_conf_get_int (modest_runtime_get_conf (),
823 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
825 /* We assume that we can only select messages of the
826 same folder and that we reply all of them from the
827 same account. In fact the interface currently only
828 allows single selection */
831 rf_helper = g_slice_new0 (ReplyForwardHelper);
832 rf_helper->reply_forward_type = reply_forward_type;
833 rf_helper->action = action;
834 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
835 if (!rf_helper->account_name)
836 rf_helper->account_name =
837 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
839 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
842 /* Get header and message. Do not free them here, the
843 reply_forward_cb must do it */
844 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
845 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
846 if (!msg || !header) {
848 g_object_unref (msg);
850 g_object_unref (header);
851 g_printerr ("modest: no message found\n");
854 reply_forward_cb (NULL, header, msg, rf_helper);
856 /* Retrieve messages */
857 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
858 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
859 modest_mail_operation_get_msgs_full (mail_op,
863 free_reply_forward_helper);
866 g_object_unref(mail_op);
870 g_object_unref (header_list);
874 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
876 g_return_if_fail (MODEST_IS_WINDOW(win));
878 reply_forward (ACTION_REPLY, win);
882 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
884 g_return_if_fail (MODEST_IS_WINDOW(win));
886 reply_forward (ACTION_FORWARD, win);
890 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
892 g_return_if_fail (MODEST_IS_WINDOW(win));
894 reply_forward (ACTION_REPLY_TO_ALL, win);
898 modest_ui_actions_on_next (GtkAction *action,
899 ModestWindow *window)
901 if (MODEST_IS_MAIN_WINDOW (window)) {
902 GtkWidget *header_view;
904 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
905 MODEST_WIDGET_TYPE_HEADER_VIEW);
909 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
910 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
911 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
913 g_return_if_reached ();
918 modest_ui_actions_on_prev (GtkAction *action,
919 ModestWindow *window)
921 g_return_if_fail (MODEST_IS_WINDOW(window));
923 if (MODEST_IS_MAIN_WINDOW (window)) {
924 GtkWidget *header_view;
925 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
926 MODEST_WIDGET_TYPE_HEADER_VIEW);
930 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
931 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
932 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
934 g_return_if_reached ();
939 modest_ui_actions_on_sort (GtkAction *action,
940 ModestWindow *window)
942 g_return_if_fail (MODEST_IS_WINDOW(window));
944 if (MODEST_IS_MAIN_WINDOW (window)) {
945 GtkWidget *header_view;
946 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
947 MODEST_WIDGET_TYPE_HEADER_VIEW);
951 /* Show sorting dialog */
952 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
956 /** Check that an appropriate connection is open.
958 gboolean check_for_connection (const gchar *account_name)
960 TnyDevice *device = modest_runtime_get_device ();
963 g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
965 TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
968 if (tny_device_is_online (device))
971 modest_platform_connect_and_wait (NULL);
973 /* TODO: Wait until a result. */
979 * This function performs the send & receive required actions. The
980 * window it's used to create the mail operation. Tipically it should
981 * be allways the main window, but we pass it as argument in order to
985 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
987 gchar *acc_name = NULL;
989 /* If no account name was provided get the current account, if
990 there is none either then pick the default one */
992 acc_name = g_strdup (modest_window_get_active_account(win));
994 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
996 g_printerr ("modest: cannot get default account\n");
1000 acc_name = g_strdup (account_name);
1003 /* Send & receive. */
1005 /* Do not continue if no suitable connection
1007 if (!check_for_connection (acc_name)) {
1012 /* TODO: Do not continue if an operation is already in progress:
1013 * Maybe there are some operations that tinymail allows to
1014 * happen simulatenously.
1015 * TODO: Maybe a simple global gboolean is_updating is enough?
1019 /* As per the UI spec,
1020 * for POP accounts, we should receive,
1021 * for IMAP we should synchronize everything, including receiving,
1022 * for SMTP we should send,
1023 * first receiving, then sending:
1025 /* Create the mail operation */
1026 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1027 ModestMailOperation *mail_op;
1028 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1029 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1030 modest_mail_operation_update_account (mail_op, acc_name);
1031 g_object_unref (G_OBJECT (mail_op));
1038 * Refreshes all accounts. This function will be used by automatic
1042 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1044 GSList *account_names, *iter;
1046 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1049 iter = account_names;
1051 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1052 iter = g_slist_next (iter);
1055 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1056 g_slist_free (account_names);
1060 * Handler of the click on Send&Receive button in the main toolbar
1063 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1065 /* Check that at least one account exists: */
1066 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1067 TRUE /* enabled accounts only */);
1068 gboolean accounts_exist = account_names != NULL;
1069 g_slist_free (account_names);
1071 /* If not, allow the user to create an account before trying to send/receive. */
1072 if (!accounts_exist)
1073 modest_ui_actions_on_accounts (NULL, win);
1075 /* Refresh the active account */
1076 modest_ui_actions_do_send_receive (NULL, win);
1081 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1084 GtkWidget *header_view;
1086 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1088 header_view = modest_main_window_get_child_widget (main_window,
1089 MODEST_WIDGET_TYPE_HEADER_VIEW);
1093 conf = modest_runtime_get_conf ();
1095 /* what is saved/restored is depending on the style; thus; we save with
1096 * old style, then update the style, and restore for this new style
1098 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1100 if (modest_header_view_get_style
1101 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1102 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1103 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1105 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1106 MODEST_HEADER_VIEW_STYLE_DETAILS);
1108 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1109 MODEST_CONF_HEADER_VIEW_KEY);
1114 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1116 ModestMainWindow *main_window)
1118 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1120 /* If no header has been selected then exit */
1124 /* Update Main window title */
1125 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1126 const gchar *subject = tny_header_get_subject (header);
1127 if (subject && strcmp (subject, ""))
1128 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1130 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1135 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1137 ModestMainWindow *main_window)
1141 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1146 headers = tny_simple_list_new ();
1147 tny_list_prepend (headers, G_OBJECT (header));
1149 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1151 g_object_unref (headers);
1155 set_active_account_from_tny_account (TnyAccount *account,
1156 ModestWindow *window)
1158 const gchar *server_acc_name = tny_account_get_id (account);
1160 /* We need the TnyAccount provided by the
1161 account store because that is the one that
1162 knows the name of the Modest account */
1163 TnyAccount *modest_server_account = modest_server_account =
1164 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1167 const gchar *modest_acc_name =
1168 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1169 modest_window_set_active_account (window, modest_acc_name);
1170 g_object_unref (modest_server_account);
1174 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1175 TnyFolderStore *folder_store,
1177 ModestMainWindow *main_window)
1180 GtkWidget *header_view;
1182 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1184 header_view = modest_main_window_get_child_widget(main_window,
1185 MODEST_WIDGET_TYPE_HEADER_VIEW);
1189 conf = modest_runtime_get_conf ();
1191 if (TNY_IS_ACCOUNT (folder_store)) {
1192 /* Update active account */
1193 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1194 /* Show account details */
1195 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1196 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1197 printf ("DEBUG: %s: folder store.\n", __FUNCTION__);
1198 //TODO: Set the virtual folder store as the "active account" somehow:
1199 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1201 if (TNY_IS_FOLDER (folder_store) && selected) {
1203 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1204 /* Update the active account */
1205 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1206 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1207 g_object_unref (account);
1210 /* Set folder on header view */
1211 modest_main_window_set_contents_style (main_window,
1212 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1213 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1214 TNY_FOLDER (folder_store));
1215 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1216 MODEST_CONF_HEADER_VIEW_KEY);
1218 /* Update the active account */
1219 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1220 /* Do not show folder */
1221 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1222 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1228 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1235 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1237 if (g_main_depth > 0)
1238 gdk_threads_enter ();
1239 online = tny_device_is_online (modest_runtime_get_device());
1242 /* already online -- the item is simply not there... */
1243 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1245 GTK_MESSAGE_WARNING,
1247 _("The %s you selected cannot be found"),
1249 gtk_dialog_run (GTK_DIALOG(dialog));
1251 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1255 GTK_RESPONSE_REJECT,
1257 GTK_RESPONSE_ACCEPT,
1259 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1260 "Do you want to get online?"), item);
1261 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1262 gtk_label_new (txt), FALSE, FALSE, 0);
1263 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1266 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1267 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1268 // modest_platform_connect_and_wait ();;
1271 gtk_widget_destroy (dialog);
1272 if (g_main_depth > 0)
1273 gdk_threads_leave ();
1277 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1280 /* g_message ("%s %s", __FUNCTION__, link); */
1285 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1288 modest_platform_activate_uri (link);
1292 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1295 modest_platform_show_uri_popup (link);
1299 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1302 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1306 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1307 const gchar *address,
1310 /* g_message ("%s %s", __FUNCTION__, address); */
1314 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1316 TnyTransportAccount *transport_account;
1317 ModestMailOperation *mail_operation;
1319 gchar *account_name, *from;
1320 ModestAccountMgr *account_mgr;
1322 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1324 data = modest_msg_edit_window_get_msg_data (edit_window);
1326 account_mgr = modest_runtime_get_account_mgr();
1327 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1329 account_name = modest_account_mgr_get_default_account (account_mgr);
1330 if (!account_name) {
1331 g_printerr ("modest: no account found\n");
1332 modest_msg_edit_window_free_msg_data (edit_window, data);
1336 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1337 (modest_runtime_get_account_store(),
1339 TNY_ACCOUNT_TYPE_TRANSPORT));
1340 if (!transport_account) {
1341 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1342 g_free (account_name);
1343 modest_msg_edit_window_free_msg_data (edit_window, data);
1346 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1348 /* Create the mail operation */
1349 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1350 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1352 modest_mail_operation_save_to_drafts (mail_operation,
1362 data->priority_flags);
1365 g_free (account_name);
1366 g_object_unref (G_OBJECT (transport_account));
1367 g_object_unref (G_OBJECT (mail_operation));
1369 modest_msg_edit_window_free_msg_data (edit_window, data);
1371 /* Save settings and close the window */
1372 gtk_widget_destroy (GTK_WIDGET (edit_window));
1375 /* For instance, when clicking the Send toolbar button when editing a message: */
1377 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1379 TnyTransportAccount *transport_account;
1380 ModestMailOperation *mail_operation;
1382 gchar *account_name, *from;
1383 ModestAccountMgr *account_mgr;
1385 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1387 if (!modest_msg_edit_window_check_names (edit_window))
1390 data = modest_msg_edit_window_get_msg_data (edit_window);
1392 /* FIXME: Code added just for testing. The final version will
1393 use the send queue provided by tinymail and some
1395 account_mgr = modest_runtime_get_account_mgr();
1396 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1398 account_name = modest_account_mgr_get_default_account (account_mgr);
1399 if (!account_name) {
1400 g_printerr ("modest: no account found\n");
1401 modest_msg_edit_window_free_msg_data (edit_window, data);
1405 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1406 (modest_runtime_get_account_store(),
1408 if (!transport_account) {
1409 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1410 g_free (account_name);
1411 modest_msg_edit_window_free_msg_data (edit_window, data);
1414 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1416 /* Create the mail operation */
1417 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1418 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1420 modest_mail_operation_send_new_mail (mail_operation,
1430 data->priority_flags);
1433 g_free (account_name);
1434 g_object_unref (G_OBJECT (transport_account));
1435 g_object_unref (G_OBJECT (mail_operation));
1437 modest_msg_edit_window_free_msg_data (edit_window, data);
1439 /* Save settings and close the window */
1440 gtk_widget_destroy (GTK_WIDGET (edit_window));
1444 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1445 ModestMsgEditWindow *window)
1447 ModestMsgEditFormatState *format_state = NULL;
1449 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1450 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1452 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1455 format_state = modest_msg_edit_window_get_format_state (window);
1456 g_return_if_fail (format_state != NULL);
1458 format_state->bold = gtk_toggle_action_get_active (action);
1459 modest_msg_edit_window_set_format_state (window, format_state);
1460 g_free (format_state);
1465 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1466 ModestMsgEditWindow *window)
1468 ModestMsgEditFormatState *format_state = NULL;
1470 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1471 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1473 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1476 format_state = modest_msg_edit_window_get_format_state (window);
1477 g_return_if_fail (format_state != NULL);
1479 format_state->italics = gtk_toggle_action_get_active (action);
1480 modest_msg_edit_window_set_format_state (window, format_state);
1481 g_free (format_state);
1486 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1487 ModestMsgEditWindow *window)
1489 ModestMsgEditFormatState *format_state = NULL;
1491 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1492 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1494 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1497 format_state = modest_msg_edit_window_get_format_state (window);
1498 g_return_if_fail (format_state != NULL);
1500 format_state->bullet = gtk_toggle_action_get_active (action);
1501 modest_msg_edit_window_set_format_state (window, format_state);
1502 g_free (format_state);
1507 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1508 GtkRadioAction *selected,
1509 ModestMsgEditWindow *window)
1511 ModestMsgEditFormatState *format_state = NULL;
1512 GtkJustification value;
1514 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1516 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1519 value = gtk_radio_action_get_current_value (selected);
1521 format_state = modest_msg_edit_window_get_format_state (window);
1522 g_return_if_fail (format_state != NULL);
1524 format_state->justification = value;
1525 modest_msg_edit_window_set_format_state (window, format_state);
1526 g_free (format_state);
1530 modest_ui_actions_on_select_editor_color (GtkAction *action,
1531 ModestMsgEditWindow *window)
1533 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1534 g_return_if_fail (GTK_IS_ACTION (action));
1536 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1539 modest_msg_edit_window_select_color (window);
1543 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1544 ModestMsgEditWindow *window)
1546 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1547 g_return_if_fail (GTK_IS_ACTION (action));
1549 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1552 modest_msg_edit_window_select_background_color (window);
1556 modest_ui_actions_on_insert_image (GtkAction *action,
1557 ModestMsgEditWindow *window)
1559 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1560 g_return_if_fail (GTK_IS_ACTION (action));
1562 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1565 modest_msg_edit_window_insert_image (window);
1569 modest_ui_actions_on_attach_file (GtkAction *action,
1570 ModestMsgEditWindow *window)
1572 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1573 g_return_if_fail (GTK_IS_ACTION (action));
1575 modest_msg_edit_window_attach_file (window);
1579 modest_ui_actions_on_remove_attachments (GtkAction *action,
1580 ModestMsgEditWindow *window)
1582 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1583 g_return_if_fail (GTK_IS_ACTION (action));
1585 modest_msg_edit_window_remove_attachments (window, NULL);
1589 * Shows a dialog with an entry that asks for some text. The returned
1590 * value must be freed by the caller. The dialog window title will be
1594 ask_for_folder_name (GtkWindow *parent_window,
1597 GtkWidget *dialog, *entry;
1598 gchar *folder_name = NULL;
1600 /* Ask for folder name */
1601 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1605 GTK_RESPONSE_REJECT,
1607 GTK_RESPONSE_ACCEPT,
1609 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1610 gtk_label_new(title),
1613 entry = gtk_entry_new_with_max_length (40);
1614 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1618 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1620 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1621 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1623 gtk_widget_destroy (dialog);
1629 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1631 TnyFolderStore *parent_folder;
1632 GtkWidget *folder_view;
1634 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1636 folder_view = modest_main_window_get_child_widget (main_window,
1637 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1641 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1643 if (parent_folder) {
1644 gboolean finished = FALSE;
1646 gchar *folder_name = NULL, *suggested_name = NULL;
1648 /* Run the new folder dialog */
1650 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1655 if (result == GTK_RESPONSE_REJECT) {
1658 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1659 TnyFolder *new_folder = NULL;
1661 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1664 new_folder = modest_mail_operation_create_folder (mail_op,
1666 (const gchar *) folder_name);
1668 g_object_unref (new_folder);
1672 /* /\* TODO: check error and follow proper actions *\/ */
1673 /* /\* suggested_name = X; *\/ */
1674 /* /\* Show error to the user *\/ */
1675 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1676 /* _("mail_in_ui_folder_create_error")); */
1678 g_object_unref (mail_op);
1680 g_free (folder_name);
1684 g_object_unref (parent_folder);
1689 modest_ui_actions_on_rename_folder (GtkAction *action,
1690 ModestMainWindow *main_window)
1692 TnyFolderStore *folder;
1693 GtkWidget *folder_view;
1694 GtkWidget *header_view;
1696 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1698 folder_view = modest_main_window_get_child_widget (main_window,
1699 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1703 header_view = modest_main_window_get_child_widget (main_window,
1704 MODEST_WIDGET_TYPE_HEADER_VIEW);
1709 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1711 if (folder && TNY_IS_FOLDER (folder)) {
1713 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1714 _("Please enter a new name for the folder"));
1716 if (folder_name != NULL && strlen (folder_name) > 0) {
1717 ModestMailOperation *mail_op;
1719 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1720 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1723 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1725 modest_mail_operation_rename_folder (mail_op,
1726 TNY_FOLDER (folder),
1727 (const gchar *) folder_name);
1729 g_object_unref (mail_op);
1730 g_free (folder_name);
1732 g_object_unref (folder);
1737 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1739 TnyFolderStore *folder;
1740 GtkWidget *folder_view;
1744 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1746 folder_view = modest_main_window_get_child_widget (main_window,
1747 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1751 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1753 /* Show an error if it's an account */
1754 if (!TNY_IS_FOLDER (folder)) {
1755 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1756 _("mail_in_ui_folder_delete_error"));
1761 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1762 tny_folder_get_name (TNY_FOLDER (folder)));
1763 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1764 (const gchar *) message);
1767 if (response == GTK_RESPONSE_OK) {
1768 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(main_window));
1770 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1772 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1774 /* Show error if happened */
1775 if (modest_mail_operation_get_error (mail_op))
1776 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1777 _("mail_in_ui_folder_delete_error"));
1779 g_object_unref (G_OBJECT (mail_op));
1782 g_object_unref (G_OBJECT (folder));
1786 modest_ui_actions_on_delete_folder (GtkAction *action,
1787 ModestMainWindow *main_window)
1789 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1791 delete_folder (main_window, FALSE);
1795 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1797 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1799 delete_folder (main_window, TRUE);
1803 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1804 const gchar* server_account_name,
1809 ModestMainWindow *main_window)
1811 g_return_if_fail(server_account_name);
1812 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1814 /* Initalize output parameters: */
1821 #ifdef MODEST_PLATFORM_MAEMO
1822 /* Maemo uses a different (awkward) button order,
1823 * It should probably just use gtk_alternative_dialog_button_order ().
1825 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1829 GTK_RESPONSE_ACCEPT,
1831 GTK_RESPONSE_REJECT,
1834 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1838 GTK_RESPONSE_REJECT,
1840 GTK_RESPONSE_ACCEPT,
1842 #endif /* MODEST_PLATFORM_MAEMO */
1844 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1846 gchar *server_name = modest_server_account_get_hostname (
1847 modest_runtime_get_account_mgr(), server_account_name);
1849 /* This causes a warning because the logical ID has no %s in it,
1850 * though the translation does, but there is not much we can do about that: */
1851 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1852 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1855 g_free (server_name);
1859 gchar *initial_username = modest_server_account_get_username (
1860 modest_runtime_get_account_mgr(), server_account_name);
1862 GtkWidget *entry_username = gtk_entry_new ();
1863 if (initial_username)
1864 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1865 /* Dim this if a connection has ever succeeded with this username,
1866 * as per the UI spec: */
1867 const gboolean username_known =
1868 modest_server_account_get_username_has_succeeded(
1869 modest_runtime_get_account_mgr(), server_account_name);
1870 gtk_widget_set_sensitive (entry_username, !username_known);
1872 #ifdef MODEST_PLATFORM_MAEMO
1873 /* Auto-capitalization is the default, so let's turn it off: */
1874 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1876 /* Create a size group to be used by all captions.
1877 * Note that HildonCaption does not create a default size group if we do not specify one.
1878 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1879 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1881 GtkWidget *caption = hildon_caption_new (sizegroup,
1882 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1883 gtk_widget_show (entry_username);
1884 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1885 FALSE, FALSE, MODEST_MARGIN_HALF);
1886 gtk_widget_show (caption);
1888 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1890 #endif /* MODEST_PLATFORM_MAEMO */
1893 GtkWidget *entry_password = gtk_entry_new ();
1894 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1895 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1897 #ifdef MODEST_PLATFORM_MAEMO
1898 /* Auto-capitalization is the default, so let's turn it off: */
1899 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1900 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1902 caption = hildon_caption_new (sizegroup,
1903 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1904 gtk_widget_show (entry_password);
1905 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1906 FALSE, FALSE, MODEST_MARGIN_HALF);
1907 gtk_widget_show (caption);
1908 g_object_unref (sizegroup);
1910 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1912 #endif /* MODEST_PLATFORM_MAEMO */
1914 /* This is not in the Maemo UI spec:
1915 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1916 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1920 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1922 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1924 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1926 modest_server_account_set_username (
1927 modest_runtime_get_account_mgr(), server_account_name,
1930 const gboolean username_was_changed =
1931 (strcmp (*username, initial_username) != 0);
1932 if (username_was_changed) {
1933 /* To actually use a changed username,
1934 * we must reset the connection, according to pvanhoof.
1935 * This _might_ be a sensible way to do that: */
1936 TnyDevice *device = modest_runtime_get_device();
1937 tny_device_force_offline (device);
1938 tny_device_force_online (device);
1943 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1945 /* We do not save the password in the configuration,
1946 * because this function is only called for passwords that should
1947 * not be remembered:
1948 modest_server_account_set_password (
1949 modest_runtime_get_account_mgr(), server_account_name,
1968 /* This is not in the Maemo UI spec:
1969 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1975 gtk_widget_destroy (dialog);
1977 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
1981 modest_ui_actions_on_cut (GtkAction *action,
1982 ModestWindow *window)
1984 GtkWidget *focused_widget;
1986 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1987 if (GTK_IS_EDITABLE (focused_widget)) {
1988 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1989 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1990 GtkTextBuffer *buffer;
1991 GtkClipboard *clipboard;
1993 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1994 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1995 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2000 modest_ui_actions_on_copy (GtkAction *action,
2001 ModestWindow *window)
2003 GtkClipboard *clipboard;
2004 GtkWidget *focused_widget;
2006 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2007 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2008 if (GTK_IS_LABEL (focused_widget)) {
2009 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2010 } else if (GTK_IS_EDITABLE (focused_widget)) {
2011 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2012 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2013 GtkTextBuffer *buffer;
2015 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2016 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2021 modest_ui_actions_on_undo (GtkAction *action,
2022 ModestWindow *window)
2024 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2025 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2027 g_return_if_reached ();
2032 modest_ui_actions_on_paste (GtkAction *action,
2033 ModestWindow *window)
2035 GtkWidget *focused_widget;
2037 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2038 if (GTK_IS_EDITABLE (focused_widget)) {
2039 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2040 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2041 GtkTextBuffer *buffer;
2042 GtkClipboard *clipboard;
2044 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2045 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2046 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2051 modest_ui_actions_on_select_all (GtkAction *action,
2052 ModestWindow *window)
2054 GtkWidget *focused_widget;
2056 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2057 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2058 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2059 } else if (GTK_IS_LABEL (focused_widget)) {
2060 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2061 } else if (GTK_IS_EDITABLE (focused_widget)) {
2062 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2063 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2064 GtkTextBuffer *buffer;
2065 GtkTextIter start, end;
2067 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2068 gtk_text_buffer_get_start_iter (buffer, &start);
2069 gtk_text_buffer_get_end_iter (buffer, &end);
2070 gtk_text_buffer_select_range (buffer, &start, &end);
2075 modest_ui_actions_on_mark_as_read (GtkAction *action,
2076 ModestWindow *window)
2078 g_return_if_fail (MODEST_IS_WINDOW(window));
2080 /* Mark each header as read */
2081 do_headers_action (window, headers_action_mark_as_read, NULL);
2085 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2086 ModestWindow *window)
2088 g_return_if_fail (MODEST_IS_WINDOW(window));
2090 /* Mark each header as read */
2091 do_headers_action (window, headers_action_mark_as_unread, NULL);
2095 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2096 GtkRadioAction *selected,
2097 ModestWindow *window)
2101 value = gtk_radio_action_get_current_value (selected);
2102 if (MODEST_IS_WINDOW (window)) {
2103 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2107 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2108 GtkRadioAction *selected,
2109 ModestWindow *window)
2111 TnyHeaderFlags flags;
2112 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2114 flags = gtk_radio_action_get_current_value (selected);
2115 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2118 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2119 GtkRadioAction *selected,
2120 ModestWindow *window)
2124 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2126 file_format = gtk_radio_action_get_current_value (selected);
2127 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2132 modest_ui_actions_on_zoom_plus (GtkAction *action,
2133 ModestWindow *window)
2135 g_return_if_fail (MODEST_IS_WINDOW (window));
2137 modest_window_zoom_plus (MODEST_WINDOW (window));
2141 modest_ui_actions_on_zoom_minus (GtkAction *action,
2142 ModestWindow *window)
2144 g_return_if_fail (MODEST_IS_WINDOW (window));
2146 modest_window_zoom_minus (MODEST_WINDOW (window));
2150 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2151 ModestWindow *window)
2153 ModestWindowMgr *mgr;
2154 gboolean fullscreen, active;
2155 g_return_if_fail (MODEST_IS_WINDOW (window));
2157 mgr = modest_runtime_get_window_mgr ();
2159 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2160 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2162 if (active != fullscreen) {
2163 modest_window_mgr_set_fullscreen_mode (mgr, active);
2164 gtk_window_present (GTK_WINDOW (window));
2169 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2170 ModestWindow *window)
2172 ModestWindowMgr *mgr;
2173 gboolean fullscreen;
2175 g_return_if_fail (MODEST_IS_WINDOW (window));
2177 mgr = modest_runtime_get_window_mgr ();
2178 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2179 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2181 gtk_window_present (GTK_WINDOW (window));
2185 * Used by modest_ui_actions_on_details to call do_headers_action
2188 headers_action_show_details (TnyHeader *header,
2189 ModestWindow *window,
2196 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2199 gtk_widget_show_all (dialog);
2200 gtk_dialog_run (GTK_DIALOG (dialog));
2202 gtk_widget_destroy (dialog);
2206 * Show the folder details in a ModestDetailsDialog widget
2209 show_folder_details (TnyFolder *folder,
2215 dialog = modest_details_dialog_new_with_folder (window, folder);
2218 gtk_widget_show_all (dialog);
2219 gtk_dialog_run (GTK_DIALOG (dialog));
2221 gtk_widget_destroy (dialog);
2225 * Show the header details in a ModestDetailsDialog widget
2228 modest_ui_actions_on_details (GtkAction *action,
2231 TnyList * headers_list;
2235 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2238 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2241 g_object_unref (msg);
2243 headers_list = get_selected_headers (win);
2247 iter = tny_list_create_iterator (headers_list);
2249 header = TNY_HEADER (tny_iterator_get_current (iter));
2250 headers_action_show_details (header, win, NULL);
2251 g_object_unref (header);
2253 g_object_unref (iter);
2254 g_object_unref (headers_list);
2256 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2257 GtkWidget *folder_view, *header_view;
2259 /* Check which widget has the focus */
2260 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2261 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2262 if (gtk_widget_is_focus (folder_view)) {
2265 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2267 /* Show only when it's a folder */
2268 if (!folder || !TNY_IS_FOLDER (folder))
2271 show_folder_details (folder, GTK_WINDOW (win));
2274 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2275 MODEST_WIDGET_TYPE_HEADER_VIEW);
2276 /* Show details of each header */
2277 do_headers_action (win, headers_action_show_details, header_view);
2283 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2284 ModestMsgEditWindow *window)
2286 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2288 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2292 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2293 ModestMsgEditWindow *window)
2295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2297 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2301 modest_ui_actions_toggle_folders_view (GtkAction *action,
2302 ModestMainWindow *main_window)
2306 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2308 conf = modest_runtime_get_conf ();
2310 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2311 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2313 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2317 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2318 ModestWindow *window)
2320 gboolean active, fullscreen = FALSE;
2321 ModestWindowMgr *mgr;
2323 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2325 /* Check if we want to toggle the toolbar vuew in fullscreen
2327 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2328 "ViewShowToolbarFullScreen")) {
2332 /* Toggle toolbar */
2333 mgr = modest_runtime_get_window_mgr ();
2334 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2338 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2339 ModestMsgEditWindow *window)
2341 modest_msg_edit_window_select_font (window);
2345 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2346 const gchar *display_name,
2349 /* Do not change the application name if the widget has not
2350 the focus. This callback could be called even if the folder
2351 view has not the focus, because the handled signal could be
2352 emitted when the folder view is redrawn */
2353 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2355 gtk_window_set_title (window, display_name);
2357 gtk_window_set_title (window, " ");
2362 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2365 modest_msg_edit_window_select_contacts (window);
2369 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2371 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2372 modest_msg_edit_window_check_names (window);
2377 create_move_to_dialog (ModestWindow *win,
2378 GtkWidget *folder_view,
2379 GtkWidget **tree_view)
2381 GtkWidget *dialog, *scroll;
2383 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2385 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2387 GTK_RESPONSE_ACCEPT,
2389 GTK_RESPONSE_REJECT,
2392 /* Create scrolled window */
2393 scroll = gtk_scrolled_window_new (NULL, NULL);
2394 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2395 GTK_POLICY_AUTOMATIC,
2396 GTK_POLICY_AUTOMATIC);
2398 /* Create folder view */
2399 *tree_view = modest_folder_view_new (NULL);
2400 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2401 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2402 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2404 /* Add scroll to dialog */
2405 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2406 scroll, FALSE, FALSE, 0);
2408 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2414 * Returns TRUE if at least one of the headers of the list belongs to
2415 * a message that has been fully retrieved.
2418 has_retrieved_msgs (TnyList *list)
2421 gboolean found = FALSE;
2423 iter = tny_list_create_iterator (list);
2424 while (tny_iterator_is_done (iter) && !found) {
2426 TnyHeaderFlags flags;
2428 header = TNY_HEADER (tny_iterator_get_current (iter));
2429 flags = tny_header_get_flags (header);
2430 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2434 tny_iterator_next (iter);
2436 g_object_unref (iter);
2442 * Shows a confirmation dialog to the user when we're moving messages
2443 * from a remote server to the local storage. Returns the dialog
2444 * response. If it's other kind of movement the it always returns
2448 msgs_move_to_confirmation (GtkWindow *win,
2449 TnyFolder *dest_folder,
2452 gint response = GTK_RESPONSE_OK;
2454 /* If the destination is a local folder */
2455 if (modest_tny_folder_is_local_folder (dest_folder)) {
2456 TnyFolder *src_folder;
2460 /* Get source folder */
2461 iter = tny_list_create_iterator (headers);
2462 header = TNY_HEADER (tny_iterator_get_current (iter));
2463 src_folder = tny_header_get_folder (header);
2464 g_object_unref (header);
2465 g_object_unref (iter);
2467 /* If the source is a remote folder */
2468 if (!modest_tny_folder_is_local_folder (src_folder)) {
2469 const gchar *message;
2471 if (tny_list_get_length (headers) == 1)
2472 if (has_retrieved_msgs (headers))
2473 message = _("mcen_nc_move_retrieve");
2475 message = _("mcen_nc_move_header");
2477 if (has_retrieved_msgs (headers))
2478 message = _("mcen_nc_move_retrieves");
2480 message = _("mcen_nc_move_headers");
2482 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2483 (const gchar *) message);
2485 g_object_unref (src_folder);
2492 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2494 ModestMsgViewWindow *self = NULL;
2495 gboolean found = FALSE;
2497 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2498 self = MODEST_MSG_VIEW_WINDOW (object);
2500 found = modest_msg_view_window_select_first_message (self);
2501 g_return_if_fail (found);
2505 move_to_error_checking (const GObject *obj, gpointer user_data)
2507 ModestWindow *win = NULL;
2509 g_return_if_fail (MODEST_IS_WINDOW (obj));
2510 win = MODEST_WINDOW (obj);
2512 /* TODO: show error message */
2513 /* modest_platform_run_information_dialog (GTK_WINDOW (win), */
2514 /* _("mail_in_ui_folder_move_target_error")); */
2518 * UI handler for the "Move to" action when invoked from the
2522 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2523 ModestMainWindow *win)
2525 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2526 GtkWidget *header_view = NULL;
2528 TnyFolderStore *folder_store = NULL;
2529 ModestMailOperation *mail_op = NULL;
2531 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2533 /* Get the folder view */
2534 folder_view = modest_main_window_get_child_widget (win,
2535 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2537 /* Get header view */
2538 header_view = modest_main_window_get_child_widget (win,
2539 MODEST_WIDGET_TYPE_HEADER_VIEW);
2541 /* Create and run the dialog */
2542 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2543 result = gtk_dialog_run (GTK_DIALOG(dialog));
2544 g_object_ref (tree_view);
2546 /* We do this to save an indentation level ;-) */
2547 if (result != GTK_RESPONSE_ACCEPT)
2550 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2552 if (TNY_IS_ACCOUNT (folder_store))
2555 /* Get folder or messages to transfer */
2556 if (gtk_widget_is_focus (folder_view)) {
2557 TnyFolderStore *src_folder;
2558 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2560 /* Clean folder on header view before moving it */
2561 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2563 if (TNY_IS_FOLDER (src_folder)) {
2564 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2566 move_to_error_checking);
2567 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2570 modest_mail_operation_xfer_folder (mail_op,
2571 TNY_FOLDER (src_folder),
2574 g_object_unref (G_OBJECT (mail_op));
2579 g_object_unref (G_OBJECT (src_folder));
2581 if (gtk_widget_is_focus (header_view)) {
2585 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2587 /* Ask for user confirmation */
2588 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2589 TNY_FOLDER (folder_store),
2592 /* Transfer messages */
2593 if (response == GTK_RESPONSE_OK) {
2594 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2595 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2598 modest_mail_operation_xfer_msgs (mail_op,
2600 TNY_FOLDER (folder_store),
2604 g_object_unref (G_OBJECT (mail_op));
2606 g_object_unref (headers);
2609 g_object_unref (folder_store);
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 (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT (window));
2792 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2793 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2796 g_object_unref (headers);
2797 g_object_unref (mail_op);