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 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
161 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
165 header_list = get_selected_headers (win);
168 iter = tny_list_create_iterator (header_list);
171 ModestMailOperation *mail_op;
173 header = TNY_HEADER (tny_iterator_get_current (iter));
174 /* TODO: thick grain mail operation involving
175 a list of objects. Composite pattern ??? */
176 /* TODO: add confirmation dialog */
177 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE);
178 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
181 /* Always delete. TODO: Move to trash still not supported */
182 modest_mail_operation_remove_msg (mail_op, header, FALSE);
185 g_object_unref (G_OBJECT (mail_op));
186 g_object_unref (G_OBJECT (header));
188 tny_iterator_next (iter);
190 } while (!tny_iterator_is_done (iter));
193 g_object_unref (G_OBJECT (iter));
196 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
197 gtk_widget_destroy (GTK_WIDGET(win));
203 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
209 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
211 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
212 gtk_widget_destroy (GTK_WIDGET (win));
213 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
215 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
216 } else if (MODEST_IS_WINDOW (win)) {
217 gtk_widget_destroy (GTK_WIDGET (win));
219 g_return_if_reached ();
224 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
226 GtkClipboard *clipboard = NULL;
227 gchar *selection = NULL;
229 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
230 selection = gtk_clipboard_wait_for_text (clipboard);
232 modest_address_book_add_address (selection);
237 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
240 /* This is currently only implemented for Maemo,
241 * because it requires a providers preset file which is not publically available.
243 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
244 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
245 gboolean accounts_exist = account_names != NULL;
246 g_slist_free (account_names);
248 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
249 if (!accounts_exist) {
250 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
251 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
252 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
253 gtk_dialog_run (GTK_DIALOG (wizard));
254 gtk_widget_destroy (GTK_WIDGET (wizard));
256 /* Show the list of accounts: */
257 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
258 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
259 gtk_dialog_run (account_win);
260 gtk_widget_destroy (GTK_WIDGET(account_win));
263 GtkWidget *dialog, *label;
265 /* Create the widgets */
267 dialog = gtk_dialog_new_with_buttons ("Message",
269 GTK_DIALOG_DESTROY_WITH_PARENT,
273 label = gtk_label_new ("Hello World!");
275 /* Ensure that the dialog box is destroyed when the user responds. */
277 g_signal_connect_swapped (dialog, "response",
278 G_CALLBACK (gtk_widget_destroy),
281 /* Add the label, and show everything we've added to the dialog. */
283 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
285 gtk_widget_show_all (dialog);
286 #endif /* MODEST_PLATFORM_MAEMO */
290 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
292 ModestWindow *msg_win;
294 TnyFolder *folder = NULL;
295 gchar *account_name = NULL;
296 gchar *from_str = NULL;
297 /* GError *err = NULL; */
298 TnyAccount *account = NULL;
299 ModestWindowMgr *mgr;
300 gchar *signature = NULL;
302 account_name = g_strdup(modest_window_get_active_account (win));
304 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
306 g_printerr ("modest: no account found\n");
310 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
312 TNY_ACCOUNT_TYPE_STORE);
314 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
318 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
320 g_printerr ("modest: failed get from string for '%s'\n", account_name);
324 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
325 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
326 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
327 MODEST_ACCOUNT_SIGNATURE, FALSE);
329 signature = g_strdup ("");
332 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
334 g_printerr ("modest: failed to create new msg\n");
338 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
340 g_printerr ("modest: failed to find Drafts folder\n");
344 /* tny_folder_add_msg (folder, msg, &err); */
346 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
348 /* g_error_free (err); */
352 /* Create and register edit window */
353 msg_win = modest_msg_edit_window_new (msg, account_name);
354 mgr = modest_runtime_get_window_mgr ();
355 modest_window_mgr_register_window (mgr, msg_win);
358 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
360 gtk_widget_show_all (GTK_WIDGET (msg_win));
363 g_free (account_name);
367 g_object_unref (G_OBJECT(account));
369 g_object_unref (G_OBJECT(msg));
371 g_object_unref (G_OBJECT(folder));
376 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
378 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
384 reply_forward_func (gpointer data, gpointer user_data)
386 TnyMsg *msg, *new_msg;
387 GetMsgAsyncHelper *helper;
388 ReplyForwardHelper *rf_helper;
389 ModestWindow *msg_win;
390 ModestEditType edit_type;
393 TnyFolder *folder = NULL;
394 TnyAccount *account = NULL;
395 ModestWindowMgr *mgr;
396 gchar *signature = NULL;
398 msg = TNY_MSG (data);
399 helper = (GetMsgAsyncHelper *) user_data;
400 rf_helper = (ReplyForwardHelper *) helper->user_data;
402 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
403 rf_helper->account_name);
404 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
405 rf_helper->account_name,
406 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
407 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
408 rf_helper->account_name,
409 MODEST_ACCOUNT_SIGNATURE, FALSE);
411 /* Create reply mail */
412 switch (rf_helper->action) {
415 modest_tny_msg_create_reply_msg (msg, from, signature,
416 rf_helper->reply_forward_type,
417 MODEST_TNY_MSG_REPLY_MODE_SENDER);
419 case ACTION_REPLY_TO_ALL:
421 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
422 MODEST_TNY_MSG_REPLY_MODE_ALL);
423 edit_type = MODEST_EDIT_TYPE_REPLY;
427 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
428 edit_type = MODEST_EDIT_TYPE_FORWARD;
431 g_return_if_reached ();
438 g_printerr ("modest: failed to create message\n");
442 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
443 rf_helper->account_name,
444 TNY_ACCOUNT_TYPE_STORE);
446 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
450 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
452 g_printerr ("modest: failed to find Drafts folder\n");
456 tny_folder_add_msg (folder, msg, &err);
458 g_printerr ("modest: error adding msg to Drafts folder: %s",
464 /* Create and register the windows */
465 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
466 mgr = modest_runtime_get_window_mgr ();
467 modest_window_mgr_register_window (mgr, msg_win);
469 /* Show edit window */
470 gtk_widget_show_all (GTK_WIDGET (msg_win));
474 g_object_unref (G_OBJECT (new_msg));
476 g_object_unref (G_OBJECT (folder));
478 g_object_unref (G_OBJECT (account));
480 g_free (rf_helper->account_name);
481 g_slice_free (ReplyForwardHelper, rf_helper);
484 * Common code for the reply and forward actions
487 reply_forward (ReplyForwardAction action, ModestWindow *win)
489 TnyList *header_list;
490 guint reply_forward_type;
493 GetMsgAsyncHelper *helper;
494 ReplyForwardHelper *rf_helper;
496 g_return_if_fail (MODEST_IS_WINDOW(win));
498 header_list = get_selected_headers (win);
502 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
503 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
505 /* We assume that we can only select messages of the
506 same folder and that we reply all of them from the
507 same account. In fact the interface currently only
508 allows single selection */
511 rf_helper = g_slice_new0 (ReplyForwardHelper);
512 rf_helper->reply_forward_type = reply_forward_type;
513 rf_helper->action = action;
515 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
516 if (!rf_helper->account_name)
517 rf_helper->account_name =
518 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
520 helper = g_slice_new0 (GetMsgAsyncHelper);
521 helper->window = win;
522 helper->func = reply_forward_func;
523 helper->iter = tny_list_create_iterator (header_list);
524 helper->user_data = rf_helper;
526 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
528 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
530 g_printerr ("modest: no message found\n");
533 reply_forward_func (msg, helper);
535 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
536 folder = tny_header_get_folder (header);
538 /* The callback will call it per each header */
539 tny_folder_get_msg_async (folder, header, get_msg_cb, NULL, helper);
540 g_object_unref (G_OBJECT (folder));
542 g_printerr ("modest: no folder for header\n");
545 g_object_unref (G_OBJECT (header));
551 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
553 g_return_if_fail (MODEST_IS_WINDOW(win));
555 reply_forward (ACTION_REPLY, win);
559 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
561 g_return_if_fail (MODEST_IS_WINDOW(win));
563 reply_forward (ACTION_FORWARD, win);
567 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
569 g_return_if_fail (MODEST_IS_WINDOW(win));
571 reply_forward (ACTION_REPLY_TO_ALL, win);
575 modest_ui_actions_on_next (GtkAction *action,
576 ModestWindow *window)
578 if (MODEST_IS_MAIN_WINDOW (window)) {
579 GtkWidget *header_view;
581 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
582 MODEST_WIDGET_TYPE_HEADER_VIEW);
586 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
587 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
588 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
590 g_return_if_reached ();
595 modest_ui_actions_on_prev (GtkAction *action,
596 ModestWindow *window)
598 g_return_if_fail (MODEST_IS_WINDOW(window));
600 if (MODEST_IS_MAIN_WINDOW (window)) {
601 GtkWidget *header_view;
602 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
603 MODEST_WIDGET_TYPE_HEADER_VIEW);
607 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
608 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
609 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
611 g_return_if_reached ();
616 modest_ui_actions_on_sort (GtkAction *action,
617 ModestWindow *window)
619 g_return_if_fail (MODEST_IS_WINDOW(window));
621 if (MODEST_IS_MAIN_WINDOW (window)) {
622 GtkWidget *header_view;
623 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
624 MODEST_WIDGET_TYPE_HEADER_VIEW);
628 /* Show sorting dialog */
629 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
635 action_send (const gchar* account_name)
637 TnyAccount *tny_account;
638 ModestTnySendQueue *send_queue;
640 g_return_val_if_fail (account_name, FALSE);
642 /* Get the transport account according to the open connection,
643 * because the account might specify connection-specific SMTP servers.
646 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
649 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
653 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
655 g_object_unref (G_OBJECT(tny_account));
656 g_printerr ("modest: cannot get send queue for %s\n", account_name);
660 //modest_tny_send_queue_flush (send_queue);
662 g_object_unref (G_OBJECT(send_queue));
663 g_object_unref (G_OBJECT(tny_account));
670 action_receive (const gchar* account_name)
672 TnyAccount *tny_account;
673 ModestMailOperation *mail_op;
675 g_return_val_if_fail (account_name, FALSE);
678 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
680 TNY_ACCOUNT_TYPE_STORE);
682 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
686 /* Create the mail operation */
687 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
688 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
689 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
690 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
692 g_object_unref (G_OBJECT(tny_account));
693 g_object_unref (G_OBJECT (mail_op));
698 /** Check that an appropriate connection is open.
700 gboolean check_for_connection (const gchar *account_name)
702 TnyDevice *device = modest_runtime_get_device ();
705 g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
707 TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
710 if (tny_device_is_online (device))
713 modest_platform_connect_and_wait (NULL);
715 /* TODO: Wait until a result. */
721 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
726 g_message ("%s: online? %s", __FUNCTION__,
727 tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
729 /* As per the UI spec, only the active account should be affected,
730 * else the default folder if there is no active account: */
732 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
734 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
736 g_printerr ("modest: cannot get default account\n");
740 /* Do not continue if no suitable connection is open: */
741 if (!check_for_connection (account_name))
744 /* As per the UI spec,
745 * for POP accounts, we should receive,
746 * for IMAP we should synchronize everything, including receiving,
747 * for SMTP we should send,
748 * first receiving, then sending:
750 if (!action_receive(account_name))
751 g_printerr ("modest: failed to receive\n");
752 if (!action_send(account_name))
753 g_printerr ("modest: failed to send\n");
760 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
763 GtkWidget *header_view;
765 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
767 header_view = modest_main_window_get_child_widget (main_window,
768 MODEST_WIDGET_TYPE_HEADER_VIEW);
772 conf = modest_runtime_get_conf ();
774 /* what is saved/restored is depending on the style; thus; we save with
775 * old style, then update the style, and restore for this new style
777 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
779 if (modest_header_view_get_style
780 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
781 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
782 MODEST_HEADER_VIEW_STYLE_TWOLINES);
784 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
785 MODEST_HEADER_VIEW_STYLE_DETAILS);
787 modest_widget_memory_restore (conf, G_OBJECT(header_view),
794 * Marks a message as read and passes it to the msg preview widget
797 read_msg_func (gpointer data, gpointer user_data)
801 GetMsgAsyncHelper *helper;
802 TnyHeaderFlags header_flags;
803 GtkWidget *msg_preview;
805 msg = TNY_MSG (data);
806 helper = (GetMsgAsyncHelper *) user_data;
808 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
809 MODEST_WIDGET_TYPE_MSG_PREVIEW);
813 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
814 header_flags = tny_header_get_flags (header);
815 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
816 g_object_unref (G_OBJECT (header));
818 /* Set message on msg view */
819 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
823 * This function is a generic handler for the tny_folder_get_msg_async
824 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
825 * contains a user provided function that is called inside this
826 * method. This will allow us to use this callback in many different
827 * places. This callback performs the common actions for the
828 * get_msg_async call, more specific actions will be done by the user
832 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
834 GetMsgAsyncHelper *helper;
836 helper = (GetMsgAsyncHelper *) user_data;
838 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
839 modest_ui_actions_on_item_not_found (NULL,
840 MODEST_ITEM_TYPE_MESSAGE,
845 /* Call user function */
846 helper->func (msg, user_data);
848 /* Process next element (if exists) */
849 tny_iterator_next (helper->iter);
850 if (tny_iterator_is_done (helper->iter)) {
852 headers = tny_iterator_get_list (helper->iter);
854 g_object_unref (G_OBJECT (headers));
855 g_object_unref (G_OBJECT (helper->iter));
856 g_slice_free (GetMsgAsyncHelper, helper);
859 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
860 tny_folder_get_msg_async (folder, header,
861 get_msg_cb, NULL, helper);
862 g_object_unref (G_OBJECT(header));
867 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
869 ModestMainWindow *main_window)
872 GetMsgAsyncHelper *helper;
875 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
877 /* when there's no header, clear the msgview */
879 GtkWidget *msg_preview;
881 /* Clear msg preview if exists */
882 msg_preview = modest_main_window_get_child_widget(main_window,
883 MODEST_WIDGET_TYPE_MSG_PREVIEW);
886 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
890 /* Update Main window title */
891 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
892 const gchar *subject = tny_header_get_subject (header);
893 if (subject && strcmp (subject, ""))
894 gtk_window_set_title (GTK_WINDOW (main_window), subject);
896 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
900 list = tny_simple_list_new ();
901 tny_list_prepend (list, G_OBJECT (header));
903 /* Fill helper data */
904 helper = g_slice_new0 (GetMsgAsyncHelper);
905 helper->window = MODEST_WINDOW (main_window);
906 helper->iter = tny_list_create_iterator (list);
907 helper->func = read_msg_func;
909 folder = tny_header_get_folder (TNY_HEADER(header));
911 tny_folder_get_msg_async (TNY_FOLDER(folder),
916 g_object_unref (G_OBJECT (folder));
922 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
923 ModestMainWindow *main_window)
925 ModestWindow *win = NULL;
926 TnyFolder *folder = NULL;
928 ModestWindowMgr *mgr;
930 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
935 folder = tny_header_get_folder (header);
937 g_printerr ("modest: cannot get folder for header\n");
941 /* FIXME: make async?; check error */
942 msg = tny_folder_get_msg (folder, header, NULL);
944 g_printerr ("modest: cannot get msg for header\n");
948 /* Look if we already have a message view for that header */
949 mgr = modest_runtime_get_window_mgr ();
950 win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
952 /* If not, create a new window */
956 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
958 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
960 win = modest_msg_view_window_new (msg, account);
961 modest_window_mgr_register_window (mgr, win);
963 gtk_window_set_transient_for (GTK_WINDOW (win),
964 GTK_WINDOW (main_window));
967 gtk_widget_show_all (GTK_WIDGET(win));
969 g_object_unref (G_OBJECT (msg));
972 g_object_unref (G_OBJECT (folder));
976 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
977 TnyFolderStore *folder_store,
979 ModestMainWindow *main_window)
982 GtkWidget *header_view;
984 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
986 header_view = modest_main_window_get_child_widget(main_window,
987 MODEST_WIDGET_TYPE_HEADER_VIEW);
991 conf = modest_runtime_get_conf ();
993 if (TNY_IS_FOLDER (folder_store)) {
995 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
998 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
999 TNY_FOLDER (folder_store));
1000 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1003 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
1004 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1006 } else if (TNY_IS_ACCOUNT (folder_store)) {
1008 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1013 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1020 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1022 if (g_main_depth > 0)
1023 gdk_threads_enter ();
1024 online = tny_device_is_online (modest_runtime_get_device());
1027 /* already online -- the item is simply not there... */
1028 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1030 GTK_MESSAGE_WARNING,
1032 _("The %s you selected cannot be found"),
1034 gtk_dialog_run (GTK_DIALOG(dialog));
1036 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1040 GTK_RESPONSE_REJECT,
1042 GTK_RESPONSE_ACCEPT,
1044 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1045 "Do you want to get online?"), item);
1046 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1047 gtk_label_new (txt), FALSE, FALSE, 0);
1048 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1051 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1052 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1053 // modest_platform_connect_and_wait ();;
1056 gtk_widget_destroy (dialog);
1057 if (g_main_depth > 0)
1058 gdk_threads_leave ();
1062 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1065 g_message ("%s %s", __FUNCTION__, link);
1070 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1073 modest_platform_activate_uri (link);
1077 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1080 modest_platform_show_uri_popup (link);
1084 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1087 g_message (__FUNCTION__);
1092 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1093 const gchar *address,
1096 g_message ("%s %s", __FUNCTION__, address);
1100 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1102 TnyTransportAccount *transport_account;
1103 ModestMailOperation *mail_operation;
1105 gchar *account_name, *from;
1106 ModestAccountMgr *account_mgr;
1108 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1110 data = modest_msg_edit_window_get_msg_data (edit_window);
1112 account_mgr = modest_runtime_get_account_mgr();
1113 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1115 account_name = modest_account_mgr_get_default_account (account_mgr);
1116 if (!account_name) {
1117 g_printerr ("modest: no account found\n");
1118 modest_msg_edit_window_free_msg_data (edit_window, data);
1122 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1123 (modest_runtime_get_account_store(),
1125 TNY_ACCOUNT_TYPE_TRANSPORT));
1126 if (!transport_account) {
1127 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1128 g_free (account_name);
1129 modest_msg_edit_window_free_msg_data (edit_window, data);
1132 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1134 /* Create the mail operation */
1135 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1136 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1138 modest_mail_operation_save_to_drafts (mail_operation,
1148 data->priority_flags);
1151 g_free (account_name);
1152 g_object_unref (G_OBJECT (transport_account));
1153 g_object_unref (G_OBJECT (mail_operation));
1155 modest_msg_edit_window_free_msg_data (edit_window, data);
1157 /* Save settings and close the window */
1158 gtk_widget_destroy (GTK_WIDGET (edit_window));
1161 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1163 TnyTransportAccount *transport_account;
1164 ModestMailOperation *mail_operation;
1166 gchar *account_name, *from;
1167 ModestAccountMgr *account_mgr;
1169 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1171 data = modest_msg_edit_window_get_msg_data (edit_window);
1173 /* FIXME: Code added just for testing. The final version will
1174 use the send queue provided by tinymail and some
1176 account_mgr = modest_runtime_get_account_mgr();
1177 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1179 account_name = modest_account_mgr_get_default_account (account_mgr);
1180 if (!account_name) {
1181 g_printerr ("modest: no account found\n");
1182 modest_msg_edit_window_free_msg_data (edit_window, data);
1186 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1187 (modest_runtime_get_account_store(),
1189 if (!transport_account) {
1190 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1191 g_free (account_name);
1192 modest_msg_edit_window_free_msg_data (edit_window, data);
1195 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1197 /* Create the mail operation */
1198 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND);
1199 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1201 modest_mail_operation_send_new_mail (mail_operation,
1211 data->priority_flags);
1214 g_free (account_name);
1215 g_object_unref (G_OBJECT (transport_account));
1216 g_object_unref (G_OBJECT (mail_operation));
1218 modest_msg_edit_window_free_msg_data (edit_window, data);
1220 /* Save settings and close the window */
1221 gtk_widget_destroy (GTK_WIDGET (edit_window));
1225 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1226 ModestMsgEditWindow *window)
1228 ModestMsgEditFormatState *format_state = NULL;
1230 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1231 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1233 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1236 format_state = modest_msg_edit_window_get_format_state (window);
1237 g_return_if_fail (format_state != NULL);
1239 format_state->bold = gtk_toggle_action_get_active (action);
1240 modest_msg_edit_window_set_format_state (window, format_state);
1241 g_free (format_state);
1246 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1247 ModestMsgEditWindow *window)
1249 ModestMsgEditFormatState *format_state = NULL;
1251 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1252 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1254 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1257 format_state = modest_msg_edit_window_get_format_state (window);
1258 g_return_if_fail (format_state != NULL);
1260 format_state->italics = gtk_toggle_action_get_active (action);
1261 modest_msg_edit_window_set_format_state (window, format_state);
1262 g_free (format_state);
1267 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1268 ModestMsgEditWindow *window)
1270 ModestMsgEditFormatState *format_state = NULL;
1272 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1273 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1275 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1278 format_state = modest_msg_edit_window_get_format_state (window);
1279 g_return_if_fail (format_state != NULL);
1281 format_state->bullet = gtk_toggle_action_get_active (action);
1282 modest_msg_edit_window_set_format_state (window, format_state);
1283 g_free (format_state);
1288 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1289 GtkRadioAction *selected,
1290 ModestMsgEditWindow *window)
1292 ModestMsgEditFormatState *format_state = NULL;
1293 GtkJustification value;
1295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1297 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1300 value = gtk_radio_action_get_current_value (selected);
1302 format_state = modest_msg_edit_window_get_format_state (window);
1303 g_return_if_fail (format_state != NULL);
1305 format_state->justification = value;
1306 modest_msg_edit_window_set_format_state (window, format_state);
1307 g_free (format_state);
1311 modest_ui_actions_on_select_editor_color (GtkAction *action,
1312 ModestMsgEditWindow *window)
1314 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1315 g_return_if_fail (GTK_IS_ACTION (action));
1317 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1320 modest_msg_edit_window_select_color (window);
1324 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1325 ModestMsgEditWindow *window)
1327 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1328 g_return_if_fail (GTK_IS_ACTION (action));
1330 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1333 modest_msg_edit_window_select_background_color (window);
1337 modest_ui_actions_on_insert_image (GtkAction *action,
1338 ModestMsgEditWindow *window)
1340 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1341 g_return_if_fail (GTK_IS_ACTION (action));
1343 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1346 modest_msg_edit_window_insert_image (window);
1350 * Shows a dialog with an entry that asks for some text. The returned
1351 * value must be freed by the caller. The dialog window title will be
1355 ask_for_folder_name (GtkWindow *parent_window,
1358 GtkWidget *dialog, *entry;
1359 gchar *folder_name = NULL;
1361 /* Ask for folder name */
1362 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1366 GTK_RESPONSE_REJECT,
1368 GTK_RESPONSE_ACCEPT,
1370 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1371 gtk_label_new(title),
1374 entry = gtk_entry_new_with_max_length (40);
1375 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1379 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1381 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1382 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1384 gtk_widget_destroy (dialog);
1390 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1392 TnyFolderStore *parent_folder;
1393 GtkWidget *folder_view;
1395 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1397 folder_view = modest_main_window_get_child_widget (main_window,
1398 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1402 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1404 if (parent_folder) {
1405 gboolean finished = FALSE;
1407 gchar *folder_name = NULL, *suggested_name = NULL;
1409 /* Run the new folder dialog */
1411 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1416 if (result == GTK_RESPONSE_REJECT) {
1419 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1420 TnyFolder *new_folder = NULL;
1422 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1425 new_folder = modest_mail_operation_create_folder (mail_op,
1427 (const gchar *) folder_name);
1429 g_object_unref (new_folder);
1433 /* /\* TODO: check error and follow proper actions *\/ */
1434 /* /\* suggested_name = X; *\/ */
1435 /* /\* Show error to the user *\/ */
1436 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1437 /* MODEST_INFORMATION_CREATE_FOLDER); */
1439 g_object_unref (mail_op);
1441 g_free (folder_name);
1445 g_object_unref (parent_folder);
1450 modest_ui_actions_on_rename_folder (GtkAction *action,
1451 ModestMainWindow *main_window)
1453 TnyFolderStore *folder;
1454 GtkWidget *folder_view;
1456 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1458 folder_view = modest_main_window_get_child_widget (main_window,
1459 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1463 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1465 if (folder && TNY_IS_FOLDER (folder)) {
1467 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1468 _("Please enter a new name for the folder"));
1470 if (folder_name != NULL && strlen (folder_name) > 0) {
1471 ModestMailOperation *mail_op;
1473 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1474 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1477 modest_mail_operation_rename_folder (mail_op,
1478 TNY_FOLDER (folder),
1479 (const gchar *) folder_name);
1481 g_object_unref (mail_op);
1482 g_free (folder_name);
1484 g_object_unref (folder);
1489 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1491 TnyFolderStore *folder;
1492 GtkWidget *folder_view;
1496 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1498 folder_view = modest_main_window_get_child_widget (main_window,
1499 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1503 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1506 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1507 tny_folder_get_name (TNY_FOLDER (folder)));
1508 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1509 (const gchar *) message);
1512 if (response == GTK_RESPONSE_OK) {
1513 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE);
1515 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1517 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1519 /* Show error if happened */
1520 if (modest_mail_operation_get_error (mail_op))
1521 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1522 MODEST_INFORMATION_DELETE_FOLDER);
1524 g_object_unref (G_OBJECT (mail_op));
1527 g_object_unref (G_OBJECT (folder));
1531 modest_ui_actions_on_delete_folder (GtkAction *action,
1532 ModestMainWindow *main_window)
1534 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1536 delete_folder (main_window, FALSE);
1540 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1542 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1544 delete_folder (main_window, TRUE);
1548 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1549 const gchar* account_name,
1553 ModestMainWindow *main_window)
1556 GtkWidget *dialog, *entry, *remember_pass_check;
1558 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1562 GTK_RESPONSE_REJECT,
1564 GTK_RESPONSE_ACCEPT,
1566 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1568 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1569 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1573 entry = gtk_entry_new_with_max_length (40);
1574 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1575 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1577 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1580 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1581 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1584 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1586 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1587 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1594 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1599 gtk_widget_destroy (dialog);
1603 modest_ui_actions_on_cut (GtkAction *action,
1604 ModestWindow *window)
1606 GtkWidget *focused_widget;
1608 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1609 if (GTK_IS_EDITABLE (focused_widget)) {
1610 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1611 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1612 GtkTextBuffer *buffer;
1613 GtkClipboard *clipboard;
1615 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1616 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1617 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1622 modest_ui_actions_on_copy (GtkAction *action,
1623 ModestWindow *window)
1625 GtkClipboard *clipboard;
1626 GtkWidget *focused_widget;
1628 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1629 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1630 if (GTK_IS_LABEL (focused_widget)) {
1631 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1632 } else if (GTK_IS_EDITABLE (focused_widget)) {
1633 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1634 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1635 GtkTextBuffer *buffer;
1637 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1638 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1643 modest_ui_actions_on_undo (GtkAction *action,
1644 ModestWindow *window)
1646 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1647 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1649 g_return_if_reached ();
1654 modest_ui_actions_on_paste (GtkAction *action,
1655 ModestWindow *window)
1657 GtkWidget *focused_widget;
1659 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1660 if (GTK_IS_EDITABLE (focused_widget)) {
1661 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1662 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1663 GtkTextBuffer *buffer;
1664 GtkClipboard *clipboard;
1666 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1667 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1668 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1673 modest_ui_actions_on_select_all (GtkAction *action,
1674 ModestWindow *window)
1676 GtkWidget *focused_widget;
1678 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1679 if (GTK_IS_LABEL (focused_widget)) {
1680 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1681 } else if (GTK_IS_EDITABLE (focused_widget)) {
1682 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1683 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1684 GtkTextBuffer *buffer;
1685 GtkTextIter start, end;
1687 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1688 gtk_text_buffer_get_start_iter (buffer, &start);
1689 gtk_text_buffer_get_end_iter (buffer, &end);
1690 gtk_text_buffer_select_range (buffer, &start, &end);
1695 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1696 GtkRadioAction *selected,
1697 ModestWindow *window)
1701 value = gtk_radio_action_get_current_value (selected);
1702 if (MODEST_IS_WINDOW (window)) {
1703 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1707 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1708 GtkRadioAction *selected,
1709 ModestWindow *window)
1711 TnyHeaderFlags flags;
1712 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1714 flags = gtk_radio_action_get_current_value (selected);
1715 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1718 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1719 GtkRadioAction *selected,
1720 ModestWindow *window)
1724 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1726 file_format = gtk_radio_action_get_current_value (selected);
1727 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1732 modest_ui_actions_on_zoom_plus (GtkAction *action,
1733 ModestWindow *window)
1735 g_return_if_fail (MODEST_IS_WINDOW (window));
1737 modest_window_zoom_plus (MODEST_WINDOW (window));
1741 modest_ui_actions_on_zoom_minus (GtkAction *action,
1742 ModestWindow *window)
1744 g_return_if_fail (MODEST_IS_WINDOW (window));
1746 modest_window_zoom_minus (MODEST_WINDOW (window));
1750 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
1751 ModestWindow *window)
1753 ModestWindowMgr *mgr;
1754 gboolean fullscreen, active;
1755 g_return_if_fail (MODEST_IS_WINDOW (window));
1757 mgr = modest_runtime_get_window_mgr ();
1759 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
1760 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1762 if (active != fullscreen) {
1763 modest_window_mgr_set_fullscreen_mode (mgr, active);
1764 gtk_window_present (GTK_WINDOW (window));
1769 modest_ui_actions_on_change_fullscreen (GtkAction *action,
1770 ModestWindow *window)
1772 ModestWindowMgr *mgr;
1773 gboolean fullscreen;
1775 g_return_if_fail (MODEST_IS_WINDOW (window));
1777 mgr = modest_runtime_get_window_mgr ();
1778 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1779 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
1781 gtk_window_present (GTK_WINDOW (window));
1785 * Show the header details in a ModestDetailsDialog widget
1788 show_header_details (TnyHeader *header,
1794 dialog = modest_details_dialog_new_with_header (window, header);
1797 gtk_widget_show_all (dialog);
1798 gtk_dialog_run (GTK_DIALOG (dialog));
1800 gtk_widget_destroy (dialog);
1804 * Show the folder details in a ModestDetailsDialog widget
1807 show_folder_details (TnyFolder *folder,
1813 dialog = modest_details_dialog_new_with_folder (window, folder);
1816 gtk_widget_show_all (dialog);
1817 gtk_dialog_run (GTK_DIALOG (dialog));
1819 gtk_widget_destroy (dialog);
1824 modest_ui_actions_on_details (GtkAction *action,
1827 TnyList * headers_list;
1831 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1834 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1838 headers_list = get_selected_headers (win);
1842 iter = tny_list_create_iterator (headers_list);
1844 header = TNY_HEADER (tny_iterator_get_current (iter));
1845 show_header_details (header, GTK_WINDOW (win));
1846 g_object_unref (header);
1848 g_object_unref (iter);
1850 } else if (MODEST_IS_MAIN_WINDOW (win)) {
1851 GtkWidget *folder_view, *header_view;
1853 /* Check which widget has the focus */
1854 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1855 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1856 if (gtk_widget_is_focus (folder_view)) {
1859 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1861 /* Show only when it's a folder */
1862 if (!folder || !TNY_IS_FOLDER (folder))
1865 show_folder_details (folder, GTK_WINDOW (win));
1868 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1869 MODEST_WIDGET_TYPE_HEADER_VIEW);
1870 if (!gtk_widget_is_focus (header_view))
1873 headers_list = get_selected_headers (win);
1877 iter = tny_list_create_iterator (headers_list);
1878 while (!tny_iterator_is_done (iter)) {
1880 header = TNY_HEADER (tny_iterator_get_current (iter));
1881 show_header_details (header, GTK_WINDOW (win));
1882 g_object_unref (header);
1884 tny_iterator_next (iter);
1886 g_object_unref (iter);
1892 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
1893 ModestMsgEditWindow *window)
1895 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1897 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
1901 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
1902 ModestMsgEditWindow *window)
1904 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1906 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
1910 modest_ui_actions_toggle_folders_view (GtkAction *action,
1911 ModestMainWindow *main_window)
1915 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1917 conf = modest_runtime_get_conf ();
1919 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
1920 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
1922 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
1926 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
1927 ModestWindow *window)
1929 gboolean active, fullscreen = FALSE;
1930 ModestWindowMgr *mgr;
1932 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
1934 /* Check if we want to toggle the toolbar vuew in fullscreen
1936 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
1937 "ViewShowToolbarFullScreen")) {
1941 /* Toggle toolbar */
1942 mgr = modest_runtime_get_window_mgr ();
1943 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
1947 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
1948 ModestMsgEditWindow *window)
1950 modest_msg_edit_window_select_font (window);
1954 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
1955 const gchar *display_name,
1958 /* Do not change the application name if the widget has not
1959 the focus. This callback could be called even if the folder
1960 view has not the focus, because the handled signal could be
1961 emitted when the folder view is redrawn */
1962 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
1964 gtk_window_set_title (window, display_name);
1966 gtk_window_set_title (window, " ");
1971 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
1973 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1974 modest_msg_edit_window_select_contacts (window);
1979 create_move_to_dialog (ModestWindow *win,
1980 GtkWidget *folder_view,
1981 GtkWidget **tree_view)
1983 GtkWidget *dialog, *scroll;
1985 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
1987 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
1989 GTK_RESPONSE_ACCEPT,
1991 GTK_RESPONSE_REJECT,
1994 /* Create scrolled window */
1995 scroll = gtk_scrolled_window_new (NULL, NULL);
1996 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
1997 GTK_POLICY_AUTOMATIC,
1998 GTK_POLICY_AUTOMATIC);
2000 /* Create folder view */
2001 *tree_view = modest_folder_view_new (NULL);
2002 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2003 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2004 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2006 /* Add scroll to dialog */
2007 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2008 scroll, FALSE, FALSE, 0);
2010 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2016 * Returns TRUE if at least one of the headers of the list belongs to
2017 * a message that has been fully retrieved.
2020 has_retrieved_msgs (TnyList *list)
2023 gboolean found = FALSE;
2025 iter = tny_list_create_iterator (list);
2026 while (tny_iterator_is_done (iter) && !found) {
2028 TnyHeaderFlags flags;
2030 header = TNY_HEADER (tny_iterator_get_current (iter));
2031 flags = tny_header_get_flags (header);
2032 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2036 tny_iterator_next (iter);
2038 g_object_unref (iter);
2044 * Shows a confirmation dialog to the user when we're moving messages
2045 * from a remote server to the local storage. Returns the dialog
2046 * response. If it's other kind of movement the it always returns
2050 msgs_move_to_confirmation (GtkWindow *win,
2051 TnyFolder *dest_folder,
2054 gint response = GTK_RESPONSE_OK;
2056 /* If the destination is a local folder */
2057 if (modest_tny_folder_is_local_folder (dest_folder)) {
2058 TnyFolder *src_folder;
2062 /* Get source folder */
2063 iter = tny_list_create_iterator (headers);
2064 header = TNY_HEADER (tny_iterator_get_current (iter));
2065 src_folder = tny_header_get_folder (header);
2066 g_object_unref (header);
2067 g_object_unref (iter);
2069 /* If the source is a remote folder */
2070 if (!modest_tny_folder_is_local_folder (src_folder)) {
2071 const gchar *message;
2073 if (tny_list_get_length (headers) == 1)
2074 if (has_retrieved_msgs (headers))
2075 message = _("mcen_nc_move_retrieve");
2077 message = _("mcen_nc_move_header");
2079 if (has_retrieved_msgs (headers))
2080 message = _("mcen_nc_move_retrieves");
2082 message = _("mcen_nc_move_headers");
2084 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2085 (const gchar *) message);
2092 * UI handler for the "Move to" action when invoked from the
2096 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2097 ModestMainWindow *win)
2099 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2101 TnyFolderStore *folder_store;
2102 ModestMailOperation *mail_op = NULL;
2104 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2106 /* Get the folder view */
2107 folder_view = modest_main_window_get_child_widget (win,
2108 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2110 /* Create and run the dialog */
2111 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2112 result = gtk_dialog_run (GTK_DIALOG(dialog));
2114 /* We do this to save an indentation level ;-) */
2115 if (result != GTK_RESPONSE_ACCEPT)
2118 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2120 if (TNY_IS_ACCOUNT (folder_store))
2123 /* Get folder or messages to transfer */
2124 if (gtk_widget_is_focus (folder_view)) {
2125 TnyFolderStore *src_folder;
2126 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2128 if (TNY_IS_FOLDER (src_folder)) {
2129 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2130 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2133 modest_mail_operation_xfer_folder (mail_op,
2134 TNY_FOLDER (src_folder),
2137 g_object_unref (G_OBJECT (mail_op));
2141 g_object_unref (G_OBJECT (src_folder));
2143 GtkWidget *header_view;
2144 header_view = modest_main_window_get_child_widget (win,
2145 MODEST_WIDGET_TYPE_HEADER_VIEW);
2146 if (gtk_widget_is_focus (header_view)) {
2150 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2152 /* Ask for user confirmation */
2153 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2154 TNY_FOLDER (folder_store),
2157 /* Transfer messages */
2158 if (response == GTK_RESPONSE_OK) {
2159 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2160 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2163 modest_mail_operation_xfer_msgs (mail_op,
2165 TNY_FOLDER (folder_store),
2167 g_object_unref (G_OBJECT (mail_op));
2171 g_object_unref (folder_store);
2174 gtk_widget_destroy (dialog);
2179 * UI handler for the "Move to" action when invoked from the
2180 * ModestMsgViewWindow
2183 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2184 ModestMsgViewWindow *win)
2186 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2188 ModestMainWindow *main_window;
2193 /* Get the folder view */
2194 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2195 folder_view = modest_main_window_get_child_widget (main_window,
2196 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2198 /* Create and run the dialog */
2199 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2200 result = gtk_dialog_run (GTK_DIALOG(dialog));
2202 if (result == GTK_RESPONSE_ACCEPT) {
2203 TnyFolderStore *folder_store;
2206 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2208 /* Create header list */
2209 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2210 header = tny_msg_get_header (msg);
2211 headers = tny_simple_list_new ();
2212 tny_list_prepend (headers, G_OBJECT (header));
2213 g_object_unref (header);
2214 g_object_unref (msg);
2216 /* Ask user for confirmation. MSG-NOT404 */
2217 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2218 TNY_FOLDER (folder_store),
2221 /* Transfer current msg */
2222 if (response == GTK_RESPONSE_OK) {
2223 ModestMailOperation *mail_op;
2225 /* Create mail op */
2226 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2227 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2230 /* Transfer messages */
2231 modest_mail_operation_xfer_msgs (mail_op,
2233 TNY_FOLDER (folder_store),
2235 g_object_unref (G_OBJECT (mail_op));
2237 g_object_unref (headers);
2239 g_object_unref (folder_store);
2241 gtk_widget_destroy (dialog);
2245 modest_ui_actions_on_move_to (GtkAction *action,
2248 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2249 MODEST_IS_MSG_VIEW_WINDOW (win));
2251 if (MODEST_IS_MAIN_WINDOW (win))
2252 modest_ui_actions_on_main_window_move_to (action,
2253 MODEST_MAIN_WINDOW (win));
2255 modest_ui_actions_on_msg_view_window_move_to (action,
2256 MODEST_MSG_VIEW_WINDOW (win));