1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
36 #include <modest-runtime.h>
37 #include <modest-tny-folder.h>
38 #include <modest-tny-msg.h>
39 #include <modest-tny-account.h>
40 #include <modest-address-book.h>
42 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
47 #include <widgets/modest-main-window.h>
48 #include <widgets/modest-msg-view-window.h>
49 #include <widgets/modest-account-view-window.h>
50 #include <widgets/modest-details-dialog.h>
52 #include "modest-account-mgr-helpers.h"
53 #include "modest-mail-operation.h"
54 #include "modest-text-utils.h"
56 #ifdef MODEST_HAVE_EASYSETUP
57 #include "easysetup/modest-easysetup-wizard.h"
58 #endif /*MODEST_HAVE_EASYSETUP*/
60 #include <modest-widget-memory.h>
61 #include <tny-error.h>
62 #include <tny-simple-list.h>
63 #include <tny-msg-view.h>
64 #include <tny-device.h>
66 typedef struct _GetMsgAsyncHelper {
73 typedef enum _ReplyForwardAction {
79 typedef struct _ReplyForwardHelper {
80 guint reply_forward_type;
81 ReplyForwardAction action;
86 static void reply_forward_func (gpointer data, gpointer user_data);
87 static void read_msg_func (gpointer data, gpointer user_data);
88 static void get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err,
90 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
92 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
96 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
99 const gchar *authors[] = {
100 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
103 about = gtk_about_dialog_new ();
104 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
105 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
106 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
107 _("Copyright (c) 2006, Nokia Corporation\n"
108 "All rights reserved."));
109 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
110 _("a modest e-mail client\n\n"
111 "design and implementation: Dirk-Jan C. Binnema\n"
112 "contributions from the fine people at KC and Ig\n"
113 "uses the tinymail email framework written by Philip van Hoof"));
114 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
115 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
117 gtk_dialog_run (GTK_DIALOG (about));
118 gtk_widget_destroy(about);
123 get_selected_headers (ModestWindow *win)
125 if (MODEST_IS_MAIN_WINDOW(win)) {
126 GtkWidget *header_view;
128 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
129 MODEST_WIDGET_TYPE_HEADER_VIEW);
130 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
132 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
133 /* for MsgViewWindows, we simply return a list with one element */
136 TnyList *list = NULL;
138 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
140 header = tny_msg_get_header (msg);
141 list = tny_simple_list_new ();
142 tny_list_prepend (list, G_OBJECT(header));
143 g_object_unref (G_OBJECT(header));
152 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
154 TnyList *header_list;
157 g_return_if_fail (MODEST_IS_WINDOW(win));
159 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
161 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
165 header_list = get_selected_headers (win);
168 iter = tny_list_create_iterator (header_list);
171 ModestMailOperation *mail_op;
173 header = TNY_HEADER (tny_iterator_get_current (iter));
174 /* TODO: thick grain mail operation involving
175 a list of objects. Composite pattern ??? */
176 /* TODO: add confirmation dialog */
177 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE);
178 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
181 /* Always delete. TODO: Move to trash still not supported */
182 modest_mail_operation_remove_msg (mail_op, header, FALSE);
185 g_object_unref (G_OBJECT (mail_op));
186 g_object_unref (G_OBJECT (header));
188 tny_iterator_next (iter);
190 } while (!tny_iterator_is_done (iter));
193 g_object_unref (G_OBJECT (iter));
196 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
197 gtk_widget_destroy (GTK_WIDGET(win));
203 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
209 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
211 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
212 gtk_widget_destroy (GTK_WIDGET (win));
213 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
215 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
216 } else if (MODEST_IS_WINDOW (win)) {
217 gtk_widget_destroy (GTK_WIDGET (win));
219 g_return_if_reached ();
224 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
226 GtkClipboard *clipboard = NULL;
227 gchar *selection = NULL;
229 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
230 selection = gtk_clipboard_wait_for_text (clipboard);
232 modest_address_book_add_address (selection);
237 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
240 /* This is currently only implemented for Maemo,
241 * because it requires a providers preset file which is not publically available.
243 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
244 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
245 gboolean accounts_exist = account_names != NULL;
246 g_slist_free (account_names);
248 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
249 if (!accounts_exist) {
250 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
251 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
252 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
253 gtk_dialog_run (GTK_DIALOG (wizard));
254 gtk_widget_destroy (GTK_WIDGET (wizard));
256 /* Show the list of accounts: */
257 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
258 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
259 gtk_dialog_run (account_win);
260 gtk_widget_destroy (GTK_WIDGET(account_win));
263 GtkWidget *dialog, *label;
265 /* Create the widgets */
267 dialog = gtk_dialog_new_with_buttons ("Message",
269 GTK_DIALOG_DESTROY_WITH_PARENT,
273 label = gtk_label_new ("Hello World!");
275 /* Ensure that the dialog box is destroyed when the user responds. */
277 g_signal_connect_swapped (dialog, "response",
278 G_CALLBACK (gtk_widget_destroy),
281 /* Add the label, and show everything we've added to the dialog. */
283 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
285 gtk_widget_show_all (dialog);
286 #endif /* MODEST_PLATFORM_MAEMO */
290 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
292 ModestWindow *msg_win;
294 TnyFolder *folder = NULL;
295 gchar *account_name = NULL;
296 gchar *from_str = NULL;
297 /* GError *err = NULL; */
298 TnyAccount *account = NULL;
299 ModestWindowMgr *mgr;
300 gchar *signature = NULL;
302 account_name = g_strdup(modest_window_get_active_account (win));
304 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
306 g_printerr ("modest: no account found\n");
310 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
312 TNY_ACCOUNT_TYPE_STORE);
314 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
318 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
320 g_printerr ("modest: failed get from string for '%s'\n", account_name);
324 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
325 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
326 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
327 MODEST_ACCOUNT_SIGNATURE, FALSE);
329 signature = g_strdup ("");
332 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
334 g_printerr ("modest: failed to create new msg\n");
338 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
340 g_printerr ("modest: failed to find Drafts folder\n");
344 /* tny_folder_add_msg (folder, msg, &err); */
346 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
348 /* g_error_free (err); */
352 /* Create and register edit window */
353 msg_win = modest_msg_edit_window_new (msg, account_name);
354 mgr = modest_runtime_get_window_mgr ();
355 modest_window_mgr_register_window (mgr, msg_win);
358 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
360 gtk_widget_show_all (GTK_WIDGET (msg_win));
363 g_free (account_name);
367 g_object_unref (G_OBJECT(account));
369 g_object_unref (G_OBJECT(msg));
371 g_object_unref (G_OBJECT(folder));
376 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
378 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
384 reply_forward_func (gpointer data, gpointer user_data)
386 TnyMsg *msg, *new_msg;
387 GetMsgAsyncHelper *helper;
388 ReplyForwardHelper *rf_helper;
389 ModestWindow *msg_win;
390 ModestEditType edit_type;
393 TnyFolder *folder = NULL;
394 TnyAccount *account = NULL;
395 ModestWindowMgr *mgr;
396 gchar *signature = NULL;
398 msg = TNY_MSG (data);
399 helper = (GetMsgAsyncHelper *) user_data;
400 rf_helper = (ReplyForwardHelper *) helper->user_data;
402 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
403 rf_helper->account_name);
404 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
405 rf_helper->account_name,
406 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
407 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
408 rf_helper->account_name,
409 MODEST_ACCOUNT_SIGNATURE, FALSE);
411 /* Create reply mail */
412 switch (rf_helper->action) {
415 modest_tny_msg_create_reply_msg (msg, from, signature,
416 rf_helper->reply_forward_type,
417 MODEST_TNY_MSG_REPLY_MODE_SENDER);
419 case ACTION_REPLY_TO_ALL:
421 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
422 MODEST_TNY_MSG_REPLY_MODE_ALL);
423 edit_type = MODEST_EDIT_TYPE_REPLY;
427 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
428 edit_type = MODEST_EDIT_TYPE_FORWARD;
431 g_return_if_reached ();
438 g_printerr ("modest: failed to create message\n");
442 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
443 rf_helper->account_name,
444 TNY_ACCOUNT_TYPE_STORE);
446 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
450 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
452 g_printerr ("modest: failed to find Drafts folder\n");
456 tny_folder_add_msg (folder, msg, &err);
458 g_printerr ("modest: error adding msg to Drafts folder: %s",
464 /* Create and register the windows */
465 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
466 mgr = modest_runtime_get_window_mgr ();
467 modest_window_mgr_register_window (mgr, msg_win);
469 /* Show edit window */
470 gtk_widget_show_all (GTK_WIDGET (msg_win));
474 g_object_unref (G_OBJECT (new_msg));
476 g_object_unref (G_OBJECT (folder));
478 g_object_unref (G_OBJECT (account));
480 g_free (rf_helper->account_name);
481 g_slice_free (ReplyForwardHelper, rf_helper);
484 * Common code for the reply and forward actions
487 reply_forward (ReplyForwardAction action, ModestWindow *win)
489 TnyList *header_list;
490 guint reply_forward_type;
493 GetMsgAsyncHelper *helper;
494 ReplyForwardHelper *rf_helper;
496 g_return_if_fail (MODEST_IS_WINDOW(win));
498 header_list = get_selected_headers (win);
502 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
503 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
505 /* We assume that we can only select messages of the
506 same folder and that we reply all of them from the
507 same account. In fact the interface currently only
508 allows single selection */
511 rf_helper = g_slice_new0 (ReplyForwardHelper);
512 rf_helper->reply_forward_type = reply_forward_type;
513 rf_helper->action = action;
515 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
516 if (!rf_helper->account_name)
517 rf_helper->account_name =
518 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
520 helper = g_slice_new0 (GetMsgAsyncHelper);
521 helper->window = win;
522 helper->func = reply_forward_func;
523 helper->iter = tny_list_create_iterator (header_list);
524 helper->user_data = rf_helper;
526 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
528 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
530 g_printerr ("modest: no message found\n");
533 reply_forward_func (msg, helper);
535 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
536 folder = tny_header_get_folder (header);
538 /* The callback will call it per each header */
539 tny_folder_get_msg_async (folder, header, get_msg_cb, NULL, helper);
540 g_object_unref (G_OBJECT (folder));
542 g_printerr ("modest: no folder for header\n");
545 g_object_unref (G_OBJECT (header));
551 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
553 g_return_if_fail (MODEST_IS_WINDOW(win));
555 reply_forward (ACTION_REPLY, win);
559 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
561 g_return_if_fail (MODEST_IS_WINDOW(win));
563 reply_forward (ACTION_FORWARD, win);
567 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
569 g_return_if_fail (MODEST_IS_WINDOW(win));
571 reply_forward (ACTION_REPLY_TO_ALL, win);
575 modest_ui_actions_on_next (GtkAction *action,
576 ModestWindow *window)
578 if (MODEST_IS_MAIN_WINDOW (window)) {
579 GtkWidget *header_view;
581 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
582 MODEST_WIDGET_TYPE_HEADER_VIEW);
586 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
587 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
588 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
590 g_return_if_reached ();
595 modest_ui_actions_on_prev (GtkAction *action,
596 ModestWindow *window)
598 g_return_if_fail (MODEST_IS_WINDOW(window));
600 if (MODEST_IS_MAIN_WINDOW (window)) {
601 GtkWidget *header_view;
602 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
603 MODEST_WIDGET_TYPE_HEADER_VIEW);
607 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
608 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
609 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
611 g_return_if_reached ();
616 modest_ui_actions_on_sort (GtkAction *action,
617 ModestWindow *window)
619 g_return_if_fail (MODEST_IS_WINDOW(window));
621 if (MODEST_IS_MAIN_WINDOW (window)) {
622 GtkWidget *header_view;
623 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
624 MODEST_WIDGET_TYPE_HEADER_VIEW);
628 /* Show sorting dialog */
629 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
635 action_send (const gchar* account_name)
637 TnyAccount *tny_account;
638 ModestTnySendQueue *send_queue;
640 g_return_val_if_fail (account_name, FALSE);
642 /* Get the transport account according to the open connection,
643 * because the account might specify connection-specific SMTP servers.
646 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
649 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
653 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
655 g_object_unref (G_OBJECT(tny_account));
656 g_printerr ("modest: cannot get send queue for %s\n", account_name);
660 //modest_tny_send_queue_flush (send_queue);
662 g_object_unref (G_OBJECT(send_queue));
663 g_object_unref (G_OBJECT(tny_account));
670 action_receive (const gchar* account_name)
672 TnyAccount *tny_account;
673 ModestMailOperation *mail_op;
675 g_return_val_if_fail (account_name, FALSE);
678 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
680 TNY_ACCOUNT_TYPE_STORE);
682 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
686 /* Create the mail operation */
687 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
688 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
689 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
690 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
692 g_object_unref (G_OBJECT(tny_account));
693 g_object_unref (G_OBJECT (mail_op));
698 /** Check that an appropriate connection is open.
700 gboolean check_for_connection (const gchar *account_name)
702 TnyDevice *device = modest_runtime_get_device ();
705 g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
707 TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
710 if (tny_device_is_online (device))
713 modest_platform_connect_and_wait (NULL);
715 /* TODO: Wait until a result. */
721 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 GSList *iter = account_names;
767 const gchar * account_name = (const char*) iter->data;
769 /* Do not continue if no suitable connection is open: */
770 if (account_name && check_for_connection (account_name)) {
771 /* As per the UI spec,
772 * for POP accounts, we should receive,
773 * for IMAP we should synchronize everything, including receiving,
774 * for SMTP we should send,
775 * first receiving, then sending:
777 if (!action_receive(account_name))
778 g_printerr ("modest: failed to receive for account %s\n", account_name);
779 if (!action_send(account_name))
780 g_printerr ("modest: failed to send for account %s\n", account_name);
785 g_slist_free (account_names);
789 do_send_receive (ModestWindow *win)
791 const gboolean auto_update = TRUE; /* TODO: Get gconf setting. */
793 do_send_receive_current_or_default (win);
795 do_send_receive_auto (win);
799 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
801 /* Check that at least one account exists: */
802 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
803 gboolean accounts_exist = account_names != NULL;
804 g_slist_free (account_names);
806 /* If not, allow the user to create an account before trying to send/receive. */
807 if (!accounts_exist) {
808 modest_ui_actions_on_accounts (NULL, win);
811 do_send_receive (win);
818 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
821 GtkWidget *header_view;
823 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
825 header_view = modest_main_window_get_child_widget (main_window,
826 MODEST_WIDGET_TYPE_HEADER_VIEW);
830 conf = modest_runtime_get_conf ();
832 /* what is saved/restored is depending on the style; thus; we save with
833 * old style, then update the style, and restore for this new style
835 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
837 if (modest_header_view_get_style
838 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
839 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
840 MODEST_HEADER_VIEW_STYLE_TWOLINES);
842 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
843 MODEST_HEADER_VIEW_STYLE_DETAILS);
845 modest_widget_memory_restore (conf, G_OBJECT(header_view),
852 * Marks a message as read and passes it to the msg preview widget
855 read_msg_func (gpointer data, gpointer user_data)
859 GetMsgAsyncHelper *helper;
860 TnyHeaderFlags header_flags;
861 GtkWidget *msg_preview;
863 msg = TNY_MSG (data);
864 helper = (GetMsgAsyncHelper *) user_data;
866 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
867 MODEST_WIDGET_TYPE_MSG_PREVIEW);
871 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
872 header_flags = tny_header_get_flags (header);
873 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
874 g_object_unref (G_OBJECT (header));
876 /* Set message on msg view */
877 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
881 * This function is a generic handler for the tny_folder_get_msg_async
882 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
883 * contains a user provided function that is called inside this
884 * method. This will allow us to use this callback in many different
885 * places. This callback performs the common actions for the
886 * get_msg_async call, more specific actions will be done by the user
890 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
892 GetMsgAsyncHelper *helper;
894 helper = (GetMsgAsyncHelper *) user_data;
896 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
897 modest_ui_actions_on_item_not_found (NULL,
898 MODEST_ITEM_TYPE_MESSAGE,
903 /* Call user function */
904 helper->func (msg, user_data);
906 /* Process next element (if exists) */
907 tny_iterator_next (helper->iter);
908 if (tny_iterator_is_done (helper->iter)) {
910 headers = tny_iterator_get_list (helper->iter);
912 g_object_unref (G_OBJECT (headers));
913 g_object_unref (G_OBJECT (helper->iter));
914 g_slice_free (GetMsgAsyncHelper, helper);
917 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
918 tny_folder_get_msg_async (folder, header,
919 get_msg_cb, NULL, helper);
920 g_object_unref (G_OBJECT(header));
925 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
927 ModestMainWindow *main_window)
930 GetMsgAsyncHelper *helper;
933 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
935 /* when there's no header, clear the msgview */
937 GtkWidget *msg_preview;
939 /* Clear msg preview if exists */
940 msg_preview = modest_main_window_get_child_widget(main_window,
941 MODEST_WIDGET_TYPE_MSG_PREVIEW);
944 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
948 /* Update Main window title */
949 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
950 const gchar *subject = tny_header_get_subject (header);
951 if (subject && strcmp (subject, ""))
952 gtk_window_set_title (GTK_WINDOW (main_window), subject);
954 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
958 list = tny_simple_list_new ();
959 tny_list_prepend (list, G_OBJECT (header));
961 /* Fill helper data */
962 helper = g_slice_new0 (GetMsgAsyncHelper);
963 helper->window = MODEST_WINDOW (main_window);
964 helper->iter = tny_list_create_iterator (list);
965 helper->func = read_msg_func;
967 folder = tny_header_get_folder (TNY_HEADER(header));
969 tny_folder_get_msg_async (TNY_FOLDER(folder),
974 g_object_unref (G_OBJECT (folder));
980 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
981 ModestMainWindow *main_window)
983 ModestWindow *win = NULL;
984 TnyFolder *folder = NULL;
986 ModestWindowMgr *mgr;
988 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
993 folder = tny_header_get_folder (header);
995 g_printerr ("modest: cannot get folder for header\n");
999 /* FIXME: make async?; check error */
1000 msg = tny_folder_get_msg (folder, header, NULL);
1002 g_printerr ("modest: cannot get msg for header\n");
1006 /* Look if we already have a message view for that header */
1007 mgr = modest_runtime_get_window_mgr ();
1008 win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
1010 /* If not, create a new window */
1014 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
1016 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1018 win = modest_msg_view_window_new (msg, account);
1019 modest_window_mgr_register_window (mgr, win);
1021 gtk_window_set_transient_for (GTK_WINDOW (win),
1022 GTK_WINDOW (main_window));
1025 gtk_widget_show_all (GTK_WIDGET(win));
1027 g_object_unref (G_OBJECT (msg));
1030 g_object_unref (G_OBJECT (folder));
1034 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1035 TnyFolderStore *folder_store,
1037 ModestMainWindow *main_window)
1040 GtkWidget *header_view;
1042 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1044 header_view = modest_main_window_get_child_widget(main_window,
1045 MODEST_WIDGET_TYPE_HEADER_VIEW);
1049 conf = modest_runtime_get_conf ();
1051 if (TNY_IS_FOLDER (folder_store)) {
1053 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1056 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1057 TNY_FOLDER (folder_store));
1058 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1061 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
1062 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1064 } else if (TNY_IS_ACCOUNT (folder_store)) {
1066 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1071 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1078 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1080 if (g_main_depth > 0)
1081 gdk_threads_enter ();
1082 online = tny_device_is_online (modest_runtime_get_device());
1085 /* already online -- the item is simply not there... */
1086 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1088 GTK_MESSAGE_WARNING,
1090 _("The %s you selected cannot be found"),
1092 gtk_dialog_run (GTK_DIALOG(dialog));
1094 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1098 GTK_RESPONSE_REJECT,
1100 GTK_RESPONSE_ACCEPT,
1102 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1103 "Do you want to get online?"), item);
1104 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1105 gtk_label_new (txt), FALSE, FALSE, 0);
1106 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1109 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1110 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1111 // modest_platform_connect_and_wait ();;
1114 gtk_widget_destroy (dialog);
1115 if (g_main_depth > 0)
1116 gdk_threads_leave ();
1120 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1123 g_message ("%s %s", __FUNCTION__, link);
1128 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1131 modest_platform_activate_uri (link);
1135 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1138 modest_platform_show_uri_popup (link);
1142 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1145 g_message (__FUNCTION__);
1150 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1151 const gchar *address,
1154 g_message ("%s %s", __FUNCTION__, address);
1158 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1160 TnyTransportAccount *transport_account;
1161 ModestMailOperation *mail_operation;
1163 gchar *account_name, *from;
1164 ModestAccountMgr *account_mgr;
1166 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1168 data = modest_msg_edit_window_get_msg_data (edit_window);
1170 account_mgr = modest_runtime_get_account_mgr();
1171 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1173 account_name = modest_account_mgr_get_default_account (account_mgr);
1174 if (!account_name) {
1175 g_printerr ("modest: no account found\n");
1176 modest_msg_edit_window_free_msg_data (edit_window, data);
1180 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1181 (modest_runtime_get_account_store(),
1183 TNY_ACCOUNT_TYPE_TRANSPORT));
1184 if (!transport_account) {
1185 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1186 g_free (account_name);
1187 modest_msg_edit_window_free_msg_data (edit_window, data);
1190 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1192 /* Create the mail operation */
1193 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1194 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1196 modest_mail_operation_save_to_drafts (mail_operation,
1206 data->priority_flags);
1209 g_free (account_name);
1210 g_object_unref (G_OBJECT (transport_account));
1211 g_object_unref (G_OBJECT (mail_operation));
1213 modest_msg_edit_window_free_msg_data (edit_window, data);
1215 /* Save settings and close the window */
1216 gtk_widget_destroy (GTK_WIDGET (edit_window));
1219 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1221 TnyTransportAccount *transport_account;
1222 ModestMailOperation *mail_operation;
1224 gchar *account_name, *from;
1225 ModestAccountMgr *account_mgr;
1227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1229 data = modest_msg_edit_window_get_msg_data (edit_window);
1231 /* FIXME: Code added just for testing. The final version will
1232 use the send queue provided by tinymail and some
1234 account_mgr = modest_runtime_get_account_mgr();
1235 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1237 account_name = modest_account_mgr_get_default_account (account_mgr);
1238 if (!account_name) {
1239 g_printerr ("modest: no account found\n");
1240 modest_msg_edit_window_free_msg_data (edit_window, data);
1244 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1245 (modest_runtime_get_account_store(),
1247 if (!transport_account) {
1248 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1249 g_free (account_name);
1250 modest_msg_edit_window_free_msg_data (edit_window, data);
1253 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1255 /* Create the mail operation */
1256 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND);
1257 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1259 modest_mail_operation_send_new_mail (mail_operation,
1269 data->priority_flags);
1272 g_free (account_name);
1273 g_object_unref (G_OBJECT (transport_account));
1274 g_object_unref (G_OBJECT (mail_operation));
1276 modest_msg_edit_window_free_msg_data (edit_window, data);
1278 /* Save settings and close the window */
1279 gtk_widget_destroy (GTK_WIDGET (edit_window));
1283 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1284 ModestMsgEditWindow *window)
1286 ModestMsgEditFormatState *format_state = NULL;
1288 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1289 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1291 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1294 format_state = modest_msg_edit_window_get_format_state (window);
1295 g_return_if_fail (format_state != NULL);
1297 format_state->bold = gtk_toggle_action_get_active (action);
1298 modest_msg_edit_window_set_format_state (window, format_state);
1299 g_free (format_state);
1304 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1305 ModestMsgEditWindow *window)
1307 ModestMsgEditFormatState *format_state = NULL;
1309 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1310 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1312 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1315 format_state = modest_msg_edit_window_get_format_state (window);
1316 g_return_if_fail (format_state != NULL);
1318 format_state->italics = gtk_toggle_action_get_active (action);
1319 modest_msg_edit_window_set_format_state (window, format_state);
1320 g_free (format_state);
1325 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1326 ModestMsgEditWindow *window)
1328 ModestMsgEditFormatState *format_state = NULL;
1330 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1331 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1333 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1336 format_state = modest_msg_edit_window_get_format_state (window);
1337 g_return_if_fail (format_state != NULL);
1339 format_state->bullet = gtk_toggle_action_get_active (action);
1340 modest_msg_edit_window_set_format_state (window, format_state);
1341 g_free (format_state);
1346 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1347 GtkRadioAction *selected,
1348 ModestMsgEditWindow *window)
1350 ModestMsgEditFormatState *format_state = NULL;
1351 GtkJustification value;
1353 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1355 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1358 value = gtk_radio_action_get_current_value (selected);
1360 format_state = modest_msg_edit_window_get_format_state (window);
1361 g_return_if_fail (format_state != NULL);
1363 format_state->justification = value;
1364 modest_msg_edit_window_set_format_state (window, format_state);
1365 g_free (format_state);
1369 modest_ui_actions_on_select_editor_color (GtkAction *action,
1370 ModestMsgEditWindow *window)
1372 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1373 g_return_if_fail (GTK_IS_ACTION (action));
1375 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1378 modest_msg_edit_window_select_color (window);
1382 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1383 ModestMsgEditWindow *window)
1385 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1386 g_return_if_fail (GTK_IS_ACTION (action));
1388 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1391 modest_msg_edit_window_select_background_color (window);
1395 modest_ui_actions_on_insert_image (GtkAction *action,
1396 ModestMsgEditWindow *window)
1398 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1399 g_return_if_fail (GTK_IS_ACTION (action));
1401 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1404 modest_msg_edit_window_insert_image (window);
1408 * Shows a dialog with an entry that asks for some text. The returned
1409 * value must be freed by the caller. The dialog window title will be
1413 ask_for_folder_name (GtkWindow *parent_window,
1416 GtkWidget *dialog, *entry;
1417 gchar *folder_name = NULL;
1419 /* Ask for folder name */
1420 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1424 GTK_RESPONSE_REJECT,
1426 GTK_RESPONSE_ACCEPT,
1428 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1429 gtk_label_new(title),
1432 entry = gtk_entry_new_with_max_length (40);
1433 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1437 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1439 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1440 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1442 gtk_widget_destroy (dialog);
1448 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1450 TnyFolderStore *parent_folder;
1451 GtkWidget *folder_view;
1453 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1455 folder_view = modest_main_window_get_child_widget (main_window,
1456 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1460 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1462 if (parent_folder) {
1463 gboolean finished = FALSE;
1465 gchar *folder_name = NULL, *suggested_name = NULL;
1467 /* Run the new folder dialog */
1469 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1474 if (result == GTK_RESPONSE_REJECT) {
1477 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1478 TnyFolder *new_folder = NULL;
1480 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1483 new_folder = modest_mail_operation_create_folder (mail_op,
1485 (const gchar *) folder_name);
1487 g_object_unref (new_folder);
1491 /* /\* TODO: check error and follow proper actions *\/ */
1492 /* /\* suggested_name = X; *\/ */
1493 /* /\* Show error to the user *\/ */
1494 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1495 /* MODEST_INFORMATION_CREATE_FOLDER); */
1497 g_object_unref (mail_op);
1499 g_free (folder_name);
1503 g_object_unref (parent_folder);
1508 modest_ui_actions_on_rename_folder (GtkAction *action,
1509 ModestMainWindow *main_window)
1511 TnyFolderStore *folder;
1512 GtkWidget *folder_view;
1514 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1516 folder_view = modest_main_window_get_child_widget (main_window,
1517 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1521 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1523 if (folder && TNY_IS_FOLDER (folder)) {
1525 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1526 _("Please enter a new name for the folder"));
1528 if (folder_name != NULL && strlen (folder_name) > 0) {
1529 ModestMailOperation *mail_op;
1531 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
1532 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1535 modest_mail_operation_rename_folder (mail_op,
1536 TNY_FOLDER (folder),
1537 (const gchar *) folder_name);
1539 g_object_unref (mail_op);
1540 g_free (folder_name);
1542 g_object_unref (folder);
1547 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1549 TnyFolderStore *folder;
1550 GtkWidget *folder_view;
1554 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1556 folder_view = modest_main_window_get_child_widget (main_window,
1557 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1561 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1564 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1565 tny_folder_get_name (TNY_FOLDER (folder)));
1566 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1567 (const gchar *) message);
1570 if (response == GTK_RESPONSE_OK) {
1571 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE);
1573 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1575 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1577 /* Show error if happened */
1578 if (modest_mail_operation_get_error (mail_op))
1579 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1580 MODEST_INFORMATION_DELETE_FOLDER);
1582 g_object_unref (G_OBJECT (mail_op));
1585 g_object_unref (G_OBJECT (folder));
1589 modest_ui_actions_on_delete_folder (GtkAction *action,
1590 ModestMainWindow *main_window)
1592 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1594 delete_folder (main_window, FALSE);
1598 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1600 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1602 delete_folder (main_window, TRUE);
1606 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1607 const gchar* account_name,
1611 ModestMainWindow *main_window)
1614 GtkWidget *dialog, *entry, *remember_pass_check;
1616 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1620 GTK_RESPONSE_REJECT,
1622 GTK_RESPONSE_ACCEPT,
1624 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1626 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1627 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1631 entry = gtk_entry_new_with_max_length (40);
1632 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1633 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1635 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1638 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1639 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1642 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1644 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1645 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1652 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1657 gtk_widget_destroy (dialog);
1661 modest_ui_actions_on_cut (GtkAction *action,
1662 ModestWindow *window)
1664 GtkWidget *focused_widget;
1666 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1667 if (GTK_IS_EDITABLE (focused_widget)) {
1668 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1669 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1670 GtkTextBuffer *buffer;
1671 GtkClipboard *clipboard;
1673 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1674 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1675 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1680 modest_ui_actions_on_copy (GtkAction *action,
1681 ModestWindow *window)
1683 GtkClipboard *clipboard;
1684 GtkWidget *focused_widget;
1686 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1687 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1688 if (GTK_IS_LABEL (focused_widget)) {
1689 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1690 } else if (GTK_IS_EDITABLE (focused_widget)) {
1691 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1692 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1693 GtkTextBuffer *buffer;
1695 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1696 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1701 modest_ui_actions_on_undo (GtkAction *action,
1702 ModestWindow *window)
1704 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1705 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1707 g_return_if_reached ();
1712 modest_ui_actions_on_paste (GtkAction *action,
1713 ModestWindow *window)
1715 GtkWidget *focused_widget;
1717 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1718 if (GTK_IS_EDITABLE (focused_widget)) {
1719 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1720 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1721 GtkTextBuffer *buffer;
1722 GtkClipboard *clipboard;
1724 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1725 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1726 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1731 modest_ui_actions_on_select_all (GtkAction *action,
1732 ModestWindow *window)
1734 GtkWidget *focused_widget;
1736 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1737 if (GTK_IS_LABEL (focused_widget)) {
1738 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1739 } else if (GTK_IS_EDITABLE (focused_widget)) {
1740 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1741 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1742 GtkTextBuffer *buffer;
1743 GtkTextIter start, end;
1745 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1746 gtk_text_buffer_get_start_iter (buffer, &start);
1747 gtk_text_buffer_get_end_iter (buffer, &end);
1748 gtk_text_buffer_select_range (buffer, &start, &end);
1753 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1754 GtkRadioAction *selected,
1755 ModestWindow *window)
1759 value = gtk_radio_action_get_current_value (selected);
1760 if (MODEST_IS_WINDOW (window)) {
1761 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1765 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1766 GtkRadioAction *selected,
1767 ModestWindow *window)
1769 TnyHeaderFlags flags;
1770 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1772 flags = gtk_radio_action_get_current_value (selected);
1773 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1776 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1777 GtkRadioAction *selected,
1778 ModestWindow *window)
1782 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1784 file_format = gtk_radio_action_get_current_value (selected);
1785 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1790 modest_ui_actions_on_zoom_plus (GtkAction *action,
1791 ModestWindow *window)
1793 g_return_if_fail (MODEST_IS_WINDOW (window));
1795 modest_window_zoom_plus (MODEST_WINDOW (window));
1799 modest_ui_actions_on_zoom_minus (GtkAction *action,
1800 ModestWindow *window)
1802 g_return_if_fail (MODEST_IS_WINDOW (window));
1804 modest_window_zoom_minus (MODEST_WINDOW (window));
1808 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
1809 ModestWindow *window)
1811 ModestWindowMgr *mgr;
1812 gboolean fullscreen, active;
1813 g_return_if_fail (MODEST_IS_WINDOW (window));
1815 mgr = modest_runtime_get_window_mgr ();
1817 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
1818 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1820 if (active != fullscreen) {
1821 modest_window_mgr_set_fullscreen_mode (mgr, active);
1822 gtk_window_present (GTK_WINDOW (window));
1827 modest_ui_actions_on_change_fullscreen (GtkAction *action,
1828 ModestWindow *window)
1830 ModestWindowMgr *mgr;
1831 gboolean fullscreen;
1833 g_return_if_fail (MODEST_IS_WINDOW (window));
1835 mgr = modest_runtime_get_window_mgr ();
1836 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1837 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
1839 gtk_window_present (GTK_WINDOW (window));
1843 * Show the header details in a ModestDetailsDialog widget
1846 show_header_details (TnyHeader *header,
1852 dialog = modest_details_dialog_new_with_header (window, header);
1855 gtk_widget_show_all (dialog);
1856 gtk_dialog_run (GTK_DIALOG (dialog));
1858 gtk_widget_destroy (dialog);
1862 * Show the folder details in a ModestDetailsDialog widget
1865 show_folder_details (TnyFolder *folder,
1871 dialog = modest_details_dialog_new_with_folder (window, folder);
1874 gtk_widget_show_all (dialog);
1875 gtk_dialog_run (GTK_DIALOG (dialog));
1877 gtk_widget_destroy (dialog);
1882 modest_ui_actions_on_details (GtkAction *action,
1885 TnyList * headers_list;
1889 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1892 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1896 headers_list = get_selected_headers (win);
1900 iter = tny_list_create_iterator (headers_list);
1902 header = TNY_HEADER (tny_iterator_get_current (iter));
1903 show_header_details (header, GTK_WINDOW (win));
1904 g_object_unref (header);
1906 g_object_unref (iter);
1908 } else if (MODEST_IS_MAIN_WINDOW (win)) {
1909 GtkWidget *folder_view, *header_view;
1911 /* Check which widget has the focus */
1912 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1913 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1914 if (gtk_widget_is_focus (folder_view)) {
1917 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1919 /* Show only when it's a folder */
1920 if (!folder || !TNY_IS_FOLDER (folder))
1923 show_folder_details (folder, GTK_WINDOW (win));
1926 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1927 MODEST_WIDGET_TYPE_HEADER_VIEW);
1928 if (!gtk_widget_is_focus (header_view))
1931 headers_list = get_selected_headers (win);
1935 iter = tny_list_create_iterator (headers_list);
1936 while (!tny_iterator_is_done (iter)) {
1938 header = TNY_HEADER (tny_iterator_get_current (iter));
1939 show_header_details (header, GTK_WINDOW (win));
1940 g_object_unref (header);
1942 tny_iterator_next (iter);
1944 g_object_unref (iter);
1950 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
1951 ModestMsgEditWindow *window)
1953 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1955 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
1959 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
1960 ModestMsgEditWindow *window)
1962 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1964 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
1968 modest_ui_actions_toggle_folders_view (GtkAction *action,
1969 ModestMainWindow *main_window)
1973 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1975 conf = modest_runtime_get_conf ();
1977 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
1978 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
1980 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
1984 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
1985 ModestWindow *window)
1987 gboolean active, fullscreen = FALSE;
1988 ModestWindowMgr *mgr;
1990 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
1992 /* Check if we want to toggle the toolbar vuew in fullscreen
1994 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
1995 "ViewShowToolbarFullScreen")) {
1999 /* Toggle toolbar */
2000 mgr = modest_runtime_get_window_mgr ();
2001 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2005 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2006 ModestMsgEditWindow *window)
2008 modest_msg_edit_window_select_font (window);
2012 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2013 const gchar *display_name,
2016 /* Do not change the application name if the widget has not
2017 the focus. This callback could be called even if the folder
2018 view has not the focus, because the handled signal could be
2019 emitted when the folder view is redrawn */
2020 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2022 gtk_window_set_title (window, display_name);
2024 gtk_window_set_title (window, " ");
2029 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2031 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2032 modest_msg_edit_window_select_contacts (window);
2037 create_move_to_dialog (ModestWindow *win,
2038 GtkWidget *folder_view,
2039 GtkWidget **tree_view)
2041 GtkWidget *dialog, *scroll;
2043 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2045 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2047 GTK_RESPONSE_ACCEPT,
2049 GTK_RESPONSE_REJECT,
2052 /* Create scrolled window */
2053 scroll = gtk_scrolled_window_new (NULL, NULL);
2054 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2055 GTK_POLICY_AUTOMATIC,
2056 GTK_POLICY_AUTOMATIC);
2058 /* Create folder view */
2059 *tree_view = modest_folder_view_new (NULL);
2060 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2061 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2062 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2064 /* Add scroll to dialog */
2065 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2066 scroll, FALSE, FALSE, 0);
2068 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2074 * Returns TRUE if at least one of the headers of the list belongs to
2075 * a message that has been fully retrieved.
2078 has_retrieved_msgs (TnyList *list)
2081 gboolean found = FALSE;
2083 iter = tny_list_create_iterator (list);
2084 while (tny_iterator_is_done (iter) && !found) {
2086 TnyHeaderFlags flags;
2088 header = TNY_HEADER (tny_iterator_get_current (iter));
2089 flags = tny_header_get_flags (header);
2090 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2094 tny_iterator_next (iter);
2096 g_object_unref (iter);
2102 * Shows a confirmation dialog to the user when we're moving messages
2103 * from a remote server to the local storage. Returns the dialog
2104 * response. If it's other kind of movement the it always returns
2108 msgs_move_to_confirmation (GtkWindow *win,
2109 TnyFolder *dest_folder,
2112 gint response = GTK_RESPONSE_OK;
2114 /* If the destination is a local folder */
2115 if (modest_tny_folder_is_local_folder (dest_folder)) {
2116 TnyFolder *src_folder;
2120 /* Get source folder */
2121 iter = tny_list_create_iterator (headers);
2122 header = TNY_HEADER (tny_iterator_get_current (iter));
2123 src_folder = tny_header_get_folder (header);
2124 g_object_unref (header);
2125 g_object_unref (iter);
2127 /* If the source is a remote folder */
2128 if (!modest_tny_folder_is_local_folder (src_folder)) {
2129 const gchar *message;
2131 if (tny_list_get_length (headers) == 1)
2132 if (has_retrieved_msgs (headers))
2133 message = _("mcen_nc_move_retrieve");
2135 message = _("mcen_nc_move_header");
2137 if (has_retrieved_msgs (headers))
2138 message = _("mcen_nc_move_retrieves");
2140 message = _("mcen_nc_move_headers");
2142 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2143 (const gchar *) message);
2150 * UI handler for the "Move to" action when invoked from the
2154 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2155 ModestMainWindow *win)
2157 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2159 TnyFolderStore *folder_store;
2160 ModestMailOperation *mail_op = NULL;
2162 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2164 /* Get the folder view */
2165 folder_view = modest_main_window_get_child_widget (win,
2166 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2168 /* Create and run the dialog */
2169 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2170 result = gtk_dialog_run (GTK_DIALOG(dialog));
2172 /* We do this to save an indentation level ;-) */
2173 if (result != GTK_RESPONSE_ACCEPT)
2176 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2178 if (TNY_IS_ACCOUNT (folder_store))
2181 /* Get folder or messages to transfer */
2182 if (gtk_widget_is_focus (folder_view)) {
2183 TnyFolderStore *src_folder;
2184 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2186 if (TNY_IS_FOLDER (src_folder)) {
2187 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2188 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2191 modest_mail_operation_xfer_folder (mail_op,
2192 TNY_FOLDER (src_folder),
2195 g_object_unref (G_OBJECT (mail_op));
2199 g_object_unref (G_OBJECT (src_folder));
2201 GtkWidget *header_view;
2202 header_view = modest_main_window_get_child_widget (win,
2203 MODEST_WIDGET_TYPE_HEADER_VIEW);
2204 if (gtk_widget_is_focus (header_view)) {
2208 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2210 /* Ask for user confirmation */
2211 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2212 TNY_FOLDER (folder_store),
2215 /* Transfer messages */
2216 if (response == GTK_RESPONSE_OK) {
2217 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2218 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2221 modest_mail_operation_xfer_msgs (mail_op,
2223 TNY_FOLDER (folder_store),
2225 g_object_unref (G_OBJECT (mail_op));
2229 g_object_unref (folder_store);
2232 gtk_widget_destroy (dialog);
2237 * UI handler for the "Move to" action when invoked from the
2238 * ModestMsgViewWindow
2241 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2242 ModestMsgViewWindow *win)
2244 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2246 ModestMainWindow *main_window;
2251 /* Get the folder view */
2252 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2253 folder_view = modest_main_window_get_child_widget (main_window,
2254 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2256 /* Create and run the dialog */
2257 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2258 result = gtk_dialog_run (GTK_DIALOG(dialog));
2260 if (result == GTK_RESPONSE_ACCEPT) {
2261 TnyFolderStore *folder_store;
2264 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2266 /* Create header list */
2267 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2268 header = tny_msg_get_header (msg);
2269 headers = tny_simple_list_new ();
2270 tny_list_prepend (headers, G_OBJECT (header));
2271 g_object_unref (header);
2272 g_object_unref (msg);
2274 /* Ask user for confirmation. MSG-NOT404 */
2275 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2276 TNY_FOLDER (folder_store),
2279 /* Transfer current msg */
2280 if (response == GTK_RESPONSE_OK) {
2281 ModestMailOperation *mail_op;
2283 /* Create mail op */
2284 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
2285 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2288 /* Transfer messages */
2289 modest_mail_operation_xfer_msgs (mail_op,
2291 TNY_FOLDER (folder_store),
2293 g_object_unref (G_OBJECT (mail_op));
2295 g_object_unref (headers);
2297 g_object_unref (folder_store);
2299 gtk_widget_destroy (dialog);
2303 modest_ui_actions_on_move_to (GtkAction *action,
2306 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2307 MODEST_IS_MSG_VIEW_WINDOW (win));
2309 if (MODEST_IS_MAIN_WINDOW (win))
2310 modest_ui_actions_on_main_window_move_to (action,
2311 MODEST_MAIN_WINDOW (win));
2313 modest_ui_actions_on_msg_view_window_move_to (action,
2314 MODEST_MSG_VIEW_WINDOW (win));