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 #include <widgets/modest-main-window.h>
48 #include <widgets/modest-msg-view-window.h>
49 #include <widgets/modest-account-view-window.h>
50 #include <widgets/modest-details-dialog.h>
52 #include "modest-account-mgr-helpers.h"
53 #include "modest-mail-operation.h"
54 #include "modest-text-utils.h"
56 #ifdef MODEST_HAVE_EASYSETUP
57 #include "easysetup/modest-easysetup-wizard.h"
58 #endif /*MODEST_HAVE_EASYSETUP*/
60 #include <modest-widget-memory.h>
61 #include <tny-error.h>
62 #include <tny-simple-list.h>
63 #include <tny-msg-view.h>
64 #include <tny-device.h>
66 typedef struct _GetMsgAsyncHelper {
73 typedef enum _ReplyForwardAction {
79 typedef struct _ReplyForwardHelper {
80 guint reply_forward_type;
81 ReplyForwardAction action;
86 static void reply_forward_func (gpointer data, gpointer user_data);
87 static void read_msg_func (gpointer data, gpointer user_data);
88 static void get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err,
90 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
92 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
96 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
99 const gchar *authors[] = {
100 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
103 about = gtk_about_dialog_new ();
104 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
105 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
106 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
107 _("Copyright (c) 2006, Nokia Corporation\n"
108 "All rights reserved."));
109 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
110 _("a modest e-mail client\n\n"
111 "design and implementation: Dirk-Jan C. Binnema\n"
112 "contributions from the fine people at KC and Ig\n"
113 "uses the tinymail email framework written by Philip van Hoof"));
114 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
115 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
117 gtk_dialog_run (GTK_DIALOG (about));
118 gtk_widget_destroy(about);
123 get_selected_headers (ModestWindow *win)
125 if (MODEST_IS_MAIN_WINDOW(win)) {
126 GtkWidget *header_view;
128 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
129 MODEST_WIDGET_TYPE_HEADER_VIEW);
130 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
132 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
133 /* for MsgViewWindows, we simply return a list with one element */
136 TnyList *list = NULL;
138 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
140 header = tny_msg_get_header (msg);
141 list = tny_simple_list_new ();
142 tny_list_prepend (list, G_OBJECT(header));
143 g_object_unref (G_OBJECT(header));
152 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
154 TnyList *header_list;
157 g_return_if_fail (MODEST_IS_WINDOW(win));
159 header_list = get_selected_headers (win);
162 iter = tny_list_create_iterator (header_list);
165 ModestMailOperation *mail_op;
167 header = TNY_HEADER (tny_iterator_get_current (iter));
168 /* TODO: thick grain mail operation involving
169 a list of objects. Composite pattern ??? */
170 /* TODO: add confirmation dialog */
171 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE);
172 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
175 /* Always delete. TODO: Move to trash still not supported */
176 modest_mail_operation_remove_msg (mail_op, header, FALSE);
179 g_object_unref (G_OBJECT (mail_op));
180 g_object_unref (G_OBJECT (header));
182 tny_iterator_next (iter);
184 } while (!tny_iterator_is_done (iter));
187 g_object_unref (G_OBJECT (iter));
190 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
191 gtk_widget_destroy (GTK_WIDGET(win));
197 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
203 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
205 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
206 gtk_widget_destroy (GTK_WIDGET (win));
207 } else if (MODEST_IS_WINDOW (win)) {
208 gtk_widget_destroy (GTK_WIDGET (win));
210 g_return_if_reached ();
215 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
217 GtkClipboard *clipboard = NULL;
218 gchar *selection = NULL;
220 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
221 selection = gtk_clipboard_wait_for_text (clipboard);
223 modest_address_book_add_address (selection);
228 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
231 /* This is currently only implemented for Maemo,
232 * because it requires a providers preset file which is not publically available.
234 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
235 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
236 gboolean accounts_exist = account_names != NULL;
237 g_slist_free (account_names);
239 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
240 if (!accounts_exist) {
241 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
242 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
243 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
244 gtk_dialog_run (GTK_DIALOG (wizard));
245 gtk_widget_destroy (GTK_WIDGET (wizard));
247 /* Show the list of accounts: */
248 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
249 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
250 gtk_dialog_run (account_win);
251 gtk_widget_destroy (GTK_WIDGET(account_win));
254 GtkWidget *dialog, *label;
256 /* Create the widgets */
258 dialog = gtk_dialog_new_with_buttons ("Message",
260 GTK_DIALOG_DESTROY_WITH_PARENT,
264 label = gtk_label_new ("Hello World!");
266 /* Ensure that the dialog box is destroyed when the user responds. */
268 g_signal_connect_swapped (dialog, "response",
269 G_CALLBACK (gtk_widget_destroy),
272 /* Add the label, and show everything we've added to the dialog. */
274 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
276 gtk_widget_show_all (dialog);
277 #endif /* MODEST_PLATFORM_MAEMO */
281 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
283 ModestWindow *msg_win;
285 TnyFolder *folder = NULL;
286 gchar *account_name = NULL;
287 gchar *from_str = NULL;
289 TnyAccount *account = NULL;
290 ModestWindowMgr *mgr;
292 account_name = g_strdup(modest_window_get_active_account (win));
294 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
296 g_printerr ("modest: no account found\n");
300 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
302 TNY_ACCOUNT_TYPE_STORE);
304 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
308 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
310 g_printerr ("modest: failed get from string for '%s'\n", account_name);
314 msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
316 g_printerr ("modest: failed to create new msg\n");
320 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
322 g_printerr ("modest: failed to find Drafts folder\n");
326 tny_folder_add_msg (folder, msg, &err);
328 g_printerr ("modest: error adding msg to Drafts folder: %s",
334 /* Create and register edit window */
335 msg_win = modest_msg_edit_window_new (msg, account_name);
336 mgr = modest_runtime_get_window_mgr ();
337 modest_window_mgr_register_window (mgr, msg_win);
340 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
342 gtk_widget_show_all (GTK_WIDGET (msg_win));
345 g_free (account_name);
348 g_object_unref (G_OBJECT(account));
350 g_object_unref (G_OBJECT(msg));
352 g_object_unref (G_OBJECT(folder));
357 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
359 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
365 reply_forward_func (gpointer data, gpointer user_data)
367 TnyMsg *msg, *new_msg;
368 GetMsgAsyncHelper *helper;
369 ReplyForwardHelper *rf_helper;
370 ModestWindow *msg_win;
371 ModestEditType edit_type;
374 TnyFolder *folder = NULL;
375 TnyAccount *account = NULL;
376 ModestWindowMgr *mgr;
378 msg = TNY_MSG (data);
379 helper = (GetMsgAsyncHelper *) user_data;
380 rf_helper = (ReplyForwardHelper *) helper->user_data;
382 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
383 rf_helper->account_name);
384 /* Create reply mail */
385 switch (rf_helper->action) {
388 modest_tny_msg_create_reply_msg (msg, from,
389 rf_helper->reply_forward_type,
390 MODEST_TNY_MSG_REPLY_MODE_SENDER);
392 case ACTION_REPLY_TO_ALL:
394 modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
395 MODEST_TNY_MSG_REPLY_MODE_ALL);
396 edit_type = MODEST_EDIT_TYPE_REPLY;
400 modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
401 edit_type = MODEST_EDIT_TYPE_FORWARD;
404 g_return_if_reached ();
409 g_printerr ("modest: failed to create message\n");
413 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
414 rf_helper->account_name,
415 TNY_ACCOUNT_TYPE_STORE);
417 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
421 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
423 g_printerr ("modest: failed to find Drafts folder\n");
427 tny_folder_add_msg (folder, msg, &err);
429 g_printerr ("modest: error adding msg to Drafts folder: %s",
435 /* Create and register the windows */
436 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
437 mgr = modest_runtime_get_window_mgr ();
438 modest_window_mgr_register_window (mgr, msg_win);
440 /* Show edit window */
441 gtk_widget_show_all (GTK_WIDGET (msg_win));
445 g_object_unref (G_OBJECT (new_msg));
447 g_object_unref (G_OBJECT (folder));
449 g_object_unref (G_OBJECT (account));
451 g_free (rf_helper->account_name);
452 g_slice_free (ReplyForwardHelper, rf_helper);
455 * Common code for the reply and forward actions
458 reply_forward (ReplyForwardAction action, ModestWindow *win)
460 TnyList *header_list;
461 guint reply_forward_type;
464 GetMsgAsyncHelper *helper;
465 ReplyForwardHelper *rf_helper;
467 g_return_if_fail (MODEST_IS_WINDOW(win));
469 header_list = get_selected_headers (win);
473 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
474 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
476 /* We assume that we can only select messages of the
477 same folder and that we reply all of them from the
478 same account. In fact the interface currently only
479 allows single selection */
482 rf_helper = g_slice_new0 (ReplyForwardHelper);
483 rf_helper->reply_forward_type = reply_forward_type;
484 rf_helper->action = action;
486 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
487 if (!rf_helper->account_name)
488 rf_helper->account_name =
489 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
491 helper = g_slice_new0 (GetMsgAsyncHelper);
492 helper->window = win;
493 helper->func = reply_forward_func;
494 helper->iter = tny_list_create_iterator (header_list);
495 helper->user_data = rf_helper;
497 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
499 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
501 g_printerr ("modest: no message found\n");
504 reply_forward_func (msg, helper);
506 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
507 folder = tny_header_get_folder (header);
509 /* The callback will call it per each header */
510 tny_folder_get_msg_async (folder, header, get_msg_cb, NULL, helper);
511 g_object_unref (G_OBJECT (folder));
513 g_printerr ("modest: no folder for header\n");
516 g_object_unref (G_OBJECT (header));
522 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
524 g_return_if_fail (MODEST_IS_WINDOW(win));
526 reply_forward (ACTION_REPLY, win);
530 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
532 g_return_if_fail (MODEST_IS_WINDOW(win));
534 reply_forward (ACTION_FORWARD, win);
538 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
540 g_return_if_fail (MODEST_IS_WINDOW(win));
542 reply_forward (ACTION_REPLY_TO_ALL, win);
546 modest_ui_actions_on_next (GtkAction *action,
547 ModestWindow *window)
549 if (MODEST_IS_MAIN_WINDOW (window)) {
550 GtkWidget *header_view;
552 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
553 MODEST_WIDGET_TYPE_HEADER_VIEW);
557 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
558 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
559 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
561 g_return_if_reached ();
566 modest_ui_actions_on_prev (GtkAction *action,
567 ModestWindow *window)
569 g_return_if_fail (MODEST_IS_WINDOW(window));
571 if (MODEST_IS_MAIN_WINDOW (window)) {
572 GtkWidget *header_view;
573 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
574 MODEST_WIDGET_TYPE_HEADER_VIEW);
578 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
579 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
580 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
582 g_return_if_reached ();
587 modest_ui_actions_on_sort (GtkAction *action,
588 ModestWindow *window)
590 g_return_if_fail (MODEST_IS_WINDOW(window));
592 if (MODEST_IS_MAIN_WINDOW (window)) {
593 GtkWidget *header_view;
594 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
595 MODEST_WIDGET_TYPE_HEADER_VIEW);
599 /* Show sorting dialog */
600 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
606 action_send (const gchar* account_name)
608 TnyAccount *tny_account;
609 ModestTnySendQueue *send_queue;
611 g_return_val_if_fail (account_name, FALSE);
613 /* Get the transport account according to the open connection,
614 * because the account might specify connection-specific SMTP servers.
617 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
620 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
624 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
626 g_object_unref (G_OBJECT(tny_account));
627 g_printerr ("modest: cannot get send queue for %s\n", account_name);
631 //modest_tny_send_queue_flush (send_queue);
633 g_object_unref (G_OBJECT(send_queue));
634 g_object_unref (G_OBJECT(tny_account));
641 action_receive (const gchar* account_name)
643 TnyAccount *tny_account;
644 ModestMailOperation *mail_op;
646 g_return_val_if_fail (account_name, FALSE);
649 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
651 TNY_ACCOUNT_TYPE_STORE);
653 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
657 /* Create the mail operation */
658 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
659 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
660 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
661 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
663 g_object_unref (G_OBJECT(tny_account));
664 g_object_unref (G_OBJECT (mail_op));
669 /** Check that an appropriate connection is open.
671 gboolean check_for_connection (const gchar *account_name)
673 TnyDevice *device = modest_runtime_get_device ();
676 g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
678 TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
681 if (tny_device_is_online (device))
684 modest_platform_connect_and_wait (NULL);
686 /* TODO: Wait until a result. */
692 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
697 g_message ("%s: online? %s", __FUNCTION__,
698 tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
700 /* As per the UI spec, only the active account should be affected,
701 * else the default folder if there is no active account: */
703 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
705 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
707 g_printerr ("modest: cannot get default account\n");
711 /* Do not continue if no suitable connection is open: */
712 if (!check_for_connection (account_name))
715 /* As per the UI spec,
716 * for POP accounts, we should receive,
717 * for IMAP we should synchronize everything, including receiving,
718 * for SMTP we should send,
719 * first receiving, then sending:
721 if (!action_receive(account_name))
722 g_printerr ("modest: failed to receive\n");
723 if (!action_send(account_name))
724 g_printerr ("modest: failed to send\n");
731 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
734 GtkWidget *header_view;
736 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
738 header_view = modest_main_window_get_child_widget (main_window,
739 MODEST_WIDGET_TYPE_HEADER_VIEW);
743 conf = modest_runtime_get_conf ();
745 /* what is saved/restored is depending on the style; thus; we save with
746 * old style, then update the style, and restore for this new style
748 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
750 if (modest_header_view_get_style
751 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
752 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
753 MODEST_HEADER_VIEW_STYLE_TWOLINES);
755 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
756 MODEST_HEADER_VIEW_STYLE_DETAILS);
758 modest_widget_memory_restore (conf, G_OBJECT(header_view),
765 * Marks a message as read and passes it to the msg preview widget
768 read_msg_func (gpointer data, gpointer user_data)
772 GetMsgAsyncHelper *helper;
773 TnyHeaderFlags header_flags;
774 GtkWidget *msg_preview;
776 msg = TNY_MSG (data);
777 helper = (GetMsgAsyncHelper *) user_data;
779 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
780 MODEST_WIDGET_TYPE_MSG_PREVIEW);
784 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
785 header_flags = tny_header_get_flags (header);
786 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
787 g_object_unref (G_OBJECT (header));
789 /* Set message on msg view */
790 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
794 * This function is a generic handler for the tny_folder_get_msg_async
795 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
796 * contains a user provided function that is called inside this
797 * method. This will allow us to use this callback in many different
798 * places. This callback performs the common actions for the
799 * get_msg_async call, more specific actions will be done by the user
803 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
805 GetMsgAsyncHelper *helper;
807 helper = (GetMsgAsyncHelper *) user_data;
809 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
810 modest_ui_actions_on_item_not_found (NULL,
811 MODEST_ITEM_TYPE_MESSAGE,
816 /* Call user function */
817 helper->func (msg, user_data);
819 /* Process next element (if exists) */
820 tny_iterator_next (helper->iter);
821 if (tny_iterator_is_done (helper->iter)) {
823 headers = tny_iterator_get_list (helper->iter);
825 g_object_unref (G_OBJECT (headers));
826 g_object_unref (G_OBJECT (helper->iter));
827 g_slice_free (GetMsgAsyncHelper, helper);
830 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
831 tny_folder_get_msg_async (folder, header,
832 get_msg_cb, NULL, helper);
833 g_object_unref (G_OBJECT(header));
838 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
840 ModestMainWindow *main_window)
843 GetMsgAsyncHelper *helper;
846 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
848 /* when there's no header, clear the msgview */
850 GtkWidget *msg_preview;
852 /* Clear msg preview if exists */
853 msg_preview = modest_main_window_get_child_widget(main_window,
854 MODEST_WIDGET_TYPE_MSG_PREVIEW);
857 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
861 /* Update Main window title */
862 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
863 const gchar *subject = tny_header_get_subject (header);
864 if (subject && strcmp (subject, ""))
865 gtk_window_set_title (GTK_WINDOW (main_window), subject);
867 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
871 list = tny_simple_list_new ();
872 tny_list_prepend (list, G_OBJECT (header));
874 /* Fill helper data */
875 helper = g_slice_new0 (GetMsgAsyncHelper);
876 helper->window = MODEST_WINDOW (main_window);
877 helper->iter = tny_list_create_iterator (list);
878 helper->func = read_msg_func;
880 folder = tny_header_get_folder (TNY_HEADER(header));
882 tny_folder_get_msg_async (TNY_FOLDER(folder),
887 g_object_unref (G_OBJECT (folder));
893 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
894 ModestMainWindow *main_window)
896 ModestWindow *win = NULL;
897 TnyFolder *folder = NULL;
899 ModestWindowMgr *mgr;
901 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
906 folder = tny_header_get_folder (header);
908 g_printerr ("modest: cannot get folder for header\n");
912 /* FIXME: make async?; check error */
913 msg = tny_folder_get_msg (folder, header, NULL);
915 g_printerr ("modest: cannot get msg for header\n");
919 /* Look if we already have a message view for that header */
920 mgr = modest_runtime_get_window_mgr ();
921 win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
923 /* If not, create a new window */
927 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
929 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
931 win = modest_msg_view_window_new (msg, account);
932 modest_window_mgr_register_window (mgr, win);
934 gtk_window_set_transient_for (GTK_WINDOW (win),
935 GTK_WINDOW (main_window));
938 gtk_widget_show_all (GTK_WIDGET(win));
940 g_object_unref (G_OBJECT (msg));
943 g_object_unref (G_OBJECT (folder));
947 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
948 TnyFolderStore *folder_store,
950 ModestMainWindow *main_window)
953 GtkWidget *header_view;
955 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
957 header_view = modest_main_window_get_child_widget(main_window,
958 MODEST_WIDGET_TYPE_HEADER_VIEW);
962 conf = modest_runtime_get_conf ();
964 if (TNY_IS_FOLDER (folder_store)) {
966 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
969 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
970 TNY_FOLDER (folder_store));
971 modest_widget_memory_restore (conf, G_OBJECT(header_view),
974 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
975 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
977 } else if (TNY_IS_ACCOUNT (folder_store)) {
979 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
984 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
991 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
993 if (g_main_depth > 0)
994 gdk_threads_enter ();
995 online = tny_device_is_online (modest_runtime_get_device());
998 /* already online -- the item is simply not there... */
999 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1001 GTK_MESSAGE_WARNING,
1003 _("The %s you selected cannot be found"),
1005 gtk_dialog_run (GTK_DIALOG(dialog));
1007 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1011 GTK_RESPONSE_REJECT,
1013 GTK_RESPONSE_ACCEPT,
1015 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1016 "Do you want to get online?"), item);
1017 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1018 gtk_label_new (txt), FALSE, FALSE, 0);
1019 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1022 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1023 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1024 // modest_platform_connect_and_wait ();;
1027 gtk_widget_destroy (dialog);
1028 if (g_main_depth > 0)
1029 gdk_threads_leave ();
1033 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1036 g_message ("%s %s", __FUNCTION__, link);
1041 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1044 modest_platform_activate_uri (link);
1048 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1051 modest_platform_show_uri_popup (link);
1055 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1058 g_message (__FUNCTION__);
1063 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1064 const gchar *address,
1067 g_message ("%s %s", __FUNCTION__, address);
1071 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1073 TnyTransportAccount *transport_account;
1074 ModestMailOperation *mail_operation;
1076 gchar *account_name, *from;
1077 ModestAccountMgr *account_mgr;
1079 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1081 data = modest_msg_edit_window_get_msg_data (edit_window);
1083 /* FIXME: Code added just for testing. The final version will
1084 use the send queue provided by tinymail and some
1086 account_mgr = modest_runtime_get_account_mgr();
1087 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1089 account_name = modest_account_mgr_get_default_account (account_mgr);
1090 if (!account_name) {
1091 g_printerr ("modest: no account found\n");
1092 modest_msg_edit_window_free_msg_data (edit_window, data);
1096 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1097 (modest_runtime_get_account_store(),
1099 if (!transport_account) {
1100 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1101 g_free (account_name);
1102 modest_msg_edit_window_free_msg_data (edit_window, data);
1105 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1107 /* Create the mail operation */
1108 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND);
1109 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1111 modest_mail_operation_send_new_mail (mail_operation,
1121 data->priority_flags);
1124 g_free (account_name);
1125 g_object_unref (G_OBJECT (transport_account));
1126 g_object_unref (G_OBJECT (mail_operation));
1128 modest_msg_edit_window_free_msg_data (edit_window, data);
1130 /* Save settings and close the window */
1131 gtk_widget_destroy (GTK_WIDGET (edit_window));
1135 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1136 ModestMsgEditWindow *window)
1138 ModestMsgEditFormatState *format_state = NULL;
1140 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1141 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1143 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1146 format_state = modest_msg_edit_window_get_format_state (window);
1147 g_return_if_fail (format_state != NULL);
1149 format_state->bold = gtk_toggle_action_get_active (action);
1150 modest_msg_edit_window_set_format_state (window, format_state);
1151 g_free (format_state);
1156 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1157 ModestMsgEditWindow *window)
1159 ModestMsgEditFormatState *format_state = NULL;
1161 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1162 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1164 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1167 format_state = modest_msg_edit_window_get_format_state (window);
1168 g_return_if_fail (format_state != NULL);
1170 format_state->italics = gtk_toggle_action_get_active (action);
1171 modest_msg_edit_window_set_format_state (window, format_state);
1172 g_free (format_state);
1177 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1178 ModestMsgEditWindow *window)
1180 ModestMsgEditFormatState *format_state = NULL;
1182 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1183 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1185 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1188 format_state = modest_msg_edit_window_get_format_state (window);
1189 g_return_if_fail (format_state != NULL);
1191 format_state->bullet = gtk_toggle_action_get_active (action);
1192 modest_msg_edit_window_set_format_state (window, format_state);
1193 g_free (format_state);
1198 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1199 GtkRadioAction *selected,
1200 ModestMsgEditWindow *window)
1202 ModestMsgEditFormatState *format_state = NULL;
1203 GtkJustification value;
1205 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1207 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1210 value = gtk_radio_action_get_current_value (selected);
1212 format_state = modest_msg_edit_window_get_format_state (window);
1213 g_return_if_fail (format_state != NULL);
1215 format_state->justification = value;
1216 modest_msg_edit_window_set_format_state (window, format_state);
1217 g_free (format_state);
1221 modest_ui_actions_on_select_editor_color (GtkAction *action,
1222 ModestMsgEditWindow *window)
1224 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1225 g_return_if_fail (GTK_IS_ACTION (action));
1227 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1230 modest_msg_edit_window_select_color (window);
1234 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1235 ModestMsgEditWindow *window)
1237 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1238 g_return_if_fail (GTK_IS_ACTION (action));
1240 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1243 modest_msg_edit_window_select_background_color (window);
1247 modest_ui_actions_on_insert_image (GtkAction *action,
1248 ModestMsgEditWindow *window)
1250 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1251 g_return_if_fail (GTK_IS_ACTION (action));
1253 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1256 modest_msg_edit_window_insert_image (window);
1260 * Shows a dialog with an entry that asks for some text. The returned
1261 * value must be freed by the caller. The dialog window title will be
1265 ask_for_folder_name (GtkWindow *parent_window,
1268 GtkWidget *dialog, *entry;
1269 gchar *folder_name = NULL;
1271 /* Ask for folder name */
1272 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1276 GTK_RESPONSE_REJECT,
1278 GTK_RESPONSE_ACCEPT,
1280 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1281 gtk_label_new(title),
1284 entry = gtk_entry_new_with_max_length (40);
1285 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1289 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1291 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1292 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1294 gtk_widget_destroy (dialog);
1300 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1302 TnyFolderStore *parent_folder;
1303 GtkWidget *folder_view;
1305 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1307 folder_view = modest_main_window_get_child_widget (main_window,
1308 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1312 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1314 if (parent_folder) {
1315 gboolean finished = FALSE;
1317 gchar *folder_name = NULL, *suggested_name = NULL;
1319 /* Run the new folder dialog */
1321 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1326 if (result == GTK_RESPONSE_REJECT) {
1329 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1330 TnyFolder *new_folder = NULL;
1332 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1335 new_folder = modest_mail_operation_create_folder (mail_op,
1337 (const gchar *) folder_name);
1339 g_object_unref (new_folder);
1343 /* /\* TODO: check error and follow proper actions *\/ */
1344 /* /\* suggested_name = X; *\/ */
1345 /* /\* Show error to the user *\/ */
1346 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1347 /* MODEST_INFORMATION_CREATE_FOLDER); */
1349 g_object_unref (mail_op);
1351 g_free (folder_name);
1355 g_object_unref (parent_folder);
1360 modest_ui_actions_on_rename_folder (GtkAction *action,
1361 ModestMainWindow *main_window)
1363 TnyFolderStore *folder;
1364 GtkWidget *folder_view;
1366 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1368 folder_view = modest_main_window_get_child_widget (main_window,
1369 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1373 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1375 if (folder && TNY_IS_FOLDER (folder)) {
1377 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1378 _("Please enter a new name for the folder"));
1380 if (folder_name != NULL && strlen (folder_name) > 0) {
1381 ModestMailOperation *mail_op;
1383 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1384 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1387 modest_mail_operation_rename_folder (mail_op,
1388 TNY_FOLDER (folder),
1389 (const gchar *) folder_name);
1391 g_object_unref (mail_op);
1392 g_free (folder_name);
1394 g_object_unref (folder);
1399 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1401 TnyFolderStore *folder;
1402 GtkWidget *folder_view;
1406 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1408 folder_view = modest_main_window_get_child_widget (main_window,
1409 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1413 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1416 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1417 tny_folder_get_name (TNY_FOLDER (folder)));
1418 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1419 (const gchar *) message);
1422 if (response == GTK_RESPONSE_OK) {
1423 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE);
1425 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1427 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1429 /* Show error if happened */
1430 if (modest_mail_operation_get_error (mail_op))
1431 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1432 MODEST_INFORMATION_DELETE_FOLDER);
1434 g_object_unref (G_OBJECT (mail_op));
1437 g_object_unref (G_OBJECT (folder));
1441 modest_ui_actions_on_delete_folder (GtkAction *action,
1442 ModestMainWindow *main_window)
1444 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1446 delete_folder (main_window, FALSE);
1450 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1452 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1454 delete_folder (main_window, TRUE);
1458 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1459 const gchar* account_name,
1463 ModestMainWindow *main_window)
1466 GtkWidget *dialog, *entry, *remember_pass_check;
1468 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1472 GTK_RESPONSE_REJECT,
1474 GTK_RESPONSE_ACCEPT,
1476 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1478 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1479 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1483 entry = gtk_entry_new_with_max_length (40);
1484 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1485 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1487 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1490 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1491 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1494 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1496 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1497 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1504 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1509 gtk_widget_destroy (dialog);
1513 modest_ui_actions_on_cut (GtkAction *action,
1514 ModestWindow *window)
1516 GtkWidget *focused_widget;
1518 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1519 if (GTK_IS_EDITABLE (focused_widget)) {
1520 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1521 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1522 GtkTextBuffer *buffer;
1523 GtkClipboard *clipboard;
1525 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1526 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1527 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1532 modest_ui_actions_on_copy (GtkAction *action,
1533 ModestWindow *window)
1535 GtkClipboard *clipboard;
1536 GtkWidget *focused_widget;
1538 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1539 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1540 if (GTK_IS_LABEL (focused_widget)) {
1541 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1542 } else if (GTK_IS_EDITABLE (focused_widget)) {
1543 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1544 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1545 GtkTextBuffer *buffer;
1547 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1548 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1553 modest_ui_actions_on_undo (GtkAction *action,
1554 ModestWindow *window)
1556 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1557 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1559 g_return_if_reached ();
1564 modest_ui_actions_on_paste (GtkAction *action,
1565 ModestWindow *window)
1567 GtkWidget *focused_widget;
1569 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1570 if (GTK_IS_EDITABLE (focused_widget)) {
1571 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1572 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1573 GtkTextBuffer *buffer;
1574 GtkClipboard *clipboard;
1576 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1577 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1578 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1583 modest_ui_actions_on_select_all (GtkAction *action,
1584 ModestWindow *window)
1586 GtkWidget *focused_widget;
1588 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1589 if (GTK_IS_LABEL (focused_widget)) {
1590 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1591 } else if (GTK_IS_EDITABLE (focused_widget)) {
1592 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1593 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1594 GtkTextBuffer *buffer;
1595 GtkTextIter start, end;
1597 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1598 gtk_text_buffer_get_start_iter (buffer, &start);
1599 gtk_text_buffer_get_end_iter (buffer, &end);
1600 gtk_text_buffer_select_range (buffer, &start, &end);
1605 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1606 GtkRadioAction *selected,
1607 ModestWindow *window)
1611 value = gtk_radio_action_get_current_value (selected);
1612 if (MODEST_IS_WINDOW (window)) {
1613 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1617 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1618 GtkRadioAction *selected,
1619 ModestWindow *window)
1621 TnyHeaderFlags flags;
1622 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1624 flags = gtk_radio_action_get_current_value (selected);
1625 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1628 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1629 GtkRadioAction *selected,
1630 ModestWindow *window)
1634 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1636 file_format = gtk_radio_action_get_current_value (selected);
1637 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1642 modest_ui_actions_on_zoom_plus (GtkAction *action,
1643 ModestWindow *window)
1645 g_return_if_fail (MODEST_IS_WINDOW (window));
1647 modest_window_zoom_plus (MODEST_WINDOW (window));
1651 modest_ui_actions_on_zoom_minus (GtkAction *action,
1652 ModestWindow *window)
1654 g_return_if_fail (MODEST_IS_WINDOW (window));
1656 modest_window_zoom_minus (MODEST_WINDOW (window));
1660 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
1661 ModestWindow *window)
1663 ModestWindowMgr *mgr;
1664 gboolean fullscreen, active;
1665 g_return_if_fail (MODEST_IS_WINDOW (window));
1667 mgr = modest_runtime_get_window_mgr ();
1669 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
1670 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1672 if (active != fullscreen) {
1673 modest_window_mgr_set_fullscreen_mode (mgr, active);
1674 gtk_window_present (GTK_WINDOW (window));
1679 modest_ui_actions_on_change_fullscreen (GtkAction *action,
1680 ModestWindow *window)
1682 ModestWindowMgr *mgr;
1683 gboolean fullscreen;
1685 g_return_if_fail (MODEST_IS_WINDOW (window));
1687 mgr = modest_runtime_get_window_mgr ();
1688 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1689 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
1691 gtk_window_present (GTK_WINDOW (window));
1695 * Show the header details in a ModestDetailsDialog widget
1698 show_header_details (TnyHeader *header,
1704 dialog = modest_details_dialog_new_with_header (window, header);
1707 gtk_widget_show_all (dialog);
1708 gtk_dialog_run (GTK_DIALOG (dialog));
1710 gtk_widget_destroy (dialog);
1714 * Show the folder details in a ModestDetailsDialog widget
1717 show_folder_details (TnyFolder *folder,
1723 dialog = modest_details_dialog_new_with_folder (window, folder);
1726 gtk_widget_show_all (dialog);
1727 gtk_dialog_run (GTK_DIALOG (dialog));
1729 gtk_widget_destroy (dialog);
1734 modest_ui_actions_on_details (GtkAction *action,
1737 TnyList * headers_list;
1741 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1744 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1748 headers_list = get_selected_headers (win);
1752 iter = tny_list_create_iterator (headers_list);
1754 header = TNY_HEADER (tny_iterator_get_current (iter));
1755 show_header_details (header, GTK_WINDOW (win));
1756 g_object_unref (header);
1758 g_object_unref (iter);
1760 } else if (MODEST_IS_MAIN_WINDOW (win)) {
1761 GtkWidget *folder_view, *header_view;
1763 /* Check which widget has the focus */
1764 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1765 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1766 if (gtk_widget_is_focus (folder_view)) {
1769 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1771 /* Show only when it's a folder */
1772 if (!folder || !TNY_IS_FOLDER (folder))
1775 show_folder_details (folder, GTK_WINDOW (win));
1778 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1779 MODEST_WIDGET_TYPE_HEADER_VIEW);
1780 if (!gtk_widget_is_focus (header_view))
1783 headers_list = get_selected_headers (win);
1787 iter = tny_list_create_iterator (headers_list);
1788 while (!tny_iterator_is_done (iter)) {
1790 header = TNY_HEADER (tny_iterator_get_current (iter));
1791 show_header_details (header, GTK_WINDOW (win));
1792 g_object_unref (header);
1794 tny_iterator_next (iter);
1796 g_object_unref (iter);
1802 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
1803 ModestMsgEditWindow *window)
1805 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1807 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
1811 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
1812 ModestMsgEditWindow *window)
1814 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1816 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
1820 modest_ui_actions_toggle_folders_view (GtkAction *action,
1821 ModestMainWindow *main_window)
1825 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1827 conf = modest_runtime_get_conf ();
1829 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
1830 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
1832 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
1836 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
1837 ModestWindow *window)
1839 gboolean active, fullscreen = FALSE;
1840 ModestWindowMgr *mgr;
1842 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
1844 /* Check if we want to toggle the toolbar vuew in fullscreen
1846 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
1847 "ViewShowToolbarFullScreen")) {
1851 /* Toggle toolbar */
1852 mgr = modest_runtime_get_window_mgr ();
1853 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
1857 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
1858 ModestMsgEditWindow *window)
1860 modest_msg_edit_window_select_font (window);
1864 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
1865 const gchar *display_name,
1868 /* Do not change the application name if the widget has not
1869 the focus. This callback could be called even if the folder
1870 view has not the focus, because the handled signal could be
1871 emitted when the folder view is redrawn */
1872 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
1874 gtk_window_set_title (window, display_name);
1876 gtk_window_set_title (window, " ");
1881 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
1883 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1884 modest_msg_edit_window_select_contacts (window);
1889 create_move_to_dialog (ModestWindow *win,
1890 GtkWidget *folder_view,
1891 GtkWidget **tree_view)
1893 GtkWidget *dialog, *scroll;
1895 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
1897 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
1899 GTK_RESPONSE_ACCEPT,
1901 GTK_RESPONSE_REJECT,
1904 /* Create scrolled window */
1905 scroll = gtk_scrolled_window_new (NULL, NULL);
1906 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
1907 GTK_POLICY_AUTOMATIC,
1908 GTK_POLICY_AUTOMATIC);
1910 /* Create folder view */
1911 *tree_view = modest_folder_view_new (NULL);
1912 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
1913 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
1914 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
1916 /* Add scroll to dialog */
1917 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
1918 scroll, FALSE, FALSE, 0);
1920 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1926 * Returns TRUE if at least one of the headers of the list belongs to
1927 * a message that has been fully retrieved.
1930 has_retrieved_msgs (TnyList *list)
1933 gboolean found = FALSE;
1935 iter = tny_list_create_iterator (list);
1936 while (tny_iterator_is_done (iter) && !found) {
1938 TnyHeaderFlags flags;
1940 header = TNY_HEADER (tny_iterator_get_current (iter));
1941 flags = tny_header_get_flags (header);
1942 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
1946 tny_iterator_next (iter);
1948 g_object_unref (iter);
1954 * Shows a confirmation dialog to the user when we're moving messages
1955 * from a remote server to the local storage. Returns the dialog
1956 * response. If it's other kind of movement the it always returns
1960 msgs_move_to_confirmation (GtkWindow *win,
1961 TnyFolder *dest_folder,
1964 gint response = GTK_RESPONSE_OK;
1966 /* If the destination is a local folder */
1967 if (modest_tny_folder_is_local_folder (dest_folder)) {
1968 TnyFolder *src_folder;
1972 /* Get source folder */
1973 iter = tny_list_create_iterator (headers);
1974 header = TNY_HEADER (tny_iterator_get_current (iter));
1975 src_folder = tny_header_get_folder (header);
1976 g_object_unref (header);
1977 g_object_unref (iter);
1979 /* If the source is a remote folder */
1980 if (!modest_tny_folder_is_local_folder (src_folder)) {
1981 const gchar *message;
1983 if (tny_list_get_length (headers) == 1)
1984 if (has_retrieved_msgs (headers))
1985 message = _("mcen_nc_move_retrieve");
1987 message = _("mcen_nc_move_header");
1989 if (has_retrieved_msgs (headers))
1990 message = _("mcen_nc_move_retrieves");
1992 message = _("mcen_nc_move_headers");
1994 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1995 (const gchar *) message);
2002 * UI handler for the "Move to" action when invoked from the
2006 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2007 ModestMainWindow *win)
2009 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2011 TnyFolderStore *folder_store;
2012 ModestMailOperation *mail_op = NULL;
2014 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2016 /* Get the folder view */
2017 folder_view = modest_main_window_get_child_widget (win,
2018 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2020 /* Create and run the dialog */
2021 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2022 result = gtk_dialog_run (GTK_DIALOG(dialog));
2024 /* We do this to save an indentation level ;-) */
2025 if (result != GTK_RESPONSE_ACCEPT)
2028 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2030 if (TNY_IS_ACCOUNT (folder_store))
2033 /* Get folder or messages to transfer */
2034 if (gtk_widget_is_focus (folder_view)) {
2035 TnyFolderStore *src_folder;
2036 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2038 if (TNY_IS_FOLDER (src_folder)) {
2039 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2040 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2043 modest_mail_operation_xfer_folder (mail_op,
2044 TNY_FOLDER (src_folder),
2047 g_object_unref (G_OBJECT (mail_op));
2051 g_object_unref (G_OBJECT (src_folder));
2053 GtkWidget *header_view;
2054 header_view = modest_main_window_get_child_widget (win,
2055 MODEST_WIDGET_TYPE_HEADER_VIEW);
2056 if (gtk_widget_is_focus (header_view)) {
2060 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2062 /* Ask for user confirmation */
2063 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2064 TNY_FOLDER (folder_store),
2067 /* Transfer messages */
2068 if (response == GTK_RESPONSE_OK) {
2069 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2070 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2073 modest_mail_operation_xfer_msgs (mail_op,
2075 TNY_FOLDER (folder_store),
2077 g_object_unref (G_OBJECT (mail_op));
2081 g_object_unref (folder_store);
2084 gtk_widget_destroy (dialog);
2089 * UI handler for the "Move to" action when invoked from the
2090 * ModestMsgViewWindow
2093 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2094 ModestMsgViewWindow *win)
2096 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2098 ModestMainWindow *main_window;
2103 /* Get the folder view */
2104 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2105 folder_view = modest_main_window_get_child_widget (main_window,
2106 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2108 /* Create and run the dialog */
2109 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2110 result = gtk_dialog_run (GTK_DIALOG(dialog));
2112 if (result == GTK_RESPONSE_ACCEPT) {
2113 TnyFolderStore *folder_store;
2116 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2118 /* Create header list */
2119 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2120 header = tny_msg_get_header (msg);
2121 headers = tny_simple_list_new ();
2122 tny_list_prepend (headers, G_OBJECT (header));
2123 g_object_unref (header);
2124 g_object_unref (msg);
2126 /* Ask user for confirmation. MSG-NOT404 */
2127 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2128 TNY_FOLDER (folder_store),
2131 /* Transfer current msg */
2132 if (response == GTK_RESPONSE_OK) {
2133 ModestMailOperation *mail_op;
2135 /* Create mail op */
2136 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2137 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2140 /* Transfer messages */
2141 modest_mail_operation_xfer_msgs (mail_op,
2143 TNY_FOLDER (folder_store),
2145 g_object_unref (G_OBJECT (mail_op));
2147 g_object_unref (headers);
2149 g_object_unref (folder_store);
2151 gtk_widget_destroy (dialog);
2155 modest_ui_actions_on_move_to (GtkAction *action,
2158 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2159 MODEST_IS_MSG_VIEW_WINDOW (win));
2161 if (MODEST_IS_MAIN_WINDOW (win))
2162 modest_ui_actions_on_main_window_move_to (action,
2163 MODEST_MAIN_WINDOW (win));
2165 modest_ui_actions_on_msg_view_window_move_to (action,
2166 MODEST_MSG_VIEW_WINDOW (win));