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 TRUE /* enabled accounts only */);
246 gboolean accounts_exist = account_names != NULL;
247 g_slist_free (account_names);
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 do_send_receive_current_or_default (ModestWindow *win)
725 g_message ("%s: online? %s", __FUNCTION__,
726 tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
728 /* As per the UI spec, only the active account should be affected,
729 * else the default folder if there is no active account: */
731 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
733 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
735 g_printerr ("modest: cannot get default account\n");
739 /* Do not continue if no suitable connection is open: */
740 if (check_for_connection (account_name)) {
741 /* As per the UI spec,
742 * for POP accounts, we should receive,
743 * for IMAP we should synchronize everything, including receiving,
744 * for SMTP we should send,
745 * first receiving, then sending:
747 if (!action_receive(account_name))
748 g_printerr ("modest: failed to receive\n");
749 if (!action_send(account_name))
750 g_printerr ("modest: failed to send\n");
752 g_free (account_name);
758 do_send_receive_auto (ModestWindow *win)
760 g_message ("%s: online? %s", __FUNCTION__,
761 tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
763 /* TODO: Delete the item->data strings as well as the list? */
764 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
765 TRUE /* enabled accounts only */);
766 GSList *iter = account_names;
768 const gchar * account_name = (const char*) iter->data;
770 /* Do not continue if no suitable connection is open: */
771 if (account_name && check_for_connection (account_name)) {
772 /* As per the UI spec,
773 * for POP accounts, we should receive,
774 * for IMAP we should synchronize everything, including receiving,
775 * for SMTP we should send,
776 * first receiving, then sending:
778 if (!action_receive(account_name))
779 g_printerr ("modest: failed to receive for account %s\n", account_name);
780 if (!action_send(account_name))
781 g_printerr ("modest: failed to send for account %s\n", account_name);
786 g_slist_free (account_names);
790 do_send_receive (ModestWindow *win)
792 const gboolean auto_update = TRUE; /* TODO: Get gconf setting. */
794 do_send_receive_current_or_default (win);
796 do_send_receive_auto (win);
800 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
802 /* Check that at least one account exists: */
803 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
804 TRUE /* enabled accounts only */);
805 gboolean accounts_exist = account_names != NULL;
806 g_slist_free (account_names);
808 /* If not, allow the user to create an account before trying to send/receive. */
809 if (!accounts_exist) {
810 modest_ui_actions_on_accounts (NULL, win);
813 do_send_receive (win);
820 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
823 GtkWidget *header_view;
825 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
827 header_view = modest_main_window_get_child_widget (main_window,
828 MODEST_WIDGET_TYPE_HEADER_VIEW);
832 conf = modest_runtime_get_conf ();
834 /* what is saved/restored is depending on the style; thus; we save with
835 * old style, then update the style, and restore for this new style
837 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
839 if (modest_header_view_get_style
840 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
841 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
842 MODEST_HEADER_VIEW_STYLE_TWOLINES);
844 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
845 MODEST_HEADER_VIEW_STYLE_DETAILS);
847 modest_widget_memory_restore (conf, G_OBJECT(header_view),
848 MODEST_CONF_HEADER_VIEW_KEY);
854 * Marks a message as read and passes it to the msg preview widget
857 read_msg_func (gpointer data, gpointer user_data)
861 GetMsgAsyncHelper *helper;
862 TnyHeaderFlags header_flags;
863 GtkWidget *msg_preview;
865 msg = TNY_MSG (data);
866 helper = (GetMsgAsyncHelper *) user_data;
868 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
869 MODEST_WIDGET_TYPE_MSG_PREVIEW);
873 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
874 header_flags = tny_header_get_flags (header);
875 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
876 g_object_unref (G_OBJECT (header));
878 /* Set message on msg view */
879 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
883 * This function is a generic handler for the tny_folder_get_msg_async
884 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
885 * contains a user provided function that is called inside this
886 * method. This will allow us to use this callback in many different
887 * places. This callback performs the common actions for the
888 * get_msg_async call, more specific actions will be done by the user
892 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
894 GetMsgAsyncHelper *helper;
896 helper = (GetMsgAsyncHelper *) user_data;
898 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
899 modest_ui_actions_on_item_not_found (NULL,
900 MODEST_ITEM_TYPE_MESSAGE,
905 /* Call user function */
906 helper->func (msg, user_data);
908 /* Process next element (if exists) */
909 tny_iterator_next (helper->iter);
910 if (tny_iterator_is_done (helper->iter)) {
912 headers = tny_iterator_get_list (helper->iter);
914 g_object_unref (G_OBJECT (headers));
915 g_object_unref (G_OBJECT (helper->iter));
916 g_slice_free (GetMsgAsyncHelper, helper);
919 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
920 tny_folder_get_msg_async (folder, header,
921 get_msg_cb, NULL, helper);
922 g_object_unref (G_OBJECT(header));
927 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
929 ModestMainWindow *main_window)
932 GetMsgAsyncHelper *helper;
935 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
937 /* when there's no header, clear the msgview */
939 GtkWidget *msg_preview;
941 /* Clear msg preview if exists */
942 msg_preview = modest_main_window_get_child_widget(main_window,
943 MODEST_WIDGET_TYPE_MSG_PREVIEW);
946 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
950 /* Update Main window title */
951 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
952 const gchar *subject = tny_header_get_subject (header);
953 if (subject && strcmp (subject, ""))
954 gtk_window_set_title (GTK_WINDOW (main_window), subject);
956 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
960 list = tny_simple_list_new ();
961 tny_list_prepend (list, G_OBJECT (header));
963 /* Fill helper data */
964 helper = g_slice_new0 (GetMsgAsyncHelper);
965 helper->window = MODEST_WINDOW (main_window);
966 helper->iter = tny_list_create_iterator (list);
967 helper->func = read_msg_func;
969 folder = tny_header_get_folder (TNY_HEADER(header));
971 tny_folder_get_msg_async (TNY_FOLDER(folder),
976 g_object_unref (G_OBJECT (folder));
982 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
983 ModestMainWindow *main_window)
985 ModestWindow *win = NULL;
986 TnyFolder *folder = NULL;
988 ModestWindowMgr *mgr;
990 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
995 folder = tny_header_get_folder (header);
997 g_printerr ("modest: cannot get folder for header\n");
1001 /* FIXME: make async?; check error */
1002 msg = tny_folder_get_msg (folder, header, NULL);
1004 g_printerr ("modest: cannot get msg for header\n");
1008 /* Look if we already have a message view for that header */
1009 mgr = modest_runtime_get_window_mgr ();
1010 win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
1012 /* If not, create a new window */
1016 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
1018 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1020 win = modest_msg_view_window_new (msg, account);
1021 modest_window_mgr_register_window (mgr, win);
1023 gtk_window_set_transient_for (GTK_WINDOW (win),
1024 GTK_WINDOW (main_window));
1027 gtk_widget_show_all (GTK_WIDGET(win));
1029 g_object_unref (G_OBJECT (msg));
1032 g_object_unref (G_OBJECT (folder));
1036 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1037 TnyFolderStore *folder_store,
1039 ModestMainWindow *main_window)
1042 GtkWidget *header_view;
1044 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1046 header_view = modest_main_window_get_child_widget(main_window,
1047 MODEST_WIDGET_TYPE_HEADER_VIEW);
1051 conf = modest_runtime_get_conf ();
1053 if (TNY_IS_FOLDER (folder_store)) {
1055 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1058 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1059 TNY_FOLDER (folder_store));
1060 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1061 MODEST_CONF_HEADER_VIEW_KEY);
1063 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1064 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1066 } else if (TNY_IS_ACCOUNT (folder_store)) {
1068 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1073 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1080 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1082 if (g_main_depth > 0)
1083 gdk_threads_enter ();
1084 online = tny_device_is_online (modest_runtime_get_device());
1087 /* already online -- the item is simply not there... */
1088 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1090 GTK_MESSAGE_WARNING,
1092 _("The %s you selected cannot be found"),
1094 gtk_dialog_run (GTK_DIALOG(dialog));
1096 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1100 GTK_RESPONSE_REJECT,
1102 GTK_RESPONSE_ACCEPT,
1104 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1105 "Do you want to get online?"), item);
1106 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1107 gtk_label_new (txt), FALSE, FALSE, 0);
1108 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1111 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1112 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1113 // modest_platform_connect_and_wait ();;
1116 gtk_widget_destroy (dialog);
1117 if (g_main_depth > 0)
1118 gdk_threads_leave ();
1122 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1125 g_message ("%s %s", __FUNCTION__, link);
1130 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1133 modest_platform_activate_uri (link);
1137 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1140 modest_platform_show_uri_popup (link);
1144 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1147 g_message (__FUNCTION__);
1152 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1153 const gchar *address,
1156 g_message ("%s %s", __FUNCTION__, address);
1160 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1162 TnyTransportAccount *transport_account;
1163 ModestMailOperation *mail_operation;
1165 gchar *account_name, *from;
1166 ModestAccountMgr *account_mgr;
1168 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1170 data = modest_msg_edit_window_get_msg_data (edit_window);
1172 account_mgr = modest_runtime_get_account_mgr();
1173 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1175 account_name = modest_account_mgr_get_default_account (account_mgr);
1176 if (!account_name) {
1177 g_printerr ("modest: no account found\n");
1178 modest_msg_edit_window_free_msg_data (edit_window, data);
1182 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1183 (modest_runtime_get_account_store(),
1185 TNY_ACCOUNT_TYPE_TRANSPORT));
1186 if (!transport_account) {
1187 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1188 g_free (account_name);
1189 modest_msg_edit_window_free_msg_data (edit_window, data);
1192 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1194 /* Create the mail operation */
1195 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1196 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1198 modest_mail_operation_save_to_drafts (mail_operation,
1208 data->priority_flags);
1211 g_free (account_name);
1212 g_object_unref (G_OBJECT (transport_account));
1213 g_object_unref (G_OBJECT (mail_operation));
1215 modest_msg_edit_window_free_msg_data (edit_window, data);
1217 /* Save settings and close the window */
1218 gtk_widget_destroy (GTK_WIDGET (edit_window));
1221 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1223 TnyTransportAccount *transport_account;
1224 ModestMailOperation *mail_operation;
1226 gchar *account_name, *from;
1227 ModestAccountMgr *account_mgr;
1229 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1231 if (!modest_msg_edit_window_check_names (edit_window))
1234 data = modest_msg_edit_window_get_msg_data (edit_window);
1236 /* FIXME: Code added just for testing. The final version will
1237 use the send queue provided by tinymail and some
1239 account_mgr = modest_runtime_get_account_mgr();
1240 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1242 account_name = modest_account_mgr_get_default_account (account_mgr);
1243 if (!account_name) {
1244 g_printerr ("modest: no account found\n");
1245 modest_msg_edit_window_free_msg_data (edit_window, data);
1249 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1250 (modest_runtime_get_account_store(),
1252 if (!transport_account) {
1253 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1254 g_free (account_name);
1255 modest_msg_edit_window_free_msg_data (edit_window, data);
1258 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1260 /* Create the mail operation */
1261 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND);
1262 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1264 modest_mail_operation_send_new_mail (mail_operation,
1274 data->priority_flags);
1277 g_free (account_name);
1278 g_object_unref (G_OBJECT (transport_account));
1279 g_object_unref (G_OBJECT (mail_operation));
1281 modest_msg_edit_window_free_msg_data (edit_window, data);
1283 /* Save settings and close the window */
1284 gtk_widget_destroy (GTK_WIDGET (edit_window));
1288 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1289 ModestMsgEditWindow *window)
1291 ModestMsgEditFormatState *format_state = NULL;
1293 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1294 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1296 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1299 format_state = modest_msg_edit_window_get_format_state (window);
1300 g_return_if_fail (format_state != NULL);
1302 format_state->bold = gtk_toggle_action_get_active (action);
1303 modest_msg_edit_window_set_format_state (window, format_state);
1304 g_free (format_state);
1309 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1310 ModestMsgEditWindow *window)
1312 ModestMsgEditFormatState *format_state = NULL;
1314 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1315 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1317 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1320 format_state = modest_msg_edit_window_get_format_state (window);
1321 g_return_if_fail (format_state != NULL);
1323 format_state->italics = gtk_toggle_action_get_active (action);
1324 modest_msg_edit_window_set_format_state (window, format_state);
1325 g_free (format_state);
1330 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1331 ModestMsgEditWindow *window)
1333 ModestMsgEditFormatState *format_state = NULL;
1335 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1336 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1338 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1341 format_state = modest_msg_edit_window_get_format_state (window);
1342 g_return_if_fail (format_state != NULL);
1344 format_state->bullet = gtk_toggle_action_get_active (action);
1345 modest_msg_edit_window_set_format_state (window, format_state);
1346 g_free (format_state);
1351 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1352 GtkRadioAction *selected,
1353 ModestMsgEditWindow *window)
1355 ModestMsgEditFormatState *format_state = NULL;
1356 GtkJustification value;
1358 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1360 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1363 value = gtk_radio_action_get_current_value (selected);
1365 format_state = modest_msg_edit_window_get_format_state (window);
1366 g_return_if_fail (format_state != NULL);
1368 format_state->justification = value;
1369 modest_msg_edit_window_set_format_state (window, format_state);
1370 g_free (format_state);
1374 modest_ui_actions_on_select_editor_color (GtkAction *action,
1375 ModestMsgEditWindow *window)
1377 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1378 g_return_if_fail (GTK_IS_ACTION (action));
1380 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1383 modest_msg_edit_window_select_color (window);
1387 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1388 ModestMsgEditWindow *window)
1390 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1391 g_return_if_fail (GTK_IS_ACTION (action));
1393 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1396 modest_msg_edit_window_select_background_color (window);
1400 modest_ui_actions_on_insert_image (GtkAction *action,
1401 ModestMsgEditWindow *window)
1403 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1404 g_return_if_fail (GTK_IS_ACTION (action));
1406 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1409 modest_msg_edit_window_insert_image (window);
1413 * Shows a dialog with an entry that asks for some text. The returned
1414 * value must be freed by the caller. The dialog window title will be
1418 ask_for_folder_name (GtkWindow *parent_window,
1421 GtkWidget *dialog, *entry;
1422 gchar *folder_name = NULL;
1424 /* Ask for folder name */
1425 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1429 GTK_RESPONSE_REJECT,
1431 GTK_RESPONSE_ACCEPT,
1433 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1434 gtk_label_new(title),
1437 entry = gtk_entry_new_with_max_length (40);
1438 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1442 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1444 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1445 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1447 gtk_widget_destroy (dialog);
1453 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1455 TnyFolderStore *parent_folder;
1456 GtkWidget *folder_view;
1458 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1460 folder_view = modest_main_window_get_child_widget (main_window,
1461 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1465 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1467 if (parent_folder) {
1468 gboolean finished = FALSE;
1470 gchar *folder_name = NULL, *suggested_name = NULL;
1472 /* Run the new folder dialog */
1474 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1479 if (result == GTK_RESPONSE_REJECT) {
1482 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1483 TnyFolder *new_folder = NULL;
1485 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1488 new_folder = modest_mail_operation_create_folder (mail_op,
1490 (const gchar *) folder_name);
1492 g_object_unref (new_folder);
1496 /* /\* TODO: check error and follow proper actions *\/ */
1497 /* /\* suggested_name = X; *\/ */
1498 /* /\* Show error to the user *\/ */
1499 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1500 /* MODEST_INFORMATION_CREATE_FOLDER); */
1502 g_object_unref (mail_op);
1504 g_free (folder_name);
1508 g_object_unref (parent_folder);
1513 modest_ui_actions_on_rename_folder (GtkAction *action,
1514 ModestMainWindow *main_window)
1516 TnyFolderStore *folder;
1517 GtkWidget *folder_view;
1519 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1521 folder_view = modest_main_window_get_child_widget (main_window,
1522 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1526 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1528 if (folder && TNY_IS_FOLDER (folder)) {
1530 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1531 _("Please enter a new name for the folder"));
1533 if (folder_name != NULL && strlen (folder_name) > 0) {
1534 ModestMailOperation *mail_op;
1536 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1537 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1540 modest_mail_operation_rename_folder (mail_op,
1541 TNY_FOLDER (folder),
1542 (const gchar *) folder_name);
1544 g_object_unref (mail_op);
1545 g_free (folder_name);
1547 g_object_unref (folder);
1552 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1554 TnyFolderStore *folder;
1555 GtkWidget *folder_view;
1559 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1561 folder_view = modest_main_window_get_child_widget (main_window,
1562 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1566 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1569 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1570 tny_folder_get_name (TNY_FOLDER (folder)));
1571 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1572 (const gchar *) message);
1575 if (response == GTK_RESPONSE_OK) {
1576 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE);
1578 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1580 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1582 /* Show error if happened */
1583 if (modest_mail_operation_get_error (mail_op))
1584 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1585 MODEST_INFORMATION_DELETE_FOLDER);
1587 g_object_unref (G_OBJECT (mail_op));
1590 g_object_unref (G_OBJECT (folder));
1594 modest_ui_actions_on_delete_folder (GtkAction *action,
1595 ModestMainWindow *main_window)
1597 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1599 delete_folder (main_window, FALSE);
1603 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1605 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1607 delete_folder (main_window, TRUE);
1611 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1612 const gchar* account_name,
1616 ModestMainWindow *main_window)
1619 GtkWidget *dialog, *entry, *remember_pass_check;
1621 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1625 GTK_RESPONSE_REJECT,
1627 GTK_RESPONSE_ACCEPT,
1629 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1631 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1632 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1636 entry = gtk_entry_new_with_max_length (40);
1637 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1638 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1640 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1643 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1644 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1647 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1649 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1650 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1657 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1662 gtk_widget_destroy (dialog);
1666 modest_ui_actions_on_cut (GtkAction *action,
1667 ModestWindow *window)
1669 GtkWidget *focused_widget;
1671 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1672 if (GTK_IS_EDITABLE (focused_widget)) {
1673 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1674 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1675 GtkTextBuffer *buffer;
1676 GtkClipboard *clipboard;
1678 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1679 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1680 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1685 modest_ui_actions_on_copy (GtkAction *action,
1686 ModestWindow *window)
1688 GtkClipboard *clipboard;
1689 GtkWidget *focused_widget;
1691 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1692 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1693 if (GTK_IS_LABEL (focused_widget)) {
1694 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1695 } else if (GTK_IS_EDITABLE (focused_widget)) {
1696 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1697 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1698 GtkTextBuffer *buffer;
1700 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1701 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1706 modest_ui_actions_on_undo (GtkAction *action,
1707 ModestWindow *window)
1709 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1710 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1712 g_return_if_reached ();
1717 modest_ui_actions_on_paste (GtkAction *action,
1718 ModestWindow *window)
1720 GtkWidget *focused_widget;
1722 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1723 if (GTK_IS_EDITABLE (focused_widget)) {
1724 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1725 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1726 GtkTextBuffer *buffer;
1727 GtkClipboard *clipboard;
1729 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1730 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1731 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1736 modest_ui_actions_on_select_all (GtkAction *action,
1737 ModestWindow *window)
1739 GtkWidget *focused_widget;
1741 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1742 if (GTK_IS_LABEL (focused_widget)) {
1743 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1744 } else if (GTK_IS_EDITABLE (focused_widget)) {
1745 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1746 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1747 GtkTextBuffer *buffer;
1748 GtkTextIter start, end;
1750 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1751 gtk_text_buffer_get_start_iter (buffer, &start);
1752 gtk_text_buffer_get_end_iter (buffer, &end);
1753 gtk_text_buffer_select_range (buffer, &start, &end);
1758 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1759 GtkRadioAction *selected,
1760 ModestWindow *window)
1764 value = gtk_radio_action_get_current_value (selected);
1765 if (MODEST_IS_WINDOW (window)) {
1766 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1770 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1771 GtkRadioAction *selected,
1772 ModestWindow *window)
1774 TnyHeaderFlags flags;
1775 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1777 flags = gtk_radio_action_get_current_value (selected);
1778 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1781 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1782 GtkRadioAction *selected,
1783 ModestWindow *window)
1787 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1789 file_format = gtk_radio_action_get_current_value (selected);
1790 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1795 modest_ui_actions_on_zoom_plus (GtkAction *action,
1796 ModestWindow *window)
1798 g_return_if_fail (MODEST_IS_WINDOW (window));
1800 modest_window_zoom_plus (MODEST_WINDOW (window));
1804 modest_ui_actions_on_zoom_minus (GtkAction *action,
1805 ModestWindow *window)
1807 g_return_if_fail (MODEST_IS_WINDOW (window));
1809 modest_window_zoom_minus (MODEST_WINDOW (window));
1813 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
1814 ModestWindow *window)
1816 ModestWindowMgr *mgr;
1817 gboolean fullscreen, active;
1818 g_return_if_fail (MODEST_IS_WINDOW (window));
1820 mgr = modest_runtime_get_window_mgr ();
1822 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
1823 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1825 if (active != fullscreen) {
1826 modest_window_mgr_set_fullscreen_mode (mgr, active);
1827 gtk_window_present (GTK_WINDOW (window));
1832 modest_ui_actions_on_change_fullscreen (GtkAction *action,
1833 ModestWindow *window)
1835 ModestWindowMgr *mgr;
1836 gboolean fullscreen;
1838 g_return_if_fail (MODEST_IS_WINDOW (window));
1840 mgr = modest_runtime_get_window_mgr ();
1841 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1842 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
1844 gtk_window_present (GTK_WINDOW (window));
1848 * Show the header details in a ModestDetailsDialog widget
1851 show_header_details (TnyHeader *header,
1857 dialog = modest_details_dialog_new_with_header (window, header);
1860 gtk_widget_show_all (dialog);
1861 gtk_dialog_run (GTK_DIALOG (dialog));
1863 gtk_widget_destroy (dialog);
1867 * Show the folder details in a ModestDetailsDialog widget
1870 show_folder_details (TnyFolder *folder,
1876 dialog = modest_details_dialog_new_with_folder (window, folder);
1879 gtk_widget_show_all (dialog);
1880 gtk_dialog_run (GTK_DIALOG (dialog));
1882 gtk_widget_destroy (dialog);
1887 modest_ui_actions_on_details (GtkAction *action,
1890 TnyList * headers_list;
1894 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1897 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1901 headers_list = get_selected_headers (win);
1905 iter = tny_list_create_iterator (headers_list);
1907 header = TNY_HEADER (tny_iterator_get_current (iter));
1908 show_header_details (header, GTK_WINDOW (win));
1909 g_object_unref (header);
1911 g_object_unref (iter);
1913 } else if (MODEST_IS_MAIN_WINDOW (win)) {
1914 GtkWidget *folder_view, *header_view;
1916 /* Check which widget has the focus */
1917 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1918 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1919 if (gtk_widget_is_focus (folder_view)) {
1922 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1924 /* Show only when it's a folder */
1925 if (!folder || !TNY_IS_FOLDER (folder))
1928 show_folder_details (folder, GTK_WINDOW (win));
1931 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1932 MODEST_WIDGET_TYPE_HEADER_VIEW);
1933 if (!gtk_widget_is_focus (header_view))
1936 headers_list = get_selected_headers (win);
1940 iter = tny_list_create_iterator (headers_list);
1941 while (!tny_iterator_is_done (iter)) {
1943 header = TNY_HEADER (tny_iterator_get_current (iter));
1944 show_header_details (header, GTK_WINDOW (win));
1945 g_object_unref (header);
1947 tny_iterator_next (iter);
1949 g_object_unref (iter);
1955 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
1956 ModestMsgEditWindow *window)
1958 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1960 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
1964 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
1965 ModestMsgEditWindow *window)
1967 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1969 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
1973 modest_ui_actions_toggle_folders_view (GtkAction *action,
1974 ModestMainWindow *main_window)
1978 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1980 conf = modest_runtime_get_conf ();
1982 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
1983 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
1985 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
1989 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
1990 ModestWindow *window)
1992 gboolean active, fullscreen = FALSE;
1993 ModestWindowMgr *mgr;
1995 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
1997 /* Check if we want to toggle the toolbar vuew in fullscreen
1999 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2000 "ViewShowToolbarFullScreen")) {
2004 /* Toggle toolbar */
2005 mgr = modest_runtime_get_window_mgr ();
2006 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2010 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2011 ModestMsgEditWindow *window)
2013 modest_msg_edit_window_select_font (window);
2017 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2018 const gchar *display_name,
2021 /* Do not change the application name if the widget has not
2022 the focus. This callback could be called even if the folder
2023 view has not the focus, because the handled signal could be
2024 emitted when the folder view is redrawn */
2025 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2027 gtk_window_set_title (window, display_name);
2029 gtk_window_set_title (window, " ");
2034 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2036 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2037 modest_msg_edit_window_select_contacts (window);
2041 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2043 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2044 modest_msg_edit_window_check_names (window);
2049 create_move_to_dialog (ModestWindow *win,
2050 GtkWidget *folder_view,
2051 GtkWidget **tree_view)
2053 GtkWidget *dialog, *scroll;
2055 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2057 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2059 GTK_RESPONSE_ACCEPT,
2061 GTK_RESPONSE_REJECT,
2064 /* Create scrolled window */
2065 scroll = gtk_scrolled_window_new (NULL, NULL);
2066 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2067 GTK_POLICY_AUTOMATIC,
2068 GTK_POLICY_AUTOMATIC);
2070 /* Create folder view */
2071 *tree_view = modest_folder_view_new (NULL);
2072 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2073 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2074 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2076 /* Add scroll to dialog */
2077 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2078 scroll, FALSE, FALSE, 0);
2080 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2086 * Returns TRUE if at least one of the headers of the list belongs to
2087 * a message that has been fully retrieved.
2090 has_retrieved_msgs (TnyList *list)
2093 gboolean found = FALSE;
2095 iter = tny_list_create_iterator (list);
2096 while (tny_iterator_is_done (iter) && !found) {
2098 TnyHeaderFlags flags;
2100 header = TNY_HEADER (tny_iterator_get_current (iter));
2101 flags = tny_header_get_flags (header);
2102 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2106 tny_iterator_next (iter);
2108 g_object_unref (iter);
2114 * Shows a confirmation dialog to the user when we're moving messages
2115 * from a remote server to the local storage. Returns the dialog
2116 * response. If it's other kind of movement the it always returns
2120 msgs_move_to_confirmation (GtkWindow *win,
2121 TnyFolder *dest_folder,
2124 gint response = GTK_RESPONSE_OK;
2126 /* If the destination is a local folder */
2127 if (modest_tny_folder_is_local_folder (dest_folder)) {
2128 TnyFolder *src_folder;
2132 /* Get source folder */
2133 iter = tny_list_create_iterator (headers);
2134 header = TNY_HEADER (tny_iterator_get_current (iter));
2135 src_folder = tny_header_get_folder (header);
2136 g_object_unref (header);
2137 g_object_unref (iter);
2139 /* If the source is a remote folder */
2140 if (!modest_tny_folder_is_local_folder (src_folder)) {
2141 const gchar *message;
2143 if (tny_list_get_length (headers) == 1)
2144 if (has_retrieved_msgs (headers))
2145 message = _("mcen_nc_move_retrieve");
2147 message = _("mcen_nc_move_header");
2149 if (has_retrieved_msgs (headers))
2150 message = _("mcen_nc_move_retrieves");
2152 message = _("mcen_nc_move_headers");
2154 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2155 (const gchar *) message);
2162 * UI handler for the "Move to" action when invoked from the
2166 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2167 ModestMainWindow *win)
2169 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2171 TnyFolderStore *folder_store;
2172 ModestMailOperation *mail_op = NULL;
2174 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2176 /* Get the folder view */
2177 folder_view = modest_main_window_get_child_widget (win,
2178 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2180 /* Create and run the dialog */
2181 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2182 result = gtk_dialog_run (GTK_DIALOG(dialog));
2184 /* We do this to save an indentation level ;-) */
2185 if (result != GTK_RESPONSE_ACCEPT)
2188 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2190 if (TNY_IS_ACCOUNT (folder_store))
2193 /* Get folder or messages to transfer */
2194 if (gtk_widget_is_focus (folder_view)) {
2195 TnyFolderStore *src_folder;
2196 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2198 if (TNY_IS_FOLDER (src_folder)) {
2199 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2200 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2203 modest_mail_operation_xfer_folder (mail_op,
2204 TNY_FOLDER (src_folder),
2207 g_object_unref (G_OBJECT (mail_op));
2211 g_object_unref (G_OBJECT (src_folder));
2213 GtkWidget *header_view;
2214 header_view = modest_main_window_get_child_widget (win,
2215 MODEST_WIDGET_TYPE_HEADER_VIEW);
2216 if (gtk_widget_is_focus (header_view)) {
2220 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2222 /* Ask for user confirmation */
2223 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2224 TNY_FOLDER (folder_store),
2227 /* Transfer messages */
2228 if (response == GTK_RESPONSE_OK) {
2229 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2230 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2233 modest_mail_operation_xfer_msgs (mail_op,
2235 TNY_FOLDER (folder_store),
2237 g_object_unref (G_OBJECT (mail_op));
2241 g_object_unref (folder_store);
2244 gtk_widget_destroy (dialog);
2249 * UI handler for the "Move to" action when invoked from the
2250 * ModestMsgViewWindow
2253 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2254 ModestMsgViewWindow *win)
2256 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2258 ModestMainWindow *main_window;
2263 /* Get the folder view */
2264 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2265 folder_view = modest_main_window_get_child_widget (main_window,
2266 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2268 /* Create and run the dialog */
2269 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2270 result = gtk_dialog_run (GTK_DIALOG(dialog));
2272 if (result == GTK_RESPONSE_ACCEPT) {
2273 TnyFolderStore *folder_store;
2276 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2278 /* Create header list */
2279 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2280 header = tny_msg_get_header (msg);
2281 headers = tny_simple_list_new ();
2282 tny_list_prepend (headers, G_OBJECT (header));
2283 g_object_unref (header);
2284 g_object_unref (msg);
2286 /* Ask user for confirmation. MSG-NOT404 */
2287 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2288 TNY_FOLDER (folder_store),
2291 /* Transfer current msg */
2292 if (response == GTK_RESPONSE_OK) {
2293 ModestMailOperation *mail_op;
2295 /* Create mail op */
2296 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2297 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2300 /* Transfer messages */
2301 modest_mail_operation_xfer_msgs (mail_op,
2303 TNY_FOLDER (folder_store),
2305 g_object_unref (G_OBJECT (mail_op));
2307 g_object_unref (headers);
2309 g_object_unref (folder_store);
2311 gtk_widget_destroy (dialog);
2315 modest_ui_actions_on_move_to (GtkAction *action,
2318 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2319 MODEST_IS_MSG_VIEW_WINDOW (win));
2321 if (MODEST_IS_MAIN_WINDOW (win))
2322 modest_ui_actions_on_main_window_move_to (action,
2323 MODEST_MAIN_WINDOW (win));
2325 modest_ui_actions_on_msg_view_window_move_to (action,
2326 MODEST_MSG_VIEW_WINDOW (win));