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), "header-view");
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),
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),
1063 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
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 data = modest_msg_edit_window_get_msg_data (edit_window);
1233 /* FIXME: Code added just for testing. The final version will
1234 use the send queue provided by tinymail and some
1236 account_mgr = modest_runtime_get_account_mgr();
1237 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1239 account_name = modest_account_mgr_get_default_account (account_mgr);
1240 if (!account_name) {
1241 g_printerr ("modest: no account found\n");
1242 modest_msg_edit_window_free_msg_data (edit_window, data);
1246 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1247 (modest_runtime_get_account_store(),
1249 if (!transport_account) {
1250 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1251 g_free (account_name);
1252 modest_msg_edit_window_free_msg_data (edit_window, data);
1255 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1257 /* Create the mail operation */
1258 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND);
1259 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1261 modest_mail_operation_send_new_mail (mail_operation,
1271 data->priority_flags);
1274 g_free (account_name);
1275 g_object_unref (G_OBJECT (transport_account));
1276 g_object_unref (G_OBJECT (mail_operation));
1278 modest_msg_edit_window_free_msg_data (edit_window, data);
1280 /* Save settings and close the window */
1281 gtk_widget_destroy (GTK_WIDGET (edit_window));
1285 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1286 ModestMsgEditWindow *window)
1288 ModestMsgEditFormatState *format_state = NULL;
1290 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1291 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1293 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1296 format_state = modest_msg_edit_window_get_format_state (window);
1297 g_return_if_fail (format_state != NULL);
1299 format_state->bold = gtk_toggle_action_get_active (action);
1300 modest_msg_edit_window_set_format_state (window, format_state);
1301 g_free (format_state);
1306 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1307 ModestMsgEditWindow *window)
1309 ModestMsgEditFormatState *format_state = NULL;
1311 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1312 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1314 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1317 format_state = modest_msg_edit_window_get_format_state (window);
1318 g_return_if_fail (format_state != NULL);
1320 format_state->italics = gtk_toggle_action_get_active (action);
1321 modest_msg_edit_window_set_format_state (window, format_state);
1322 g_free (format_state);
1327 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1328 ModestMsgEditWindow *window)
1330 ModestMsgEditFormatState *format_state = NULL;
1332 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1333 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1335 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1338 format_state = modest_msg_edit_window_get_format_state (window);
1339 g_return_if_fail (format_state != NULL);
1341 format_state->bullet = gtk_toggle_action_get_active (action);
1342 modest_msg_edit_window_set_format_state (window, format_state);
1343 g_free (format_state);
1348 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1349 GtkRadioAction *selected,
1350 ModestMsgEditWindow *window)
1352 ModestMsgEditFormatState *format_state = NULL;
1353 GtkJustification value;
1355 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1357 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1360 value = gtk_radio_action_get_current_value (selected);
1362 format_state = modest_msg_edit_window_get_format_state (window);
1363 g_return_if_fail (format_state != NULL);
1365 format_state->justification = value;
1366 modest_msg_edit_window_set_format_state (window, format_state);
1367 g_free (format_state);
1371 modest_ui_actions_on_select_editor_color (GtkAction *action,
1372 ModestMsgEditWindow *window)
1374 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1375 g_return_if_fail (GTK_IS_ACTION (action));
1377 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1380 modest_msg_edit_window_select_color (window);
1384 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1385 ModestMsgEditWindow *window)
1387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1388 g_return_if_fail (GTK_IS_ACTION (action));
1390 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1393 modest_msg_edit_window_select_background_color (window);
1397 modest_ui_actions_on_insert_image (GtkAction *action,
1398 ModestMsgEditWindow *window)
1400 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1401 g_return_if_fail (GTK_IS_ACTION (action));
1403 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1406 modest_msg_edit_window_insert_image (window);
1410 * Shows a dialog with an entry that asks for some text. The returned
1411 * value must be freed by the caller. The dialog window title will be
1415 ask_for_folder_name (GtkWindow *parent_window,
1418 GtkWidget *dialog, *entry;
1419 gchar *folder_name = NULL;
1421 /* Ask for folder name */
1422 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1426 GTK_RESPONSE_REJECT,
1428 GTK_RESPONSE_ACCEPT,
1430 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1431 gtk_label_new(title),
1434 entry = gtk_entry_new_with_max_length (40);
1435 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1439 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1441 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1442 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1444 gtk_widget_destroy (dialog);
1450 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1452 TnyFolderStore *parent_folder;
1453 GtkWidget *folder_view;
1455 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1457 folder_view = modest_main_window_get_child_widget (main_window,
1458 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1462 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1464 if (parent_folder) {
1465 gboolean finished = FALSE;
1467 gchar *folder_name = NULL, *suggested_name = NULL;
1469 /* Run the new folder dialog */
1471 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1476 if (result == GTK_RESPONSE_REJECT) {
1479 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1480 TnyFolder *new_folder = NULL;
1482 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1485 new_folder = modest_mail_operation_create_folder (mail_op,
1487 (const gchar *) folder_name);
1489 g_object_unref (new_folder);
1493 /* /\* TODO: check error and follow proper actions *\/ */
1494 /* /\* suggested_name = X; *\/ */
1495 /* /\* Show error to the user *\/ */
1496 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1497 /* MODEST_INFORMATION_CREATE_FOLDER); */
1499 g_object_unref (mail_op);
1501 g_free (folder_name);
1505 g_object_unref (parent_folder);
1510 modest_ui_actions_on_rename_folder (GtkAction *action,
1511 ModestMainWindow *main_window)
1513 TnyFolderStore *folder;
1514 GtkWidget *folder_view;
1516 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1518 folder_view = modest_main_window_get_child_widget (main_window,
1519 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1523 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1525 if (folder && TNY_IS_FOLDER (folder)) {
1527 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1528 _("Please enter a new name for the folder"));
1530 if (folder_name != NULL && strlen (folder_name) > 0) {
1531 ModestMailOperation *mail_op;
1533 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1534 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1537 modest_mail_operation_rename_folder (mail_op,
1538 TNY_FOLDER (folder),
1539 (const gchar *) folder_name);
1541 g_object_unref (mail_op);
1542 g_free (folder_name);
1544 g_object_unref (folder);
1549 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1551 TnyFolderStore *folder;
1552 GtkWidget *folder_view;
1556 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1558 folder_view = modest_main_window_get_child_widget (main_window,
1559 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1563 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1566 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1567 tny_folder_get_name (TNY_FOLDER (folder)));
1568 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1569 (const gchar *) message);
1572 if (response == GTK_RESPONSE_OK) {
1573 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE);
1575 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1577 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1579 /* Show error if happened */
1580 if (modest_mail_operation_get_error (mail_op))
1581 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1582 MODEST_INFORMATION_DELETE_FOLDER);
1584 g_object_unref (G_OBJECT (mail_op));
1587 g_object_unref (G_OBJECT (folder));
1591 modest_ui_actions_on_delete_folder (GtkAction *action,
1592 ModestMainWindow *main_window)
1594 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1596 delete_folder (main_window, FALSE);
1600 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1602 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1604 delete_folder (main_window, TRUE);
1608 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1609 const gchar* account_name,
1613 ModestMainWindow *main_window)
1616 GtkWidget *dialog, *entry, *remember_pass_check;
1618 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1622 GTK_RESPONSE_REJECT,
1624 GTK_RESPONSE_ACCEPT,
1626 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1628 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1629 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1633 entry = gtk_entry_new_with_max_length (40);
1634 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1635 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1637 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1640 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1641 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1644 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1646 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1647 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1654 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1659 gtk_widget_destroy (dialog);
1663 modest_ui_actions_on_cut (GtkAction *action,
1664 ModestWindow *window)
1666 GtkWidget *focused_widget;
1668 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1669 if (GTK_IS_EDITABLE (focused_widget)) {
1670 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1671 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1672 GtkTextBuffer *buffer;
1673 GtkClipboard *clipboard;
1675 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1676 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1677 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1682 modest_ui_actions_on_copy (GtkAction *action,
1683 ModestWindow *window)
1685 GtkClipboard *clipboard;
1686 GtkWidget *focused_widget;
1688 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1689 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1690 if (GTK_IS_LABEL (focused_widget)) {
1691 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1692 } else if (GTK_IS_EDITABLE (focused_widget)) {
1693 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1694 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1695 GtkTextBuffer *buffer;
1697 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1698 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1703 modest_ui_actions_on_undo (GtkAction *action,
1704 ModestWindow *window)
1706 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1707 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1709 g_return_if_reached ();
1714 modest_ui_actions_on_paste (GtkAction *action,
1715 ModestWindow *window)
1717 GtkWidget *focused_widget;
1719 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1720 if (GTK_IS_EDITABLE (focused_widget)) {
1721 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1722 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1723 GtkTextBuffer *buffer;
1724 GtkClipboard *clipboard;
1726 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1727 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1728 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1733 modest_ui_actions_on_select_all (GtkAction *action,
1734 ModestWindow *window)
1736 GtkWidget *focused_widget;
1738 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1739 if (GTK_IS_LABEL (focused_widget)) {
1740 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1741 } else if (GTK_IS_EDITABLE (focused_widget)) {
1742 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1743 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1744 GtkTextBuffer *buffer;
1745 GtkTextIter start, end;
1747 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1748 gtk_text_buffer_get_start_iter (buffer, &start);
1749 gtk_text_buffer_get_end_iter (buffer, &end);
1750 gtk_text_buffer_select_range (buffer, &start, &end);
1755 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1756 GtkRadioAction *selected,
1757 ModestWindow *window)
1761 value = gtk_radio_action_get_current_value (selected);
1762 if (MODEST_IS_WINDOW (window)) {
1763 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1767 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1768 GtkRadioAction *selected,
1769 ModestWindow *window)
1771 TnyHeaderFlags flags;
1772 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1774 flags = gtk_radio_action_get_current_value (selected);
1775 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1778 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1779 GtkRadioAction *selected,
1780 ModestWindow *window)
1784 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1786 file_format = gtk_radio_action_get_current_value (selected);
1787 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1792 modest_ui_actions_on_zoom_plus (GtkAction *action,
1793 ModestWindow *window)
1795 g_return_if_fail (MODEST_IS_WINDOW (window));
1797 modest_window_zoom_plus (MODEST_WINDOW (window));
1801 modest_ui_actions_on_zoom_minus (GtkAction *action,
1802 ModestWindow *window)
1804 g_return_if_fail (MODEST_IS_WINDOW (window));
1806 modest_window_zoom_minus (MODEST_WINDOW (window));
1810 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
1811 ModestWindow *window)
1813 ModestWindowMgr *mgr;
1814 gboolean fullscreen, active;
1815 g_return_if_fail (MODEST_IS_WINDOW (window));
1817 mgr = modest_runtime_get_window_mgr ();
1819 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
1820 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1822 if (active != fullscreen) {
1823 modest_window_mgr_set_fullscreen_mode (mgr, active);
1824 gtk_window_present (GTK_WINDOW (window));
1829 modest_ui_actions_on_change_fullscreen (GtkAction *action,
1830 ModestWindow *window)
1832 ModestWindowMgr *mgr;
1833 gboolean fullscreen;
1835 g_return_if_fail (MODEST_IS_WINDOW (window));
1837 mgr = modest_runtime_get_window_mgr ();
1838 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1839 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
1841 gtk_window_present (GTK_WINDOW (window));
1845 * Show the header details in a ModestDetailsDialog widget
1848 show_header_details (TnyHeader *header,
1854 dialog = modest_details_dialog_new_with_header (window, header);
1857 gtk_widget_show_all (dialog);
1858 gtk_dialog_run (GTK_DIALOG (dialog));
1860 gtk_widget_destroy (dialog);
1864 * Show the folder details in a ModestDetailsDialog widget
1867 show_folder_details (TnyFolder *folder,
1873 dialog = modest_details_dialog_new_with_folder (window, folder);
1876 gtk_widget_show_all (dialog);
1877 gtk_dialog_run (GTK_DIALOG (dialog));
1879 gtk_widget_destroy (dialog);
1884 modest_ui_actions_on_details (GtkAction *action,
1887 TnyList * headers_list;
1891 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1894 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1898 headers_list = get_selected_headers (win);
1902 iter = tny_list_create_iterator (headers_list);
1904 header = TNY_HEADER (tny_iterator_get_current (iter));
1905 show_header_details (header, GTK_WINDOW (win));
1906 g_object_unref (header);
1908 g_object_unref (iter);
1910 } else if (MODEST_IS_MAIN_WINDOW (win)) {
1911 GtkWidget *folder_view, *header_view;
1913 /* Check which widget has the focus */
1914 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1915 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1916 if (gtk_widget_is_focus (folder_view)) {
1919 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1921 /* Show only when it's a folder */
1922 if (!folder || !TNY_IS_FOLDER (folder))
1925 show_folder_details (folder, GTK_WINDOW (win));
1928 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1929 MODEST_WIDGET_TYPE_HEADER_VIEW);
1930 if (!gtk_widget_is_focus (header_view))
1933 headers_list = get_selected_headers (win);
1937 iter = tny_list_create_iterator (headers_list);
1938 while (!tny_iterator_is_done (iter)) {
1940 header = TNY_HEADER (tny_iterator_get_current (iter));
1941 show_header_details (header, GTK_WINDOW (win));
1942 g_object_unref (header);
1944 tny_iterator_next (iter);
1946 g_object_unref (iter);
1952 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
1953 ModestMsgEditWindow *window)
1955 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1957 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
1961 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
1962 ModestMsgEditWindow *window)
1964 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1966 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
1970 modest_ui_actions_toggle_folders_view (GtkAction *action,
1971 ModestMainWindow *main_window)
1975 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1977 conf = modest_runtime_get_conf ();
1979 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
1980 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
1982 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
1986 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
1987 ModestWindow *window)
1989 gboolean active, fullscreen = FALSE;
1990 ModestWindowMgr *mgr;
1992 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
1994 /* Check if we want to toggle the toolbar vuew in fullscreen
1996 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
1997 "ViewShowToolbarFullScreen")) {
2001 /* Toggle toolbar */
2002 mgr = modest_runtime_get_window_mgr ();
2003 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2007 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2008 ModestMsgEditWindow *window)
2010 modest_msg_edit_window_select_font (window);
2014 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2015 const gchar *display_name,
2018 /* Do not change the application name if the widget has not
2019 the focus. This callback could be called even if the folder
2020 view has not the focus, because the handled signal could be
2021 emitted when the folder view is redrawn */
2022 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2024 gtk_window_set_title (window, display_name);
2026 gtk_window_set_title (window, " ");
2031 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2033 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2034 modest_msg_edit_window_select_contacts (window);
2039 create_move_to_dialog (ModestWindow *win,
2040 GtkWidget *folder_view,
2041 GtkWidget **tree_view)
2043 GtkWidget *dialog, *scroll;
2045 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2047 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2049 GTK_RESPONSE_ACCEPT,
2051 GTK_RESPONSE_REJECT,
2054 /* Create scrolled window */
2055 scroll = gtk_scrolled_window_new (NULL, NULL);
2056 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2057 GTK_POLICY_AUTOMATIC,
2058 GTK_POLICY_AUTOMATIC);
2060 /* Create folder view */
2061 *tree_view = modest_folder_view_new (NULL);
2062 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2063 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2064 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2066 /* Add scroll to dialog */
2067 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2068 scroll, FALSE, FALSE, 0);
2070 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2076 * Returns TRUE if at least one of the headers of the list belongs to
2077 * a message that has been fully retrieved.
2080 has_retrieved_msgs (TnyList *list)
2083 gboolean found = FALSE;
2085 iter = tny_list_create_iterator (list);
2086 while (tny_iterator_is_done (iter) && !found) {
2088 TnyHeaderFlags flags;
2090 header = TNY_HEADER (tny_iterator_get_current (iter));
2091 flags = tny_header_get_flags (header);
2092 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2096 tny_iterator_next (iter);
2098 g_object_unref (iter);
2104 * Shows a confirmation dialog to the user when we're moving messages
2105 * from a remote server to the local storage. Returns the dialog
2106 * response. If it's other kind of movement the it always returns
2110 msgs_move_to_confirmation (GtkWindow *win,
2111 TnyFolder *dest_folder,
2114 gint response = GTK_RESPONSE_OK;
2116 /* If the destination is a local folder */
2117 if (modest_tny_folder_is_local_folder (dest_folder)) {
2118 TnyFolder *src_folder;
2122 /* Get source folder */
2123 iter = tny_list_create_iterator (headers);
2124 header = TNY_HEADER (tny_iterator_get_current (iter));
2125 src_folder = tny_header_get_folder (header);
2126 g_object_unref (header);
2127 g_object_unref (iter);
2129 /* If the source is a remote folder */
2130 if (!modest_tny_folder_is_local_folder (src_folder)) {
2131 const gchar *message;
2133 if (tny_list_get_length (headers) == 1)
2134 if (has_retrieved_msgs (headers))
2135 message = _("mcen_nc_move_retrieve");
2137 message = _("mcen_nc_move_header");
2139 if (has_retrieved_msgs (headers))
2140 message = _("mcen_nc_move_retrieves");
2142 message = _("mcen_nc_move_headers");
2144 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2145 (const gchar *) message);
2152 * UI handler for the "Move to" action when invoked from the
2156 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2157 ModestMainWindow *win)
2159 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2161 TnyFolderStore *folder_store;
2162 ModestMailOperation *mail_op = NULL;
2164 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2166 /* Get the folder view */
2167 folder_view = modest_main_window_get_child_widget (win,
2168 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2170 /* Create and run the dialog */
2171 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2172 result = gtk_dialog_run (GTK_DIALOG(dialog));
2174 /* We do this to save an indentation level ;-) */
2175 if (result != GTK_RESPONSE_ACCEPT)
2178 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2180 if (TNY_IS_ACCOUNT (folder_store))
2183 /* Get folder or messages to transfer */
2184 if (gtk_widget_is_focus (folder_view)) {
2185 TnyFolderStore *src_folder;
2186 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2188 if (TNY_IS_FOLDER (src_folder)) {
2189 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2190 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2193 modest_mail_operation_xfer_folder (mail_op,
2194 TNY_FOLDER (src_folder),
2197 g_object_unref (G_OBJECT (mail_op));
2201 g_object_unref (G_OBJECT (src_folder));
2203 GtkWidget *header_view;
2204 header_view = modest_main_window_get_child_widget (win,
2205 MODEST_WIDGET_TYPE_HEADER_VIEW);
2206 if (gtk_widget_is_focus (header_view)) {
2210 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2212 /* Ask for user confirmation */
2213 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2214 TNY_FOLDER (folder_store),
2217 /* Transfer messages */
2218 if (response == GTK_RESPONSE_OK) {
2219 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2220 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2223 modest_mail_operation_xfer_msgs (mail_op,
2225 TNY_FOLDER (folder_store),
2227 g_object_unref (G_OBJECT (mail_op));
2231 g_object_unref (folder_store);
2234 gtk_widget_destroy (dialog);
2239 * UI handler for the "Move to" action when invoked from the
2240 * ModestMsgViewWindow
2243 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2244 ModestMsgViewWindow *win)
2246 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2248 ModestMainWindow *main_window;
2253 /* Get the folder view */
2254 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2255 folder_view = modest_main_window_get_child_widget (main_window,
2256 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2258 /* Create and run the dialog */
2259 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2260 result = gtk_dialog_run (GTK_DIALOG(dialog));
2262 if (result == GTK_RESPONSE_ACCEPT) {
2263 TnyFolderStore *folder_store;
2266 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2268 /* Create header list */
2269 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2270 header = tny_msg_get_header (msg);
2271 headers = tny_simple_list_new ();
2272 tny_list_prepend (headers, G_OBJECT (header));
2273 g_object_unref (header);
2274 g_object_unref (msg);
2276 /* Ask user for confirmation. MSG-NOT404 */
2277 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2278 TNY_FOLDER (folder_store),
2281 /* Transfer current msg */
2282 if (response == GTK_RESPONSE_OK) {
2283 ModestMailOperation *mail_op;
2285 /* Create mail op */
2286 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2287 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2290 /* Transfer messages */
2291 modest_mail_operation_xfer_msgs (mail_op,
2293 TNY_FOLDER (folder_store),
2295 g_object_unref (G_OBJECT (mail_op));
2297 g_object_unref (headers);
2299 g_object_unref (folder_store);
2301 gtk_widget_destroy (dialog);
2305 modest_ui_actions_on_move_to (GtkAction *action,
2308 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2309 MODEST_IS_MSG_VIEW_WINDOW (win));
2311 if (MODEST_IS_MAIN_WINDOW (win))
2312 modest_ui_actions_on_main_window_move_to (action,
2313 MODEST_MAIN_WINDOW (win));
2315 modest_ui_actions_on_msg_view_window_move_to (action,
2316 MODEST_MSG_VIEW_WINDOW (win));