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. */
870 /* Do not continue if no suitable connection
872 if (!check_for_connection (acc_name)) {
877 /* TODO: Do not continue if an operation is already in progress:
878 * Maybe there are some operations that tinymail allows to
879 * happen simulatenously.
880 * TODO: Maybe a simple global gboolean is_updating is enough?
884 /* As per the UI spec,
885 * for POP accounts, we should receive,
886 * for IMAP we should synchronize everything, including receiving,
887 * for SMTP we should send,
888 * first receiving, then sending:
890 /* Create the mail operation */
891 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
892 ModestMailOperation *mail_op;
893 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
894 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
895 modest_mail_operation_update_account (mail_op, acc_name);
896 g_object_unref (G_OBJECT (mail_op));
903 * Refreshes all accounts. This function will be used by automatic
907 modest_ui_actions_do_send_receive_all (ModestWindow *win)
909 GSList *account_names, *iter;
911 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
914 iter = account_names;
916 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
917 iter = g_slist_next (iter);
920 g_slist_foreach (account_names, (GFunc) g_free, NULL);
921 g_slist_free (account_names);
925 * Handler of the click on Send&Receive button in the main toolbar
928 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
930 /* Check that at least one account exists: */
931 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
932 TRUE /* enabled accounts only */);
933 gboolean accounts_exist = account_names != NULL;
934 g_slist_free (account_names);
936 /* If not, allow the user to create an account before trying to send/receive. */
938 modest_ui_actions_on_accounts (NULL, win);
940 /* Refresh the active account */
941 modest_ui_actions_do_send_receive (NULL, win);
946 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
949 GtkWidget *header_view;
951 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
953 header_view = modest_main_window_get_child_widget (main_window,
954 MODEST_WIDGET_TYPE_HEADER_VIEW);
958 conf = modest_runtime_get_conf ();
960 /* what is saved/restored is depending on the style; thus; we save with
961 * old style, then update the style, and restore for this new style
963 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
965 if (modest_header_view_get_style
966 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
967 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
968 MODEST_HEADER_VIEW_STYLE_TWOLINES);
970 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
971 MODEST_HEADER_VIEW_STYLE_DETAILS);
973 modest_widget_memory_restore (conf, G_OBJECT(header_view),
974 MODEST_CONF_HEADER_VIEW_KEY);
979 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
981 ModestMainWindow *main_window)
983 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
985 /* If no header has been selected then exit */
989 /* Update Main window title */
990 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
991 const gchar *subject = tny_header_get_subject (header);
992 if (subject && strcmp (subject, ""))
993 gtk_window_set_title (GTK_WINDOW (main_window), subject);
995 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1000 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1002 ModestMainWindow *main_window)
1004 ModestMailOperation *mail_op = NULL;
1005 HeaderActivatedHelper *helper = NULL;
1006 ModestWindowMgr *mgr = NULL;
1007 ModestWindow *win = NULL;
1008 GtkTreeModel *model = NULL;
1009 GtkTreeSelection *sel = NULL;
1010 GList *sel_list = NULL;
1012 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1017 /* Look if we already have a message view for that header */
1018 mgr = modest_runtime_get_window_mgr ();
1019 win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
1023 helper = g_slice_new0 (HeaderActivatedHelper);
1024 helper->folder = tny_header_get_folder (header);
1025 helper->header = g_object_ref(header);
1026 helper->model = NULL;
1028 /* Get headers tree model and selected row reference to build message view */
1029 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1030 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1031 if (sel_list != NULL) {
1034 helper->model = model;
1035 helper->row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
1037 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1038 g_list_free (sel_list);
1041 /* New mail operation */
1042 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(main_window));
1043 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1044 modest_mail_operation_get_msg (mail_op, header, open_msg_func, helper);
1047 g_object_unref (mail_op);
1051 set_active_account_from_tny_account (TnyAccount *account,
1052 ModestWindow *window)
1054 TnyAccount *modest_server_account;
1055 const gchar *server_acc_name;
1056 gchar *modest_acc_name;
1058 server_acc_name = tny_account_get_id (account);
1059 /* We need the TnyAccount provided by the
1060 account store because that is the one that
1061 knows the name of the Modest account */
1062 modest_server_account =
1063 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1065 modest_acc_name = (gchar *) g_object_get_data (G_OBJECT (modest_server_account), "modest_account");
1066 modest_window_set_active_account (window, modest_acc_name);
1067 g_object_unref (modest_server_account);
1071 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1072 TnyFolderStore *folder_store,
1074 ModestMainWindow *main_window)
1077 GtkWidget *header_view;
1078 TnyAccount *account;
1080 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1082 header_view = modest_main_window_get_child_widget(main_window,
1083 MODEST_WIDGET_TYPE_HEADER_VIEW);
1087 conf = modest_runtime_get_conf ();
1089 if (TNY_IS_ACCOUNT (folder_store)) {
1090 /* Update active account */
1091 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1092 /* Show account details */
1093 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1095 if (TNY_IS_FOLDER (folder_store) && selected) {
1096 /* Update the active account */
1097 account = tny_folder_get_account (TNY_FOLDER (folder_store));
1098 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1099 g_object_unref (account);
1101 /* Set folder on header view */
1102 modest_main_window_set_contents_style (main_window,
1103 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1104 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1105 TNY_FOLDER (folder_store));
1106 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1107 MODEST_CONF_HEADER_VIEW_KEY);
1109 /* Update the active account */
1110 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1111 /* Do not show folder */
1112 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1113 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1119 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1126 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1128 if (g_main_depth > 0)
1129 gdk_threads_enter ();
1130 online = tny_device_is_online (modest_runtime_get_device());
1133 /* already online -- the item is simply not there... */
1134 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1136 GTK_MESSAGE_WARNING,
1138 _("The %s you selected cannot be found"),
1140 gtk_dialog_run (GTK_DIALOG(dialog));
1142 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1146 GTK_RESPONSE_REJECT,
1148 GTK_RESPONSE_ACCEPT,
1150 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1151 "Do you want to get online?"), item);
1152 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1153 gtk_label_new (txt), FALSE, FALSE, 0);
1154 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1157 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1158 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1159 // modest_platform_connect_and_wait ();;
1162 gtk_widget_destroy (dialog);
1163 if (g_main_depth > 0)
1164 gdk_threads_leave ();
1168 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1171 /* g_message ("%s %s", __FUNCTION__, link); */
1176 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1179 modest_platform_activate_uri (link);
1183 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1186 modest_platform_show_uri_popup (link);
1190 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1193 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1197 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1198 const gchar *address,
1201 /* g_message ("%s %s", __FUNCTION__, address); */
1205 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1207 TnyTransportAccount *transport_account;
1208 ModestMailOperation *mail_operation;
1210 gchar *account_name, *from;
1211 ModestAccountMgr *account_mgr;
1213 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1215 data = modest_msg_edit_window_get_msg_data (edit_window);
1217 account_mgr = modest_runtime_get_account_mgr();
1218 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1220 account_name = modest_account_mgr_get_default_account (account_mgr);
1221 if (!account_name) {
1222 g_printerr ("modest: no account found\n");
1223 modest_msg_edit_window_free_msg_data (edit_window, data);
1227 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1228 (modest_runtime_get_account_store(),
1230 TNY_ACCOUNT_TYPE_TRANSPORT));
1231 if (!transport_account) {
1232 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1233 g_free (account_name);
1234 modest_msg_edit_window_free_msg_data (edit_window, data);
1237 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1239 /* Create the mail operation */
1240 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(edit_window));
1241 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1243 modest_mail_operation_save_to_drafts (mail_operation,
1253 data->priority_flags);
1256 g_free (account_name);
1257 g_object_unref (G_OBJECT (transport_account));
1258 g_object_unref (G_OBJECT (mail_operation));
1260 modest_msg_edit_window_free_msg_data (edit_window, data);
1262 /* Save settings and close the window */
1263 gtk_widget_destroy (GTK_WIDGET (edit_window));
1266 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1268 TnyTransportAccount *transport_account;
1269 ModestMailOperation *mail_operation;
1271 gchar *account_name, *from;
1272 ModestAccountMgr *account_mgr;
1274 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1276 if (!modest_msg_edit_window_check_names (edit_window))
1279 data = modest_msg_edit_window_get_msg_data (edit_window);
1281 /* FIXME: Code added just for testing. The final version will
1282 use the send queue provided by tinymail and some
1284 account_mgr = modest_runtime_get_account_mgr();
1285 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1287 account_name = modest_account_mgr_get_default_account (account_mgr);
1288 if (!account_name) {
1289 g_printerr ("modest: no account found\n");
1290 modest_msg_edit_window_free_msg_data (edit_window, data);
1294 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1295 (modest_runtime_get_account_store(),
1297 if (!transport_account) {
1298 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1299 g_free (account_name);
1300 modest_msg_edit_window_free_msg_data (edit_window, data);
1303 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1305 /* Create the mail operation */
1306 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND, G_OBJECT(edit_window));
1307 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1309 modest_mail_operation_send_new_mail (mail_operation,
1319 data->priority_flags);
1322 g_free (account_name);
1323 g_object_unref (G_OBJECT (transport_account));
1324 g_object_unref (G_OBJECT (mail_operation));
1326 modest_msg_edit_window_free_msg_data (edit_window, data);
1328 /* Save settings and close the window */
1329 gtk_widget_destroy (GTK_WIDGET (edit_window));
1333 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1334 ModestMsgEditWindow *window)
1336 ModestMsgEditFormatState *format_state = NULL;
1338 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1339 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1341 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1344 format_state = modest_msg_edit_window_get_format_state (window);
1345 g_return_if_fail (format_state != NULL);
1347 format_state->bold = gtk_toggle_action_get_active (action);
1348 modest_msg_edit_window_set_format_state (window, format_state);
1349 g_free (format_state);
1354 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1355 ModestMsgEditWindow *window)
1357 ModestMsgEditFormatState *format_state = NULL;
1359 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1360 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1362 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1365 format_state = modest_msg_edit_window_get_format_state (window);
1366 g_return_if_fail (format_state != NULL);
1368 format_state->italics = gtk_toggle_action_get_active (action);
1369 modest_msg_edit_window_set_format_state (window, format_state);
1370 g_free (format_state);
1375 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1376 ModestMsgEditWindow *window)
1378 ModestMsgEditFormatState *format_state = NULL;
1380 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1381 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1383 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1386 format_state = modest_msg_edit_window_get_format_state (window);
1387 g_return_if_fail (format_state != NULL);
1389 format_state->bullet = gtk_toggle_action_get_active (action);
1390 modest_msg_edit_window_set_format_state (window, format_state);
1391 g_free (format_state);
1396 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1397 GtkRadioAction *selected,
1398 ModestMsgEditWindow *window)
1400 ModestMsgEditFormatState *format_state = NULL;
1401 GtkJustification value;
1403 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1405 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1408 value = gtk_radio_action_get_current_value (selected);
1410 format_state = modest_msg_edit_window_get_format_state (window);
1411 g_return_if_fail (format_state != NULL);
1413 format_state->justification = value;
1414 modest_msg_edit_window_set_format_state (window, format_state);
1415 g_free (format_state);
1419 modest_ui_actions_on_select_editor_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_color (window);
1432 modest_ui_actions_on_select_editor_background_color (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_select_background_color (window);
1445 modest_ui_actions_on_insert_image (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 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1454 modest_msg_edit_window_insert_image (window);
1458 modest_ui_actions_on_attach_file (GtkAction *action,
1459 ModestMsgEditWindow *window)
1461 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1462 g_return_if_fail (GTK_IS_ACTION (action));
1464 modest_msg_edit_window_attach_file (window);
1468 modest_ui_actions_on_remove_attachments (GtkAction *action,
1469 ModestMsgEditWindow *window)
1471 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1472 g_return_if_fail (GTK_IS_ACTION (action));
1474 modest_msg_edit_window_remove_attachments (window, NULL);
1478 * Shows a dialog with an entry that asks for some text. The returned
1479 * value must be freed by the caller. The dialog window title will be
1483 ask_for_folder_name (GtkWindow *parent_window,
1486 GtkWidget *dialog, *entry;
1487 gchar *folder_name = NULL;
1489 /* Ask for folder name */
1490 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1494 GTK_RESPONSE_REJECT,
1496 GTK_RESPONSE_ACCEPT,
1498 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1499 gtk_label_new(title),
1502 entry = gtk_entry_new_with_max_length (40);
1503 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1507 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1509 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1510 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1512 gtk_widget_destroy (dialog);
1518 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1520 TnyFolderStore *parent_folder;
1521 GtkWidget *folder_view;
1523 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1525 folder_view = modest_main_window_get_child_widget (main_window,
1526 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1530 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1532 if (parent_folder) {
1533 gboolean finished = FALSE;
1535 gchar *folder_name = NULL, *suggested_name = NULL;
1537 /* Run the new folder dialog */
1539 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1544 if (result == GTK_RESPONSE_REJECT) {
1547 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window));
1548 TnyFolder *new_folder = NULL;
1550 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1553 new_folder = modest_mail_operation_create_folder (mail_op,
1555 (const gchar *) folder_name);
1557 g_object_unref (new_folder);
1561 /* /\* TODO: check error and follow proper actions *\/ */
1562 /* /\* suggested_name = X; *\/ */
1563 /* /\* Show error to the user *\/ */
1564 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1565 /* _("mail_in_ui_folder_create_error")); */
1567 g_object_unref (mail_op);
1569 g_free (folder_name);
1573 g_object_unref (parent_folder);
1578 modest_ui_actions_on_rename_folder (GtkAction *action,
1579 ModestMainWindow *main_window)
1581 TnyFolderStore *folder;
1582 GtkWidget *folder_view;
1583 GtkWidget *header_view;
1585 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1587 folder_view = modest_main_window_get_child_widget (main_window,
1588 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1592 header_view = modest_main_window_get_child_widget (main_window,
1593 MODEST_WIDGET_TYPE_HEADER_VIEW);
1598 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1600 if (folder && TNY_IS_FOLDER (folder)) {
1602 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1603 _("Please enter a new name for the folder"));
1605 if (folder_name != NULL && strlen (folder_name) > 0) {
1606 ModestMailOperation *mail_op;
1608 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window));
1609 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1612 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1614 modest_mail_operation_rename_folder (mail_op,
1615 TNY_FOLDER (folder),
1616 (const gchar *) folder_name);
1618 g_object_unref (mail_op);
1619 g_free (folder_name);
1621 g_object_unref (folder);
1626 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1628 TnyFolderStore *folder;
1629 GtkWidget *folder_view;
1633 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1635 folder_view = modest_main_window_get_child_widget (main_window,
1636 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1640 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1642 /* Show an error if it's an account */
1643 if (!TNY_IS_FOLDER (folder)) {
1644 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1645 _("mail_in_ui_folder_delete_error"));
1650 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1651 tny_folder_get_name (TNY_FOLDER (folder)));
1652 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1653 (const gchar *) message);
1656 if (response == GTK_RESPONSE_OK) {
1657 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(main_window));
1659 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1661 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1663 /* Show error if happened */
1664 if (modest_mail_operation_get_error (mail_op))
1665 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1666 _("mail_in_ui_folder_delete_error"));
1668 g_object_unref (G_OBJECT (mail_op));
1671 g_object_unref (G_OBJECT (folder));
1675 modest_ui_actions_on_delete_folder (GtkAction *action,
1676 ModestMainWindow *main_window)
1678 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1680 delete_folder (main_window, FALSE);
1684 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1686 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1688 delete_folder (main_window, TRUE);
1692 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1693 const gchar* server_account_name,
1698 ModestMainWindow *main_window)
1700 g_return_if_fail(server_account_name);
1701 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1703 /* Initalize output parameters: */
1710 #ifdef MODEST_PLATFORM_MAEMO
1711 /* Maemo uses a different (awkward) button order,
1712 * It should probably just use gtk_alternative_dialog_button_order ().
1714 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1718 GTK_RESPONSE_ACCEPT,
1720 GTK_RESPONSE_REJECT,
1723 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1727 GTK_RESPONSE_REJECT,
1729 GTK_RESPONSE_ACCEPT,
1731 #endif /* MODEST_PLATFORM_MAEMO */
1733 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1735 gchar *server_name = modest_server_account_get_hostname (
1736 modest_runtime_get_account_mgr(), server_account_name);
1738 /* This causes a warning because the logical ID has no %s in it,
1739 * though the translation does, but there is not much we can do about that: */
1740 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1741 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1744 g_free (server_name);
1748 gchar *initial_username = modest_server_account_get_username (
1749 modest_runtime_get_account_mgr(), server_account_name);
1751 GtkWidget *entry_username = gtk_entry_new ();
1752 if (initial_username)
1753 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1754 /* Dim this if a connection has ever succeeded with this username,
1755 * as per the UI spec: */
1756 const gboolean username_known =
1757 modest_server_account_get_username_has_succeeded(
1758 modest_runtime_get_account_mgr(), server_account_name);
1759 gtk_widget_set_sensitive (entry_username, !username_known);
1761 #ifdef MODEST_PLATFORM_MAEMO
1762 /* Auto-capitalization is the default, so let's turn it off: */
1763 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1765 /* Create a size group to be used by all captions.
1766 * Note that HildonCaption does not create a default size group if we do not specify one.
1767 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1768 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1770 GtkWidget *caption = hildon_caption_new (sizegroup,
1771 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1772 gtk_widget_show (entry_username);
1773 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1774 FALSE, FALSE, MODEST_MARGIN_HALF);
1775 gtk_widget_show (caption);
1777 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1779 #endif /* MODEST_PLATFORM_MAEMO */
1782 GtkWidget *entry_password = gtk_entry_new ();
1783 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1784 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1786 #ifdef MODEST_PLATFORM_MAEMO
1787 /* Auto-capitalization is the default, so let's turn it off: */
1788 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1789 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1791 caption = hildon_caption_new (sizegroup,
1792 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1793 gtk_widget_show (entry_password);
1794 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1795 FALSE, FALSE, MODEST_MARGIN_HALF);
1796 gtk_widget_show (caption);
1797 g_object_unref (sizegroup);
1799 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1801 #endif /* MODEST_PLATFORM_MAEMO */
1803 /* This is not in the Maemo UI spec:
1804 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1805 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1809 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1811 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1813 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1815 modest_server_account_set_username (
1816 modest_runtime_get_account_mgr(), server_account_name,
1819 const gboolean username_was_changed =
1820 (strcmp (*username, initial_username) != 0);
1821 if (username_was_changed) {
1822 /* To actually use a changed username,
1823 * we must reset the connection, according to pvanhoof.
1824 * This _might_ be a sensible way to do that: */
1825 TnyDevice *device = modest_runtime_get_device();
1826 tny_device_force_offline (device);
1827 tny_device_force_online (device);
1832 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1834 /* We do not save the password in the configuration,
1835 * because this function is only called for passwords that should
1836 * not be remembered:
1837 modest_server_account_set_password (
1838 modest_runtime_get_account_mgr(), server_account_name,
1857 /* This is not in the Maemo UI spec:
1858 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1864 gtk_widget_destroy (dialog);
1866 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
1870 modest_ui_actions_on_cut (GtkAction *action,
1871 ModestWindow *window)
1873 GtkWidget *focused_widget;
1875 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1876 if (GTK_IS_EDITABLE (focused_widget)) {
1877 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1878 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1879 GtkTextBuffer *buffer;
1880 GtkClipboard *clipboard;
1882 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1883 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1884 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1889 modest_ui_actions_on_copy (GtkAction *action,
1890 ModestWindow *window)
1892 GtkClipboard *clipboard;
1893 GtkWidget *focused_widget;
1895 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1896 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1897 if (GTK_IS_LABEL (focused_widget)) {
1898 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1899 } else if (GTK_IS_EDITABLE (focused_widget)) {
1900 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1901 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1902 GtkTextBuffer *buffer;
1904 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1905 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1910 modest_ui_actions_on_undo (GtkAction *action,
1911 ModestWindow *window)
1913 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1914 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1916 g_return_if_reached ();
1921 modest_ui_actions_on_paste (GtkAction *action,
1922 ModestWindow *window)
1924 GtkWidget *focused_widget;
1926 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1927 if (GTK_IS_EDITABLE (focused_widget)) {
1928 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1929 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1930 GtkTextBuffer *buffer;
1931 GtkClipboard *clipboard;
1933 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1934 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1935 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1940 modest_ui_actions_on_select_all (GtkAction *action,
1941 ModestWindow *window)
1943 GtkWidget *focused_widget;
1945 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1946 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
1947 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
1948 } else if (GTK_IS_LABEL (focused_widget)) {
1949 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1950 } else if (GTK_IS_EDITABLE (focused_widget)) {
1951 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1952 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1953 GtkTextBuffer *buffer;
1954 GtkTextIter start, end;
1956 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1957 gtk_text_buffer_get_start_iter (buffer, &start);
1958 gtk_text_buffer_get_end_iter (buffer, &end);
1959 gtk_text_buffer_select_range (buffer, &start, &end);
1964 modest_ui_actions_on_mark_as_read (GtkAction *action,
1965 ModestWindow *window)
1967 g_return_if_fail (MODEST_IS_WINDOW(window));
1969 /* Mark each header as read */
1970 do_headers_action (window, headers_action_mark_as_read, NULL);
1974 modest_ui_actions_on_mark_as_unread (GtkAction *action,
1975 ModestWindow *window)
1977 g_return_if_fail (MODEST_IS_WINDOW(window));
1979 /* Mark each header as read */
1980 do_headers_action (window, headers_action_mark_as_unread, NULL);
1984 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1985 GtkRadioAction *selected,
1986 ModestWindow *window)
1990 value = gtk_radio_action_get_current_value (selected);
1991 if (MODEST_IS_WINDOW (window)) {
1992 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1996 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1997 GtkRadioAction *selected,
1998 ModestWindow *window)
2000 TnyHeaderFlags flags;
2001 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2003 flags = gtk_radio_action_get_current_value (selected);
2004 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2007 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2008 GtkRadioAction *selected,
2009 ModestWindow *window)
2013 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2015 file_format = gtk_radio_action_get_current_value (selected);
2016 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2021 modest_ui_actions_on_zoom_plus (GtkAction *action,
2022 ModestWindow *window)
2024 g_return_if_fail (MODEST_IS_WINDOW (window));
2026 modest_window_zoom_plus (MODEST_WINDOW (window));
2030 modest_ui_actions_on_zoom_minus (GtkAction *action,
2031 ModestWindow *window)
2033 g_return_if_fail (MODEST_IS_WINDOW (window));
2035 modest_window_zoom_minus (MODEST_WINDOW (window));
2039 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2040 ModestWindow *window)
2042 ModestWindowMgr *mgr;
2043 gboolean fullscreen, active;
2044 g_return_if_fail (MODEST_IS_WINDOW (window));
2046 mgr = modest_runtime_get_window_mgr ();
2048 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2049 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2051 if (active != fullscreen) {
2052 modest_window_mgr_set_fullscreen_mode (mgr, active);
2053 gtk_window_present (GTK_WINDOW (window));
2058 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2059 ModestWindow *window)
2061 ModestWindowMgr *mgr;
2062 gboolean fullscreen;
2064 g_return_if_fail (MODEST_IS_WINDOW (window));
2066 mgr = modest_runtime_get_window_mgr ();
2067 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2068 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2070 gtk_window_present (GTK_WINDOW (window));
2074 * Used by modest_ui_actions_on_details to call do_headers_action
2077 headers_action_show_details (TnyHeader *header,
2078 ModestWindow *window,
2085 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2088 gtk_widget_show_all (dialog);
2089 gtk_dialog_run (GTK_DIALOG (dialog));
2091 gtk_widget_destroy (dialog);
2095 * Show the folder details in a ModestDetailsDialog widget
2098 show_folder_details (TnyFolder *folder,
2104 dialog = modest_details_dialog_new_with_folder (window, folder);
2107 gtk_widget_show_all (dialog);
2108 gtk_dialog_run (GTK_DIALOG (dialog));
2110 gtk_widget_destroy (dialog);
2114 * Show the header details in a ModestDetailsDialog widget
2117 modest_ui_actions_on_details (GtkAction *action,
2120 TnyList * headers_list;
2124 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2127 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2131 headers_list = get_selected_headers (win);
2135 iter = tny_list_create_iterator (headers_list);
2137 header = TNY_HEADER (tny_iterator_get_current (iter));
2138 headers_action_show_details (header, win, NULL);
2139 g_object_unref (header);
2141 g_object_unref (iter);
2143 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2144 GtkWidget *folder_view, *header_view;
2146 /* Check which widget has the focus */
2147 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2148 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2149 if (gtk_widget_is_focus (folder_view)) {
2152 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2154 /* Show only when it's a folder */
2155 if (!folder || !TNY_IS_FOLDER (folder))
2158 show_folder_details (folder, GTK_WINDOW (win));
2161 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2162 MODEST_WIDGET_TYPE_HEADER_VIEW);
2163 /* Show details of each header */
2164 do_headers_action (win, headers_action_show_details, header_view);
2170 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2171 ModestMsgEditWindow *window)
2173 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2175 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2179 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2180 ModestMsgEditWindow *window)
2182 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2184 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2188 modest_ui_actions_toggle_folders_view (GtkAction *action,
2189 ModestMainWindow *main_window)
2193 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2195 conf = modest_runtime_get_conf ();
2197 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2198 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2200 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2204 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2205 ModestWindow *window)
2207 gboolean active, fullscreen = FALSE;
2208 ModestWindowMgr *mgr;
2210 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2212 /* Check if we want to toggle the toolbar vuew in fullscreen
2214 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2215 "ViewShowToolbarFullScreen")) {
2219 /* Toggle toolbar */
2220 mgr = modest_runtime_get_window_mgr ();
2221 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2225 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2226 ModestMsgEditWindow *window)
2228 modest_msg_edit_window_select_font (window);
2232 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2233 const gchar *display_name,
2236 /* Do not change the application name if the widget has not
2237 the focus. This callback could be called even if the folder
2238 view has not the focus, because the handled signal could be
2239 emitted when the folder view is redrawn */
2240 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2242 gtk_window_set_title (window, display_name);
2244 gtk_window_set_title (window, " ");
2249 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2251 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2252 modest_msg_edit_window_select_contacts (window);
2256 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2258 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2259 modest_msg_edit_window_check_names (window);
2264 create_move_to_dialog (ModestWindow *win,
2265 GtkWidget *folder_view,
2266 GtkWidget **tree_view)
2268 GtkWidget *dialog, *scroll;
2270 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2272 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2274 GTK_RESPONSE_ACCEPT,
2276 GTK_RESPONSE_REJECT,
2279 /* Create scrolled window */
2280 scroll = gtk_scrolled_window_new (NULL, NULL);
2281 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2282 GTK_POLICY_AUTOMATIC,
2283 GTK_POLICY_AUTOMATIC);
2285 /* Create folder view */
2286 *tree_view = modest_folder_view_new (NULL);
2287 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2288 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2289 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2291 /* Add scroll to dialog */
2292 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2293 scroll, FALSE, FALSE, 0);
2295 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2301 * Returns TRUE if at least one of the headers of the list belongs to
2302 * a message that has been fully retrieved.
2305 has_retrieved_msgs (TnyList *list)
2308 gboolean found = FALSE;
2310 iter = tny_list_create_iterator (list);
2311 while (tny_iterator_is_done (iter) && !found) {
2313 TnyHeaderFlags flags;
2315 header = TNY_HEADER (tny_iterator_get_current (iter));
2316 flags = tny_header_get_flags (header);
2317 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2321 tny_iterator_next (iter);
2323 g_object_unref (iter);
2329 * Shows a confirmation dialog to the user when we're moving messages
2330 * from a remote server to the local storage. Returns the dialog
2331 * response. If it's other kind of movement the it always returns
2335 msgs_move_to_confirmation (GtkWindow *win,
2336 TnyFolder *dest_folder,
2339 gint response = GTK_RESPONSE_OK;
2341 /* If the destination is a local folder */
2342 if (modest_tny_folder_is_local_folder (dest_folder)) {
2343 TnyFolder *src_folder;
2347 /* Get source folder */
2348 iter = tny_list_create_iterator (headers);
2349 header = TNY_HEADER (tny_iterator_get_current (iter));
2350 src_folder = tny_header_get_folder (header);
2351 g_object_unref (header);
2352 g_object_unref (iter);
2354 /* If the source is a remote folder */
2355 if (!modest_tny_folder_is_local_folder (src_folder)) {
2356 const gchar *message;
2358 if (tny_list_get_length (headers) == 1)
2359 if (has_retrieved_msgs (headers))
2360 message = _("mcen_nc_move_retrieve");
2362 message = _("mcen_nc_move_header");
2364 if (has_retrieved_msgs (headers))
2365 message = _("mcen_nc_move_retrieves");
2367 message = _("mcen_nc_move_headers");
2369 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2370 (const gchar *) message);
2378 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2380 ModestMsgViewWindow *self = NULL;
2381 gboolean found = FALSE;
2383 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2384 self = MODEST_MSG_VIEW_WINDOW (object);
2386 found = modest_msg_view_window_select_first_message (self);
2387 g_return_if_fail (found);
2391 move_to_error_checking (const GObject *obj, gpointer user_data)
2393 ModestWindow *win = NULL;
2395 g_return_if_fail (MODEST_IS_WINDOW (obj));
2396 win = MODEST_WINDOW (obj);
2398 /* TODO: show error message */
2399 /* modest_platform_run_information_dialog (GTK_WINDOW (win), */
2400 /* _("mail_in_ui_folder_move_target_error")); */
2404 * UI handler for the "Move to" action when invoked from the
2408 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2409 ModestMainWindow *win)
2411 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2412 GtkWidget *header_view = NULL;
2414 TnyFolderStore *folder_store = NULL;
2415 ModestMailOperation *mail_op = NULL;
2417 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2419 /* Get the folder view */
2420 folder_view = modest_main_window_get_child_widget (win,
2421 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2423 /* Get header view */
2424 header_view = modest_main_window_get_child_widget (win,
2425 MODEST_WIDGET_TYPE_HEADER_VIEW);
2427 /* Create and run the dialog */
2428 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2429 result = gtk_dialog_run (GTK_DIALOG(dialog));
2430 g_object_ref (tree_view);
2432 /* We do this to save an indentation level ;-) */
2433 if (result != GTK_RESPONSE_ACCEPT)
2436 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2438 if (TNY_IS_ACCOUNT (folder_store))
2441 /* Get folder or messages to transfer */
2442 if (gtk_widget_is_focus (folder_view)) {
2443 TnyFolderStore *src_folder;
2444 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2446 /* Clean folder on header view before moving it */
2447 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2449 if (TNY_IS_FOLDER (src_folder)) {
2450 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_ID_RECEIVE,
2452 move_to_error_checking);
2453 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2456 modest_mail_operation_xfer_folder (mail_op,
2457 TNY_FOLDER (src_folder),
2460 g_object_unref (G_OBJECT (mail_op));
2465 g_object_unref (G_OBJECT (src_folder));
2467 if (gtk_widget_is_focus (header_view)) {
2471 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2473 /* Ask for user confirmation */
2474 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2475 TNY_FOLDER (folder_store),
2478 /* Transfer messages */
2479 if (response == GTK_RESPONSE_OK) {
2480 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2481 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2484 modest_mail_operation_xfer_msgs (mail_op,
2486 TNY_FOLDER (folder_store),
2490 g_object_unref (G_OBJECT (mail_op));
2492 g_object_unref (headers);
2495 g_object_unref (folder_store);
2498 gtk_widget_destroy (dialog);
2503 * UI handler for the "Move to" action when invoked from the
2504 * ModestMsgViewWindow
2507 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2508 ModestMsgViewWindow *win)
2510 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2512 ModestMainWindow *main_window;
2516 /* Get the folder view */
2517 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2518 folder_view = modest_main_window_get_child_widget (main_window,
2519 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2521 /* Create and run the dialog */
2522 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2523 result = gtk_dialog_run (GTK_DIALOG(dialog));
2524 g_object_ref (tree_view);
2526 if (result == GTK_RESPONSE_ACCEPT) {
2527 TnyFolderStore *folder_store;
2530 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2532 /* Create header list */
2533 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2534 headers = tny_simple_list_new ();
2535 tny_list_prepend (headers, G_OBJECT (header));
2536 g_object_unref (header);
2538 /* Ask user for confirmation. MSG-NOT404 */
2539 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2540 TNY_FOLDER (folder_store),
2543 /* Transfer current msg */
2544 if (response == GTK_RESPONSE_OK) {
2545 ModestMailOperation *mail_op;
2547 /* Create mail op */
2548 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2549 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2552 /* Transfer messages */
2553 modest_mail_operation_xfer_msgs (mail_op,
2555 TNY_FOLDER (folder_store),
2557 tranasfer_msgs_from_viewer_cb,
2559 g_object_unref (G_OBJECT (mail_op));
2561 g_object_unref (headers);
2562 g_object_unref (folder_store);
2564 gtk_widget_destroy (dialog);
2568 modest_ui_actions_on_move_to (GtkAction *action,
2571 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2572 MODEST_IS_MSG_VIEW_WINDOW (win));
2574 if (MODEST_IS_MAIN_WINDOW (win))
2575 modest_ui_actions_on_main_window_move_to (action,
2576 MODEST_MAIN_WINDOW (win));
2578 modest_ui_actions_on_msg_view_window_move_to (action,
2579 MODEST_MSG_VIEW_WINDOW (win));
2583 * Calls #HeadersFunc for each header already selected in the main
2584 * window or the message currently being shown in the msg view window
2587 do_headers_action (ModestWindow *win,
2591 TnyList *headers_list;
2595 headers_list = get_selected_headers (win);
2599 /* Call the function for each header */
2600 iter = tny_list_create_iterator (headers_list);
2601 while (!tny_iterator_is_done (iter)) {
2604 header = TNY_HEADER (tny_iterator_get_current (iter));
2605 func (header, win, user_data);
2606 g_object_unref (header);
2607 tny_iterator_next (iter);
2609 g_object_unref (iter);
2613 modest_ui_actions_view_attachment (GtkAction *action,
2614 ModestWindow *window)
2616 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2617 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2619 /* not supported window for this action */
2620 g_return_if_reached ();
2625 modest_ui_actions_save_attachments (GtkAction *action,
2626 ModestWindow *window)
2628 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2629 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2631 /* not supported window for this action */
2632 g_return_if_reached ();
2637 modest_ui_actions_remove_attachments (GtkAction *action,
2638 ModestWindow *window)
2640 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2641 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2643 /* not supported window for this action */
2644 g_return_if_reached ();
2649 modest_ui_actions_on_settings (GtkAction *action,
2654 dialog = modest_platform_get_global_settings_dialog ();
2655 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2656 gtk_widget_show (dialog);
2658 gtk_dialog_run (GTK_DIALOG (dialog));
2660 gtk_widget_destroy (dialog);