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 #ifdef MODEST_PLATFORM_MAEMO
48 #include "maemo/modest-osso-state-saving.h"
49 #endif /* MODEST_PLATFORM_MAEMO */
51 #include "widgets/modest-ui-constants.h"
52 #include <widgets/modest-main-window.h>
53 #include <widgets/modest-msg-view-window.h>
54 #include <widgets/modest-account-view-window.h>
55 #include <widgets/modest-details-dialog.h>
56 #include <widgets/modest-attachments-view.h>
57 #include "widgets/modest-global-settings-dialog.h"
58 #include "modest-connection-specific-smtp-window.h"
59 #include "modest-account-mgr-helpers.h"
60 #include "modest-mail-operation.h"
61 #include "modest-text-utils.h"
63 #ifdef MODEST_HAVE_EASYSETUP
64 #include "easysetup/modest-easysetup-wizard.h"
65 #endif /* MODEST_HAVE_EASYSETUP */
67 #include <modest-widget-memory.h>
68 #include <tny-error.h>
69 #include <tny-simple-list.h>
70 #include <tny-msg-view.h>
71 #include <tny-device.h>
73 typedef struct _GetMsgAsyncHelper {
75 ModestMailOperation *mail_op;
82 typedef enum _ReplyForwardAction {
88 typedef struct _ReplyForwardHelper {
89 guint reply_forward_type;
90 ReplyForwardAction action;
94 typedef struct _HeaderActivatedHelper {
96 GtkTreeRowReference *row_reference;
99 } HeaderActivatedHelper;
102 * The do_headers_action uses this kind of functions to perform some
103 * action to each member of a list of headers
105 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
108 do_headers_action (ModestWindow *win,
113 static void open_msg_func (const GObject *obj, TnyMsg *msg, gpointer user_data);
115 static void reply_forward_func (const GObject *obj, TnyMsg *msg, gpointer user_data);
117 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
119 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
122 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
125 const gchar *authors[] = {
126 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
129 about = gtk_about_dialog_new ();
130 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
131 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
132 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
133 _("Copyright (c) 2006, Nokia Corporation\n"
134 "All rights reserved."));
135 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
136 _("a modest e-mail client\n\n"
137 "design and implementation: Dirk-Jan C. Binnema\n"
138 "contributions from the fine people at KC and Ig\n"
139 "uses the tinymail email framework written by Philip van Hoof"));
140 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
141 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
143 gtk_dialog_run (GTK_DIALOG (about));
144 gtk_widget_destroy(about);
149 get_selected_headers (ModestWindow *win)
151 if (MODEST_IS_MAIN_WINDOW(win)) {
152 GtkWidget *header_view;
154 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
155 MODEST_WIDGET_TYPE_HEADER_VIEW);
156 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
158 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
159 /* for MsgViewWindows, we simply return a list with one element */
161 TnyList *list = NULL;
163 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
164 if (header != NULL) {
165 list = tny_simple_list_new ();
166 tny_list_prepend (list, G_OBJECT(header));
167 g_object_unref (G_OBJECT(header));
177 headers_action_mark_as_read (TnyHeader *header,
181 TnyHeaderFlags flags;
183 g_return_if_fail (TNY_IS_HEADER(header));
185 flags = tny_header_get_flags (header);
186 if (flags & TNY_HEADER_FLAG_SEEN) return;
187 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
191 headers_action_mark_as_unread (TnyHeader *header,
195 TnyHeaderFlags flags;
197 g_return_if_fail (TNY_IS_HEADER(header));
199 flags = tny_header_get_flags (header);
200 if (flags & TNY_HEADER_FLAG_SEEN) {
201 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
207 headers_action_delete (TnyHeader *header,
211 ModestMailOperation *mail_op = NULL;
213 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(win));
214 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
217 /* Always delete. TODO: Move to trash still not supported */
218 modest_mail_operation_remove_msg (mail_op, header, FALSE);
219 g_object_unref (G_OBJECT (mail_op));
223 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
225 TnyList *header_list = NULL;
226 TnyIterator *iter = NULL;
227 TnyHeader *header = NULL;
228 gchar *message = NULL;
232 g_return_if_fail (MODEST_IS_WINDOW(win));
234 header_list = get_selected_headers (win);
235 if (!header_list) return;
238 if (tny_list_get_length(header_list) > 1)
239 message = g_strdup(_("emev_nc_delete_messages"));
241 iter = tny_list_create_iterator (header_list);
242 header = TNY_HEADER (tny_iterator_get_current (iter));
243 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
244 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
247 /* Confirmation dialog */
248 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
252 if (response == GTK_RESPONSE_OK) {
253 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
255 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
259 /* Remove each header */
260 do_headers_action (win, headers_action_delete, NULL);
262 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
263 gtk_widget_destroy (GTK_WIDGET(win));
270 g_object_unref (header_list);
271 g_object_unref (iter);
276 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
278 #ifdef MODEST_PLATFORM_MAEMO
279 modest_osso_save_state();
280 #endif /* MODEST_PLATFORM_MAEMO */
286 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
288 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
289 gtk_widget_destroy (GTK_WIDGET (win));
290 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
292 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
293 } else if (MODEST_IS_WINDOW (win)) {
294 gtk_widget_destroy (GTK_WIDGET (win));
296 g_return_if_reached ();
301 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
303 GtkClipboard *clipboard = NULL;
304 gchar *selection = NULL;
306 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
307 selection = gtk_clipboard_wait_for_text (clipboard);
309 modest_address_book_add_address (selection);
314 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
316 /* This is currently only implemented for Maemo,
317 * because it requires a providers preset file which is not publically available.
319 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
320 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
321 TRUE /* enabled accounts only */);
322 gboolean accounts_exist = account_names != NULL;
323 g_slist_free (account_names);
325 if (!accounts_exist) {
326 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
327 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
328 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
329 gtk_dialog_run (GTK_DIALOG (wizard));
330 gtk_widget_destroy (GTK_WIDGET (wizard));
332 /* Show the list of accounts: */
333 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
334 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
335 gtk_dialog_run (account_win);
336 gtk_widget_destroy (GTK_WIDGET(account_win));
339 GtkWidget *dialog, *label;
341 /* Create the widgets */
343 dialog = gtk_dialog_new_with_buttons ("Message",
345 GTK_DIALOG_DESTROY_WITH_PARENT,
349 label = gtk_label_new ("Hello World!");
351 /* Ensure that the dialog box is destroyed when the user responds. */
353 g_signal_connect_swapped (dialog, "response",
354 G_CALLBACK (gtk_widget_destroy),
357 /* Add the label, and show everything we've added to the dialog. */
359 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
361 gtk_widget_show_all (dialog);
362 #endif /* MODEST_PLATFORM_MAEMO */
366 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
368 ModestWindow *main_window = MODEST_WINDOW (user_data);
370 /* Save any changes. */
371 modest_connection_specific_smtp_window_save_server_accounts (
372 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
373 modest_window_get_active_account (main_window));
374 gtk_widget_destroy (GTK_WIDGET (window));
378 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
380 /* This is currently only implemented for Maemo,
381 * because it requires an API (libconic) to detect different connection
384 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
386 /* Create the window if necessary: */
387 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
388 modest_connection_specific_smtp_window_fill_with_connections (
389 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
390 modest_runtime_get_account_mgr(),
391 modest_window_get_active_account (win));
393 /* Show the window: */
394 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
395 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
396 gtk_widget_show (specific_window);
398 /* Save changes when the window is hidden: */
399 g_signal_connect (specific_window, "hide",
400 G_CALLBACK (on_smtp_servers_window_hide), win);
401 #endif /* MODEST_PLATFORM_MAEMO */
405 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
407 ModestWindow *msg_win;
409 TnyFolder *folder = NULL;
410 gchar *account_name = NULL;
411 gchar *from_str = NULL;
412 /* GError *err = NULL; */
413 TnyAccount *account = NULL;
414 ModestWindowMgr *mgr;
415 gchar *signature = NULL;
417 account_name = g_strdup(modest_window_get_active_account (win));
419 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
421 g_printerr ("modest: no account found\n");
425 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
427 TNY_ACCOUNT_TYPE_STORE);
429 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
433 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
435 g_printerr ("modest: failed get from string for '%s'\n", account_name);
439 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
440 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
441 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
442 MODEST_ACCOUNT_SIGNATURE, FALSE);
444 signature = g_strdup ("");
447 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
449 g_printerr ("modest: failed to create new msg\n");
453 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
455 g_printerr ("modest: failed to find Drafts folder\n");
459 /* tny_folder_add_msg (folder, msg, &err); */
461 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
463 /* g_error_free (err); */
467 /* Create and register edit window */
468 msg_win = modest_msg_edit_window_new (msg, account_name);
469 mgr = modest_runtime_get_window_mgr ();
470 modest_window_mgr_register_window (mgr, msg_win);
473 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
475 gtk_widget_show_all (GTK_WIDGET (msg_win));
478 g_free (account_name);
482 g_object_unref (G_OBJECT(account));
484 g_object_unref (G_OBJECT(msg));
486 g_object_unref (G_OBJECT(folder));
490 headers_action_open (TnyHeader *header,
494 modest_ui_actions_on_header_activated (MODEST_HEADER_VIEW (user_data),
496 MODEST_MAIN_WINDOW (win));
500 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
502 GtkWidget *header_view;
504 /* Get header view */
505 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
506 MODEST_WIDGET_TYPE_HEADER_VIEW);
508 /* Open each message */
509 do_headers_action (win, headers_action_open, header_view);
514 open_msg_func (const GObject *obj, TnyMsg *msg, gpointer user_data)
516 ModestWindowMgr *mgr = NULL;
517 ModestWindow *parent_win = NULL;
518 ModestWindow *win = NULL;
519 HeaderActivatedHelper *helper = NULL;
520 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
521 gchar *account = NULL;
523 g_return_if_fail (MODEST_IS_WINDOW(obj));
524 g_return_if_fail (user_data != NULL);
526 /* TODO: Show an error? (review the specs) */
530 parent_win = MODEST_WINDOW(obj);
531 helper = (HeaderActivatedHelper *) user_data;
533 /* Mark header as read */
534 headers_action_mark_as_read (helper->header, MODEST_WINDOW(parent_win), NULL);
537 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(parent_win)));
539 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
541 /* Gets foldert type (OUTBOX headers will be opened in edit window */
542 if (modest_tny_folder_is_local_folder (helper->folder))
543 folder_type = modest_tny_folder_get_local_folder_type (helper->folder);
545 switch (folder_type) {
546 case TNY_FOLDER_TYPE_DRAFTS:
547 win = modest_msg_edit_window_new ((TnyMsg *) msg, account);
550 if (helper->model != NULL)
551 win = modest_msg_view_window_new_with_header_model ((TnyMsg *) msg, account, helper->model, helper->row_reference);
553 win = modest_msg_view_window_new ((TnyMsg *) msg, account);
556 /* Register and show new window */
558 mgr = modest_runtime_get_window_mgr ();
559 modest_window_mgr_register_window (mgr, win);
560 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
561 gtk_widget_show_all (GTK_WIDGET(win));
566 /* g_object_unref (G_OBJECT(msg)); */
567 g_object_unref (G_OBJECT(helper->folder));
568 g_object_unref (G_OBJECT(helper->header));
569 gtk_tree_row_reference_free (helper->row_reference);
570 g_slice_free (HeaderActivatedHelper, helper);
574 free_reply_forward_helper (gpointer data)
576 ReplyForwardHelper *helper;
578 helper = (ReplyForwardHelper *) data;
579 g_free (helper->account_name);
580 g_slice_free (ReplyForwardHelper, helper);
584 reply_forward_func (const GObject *obj, TnyMsg *msg, gpointer user_data)
587 ReplyForwardHelper *rf_helper;
588 ModestWindow *msg_win;
589 ModestEditType edit_type;
592 TnyFolder *folder = NULL;
593 TnyAccount *account = NULL;
594 ModestWindowMgr *mgr;
595 gchar *signature = NULL;
597 g_return_if_fail (user_data != NULL);
598 rf_helper = (ReplyForwardHelper *) user_data;
600 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
601 rf_helper->account_name);
602 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
603 rf_helper->account_name,
604 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
605 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
606 rf_helper->account_name,
607 MODEST_ACCOUNT_SIGNATURE, FALSE);
610 /* Create reply mail */
611 switch (rf_helper->action) {
614 modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature,
615 rf_helper->reply_forward_type,
616 MODEST_TNY_MSG_REPLY_MODE_SENDER);
618 case ACTION_REPLY_TO_ALL:
620 modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type,
621 MODEST_TNY_MSG_REPLY_MODE_ALL);
622 edit_type = MODEST_EDIT_TYPE_REPLY;
626 modest_tny_msg_create_forward_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type);
627 edit_type = MODEST_EDIT_TYPE_FORWARD;
630 g_return_if_reached ();
637 g_printerr ("modest: failed to create message\n");
641 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
642 rf_helper->account_name,
643 TNY_ACCOUNT_TYPE_STORE);
645 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
649 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
651 g_printerr ("modest: failed to find Drafts folder\n");
655 tny_folder_add_msg (folder, (TnyMsg *) msg, &err);
656 g_object_unref (msg);
658 g_printerr ("modest: error adding msg to Drafts folder: %s",
664 /* Create and register the windows */
665 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
666 mgr = modest_runtime_get_window_mgr ();
667 modest_window_mgr_register_window (mgr, msg_win);
669 /* Show edit window */
670 gtk_widget_show_all (GTK_WIDGET (msg_win));
674 g_object_unref (G_OBJECT (new_msg));
676 g_object_unref (G_OBJECT (folder));
678 g_object_unref (G_OBJECT (account));
682 * Common code for the reply and forward actions
685 reply_forward (ReplyForwardAction action, ModestWindow *win)
687 ModestMailOperation *mail_op = NULL;
688 TnyList *header_list = NULL;
689 ReplyForwardHelper *rf_helper = NULL;
690 guint reply_forward_type;
692 g_return_if_fail (MODEST_IS_WINDOW(win));
694 header_list = get_selected_headers (win);
698 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
699 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
701 /* We assume that we can only select messages of the
702 same folder and that we reply all of them from the
703 same account. In fact the interface currently only
704 allows single selection */
707 rf_helper = g_slice_new0 (ReplyForwardHelper);
708 rf_helper->reply_forward_type = reply_forward_type;
709 rf_helper->action = action;
710 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
711 if (!rf_helper->account_name)
712 rf_helper->account_name =
713 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
715 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
717 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
719 g_printerr ("modest: no message found\n");
722 reply_forward_func (G_OBJECT(win), g_object_ref (msg), rf_helper);
724 /* Retrieve messages */
725 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
726 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
727 modest_mail_operation_get_msgs_full (mail_op,
731 free_reply_forward_helper);
734 g_object_unref(mail_op);
739 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
741 g_return_if_fail (MODEST_IS_WINDOW(win));
743 reply_forward (ACTION_REPLY, win);
747 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
749 g_return_if_fail (MODEST_IS_WINDOW(win));
751 reply_forward (ACTION_FORWARD, win);
755 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
757 g_return_if_fail (MODEST_IS_WINDOW(win));
759 reply_forward (ACTION_REPLY_TO_ALL, win);
763 modest_ui_actions_on_next (GtkAction *action,
764 ModestWindow *window)
766 if (MODEST_IS_MAIN_WINDOW (window)) {
767 GtkWidget *header_view;
769 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
770 MODEST_WIDGET_TYPE_HEADER_VIEW);
774 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
775 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
776 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
778 g_return_if_reached ();
783 modest_ui_actions_on_prev (GtkAction *action,
784 ModestWindow *window)
786 g_return_if_fail (MODEST_IS_WINDOW(window));
788 if (MODEST_IS_MAIN_WINDOW (window)) {
789 GtkWidget *header_view;
790 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
791 MODEST_WIDGET_TYPE_HEADER_VIEW);
795 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
796 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
797 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
799 g_return_if_reached ();
804 modest_ui_actions_on_sort (GtkAction *action,
805 ModestWindow *window)
807 g_return_if_fail (MODEST_IS_WINDOW(window));
809 if (MODEST_IS_MAIN_WINDOW (window)) {
810 GtkWidget *header_view;
811 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
812 MODEST_WIDGET_TYPE_HEADER_VIEW);
816 /* Show sorting dialog */
817 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
821 /** Check that an appropriate connection is open.
823 gboolean check_for_connection (const gchar *account_name)
825 TnyDevice *device = modest_runtime_get_device ();
828 g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
830 TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
833 if (tny_device_is_online (device))
836 modest_platform_connect_and_wait (NULL);
838 /* TODO: Wait until a result. */
844 * This function performs the send & receive required actions. The
845 * window it's used to create the mail operation. Tipically it should
846 * be allways the main window, but we pass it as argument in order to
850 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
852 gchar *acc_name = NULL;
854 /* If no account name was provided get the current account, if
855 there is none either then pick the default one */
857 acc_name = g_strdup (modest_window_get_active_account(win));
859 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
861 g_printerr ("modest: cannot get default account\n");
865 acc_name = g_strdup (account_name);
868 /* Send & receive. Do not continue if no suitable connection
870 if (check_for_connection (acc_name)) {
871 /* As per the UI spec,
872 * for POP accounts, we should receive,
873 * for IMAP we should synchronize everything, including receiving,
874 * for SMTP we should send,
875 * first receiving, then sending:
877 /* Create the mail operation */
878 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
879 ModestMailOperation *mail_op;
880 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
881 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
882 modest_mail_operation_update_account (mail_op, acc_name);
883 g_object_unref (G_OBJECT (mail_op));
890 * Refreshes all accounts. This function will be used by automatic
894 modest_ui_actions_do_send_receive_all (ModestWindow *win)
896 GSList *account_names, *iter;
898 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
901 iter = account_names;
903 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
904 iter = g_slist_next (iter);
907 g_slist_foreach (account_names, (GFunc) g_free, NULL);
908 g_slist_free (account_names);
912 * Handler of the click on Send&Receive button in the main toolbar
915 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
917 /* Check that at least one account exists: */
918 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
919 TRUE /* enabled accounts only */);
920 gboolean accounts_exist = account_names != NULL;
921 g_slist_free (account_names);
923 /* If not, allow the user to create an account before trying to send/receive. */
925 modest_ui_actions_on_accounts (NULL, win);
927 /* Refresh the active account */
928 modest_ui_actions_do_send_receive (NULL, win);
933 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
936 GtkWidget *header_view;
938 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
940 header_view = modest_main_window_get_child_widget (main_window,
941 MODEST_WIDGET_TYPE_HEADER_VIEW);
945 conf = modest_runtime_get_conf ();
947 /* what is saved/restored is depending on the style; thus; we save with
948 * old style, then update the style, and restore for this new style
950 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
952 if (modest_header_view_get_style
953 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
954 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
955 MODEST_HEADER_VIEW_STYLE_TWOLINES);
957 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
958 MODEST_HEADER_VIEW_STYLE_DETAILS);
960 modest_widget_memory_restore (conf, G_OBJECT(header_view),
961 MODEST_CONF_HEADER_VIEW_KEY);
966 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
968 ModestMainWindow *main_window)
970 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
972 /* If no header has been selected then exit */
976 /* Update Main window title */
977 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
978 const gchar *subject = tny_header_get_subject (header);
979 if (subject && strcmp (subject, ""))
980 gtk_window_set_title (GTK_WINDOW (main_window), subject);
982 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
987 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
989 ModestMainWindow *main_window)
991 ModestMailOperation *mail_op = NULL;
992 HeaderActivatedHelper *helper = NULL;
993 ModestWindowMgr *mgr = NULL;
994 ModestWindow *win = NULL;
995 GtkTreeModel *model = NULL;
996 GtkTreeSelection *sel = NULL;
997 GList *sel_list = NULL;
999 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1004 /* Look if we already have a message view for that header */
1005 mgr = modest_runtime_get_window_mgr ();
1006 win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
1010 helper = g_slice_new0 (HeaderActivatedHelper);
1011 helper->folder = tny_header_get_folder (header);
1012 helper->header = g_object_ref(header);
1013 helper->model = NULL;
1015 /* Get headers tree model and selected row reference to build message view */
1016 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1017 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1018 if (sel_list != NULL) {
1021 helper->model = model;
1022 helper->row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
1024 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1025 g_list_free (sel_list);
1028 /* New mail operation */
1029 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(main_window));
1030 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1031 modest_mail_operation_get_msg (mail_op, header, open_msg_func, helper);
1034 g_object_unref (mail_op);
1038 set_active_account_from_tny_account (TnyAccount *account,
1039 ModestWindow *window)
1041 TnyAccount *modest_server_account;
1042 const gchar *server_acc_name;
1043 gchar *modest_acc_name;
1045 server_acc_name = tny_account_get_id (account);
1046 /* We need the TnyAccount provided by the
1047 account store because that is the one that
1048 knows the name of the Modest account */
1049 modest_server_account =
1050 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1052 modest_acc_name = (gchar *) g_object_get_data (G_OBJECT (modest_server_account), "modest_account");
1053 modest_window_set_active_account (window, modest_acc_name);
1054 g_object_unref (modest_server_account);
1058 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1059 TnyFolderStore *folder_store,
1061 ModestMainWindow *main_window)
1064 GtkWidget *header_view;
1065 TnyAccount *account;
1067 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1069 header_view = modest_main_window_get_child_widget(main_window,
1070 MODEST_WIDGET_TYPE_HEADER_VIEW);
1074 conf = modest_runtime_get_conf ();
1076 if (TNY_IS_ACCOUNT (folder_store)) {
1077 /* Update active account */
1078 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1079 /* Show account details */
1080 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1082 if (TNY_IS_FOLDER (folder_store) && selected) {
1083 /* Update the active account */
1084 account = tny_folder_get_account (TNY_FOLDER (folder_store));
1085 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1086 g_object_unref (account);
1088 /* Set folder on header view */
1089 modest_main_window_set_contents_style (main_window,
1090 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1091 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1092 TNY_FOLDER (folder_store));
1093 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1094 MODEST_CONF_HEADER_VIEW_KEY);
1096 /* Update the active account */
1097 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1098 /* Do not show folder */
1099 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1100 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1106 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1113 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1115 if (g_main_depth > 0)
1116 gdk_threads_enter ();
1117 online = tny_device_is_online (modest_runtime_get_device());
1120 /* already online -- the item is simply not there... */
1121 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1123 GTK_MESSAGE_WARNING,
1125 _("The %s you selected cannot be found"),
1127 gtk_dialog_run (GTK_DIALOG(dialog));
1129 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1133 GTK_RESPONSE_REJECT,
1135 GTK_RESPONSE_ACCEPT,
1137 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1138 "Do you want to get online?"), item);
1139 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1140 gtk_label_new (txt), FALSE, FALSE, 0);
1141 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1144 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1145 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1146 // modest_platform_connect_and_wait ();;
1149 gtk_widget_destroy (dialog);
1150 if (g_main_depth > 0)
1151 gdk_threads_leave ();
1155 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1158 /* g_message ("%s %s", __FUNCTION__, link); */
1163 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1166 modest_platform_activate_uri (link);
1170 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1173 modest_platform_show_uri_popup (link);
1177 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1180 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1184 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1185 const gchar *address,
1188 /* g_message ("%s %s", __FUNCTION__, address); */
1192 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1194 TnyTransportAccount *transport_account;
1195 ModestMailOperation *mail_operation;
1197 gchar *account_name, *from;
1198 ModestAccountMgr *account_mgr;
1200 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1202 data = modest_msg_edit_window_get_msg_data (edit_window);
1204 account_mgr = modest_runtime_get_account_mgr();
1205 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1207 account_name = modest_account_mgr_get_default_account (account_mgr);
1208 if (!account_name) {
1209 g_printerr ("modest: no account found\n");
1210 modest_msg_edit_window_free_msg_data (edit_window, data);
1214 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1215 (modest_runtime_get_account_store(),
1217 TNY_ACCOUNT_TYPE_TRANSPORT));
1218 if (!transport_account) {
1219 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1220 g_free (account_name);
1221 modest_msg_edit_window_free_msg_data (edit_window, data);
1224 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1226 /* Create the mail operation */
1227 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(edit_window));
1228 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1230 modest_mail_operation_save_to_drafts (mail_operation,
1240 data->priority_flags);
1243 g_free (account_name);
1244 g_object_unref (G_OBJECT (transport_account));
1245 g_object_unref (G_OBJECT (mail_operation));
1247 modest_msg_edit_window_free_msg_data (edit_window, data);
1249 /* Save settings and close the window */
1250 gtk_widget_destroy (GTK_WIDGET (edit_window));
1253 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1255 TnyTransportAccount *transport_account;
1256 ModestMailOperation *mail_operation;
1258 gchar *account_name, *from;
1259 ModestAccountMgr *account_mgr;
1261 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1263 if (!modest_msg_edit_window_check_names (edit_window))
1266 data = modest_msg_edit_window_get_msg_data (edit_window);
1268 /* FIXME: Code added just for testing. The final version will
1269 use the send queue provided by tinymail and some
1271 account_mgr = modest_runtime_get_account_mgr();
1272 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1274 account_name = modest_account_mgr_get_default_account (account_mgr);
1275 if (!account_name) {
1276 g_printerr ("modest: no account found\n");
1277 modest_msg_edit_window_free_msg_data (edit_window, data);
1281 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1282 (modest_runtime_get_account_store(),
1284 if (!transport_account) {
1285 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1286 g_free (account_name);
1287 modest_msg_edit_window_free_msg_data (edit_window, data);
1290 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1292 /* Create the mail operation */
1293 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND, G_OBJECT(edit_window));
1294 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1296 modest_mail_operation_send_new_mail (mail_operation,
1306 data->priority_flags);
1309 g_free (account_name);
1310 g_object_unref (G_OBJECT (transport_account));
1311 g_object_unref (G_OBJECT (mail_operation));
1313 modest_msg_edit_window_free_msg_data (edit_window, data);
1315 /* Save settings and close the window */
1316 gtk_widget_destroy (GTK_WIDGET (edit_window));
1320 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1321 ModestMsgEditWindow *window)
1323 ModestMsgEditFormatState *format_state = NULL;
1325 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1326 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1328 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1331 format_state = modest_msg_edit_window_get_format_state (window);
1332 g_return_if_fail (format_state != NULL);
1334 format_state->bold = gtk_toggle_action_get_active (action);
1335 modest_msg_edit_window_set_format_state (window, format_state);
1336 g_free (format_state);
1341 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1342 ModestMsgEditWindow *window)
1344 ModestMsgEditFormatState *format_state = NULL;
1346 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1347 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1349 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1352 format_state = modest_msg_edit_window_get_format_state (window);
1353 g_return_if_fail (format_state != NULL);
1355 format_state->italics = gtk_toggle_action_get_active (action);
1356 modest_msg_edit_window_set_format_state (window, format_state);
1357 g_free (format_state);
1362 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1363 ModestMsgEditWindow *window)
1365 ModestMsgEditFormatState *format_state = NULL;
1367 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1368 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1370 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1373 format_state = modest_msg_edit_window_get_format_state (window);
1374 g_return_if_fail (format_state != NULL);
1376 format_state->bullet = gtk_toggle_action_get_active (action);
1377 modest_msg_edit_window_set_format_state (window, format_state);
1378 g_free (format_state);
1383 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1384 GtkRadioAction *selected,
1385 ModestMsgEditWindow *window)
1387 ModestMsgEditFormatState *format_state = NULL;
1388 GtkJustification value;
1390 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1392 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1395 value = gtk_radio_action_get_current_value (selected);
1397 format_state = modest_msg_edit_window_get_format_state (window);
1398 g_return_if_fail (format_state != NULL);
1400 format_state->justification = value;
1401 modest_msg_edit_window_set_format_state (window, format_state);
1402 g_free (format_state);
1406 modest_ui_actions_on_select_editor_color (GtkAction *action,
1407 ModestMsgEditWindow *window)
1409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1410 g_return_if_fail (GTK_IS_ACTION (action));
1412 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1415 modest_msg_edit_window_select_color (window);
1419 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1420 ModestMsgEditWindow *window)
1422 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1423 g_return_if_fail (GTK_IS_ACTION (action));
1425 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1428 modest_msg_edit_window_select_background_color (window);
1432 modest_ui_actions_on_insert_image (GtkAction *action,
1433 ModestMsgEditWindow *window)
1435 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1436 g_return_if_fail (GTK_IS_ACTION (action));
1438 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1441 modest_msg_edit_window_insert_image (window);
1445 modest_ui_actions_on_attach_file (GtkAction *action,
1446 ModestMsgEditWindow *window)
1448 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1449 g_return_if_fail (GTK_IS_ACTION (action));
1451 modest_msg_edit_window_attach_file (window);
1455 modest_ui_actions_on_remove_attachments (GtkAction *action,
1456 ModestMsgEditWindow *window)
1458 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1459 g_return_if_fail (GTK_IS_ACTION (action));
1461 modest_msg_edit_window_remove_attachments (window, NULL);
1465 * Shows a dialog with an entry that asks for some text. The returned
1466 * value must be freed by the caller. The dialog window title will be
1470 ask_for_folder_name (GtkWindow *parent_window,
1473 GtkWidget *dialog, *entry;
1474 gchar *folder_name = NULL;
1476 /* Ask for folder name */
1477 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1481 GTK_RESPONSE_REJECT,
1483 GTK_RESPONSE_ACCEPT,
1485 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1486 gtk_label_new(title),
1489 entry = gtk_entry_new_with_max_length (40);
1490 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1494 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1496 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1497 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1499 gtk_widget_destroy (dialog);
1505 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1507 TnyFolderStore *parent_folder;
1508 GtkWidget *folder_view;
1510 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1512 folder_view = modest_main_window_get_child_widget (main_window,
1513 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1517 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1519 if (parent_folder) {
1520 gboolean finished = FALSE;
1522 gchar *folder_name = NULL, *suggested_name = NULL;
1524 /* Run the new folder dialog */
1526 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1531 if (result == GTK_RESPONSE_REJECT) {
1534 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window));
1535 TnyFolder *new_folder = NULL;
1537 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1540 new_folder = modest_mail_operation_create_folder (mail_op,
1542 (const gchar *) folder_name);
1544 g_object_unref (new_folder);
1548 /* /\* TODO: check error and follow proper actions *\/ */
1549 /* /\* suggested_name = X; *\/ */
1550 /* /\* Show error to the user *\/ */
1551 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1552 /* _("mail_in_ui_folder_create_error")); */
1554 g_object_unref (mail_op);
1556 g_free (folder_name);
1560 g_object_unref (parent_folder);
1565 modest_ui_actions_on_rename_folder (GtkAction *action,
1566 ModestMainWindow *main_window)
1568 TnyFolderStore *folder;
1569 GtkWidget *folder_view;
1570 GtkWidget *header_view;
1572 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1574 folder_view = modest_main_window_get_child_widget (main_window,
1575 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1579 header_view = modest_main_window_get_child_widget (main_window,
1580 MODEST_WIDGET_TYPE_HEADER_VIEW);
1585 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1587 if (folder && TNY_IS_FOLDER (folder)) {
1589 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1590 _("Please enter a new name for the folder"));
1592 if (folder_name != NULL && strlen (folder_name) > 0) {
1593 ModestMailOperation *mail_op;
1595 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window));
1596 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1599 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1601 modest_mail_operation_rename_folder (mail_op,
1602 TNY_FOLDER (folder),
1603 (const gchar *) folder_name);
1605 g_object_unref (mail_op);
1606 g_free (folder_name);
1608 g_object_unref (folder);
1613 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1615 TnyFolderStore *folder;
1616 GtkWidget *folder_view;
1620 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1622 folder_view = modest_main_window_get_child_widget (main_window,
1623 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1627 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1629 /* Show an error if it's an account */
1630 if (!TNY_IS_FOLDER (folder)) {
1631 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1632 _("mail_in_ui_folder_delete_error"));
1637 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1638 tny_folder_get_name (TNY_FOLDER (folder)));
1639 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1640 (const gchar *) message);
1643 if (response == GTK_RESPONSE_OK) {
1644 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(main_window));
1646 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1648 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1650 /* Show error if happened */
1651 if (modest_mail_operation_get_error (mail_op))
1652 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1653 _("mail_in_ui_folder_delete_error"));
1655 g_object_unref (G_OBJECT (mail_op));
1658 g_object_unref (G_OBJECT (folder));
1662 modest_ui_actions_on_delete_folder (GtkAction *action,
1663 ModestMainWindow *main_window)
1665 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1667 delete_folder (main_window, FALSE);
1671 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1673 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1675 delete_folder (main_window, TRUE);
1679 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1680 const gchar* server_account_name,
1685 ModestMainWindow *main_window)
1687 g_return_if_fail(server_account_name);
1688 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1690 #ifdef MODEST_PLATFORM_MAEMO
1691 /* Maemo uses a different (awkward) button order,
1692 * It should probably just use gtk_alternative_dialog_button_order ().
1694 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1698 GTK_RESPONSE_ACCEPT,
1700 GTK_RESPONSE_REJECT,
1703 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1707 GTK_RESPONSE_REJECT,
1709 GTK_RESPONSE_ACCEPT,
1711 #endif /* MODEST_PLATFORM_MAEMO */
1713 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1715 gchar *server_name = modest_server_account_get_hostname (
1716 modest_runtime_get_account_mgr(), server_account_name);
1718 /* This causes a warning because the logical ID has no %s in it,
1719 * though the translation does, but there is not much we can do about that: */
1720 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1721 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1724 g_free (server_name);
1728 gchar *initial_username = modest_server_account_get_username (
1729 modest_runtime_get_account_mgr(), server_account_name);
1731 GtkWidget *entry_username = gtk_entry_new ();
1732 if (initial_username)
1733 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1734 /* Dim this if a connection has ever succeeded with this username,
1735 * as per the UI spec: */
1736 const gboolean username_known =
1737 modest_server_account_get_username_has_succeeded(
1738 modest_runtime_get_account_mgr(), server_account_name);
1739 gtk_widget_set_sensitive (entry_username, !username_known);
1741 #ifdef MODEST_PLATFORM_MAEMO
1742 /* Auto-capitalization is the default, so let's turn it off: */
1743 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1745 /* Create a size group to be used by all captions.
1746 * Note that HildonCaption does not create a default size group if we do not specify one.
1747 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1748 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1750 GtkWidget *caption = hildon_caption_new (sizegroup,
1751 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1752 gtk_widget_show (entry_username);
1753 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1754 FALSE, FALSE, MODEST_MARGIN_HALF);
1755 gtk_widget_show (caption);
1757 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1759 #endif /* MODEST_PLATFORM_MAEMO */
1762 GtkWidget *entry_password = gtk_entry_new ();
1763 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1764 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1766 #ifdef MODEST_PLATFORM_MAEMO
1767 /* Auto-capitalization is the default, so let's turn it off: */
1768 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1769 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1771 caption = hildon_caption_new (sizegroup,
1772 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1773 gtk_widget_show (entry_password);
1774 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1775 FALSE, FALSE, MODEST_MARGIN_HALF);
1776 gtk_widget_show (caption);
1777 g_object_unref (sizegroup);
1779 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1781 #endif /* MODEST_PLATFORM_MAEMO */
1783 /* This is not in the Maemo UI spec:
1784 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1785 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1789 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1791 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1793 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1795 modest_server_account_set_username (
1796 modest_runtime_get_account_mgr(), server_account_name,
1799 const gboolean username_was_changed =
1800 (strcmp (*username, initial_username) != 0);
1801 if (username_was_changed) {
1802 /* To actually use a changed username,
1803 * we must reset the connection, according to pvanhoof.
1804 * This _might_ be a sensible way to do that: */
1805 TnyDevice *device = modest_runtime_get_device();
1806 tny_device_force_offline (device);
1807 tny_device_force_online (device);
1812 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1814 /* We do not save the password in the configuration,
1815 * because this function is only called for passwords that should
1816 * not be remembered:
1817 modest_server_account_set_password (
1818 modest_runtime_get_account_mgr(), server_account_name,
1837 /* This is not in the Maemo UI spec:
1838 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1844 gtk_widget_destroy (dialog);
1848 modest_ui_actions_on_cut (GtkAction *action,
1849 ModestWindow *window)
1851 GtkWidget *focused_widget;
1853 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1854 if (GTK_IS_EDITABLE (focused_widget)) {
1855 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1856 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1857 GtkTextBuffer *buffer;
1858 GtkClipboard *clipboard;
1860 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1861 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1862 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1867 modest_ui_actions_on_copy (GtkAction *action,
1868 ModestWindow *window)
1870 GtkClipboard *clipboard;
1871 GtkWidget *focused_widget;
1873 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1874 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1875 if (GTK_IS_LABEL (focused_widget)) {
1876 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1877 } else if (GTK_IS_EDITABLE (focused_widget)) {
1878 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1879 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1880 GtkTextBuffer *buffer;
1882 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1883 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1888 modest_ui_actions_on_undo (GtkAction *action,
1889 ModestWindow *window)
1891 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1892 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1894 g_return_if_reached ();
1899 modest_ui_actions_on_paste (GtkAction *action,
1900 ModestWindow *window)
1902 GtkWidget *focused_widget;
1904 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1905 if (GTK_IS_EDITABLE (focused_widget)) {
1906 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1907 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1908 GtkTextBuffer *buffer;
1909 GtkClipboard *clipboard;
1911 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1912 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1913 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1918 modest_ui_actions_on_select_all (GtkAction *action,
1919 ModestWindow *window)
1921 GtkWidget *focused_widget;
1923 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1924 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
1925 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
1926 } else if (GTK_IS_LABEL (focused_widget)) {
1927 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1928 } else if (GTK_IS_EDITABLE (focused_widget)) {
1929 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1930 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1931 GtkTextBuffer *buffer;
1932 GtkTextIter start, end;
1934 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1935 gtk_text_buffer_get_start_iter (buffer, &start);
1936 gtk_text_buffer_get_end_iter (buffer, &end);
1937 gtk_text_buffer_select_range (buffer, &start, &end);
1942 modest_ui_actions_on_mark_as_read (GtkAction *action,
1943 ModestWindow *window)
1945 g_return_if_fail (MODEST_IS_WINDOW(window));
1947 /* Mark each header as read */
1948 do_headers_action (window, headers_action_mark_as_read, NULL);
1952 modest_ui_actions_on_mark_as_unread (GtkAction *action,
1953 ModestWindow *window)
1955 g_return_if_fail (MODEST_IS_WINDOW(window));
1957 /* Mark each header as read */
1958 do_headers_action (window, headers_action_mark_as_unread, NULL);
1962 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1963 GtkRadioAction *selected,
1964 ModestWindow *window)
1968 value = gtk_radio_action_get_current_value (selected);
1969 if (MODEST_IS_WINDOW (window)) {
1970 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1974 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1975 GtkRadioAction *selected,
1976 ModestWindow *window)
1978 TnyHeaderFlags flags;
1979 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1981 flags = gtk_radio_action_get_current_value (selected);
1982 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1985 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1986 GtkRadioAction *selected,
1987 ModestWindow *window)
1991 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1993 file_format = gtk_radio_action_get_current_value (selected);
1994 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1999 modest_ui_actions_on_zoom_plus (GtkAction *action,
2000 ModestWindow *window)
2002 g_return_if_fail (MODEST_IS_WINDOW (window));
2004 modest_window_zoom_plus (MODEST_WINDOW (window));
2008 modest_ui_actions_on_zoom_minus (GtkAction *action,
2009 ModestWindow *window)
2011 g_return_if_fail (MODEST_IS_WINDOW (window));
2013 modest_window_zoom_minus (MODEST_WINDOW (window));
2017 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2018 ModestWindow *window)
2020 ModestWindowMgr *mgr;
2021 gboolean fullscreen, active;
2022 g_return_if_fail (MODEST_IS_WINDOW (window));
2024 mgr = modest_runtime_get_window_mgr ();
2026 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2027 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2029 if (active != fullscreen) {
2030 modest_window_mgr_set_fullscreen_mode (mgr, active);
2031 gtk_window_present (GTK_WINDOW (window));
2036 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2037 ModestWindow *window)
2039 ModestWindowMgr *mgr;
2040 gboolean fullscreen;
2042 g_return_if_fail (MODEST_IS_WINDOW (window));
2044 mgr = modest_runtime_get_window_mgr ();
2045 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2046 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2048 gtk_window_present (GTK_WINDOW (window));
2052 * Used by modest_ui_actions_on_details to call do_headers_action
2055 headers_action_show_details (TnyHeader *header,
2056 ModestWindow *window,
2063 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2066 gtk_widget_show_all (dialog);
2067 gtk_dialog_run (GTK_DIALOG (dialog));
2069 gtk_widget_destroy (dialog);
2073 * Show the folder details in a ModestDetailsDialog widget
2076 show_folder_details (TnyFolder *folder,
2082 dialog = modest_details_dialog_new_with_folder (window, folder);
2085 gtk_widget_show_all (dialog);
2086 gtk_dialog_run (GTK_DIALOG (dialog));
2088 gtk_widget_destroy (dialog);
2092 * Show the header details in a ModestDetailsDialog widget
2095 modest_ui_actions_on_details (GtkAction *action,
2098 TnyList * headers_list;
2102 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2105 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2109 headers_list = get_selected_headers (win);
2113 iter = tny_list_create_iterator (headers_list);
2115 header = TNY_HEADER (tny_iterator_get_current (iter));
2116 headers_action_show_details (header, win, NULL);
2117 g_object_unref (header);
2119 g_object_unref (iter);
2121 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2122 GtkWidget *folder_view, *header_view;
2124 /* Check which widget has the focus */
2125 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2126 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2127 if (gtk_widget_is_focus (folder_view)) {
2130 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2132 /* Show only when it's a folder */
2133 if (!folder || !TNY_IS_FOLDER (folder))
2136 show_folder_details (folder, GTK_WINDOW (win));
2139 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2140 MODEST_WIDGET_TYPE_HEADER_VIEW);
2141 /* Show details of each header */
2142 do_headers_action (win, headers_action_show_details, header_view);
2148 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2149 ModestMsgEditWindow *window)
2151 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2153 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2157 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2158 ModestMsgEditWindow *window)
2160 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2162 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2166 modest_ui_actions_toggle_folders_view (GtkAction *action,
2167 ModestMainWindow *main_window)
2171 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2173 conf = modest_runtime_get_conf ();
2175 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2176 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2178 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2182 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2183 ModestWindow *window)
2185 gboolean active, fullscreen = FALSE;
2186 ModestWindowMgr *mgr;
2188 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2190 /* Check if we want to toggle the toolbar vuew in fullscreen
2192 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2193 "ViewShowToolbarFullScreen")) {
2197 /* Toggle toolbar */
2198 mgr = modest_runtime_get_window_mgr ();
2199 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2203 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2204 ModestMsgEditWindow *window)
2206 modest_msg_edit_window_select_font (window);
2210 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2211 const gchar *display_name,
2214 /* Do not change the application name if the widget has not
2215 the focus. This callback could be called even if the folder
2216 view has not the focus, because the handled signal could be
2217 emitted when the folder view is redrawn */
2218 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2220 gtk_window_set_title (window, display_name);
2222 gtk_window_set_title (window, " ");
2227 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2229 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2230 modest_msg_edit_window_select_contacts (window);
2234 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2236 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2237 modest_msg_edit_window_check_names (window);
2242 create_move_to_dialog (ModestWindow *win,
2243 GtkWidget *folder_view,
2244 GtkWidget **tree_view)
2246 GtkWidget *dialog, *scroll;
2248 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2250 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2252 GTK_RESPONSE_ACCEPT,
2254 GTK_RESPONSE_REJECT,
2257 /* Create scrolled window */
2258 scroll = gtk_scrolled_window_new (NULL, NULL);
2259 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2260 GTK_POLICY_AUTOMATIC,
2261 GTK_POLICY_AUTOMATIC);
2263 /* Create folder view */
2264 *tree_view = modest_folder_view_new (NULL);
2265 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2266 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2267 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2269 /* Add scroll to dialog */
2270 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2271 scroll, FALSE, FALSE, 0);
2273 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2279 * Returns TRUE if at least one of the headers of the list belongs to
2280 * a message that has been fully retrieved.
2283 has_retrieved_msgs (TnyList *list)
2286 gboolean found = FALSE;
2288 iter = tny_list_create_iterator (list);
2289 while (tny_iterator_is_done (iter) && !found) {
2291 TnyHeaderFlags flags;
2293 header = TNY_HEADER (tny_iterator_get_current (iter));
2294 flags = tny_header_get_flags (header);
2295 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2299 tny_iterator_next (iter);
2301 g_object_unref (iter);
2307 * Shows a confirmation dialog to the user when we're moving messages
2308 * from a remote server to the local storage. Returns the dialog
2309 * response. If it's other kind of movement the it always returns
2313 msgs_move_to_confirmation (GtkWindow *win,
2314 TnyFolder *dest_folder,
2317 gint response = GTK_RESPONSE_OK;
2319 /* If the destination is a local folder */
2320 if (modest_tny_folder_is_local_folder (dest_folder)) {
2321 TnyFolder *src_folder;
2325 /* Get source folder */
2326 iter = tny_list_create_iterator (headers);
2327 header = TNY_HEADER (tny_iterator_get_current (iter));
2328 src_folder = tny_header_get_folder (header);
2329 g_object_unref (header);
2330 g_object_unref (iter);
2332 /* If the source is a remote folder */
2333 if (!modest_tny_folder_is_local_folder (src_folder)) {
2334 const gchar *message;
2336 if (tny_list_get_length (headers) == 1)
2337 if (has_retrieved_msgs (headers))
2338 message = _("mcen_nc_move_retrieve");
2340 message = _("mcen_nc_move_header");
2342 if (has_retrieved_msgs (headers))
2343 message = _("mcen_nc_move_retrieves");
2345 message = _("mcen_nc_move_headers");
2347 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2348 (const gchar *) message);
2356 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2358 ModestMsgViewWindow *self = NULL;
2359 gboolean found = FALSE;
2361 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2362 self = MODEST_MSG_VIEW_WINDOW (object);
2364 found = modest_msg_view_window_select_first_message (self);
2365 g_return_if_fail (found);
2369 move_to_error_checking (const GObject *obj, gpointer user_data)
2371 ModestWindow *win = NULL;
2373 g_return_if_fail (MODEST_IS_WINDOW (obj));
2374 win = MODEST_WINDOW (obj);
2376 /* TODO: show error message */
2377 /* modest_platform_run_information_dialog (GTK_WINDOW (win), */
2378 /* _("mail_in_ui_folder_move_target_error")); */
2382 * UI handler for the "Move to" action when invoked from the
2386 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2387 ModestMainWindow *win)
2389 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2390 GtkWidget *header_view = NULL;
2392 TnyFolderStore *folder_store = NULL;
2393 ModestMailOperation *mail_op = NULL;
2395 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2397 /* Get the folder view */
2398 folder_view = modest_main_window_get_child_widget (win,
2399 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2401 /* Get header view */
2402 header_view = modest_main_window_get_child_widget (win,
2403 MODEST_WIDGET_TYPE_HEADER_VIEW);
2405 /* Create and run the dialog */
2406 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2407 result = gtk_dialog_run (GTK_DIALOG(dialog));
2408 g_object_ref (tree_view);
2410 /* We do this to save an indentation level ;-) */
2411 if (result != GTK_RESPONSE_ACCEPT)
2414 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2416 if (TNY_IS_ACCOUNT (folder_store))
2419 /* Get folder or messages to transfer */
2420 if (gtk_widget_is_focus (folder_view)) {
2421 TnyFolderStore *src_folder;
2422 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2424 /* Clean folder on header view before moving it */
2425 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2427 if (TNY_IS_FOLDER (src_folder)) {
2428 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_ID_RECEIVE,
2430 move_to_error_checking);
2431 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2434 modest_mail_operation_xfer_folder_async (mail_op,
2435 TNY_FOLDER (src_folder),
2438 g_object_unref (G_OBJECT (mail_op));
2443 g_object_unref (G_OBJECT (src_folder));
2445 if (gtk_widget_is_focus (header_view)) {
2449 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2451 /* Ask for user confirmation */
2452 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2453 TNY_FOLDER (folder_store),
2456 /* Transfer messages */
2457 if (response == GTK_RESPONSE_OK) {
2458 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2459 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2462 modest_mail_operation_xfer_msgs (mail_op,
2464 TNY_FOLDER (folder_store),
2468 g_object_unref (G_OBJECT (mail_op));
2470 g_object_unref (headers);
2473 g_object_unref (folder_store);
2476 gtk_widget_destroy (dialog);
2481 * UI handler for the "Move to" action when invoked from the
2482 * ModestMsgViewWindow
2485 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2486 ModestMsgViewWindow *win)
2488 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2490 ModestMainWindow *main_window;
2494 /* Get the folder view */
2495 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2496 folder_view = modest_main_window_get_child_widget (main_window,
2497 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2499 /* Create and run the dialog */
2500 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2501 result = gtk_dialog_run (GTK_DIALOG(dialog));
2502 g_object_ref (tree_view);
2504 if (result == GTK_RESPONSE_ACCEPT) {
2505 TnyFolderStore *folder_store;
2508 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2510 /* Create header list */
2511 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2512 headers = tny_simple_list_new ();
2513 tny_list_prepend (headers, G_OBJECT (header));
2514 g_object_unref (header);
2516 /* Ask user for confirmation. MSG-NOT404 */
2517 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2518 TNY_FOLDER (folder_store),
2521 /* Transfer current msg */
2522 if (response == GTK_RESPONSE_OK) {
2523 ModestMailOperation *mail_op;
2525 /* Create mail op */
2526 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2527 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2530 /* Transfer messages */
2531 modest_mail_operation_xfer_msgs (mail_op,
2533 TNY_FOLDER (folder_store),
2535 tranasfer_msgs_from_viewer_cb,
2537 g_object_unref (G_OBJECT (mail_op));
2539 g_object_unref (headers);
2540 g_object_unref (folder_store);
2542 gtk_widget_destroy (dialog);
2546 modest_ui_actions_on_move_to (GtkAction *action,
2549 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2550 MODEST_IS_MSG_VIEW_WINDOW (win));
2552 if (MODEST_IS_MAIN_WINDOW (win))
2553 modest_ui_actions_on_main_window_move_to (action,
2554 MODEST_MAIN_WINDOW (win));
2556 modest_ui_actions_on_msg_view_window_move_to (action,
2557 MODEST_MSG_VIEW_WINDOW (win));
2561 * Calls #HeadersFunc for each header already selected in the main
2562 * window or the message currently being shown in the msg view window
2565 do_headers_action (ModestWindow *win,
2569 TnyList *headers_list;
2573 headers_list = get_selected_headers (win);
2577 /* Call the function for each header */
2578 iter = tny_list_create_iterator (headers_list);
2579 while (!tny_iterator_is_done (iter)) {
2582 header = TNY_HEADER (tny_iterator_get_current (iter));
2583 func (header, win, user_data);
2584 g_object_unref (header);
2585 tny_iterator_next (iter);
2587 g_object_unref (iter);
2591 modest_ui_actions_view_attachment (GtkAction *action,
2592 ModestWindow *window)
2594 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2595 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2597 /* not supported window for this action */
2598 g_return_if_reached ();
2603 modest_ui_actions_save_attachments (GtkAction *action,
2604 ModestWindow *window)
2606 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2607 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2609 /* not supported window for this action */
2610 g_return_if_reached ();
2615 modest_ui_actions_remove_attachments (GtkAction *action,
2616 ModestWindow *window)
2618 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2619 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2621 /* not supported window for this action */
2622 g_return_if_reached ();
2627 modest_ui_actions_on_settings (GtkAction *action,
2632 dialog = modest_platform_get_global_settings_dialog ();
2633 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2634 gtk_widget_show (dialog);
2636 gtk_dialog_run (GTK_DIALOG (dialog));
2638 gtk_widget_destroy (dialog);