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;
95 typedef struct _HeaderActivatedHelper {
97 GtkTreeRowReference *row_reference;
100 } HeaderActivatedHelper;
103 * The do_headers_action uses this kind of functions to perform some
104 * action to each member of a list of headers
106 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
109 do_headers_action (ModestWindow *win,
114 static void open_msg_func (const GObject *obj, const TnyMsg *msg, gpointer user_data);
116 static void reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data);
118 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
120 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
123 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
126 const gchar *authors[] = {
127 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
130 about = gtk_about_dialog_new ();
131 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
132 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
133 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
134 _("Copyright (c) 2006, Nokia Corporation\n"
135 "All rights reserved."));
136 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
137 _("a modest e-mail client\n\n"
138 "design and implementation: Dirk-Jan C. Binnema\n"
139 "contributions from the fine people at KC and Ig\n"
140 "uses the tinymail email framework written by Philip van Hoof"));
141 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
142 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
144 gtk_dialog_run (GTK_DIALOG (about));
145 gtk_widget_destroy(about);
150 get_selected_headers (ModestWindow *win)
152 if (MODEST_IS_MAIN_WINDOW(win)) {
153 GtkWidget *header_view;
155 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
156 MODEST_WIDGET_TYPE_HEADER_VIEW);
157 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
159 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
160 /* for MsgViewWindows, we simply return a list with one element */
163 TnyList *list = NULL;
165 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
167 header = tny_msg_get_header (msg);
168 list = tny_simple_list_new ();
169 tny_list_prepend (list, G_OBJECT(header));
170 g_object_unref (G_OBJECT(header));
179 headers_action_mark_as_read (TnyHeader *header,
183 TnyHeaderFlags flags;
185 g_return_if_fail (TNY_IS_HEADER(header));
187 flags = tny_header_get_flags (header);
188 if (flags & TNY_HEADER_FLAG_SEEN) return;
189 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
193 headers_action_mark_as_unread (TnyHeader *header,
197 TnyHeaderFlags flags;
199 g_return_if_fail (TNY_IS_HEADER(header));
201 flags = tny_header_get_flags (header);
202 if (flags & TNY_HEADER_FLAG_SEEN) {
203 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
209 headers_action_delete (TnyHeader *header,
213 ModestMailOperation *mail_op = NULL;
215 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(win));
216 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
219 /* Always delete. TODO: Move to trash still not supported */
220 modest_mail_operation_remove_msg (mail_op, header, FALSE);
221 g_object_unref (G_OBJECT (mail_op));
225 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
227 TnyList *header_list = NULL;
228 TnyIterator *iter = NULL;
229 TnyHeader *header = NULL;
230 gchar *message = NULL;
234 g_return_if_fail (MODEST_IS_WINDOW(win));
236 header_list = get_selected_headers (win);
237 if (!header_list) return;
240 if (tny_list_get_length(header_list) > 1)
241 message = g_strdup(_("emev_nc_delete_messages"));
243 iter = tny_list_create_iterator (header_list);
244 header = TNY_HEADER (tny_iterator_get_current (iter));
245 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
246 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
249 /* Confirmation dialog */
250 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
254 if (response == GTK_RESPONSE_OK) {
255 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
257 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
261 /* Remove each header */
262 do_headers_action (win, headers_action_delete, NULL);
264 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
265 gtk_widget_destroy (GTK_WIDGET(win));
272 g_object_unref (header_list);
273 g_object_unref (iter);
278 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
280 #ifdef MODEST_PLATFORM_MAEMO
281 modest_osso_save_state();
282 #endif /* MODEST_PLATFORM_MAEMO */
288 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
290 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
291 gtk_widget_destroy (GTK_WIDGET (win));
292 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
294 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
295 } else if (MODEST_IS_WINDOW (win)) {
296 gtk_widget_destroy (GTK_WIDGET (win));
298 g_return_if_reached ();
303 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
305 GtkClipboard *clipboard = NULL;
306 gchar *selection = NULL;
308 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
309 selection = gtk_clipboard_wait_for_text (clipboard);
311 modest_address_book_add_address (selection);
316 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
318 /* This is currently only implemented for Maemo,
319 * because it requires a providers preset file which is not publically available.
321 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
322 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
323 TRUE /* enabled accounts only */);
324 gboolean accounts_exist = account_names != NULL;
325 g_slist_free (account_names);
327 if (!accounts_exist) {
328 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
329 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
330 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
331 gtk_dialog_run (GTK_DIALOG (wizard));
332 gtk_widget_destroy (GTK_WIDGET (wizard));
334 /* Show the list of accounts: */
335 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
336 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
337 gtk_dialog_run (account_win);
338 gtk_widget_destroy (GTK_WIDGET(account_win));
341 GtkWidget *dialog, *label;
343 /* Create the widgets */
345 dialog = gtk_dialog_new_with_buttons ("Message",
347 GTK_DIALOG_DESTROY_WITH_PARENT,
351 label = gtk_label_new ("Hello World!");
353 /* Ensure that the dialog box is destroyed when the user responds. */
355 g_signal_connect_swapped (dialog, "response",
356 G_CALLBACK (gtk_widget_destroy),
359 /* Add the label, and show everything we've added to the dialog. */
361 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
363 gtk_widget_show_all (dialog);
364 #endif /* MODEST_PLATFORM_MAEMO */
368 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
370 ModestWindow *main_window = MODEST_WINDOW (user_data);
372 /* Save any changes. */
373 modest_connection_specific_smtp_window_save_server_accounts (
374 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
375 modest_window_get_active_account (main_window));
376 gtk_widget_destroy (GTK_WIDGET (window));
380 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
382 /* This is currently only implemented for Maemo,
383 * because it requires an API (libconic) to detect different connection
386 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
388 /* Create the window if necessary: */
389 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
390 modest_connection_specific_smtp_window_fill_with_connections (
391 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
392 modest_runtime_get_account_mgr(),
393 modest_window_get_active_account (win));
395 /* Show the window: */
396 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
397 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
398 gtk_widget_show (specific_window);
400 /* Save changes when the window is hidden: */
401 g_signal_connect (specific_window, "hide",
402 G_CALLBACK (on_smtp_servers_window_hide), win);
403 #endif /* MODEST_PLATFORM_MAEMO */
407 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
409 ModestWindow *msg_win;
411 TnyFolder *folder = NULL;
412 gchar *account_name = NULL;
413 gchar *from_str = NULL;
414 /* GError *err = NULL; */
415 TnyAccount *account = NULL;
416 ModestWindowMgr *mgr;
417 gchar *signature = NULL;
419 account_name = g_strdup(modest_window_get_active_account (win));
421 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
423 g_printerr ("modest: no account found\n");
427 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
429 TNY_ACCOUNT_TYPE_STORE);
431 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
435 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
437 g_printerr ("modest: failed get from string for '%s'\n", account_name);
441 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
442 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
443 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
444 MODEST_ACCOUNT_SIGNATURE, FALSE);
446 signature = g_strdup ("");
449 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
451 g_printerr ("modest: failed to create new msg\n");
455 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
457 g_printerr ("modest: failed to find Drafts folder\n");
461 /* tny_folder_add_msg (folder, msg, &err); */
463 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
465 /* g_error_free (err); */
469 /* Create and register edit window */
470 msg_win = modest_msg_edit_window_new (msg, account_name);
471 mgr = modest_runtime_get_window_mgr ();
472 modest_window_mgr_register_window (mgr, msg_win);
475 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
477 gtk_widget_show_all (GTK_WIDGET (msg_win));
480 g_free (account_name);
484 g_object_unref (G_OBJECT(account));
486 g_object_unref (G_OBJECT(msg));
488 g_object_unref (G_OBJECT(folder));
492 headers_action_open (TnyHeader *header,
496 modest_ui_actions_on_header_activated (MODEST_HEADER_VIEW (user_data),
498 MODEST_MAIN_WINDOW (win));
502 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
504 GtkWidget *header_view;
506 /* Get header view */
507 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
508 MODEST_WIDGET_TYPE_HEADER_VIEW);
510 /* Open each message */
511 do_headers_action (win, headers_action_open, header_view);
516 open_msg_func (const GObject *obj, const TnyMsg *msg, gpointer user_data)
518 ModestWindowMgr *mgr = NULL;
519 ModestWindow *parent_win = NULL;
520 ModestWindow *win = NULL;
521 HeaderActivatedHelper *helper = NULL;
522 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
523 gchar *account = NULL;
525 g_return_if_fail (MODEST_IS_WINDOW(obj));
526 g_return_if_fail (user_data != NULL);
528 /* TODO: Show an error? (review the specs) */
532 parent_win = MODEST_WINDOW(obj);
533 helper = (HeaderActivatedHelper *) user_data;
535 /* Mark header as read */
536 headers_action_mark_as_read (helper->header, MODEST_WINDOW(parent_win), NULL);
539 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(parent_win)));
541 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
543 /* Gets foldert type (OUTBOX headers will be opened in edit window */
544 if (modest_tny_folder_is_local_folder (helper->folder))
545 folder_type = modest_tny_folder_get_local_folder_type (helper->folder);
547 switch (folder_type) {
548 case TNY_FOLDER_TYPE_DRAFTS:
549 win = modest_msg_edit_window_new ((TnyMsg *) msg, account);
552 if (helper->model != NULL)
553 win = modest_msg_view_window_new_with_header_model ((TnyMsg *) msg, account, helper->model, helper->row_reference);
555 win = modest_msg_view_window_new ((TnyMsg *) msg, account);
558 /* Register and show new window */
560 mgr = modest_runtime_get_window_mgr ();
561 modest_window_mgr_register_window (mgr, win);
562 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
563 gtk_widget_show_all (GTK_WIDGET(win));
568 /* g_object_unref (G_OBJECT(msg)); */
569 g_object_unref (G_OBJECT(helper->folder));
570 g_object_unref (G_OBJECT(helper->header));
571 gtk_tree_row_reference_free (helper->row_reference);
572 g_slice_free (HeaderActivatedHelper, helper);
576 reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data)
579 ReplyForwardHelper *rf_helper;
580 ModestWindow *msg_win;
581 ModestEditType edit_type;
584 TnyFolder *folder = NULL;
585 TnyAccount *account = NULL;
586 ModestWindowMgr *mgr;
587 gchar *signature = NULL;
589 g_return_if_fail (user_data != NULL);
590 rf_helper = (ReplyForwardHelper *) user_data;
592 rf_helper->pending_ops--;
594 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
595 rf_helper->account_name);
596 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
597 rf_helper->account_name,
598 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
599 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
600 rf_helper->account_name,
601 MODEST_ACCOUNT_SIGNATURE, FALSE);
604 /* Create reply mail */
605 switch (rf_helper->action) {
608 modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature,
609 rf_helper->reply_forward_type,
610 MODEST_TNY_MSG_REPLY_MODE_SENDER);
612 case ACTION_REPLY_TO_ALL:
614 modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type,
615 MODEST_TNY_MSG_REPLY_MODE_ALL);
616 edit_type = MODEST_EDIT_TYPE_REPLY;
620 modest_tny_msg_create_forward_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type);
621 edit_type = MODEST_EDIT_TYPE_FORWARD;
624 g_return_if_reached ();
631 g_printerr ("modest: failed to create message\n");
635 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
636 rf_helper->account_name,
637 TNY_ACCOUNT_TYPE_STORE);
639 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
643 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
645 g_printerr ("modest: failed to find Drafts folder\n");
649 tny_folder_add_msg (folder, (TnyMsg *) msg, &err);
651 g_printerr ("modest: error adding msg to Drafts folder: %s",
657 /* Create and register the windows */
658 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
659 mgr = modest_runtime_get_window_mgr ();
660 modest_window_mgr_register_window (mgr, msg_win);
662 /* Show edit window */
663 gtk_widget_show_all (GTK_WIDGET (msg_win));
667 g_object_unref (G_OBJECT (new_msg));
669 g_object_unref (G_OBJECT (folder));
671 g_object_unref (G_OBJECT (account));
673 if (rf_helper->pending_ops == 0) {
674 g_free (rf_helper->account_name);
675 g_slice_free (ReplyForwardHelper, rf_helper);
679 * Common code for the reply and forward actions
682 reply_forward (ReplyForwardAction action, ModestWindow *win)
684 ModestMailOperation *mail_op = NULL;
685 TnyList *header_list = NULL;
686 ReplyForwardHelper *rf_helper = NULL;
687 guint reply_forward_type;
689 g_return_if_fail (MODEST_IS_WINDOW(win));
691 header_list = get_selected_headers (win);
695 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
696 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
698 /* We assume that we can only select messages of the
699 same folder and that we reply all of them from the
700 same account. In fact the interface currently only
701 allows single selection */
704 rf_helper = g_slice_new0 (ReplyForwardHelper);
705 rf_helper->reply_forward_type = reply_forward_type;
706 rf_helper->action = action;
707 rf_helper->pending_ops = tny_list_get_length (header_list);
708 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
709 if (!rf_helper->account_name)
710 rf_helper->account_name =
711 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
713 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
715 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
717 g_printerr ("modest: no message found\n");
720 reply_forward_func (G_OBJECT(win), msg, rf_helper);
723 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
724 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
725 modest_mail_operation_process_msg (mail_op, header_list, reply_forward_func, rf_helper);
728 g_object_unref(mail_op);
733 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
735 g_return_if_fail (MODEST_IS_WINDOW(win));
737 reply_forward (ACTION_REPLY, win);
741 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
743 g_return_if_fail (MODEST_IS_WINDOW(win));
745 reply_forward (ACTION_FORWARD, win);
749 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
751 g_return_if_fail (MODEST_IS_WINDOW(win));
753 reply_forward (ACTION_REPLY_TO_ALL, win);
757 modest_ui_actions_on_next (GtkAction *action,
758 ModestWindow *window)
760 if (MODEST_IS_MAIN_WINDOW (window)) {
761 GtkWidget *header_view;
763 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
764 MODEST_WIDGET_TYPE_HEADER_VIEW);
768 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
769 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
770 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
772 g_return_if_reached ();
777 modest_ui_actions_on_prev (GtkAction *action,
778 ModestWindow *window)
780 g_return_if_fail (MODEST_IS_WINDOW(window));
782 if (MODEST_IS_MAIN_WINDOW (window)) {
783 GtkWidget *header_view;
784 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
785 MODEST_WIDGET_TYPE_HEADER_VIEW);
789 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
790 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
791 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
793 g_return_if_reached ();
798 modest_ui_actions_on_sort (GtkAction *action,
799 ModestWindow *window)
801 g_return_if_fail (MODEST_IS_WINDOW(window));
803 if (MODEST_IS_MAIN_WINDOW (window)) {
804 GtkWidget *header_view;
805 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
806 MODEST_WIDGET_TYPE_HEADER_VIEW);
810 /* Show sorting dialog */
811 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
815 /** Check that an appropriate connection is open.
817 gboolean check_for_connection (const gchar *account_name)
819 TnyDevice *device = modest_runtime_get_device ();
822 g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
824 TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
827 if (tny_device_is_online (device))
830 modest_platform_connect_and_wait (NULL);
832 /* TODO: Wait until a result. */
838 * This function performs the send & receive required actions. The
839 * window it's used to create the mail operation. Tipically it should
840 * be allways the main window, but we pass it as argument in order to
844 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
846 gchar *acc_name = NULL;
848 /* If no account name was provided get the current account, if
849 there is none either then pick the default one */
851 acc_name = g_strdup (modest_window_get_active_account(win));
853 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
855 g_printerr ("modest: cannot get default account\n");
859 acc_name = g_strdup (account_name);
862 /* Send & receive. Do not continue if no suitable connection
864 if (check_for_connection (acc_name)) {
865 /* As per the UI spec,
866 * for POP accounts, we should receive,
867 * for IMAP we should synchronize everything, including receiving,
868 * for SMTP we should send,
869 * first receiving, then sending:
871 /* Create the mail operation */
872 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
873 ModestMailOperation *mail_op;
874 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
875 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
876 modest_mail_operation_update_account (mail_op, acc_name);
877 g_object_unref (G_OBJECT (mail_op));
884 * Refreshes all accounts. This function will be used by automatic
888 modest_ui_actions_do_send_receive_all (ModestWindow *win)
890 GSList *account_names, *iter;
892 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
895 iter = account_names;
897 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
898 iter = g_slist_next (iter);
901 g_slist_foreach (account_names, (GFunc) g_free, NULL);
902 g_slist_free (account_names);
906 * Handler of the click on Send&Receive button in the main toolbar
909 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
911 /* Check that at least one account exists: */
912 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
913 TRUE /* enabled accounts only */);
914 gboolean accounts_exist = account_names != NULL;
915 g_slist_free (account_names);
917 /* If not, allow the user to create an account before trying to send/receive. */
919 modest_ui_actions_on_accounts (NULL, win);
921 /* Refresh the active account */
922 modest_ui_actions_do_send_receive (NULL, win);
927 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
930 GtkWidget *header_view;
932 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
934 header_view = modest_main_window_get_child_widget (main_window,
935 MODEST_WIDGET_TYPE_HEADER_VIEW);
939 conf = modest_runtime_get_conf ();
941 /* what is saved/restored is depending on the style; thus; we save with
942 * old style, then update the style, and restore for this new style
944 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
946 if (modest_header_view_get_style
947 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
948 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
949 MODEST_HEADER_VIEW_STYLE_TWOLINES);
951 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
952 MODEST_HEADER_VIEW_STYLE_DETAILS);
954 modest_widget_memory_restore (conf, G_OBJECT(header_view),
955 MODEST_CONF_HEADER_VIEW_KEY);
960 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
962 ModestMainWindow *main_window)
964 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
966 /* If no header has been selected then exit */
970 /* Update Main window title */
971 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
972 const gchar *subject = tny_header_get_subject (header);
973 if (subject && strcmp (subject, ""))
974 gtk_window_set_title (GTK_WINDOW (main_window), subject);
976 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
981 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
983 ModestMainWindow *main_window)
985 ModestMailOperation *mail_op = NULL;
986 HeaderActivatedHelper *helper = NULL;
987 ModestWindowMgr *mgr = NULL;
988 ModestWindow *win = NULL;
989 GtkTreeModel *model = NULL;
990 GtkTreeSelection *sel = NULL;
991 GList *sel_list = NULL;
993 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
998 /* Look if we already have a message view for that header */
999 mgr = modest_runtime_get_window_mgr ();
1000 win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
1004 helper = g_slice_new0 (HeaderActivatedHelper);
1005 helper->folder = tny_header_get_folder (header);
1006 helper->header = g_object_ref(header);
1007 helper->model = NULL;
1009 /* Get headers tree model and selected row reference to build message view */
1010 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1011 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1012 if (sel_list != NULL) {
1015 helper->model = model;
1016 helper->row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
1018 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1019 g_list_free (sel_list);
1022 /* New mail operation */
1023 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(main_window));
1024 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1025 modest_mail_operation_get_msg (mail_op, header, open_msg_func, helper);
1028 g_object_unref (mail_op);
1032 set_active_account_from_tny_account (TnyAccount *account,
1033 ModestWindow *window)
1035 TnyAccount *modest_server_account;
1036 const gchar *server_acc_name;
1037 gchar *modest_acc_name;
1039 server_acc_name = tny_account_get_id (account);
1040 /* We need the TnyAccount provided by the
1041 account store because that is the one that
1042 knows the name of the Modest account */
1043 modest_server_account =
1044 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1046 modest_acc_name = (gchar *) g_object_get_data (G_OBJECT (modest_server_account), "modest_account");
1047 modest_window_set_active_account (window, modest_acc_name);
1048 g_object_unref (modest_server_account);
1052 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1053 TnyFolderStore *folder_store,
1055 ModestMainWindow *main_window)
1058 GtkWidget *header_view;
1059 TnyAccount *account;
1061 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1063 header_view = modest_main_window_get_child_widget(main_window,
1064 MODEST_WIDGET_TYPE_HEADER_VIEW);
1068 conf = modest_runtime_get_conf ();
1070 if (TNY_IS_FOLDER (folder_store)) {
1073 /* Update the active account */
1074 account = tny_folder_get_account (TNY_FOLDER (folder_store));
1075 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1076 g_object_unref (account);
1078 /* Set folder on header view */
1079 modest_main_window_set_contents_style (main_window,
1080 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1081 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1082 TNY_FOLDER (folder_store));
1083 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1084 MODEST_CONF_HEADER_VIEW_KEY);
1086 /* Update the active account */
1087 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1088 /* Do not show folder */
1089 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1090 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1092 } else if (TNY_IS_ACCOUNT (folder_store)) {
1093 /* Update active account */
1094 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1095 /* Show account details */
1096 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1101 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1108 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1110 if (g_main_depth > 0)
1111 gdk_threads_enter ();
1112 online = tny_device_is_online (modest_runtime_get_device());
1115 /* already online -- the item is simply not there... */
1116 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1118 GTK_MESSAGE_WARNING,
1120 _("The %s you selected cannot be found"),
1122 gtk_dialog_run (GTK_DIALOG(dialog));
1124 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1128 GTK_RESPONSE_REJECT,
1130 GTK_RESPONSE_ACCEPT,
1132 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1133 "Do you want to get online?"), item);
1134 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1135 gtk_label_new (txt), FALSE, FALSE, 0);
1136 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1139 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1140 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1141 // modest_platform_connect_and_wait ();;
1144 gtk_widget_destroy (dialog);
1145 if (g_main_depth > 0)
1146 gdk_threads_leave ();
1150 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1153 /* g_message ("%s %s", __FUNCTION__, link); */
1158 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1161 modest_platform_activate_uri (link);
1165 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1168 modest_platform_show_uri_popup (link);
1172 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1175 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1179 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1180 const gchar *address,
1183 /* g_message ("%s %s", __FUNCTION__, address); */
1187 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1189 TnyTransportAccount *transport_account;
1190 ModestMailOperation *mail_operation;
1192 gchar *account_name, *from;
1193 ModestAccountMgr *account_mgr;
1195 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1197 data = modest_msg_edit_window_get_msg_data (edit_window);
1199 account_mgr = modest_runtime_get_account_mgr();
1200 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1202 account_name = modest_account_mgr_get_default_account (account_mgr);
1203 if (!account_name) {
1204 g_printerr ("modest: no account found\n");
1205 modest_msg_edit_window_free_msg_data (edit_window, data);
1209 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1210 (modest_runtime_get_account_store(),
1212 TNY_ACCOUNT_TYPE_TRANSPORT));
1213 if (!transport_account) {
1214 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1215 g_free (account_name);
1216 modest_msg_edit_window_free_msg_data (edit_window, data);
1219 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1221 /* Create the mail operation */
1222 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(edit_window));
1223 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1225 modest_mail_operation_save_to_drafts (mail_operation,
1235 data->priority_flags);
1238 g_free (account_name);
1239 g_object_unref (G_OBJECT (transport_account));
1240 g_object_unref (G_OBJECT (mail_operation));
1242 modest_msg_edit_window_free_msg_data (edit_window, data);
1244 /* Save settings and close the window */
1245 gtk_widget_destroy (GTK_WIDGET (edit_window));
1248 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1250 TnyTransportAccount *transport_account;
1251 ModestMailOperation *mail_operation;
1253 gchar *account_name, *from;
1254 ModestAccountMgr *account_mgr;
1256 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1258 if (!modest_msg_edit_window_check_names (edit_window))
1261 data = modest_msg_edit_window_get_msg_data (edit_window);
1263 /* FIXME: Code added just for testing. The final version will
1264 use the send queue provided by tinymail and some
1266 account_mgr = modest_runtime_get_account_mgr();
1267 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1269 account_name = modest_account_mgr_get_default_account (account_mgr);
1270 if (!account_name) {
1271 g_printerr ("modest: no account found\n");
1272 modest_msg_edit_window_free_msg_data (edit_window, data);
1276 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1277 (modest_runtime_get_account_store(),
1279 if (!transport_account) {
1280 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1281 g_free (account_name);
1282 modest_msg_edit_window_free_msg_data (edit_window, data);
1285 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1287 /* Create the mail operation */
1288 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND, G_OBJECT(edit_window));
1289 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1291 modest_mail_operation_send_new_mail (mail_operation,
1301 data->priority_flags);
1304 g_free (account_name);
1305 g_object_unref (G_OBJECT (transport_account));
1306 g_object_unref (G_OBJECT (mail_operation));
1308 modest_msg_edit_window_free_msg_data (edit_window, data);
1310 /* Save settings and close the window */
1311 gtk_widget_destroy (GTK_WIDGET (edit_window));
1315 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1316 ModestMsgEditWindow *window)
1318 ModestMsgEditFormatState *format_state = NULL;
1320 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1321 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1323 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1326 format_state = modest_msg_edit_window_get_format_state (window);
1327 g_return_if_fail (format_state != NULL);
1329 format_state->bold = gtk_toggle_action_get_active (action);
1330 modest_msg_edit_window_set_format_state (window, format_state);
1331 g_free (format_state);
1336 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1337 ModestMsgEditWindow *window)
1339 ModestMsgEditFormatState *format_state = NULL;
1341 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1342 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1344 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1347 format_state = modest_msg_edit_window_get_format_state (window);
1348 g_return_if_fail (format_state != NULL);
1350 format_state->italics = gtk_toggle_action_get_active (action);
1351 modest_msg_edit_window_set_format_state (window, format_state);
1352 g_free (format_state);
1357 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1358 ModestMsgEditWindow *window)
1360 ModestMsgEditFormatState *format_state = NULL;
1362 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1363 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1365 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1368 format_state = modest_msg_edit_window_get_format_state (window);
1369 g_return_if_fail (format_state != NULL);
1371 format_state->bullet = gtk_toggle_action_get_active (action);
1372 modest_msg_edit_window_set_format_state (window, format_state);
1373 g_free (format_state);
1378 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1379 GtkRadioAction *selected,
1380 ModestMsgEditWindow *window)
1382 ModestMsgEditFormatState *format_state = NULL;
1383 GtkJustification value;
1385 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1387 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1390 value = gtk_radio_action_get_current_value (selected);
1392 format_state = modest_msg_edit_window_get_format_state (window);
1393 g_return_if_fail (format_state != NULL);
1395 format_state->justification = value;
1396 modest_msg_edit_window_set_format_state (window, format_state);
1397 g_free (format_state);
1401 modest_ui_actions_on_select_editor_color (GtkAction *action,
1402 ModestMsgEditWindow *window)
1404 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1405 g_return_if_fail (GTK_IS_ACTION (action));
1407 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1410 modest_msg_edit_window_select_color (window);
1414 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1415 ModestMsgEditWindow *window)
1417 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1418 g_return_if_fail (GTK_IS_ACTION (action));
1420 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1423 modest_msg_edit_window_select_background_color (window);
1427 modest_ui_actions_on_insert_image (GtkAction *action,
1428 ModestMsgEditWindow *window)
1430 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1431 g_return_if_fail (GTK_IS_ACTION (action));
1433 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1436 modest_msg_edit_window_insert_image (window);
1440 modest_ui_actions_on_attach_file (GtkAction *action,
1441 ModestMsgEditWindow *window)
1443 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1444 g_return_if_fail (GTK_IS_ACTION (action));
1446 modest_msg_edit_window_attach_file (window);
1450 modest_ui_actions_on_remove_attachments (GtkAction *action,
1451 ModestMsgEditWindow *window)
1453 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1454 g_return_if_fail (GTK_IS_ACTION (action));
1456 modest_msg_edit_window_remove_attachments (window, NULL);
1460 * Shows a dialog with an entry that asks for some text. The returned
1461 * value must be freed by the caller. The dialog window title will be
1465 ask_for_folder_name (GtkWindow *parent_window,
1468 GtkWidget *dialog, *entry;
1469 gchar *folder_name = NULL;
1471 /* Ask for folder name */
1472 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1476 GTK_RESPONSE_REJECT,
1478 GTK_RESPONSE_ACCEPT,
1480 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1481 gtk_label_new(title),
1484 entry = gtk_entry_new_with_max_length (40);
1485 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1489 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1491 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1492 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1494 gtk_widget_destroy (dialog);
1500 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1502 TnyFolderStore *parent_folder;
1503 GtkWidget *folder_view;
1505 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1507 folder_view = modest_main_window_get_child_widget (main_window,
1508 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1512 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1514 if (parent_folder) {
1515 gboolean finished = FALSE;
1517 gchar *folder_name = NULL, *suggested_name = NULL;
1519 /* Run the new folder dialog */
1521 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1526 if (result == GTK_RESPONSE_REJECT) {
1529 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window));
1530 TnyFolder *new_folder = NULL;
1532 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1535 new_folder = modest_mail_operation_create_folder (mail_op,
1537 (const gchar *) folder_name);
1539 g_object_unref (new_folder);
1543 /* /\* TODO: check error and follow proper actions *\/ */
1544 /* /\* suggested_name = X; *\/ */
1545 /* /\* Show error to the user *\/ */
1546 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1547 /* _("mail_in_ui_folder_create_error")); */
1549 g_object_unref (mail_op);
1551 g_free (folder_name);
1555 g_object_unref (parent_folder);
1560 modest_ui_actions_on_rename_folder (GtkAction *action,
1561 ModestMainWindow *main_window)
1563 TnyFolderStore *folder;
1564 GtkWidget *folder_view;
1566 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1568 folder_view = modest_main_window_get_child_widget (main_window,
1569 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1573 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1575 if (folder && TNY_IS_FOLDER (folder)) {
1577 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1578 _("Please enter a new name for the folder"));
1580 if (folder_name != NULL && strlen (folder_name) > 0) {
1581 ModestMailOperation *mail_op;
1583 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window));
1584 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1587 modest_mail_operation_rename_folder (mail_op,
1588 TNY_FOLDER (folder),
1589 (const gchar *) folder_name);
1591 g_object_unref (mail_op);
1592 g_free (folder_name);
1594 g_object_unref (folder);
1599 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1601 TnyFolderStore *folder;
1602 GtkWidget *folder_view;
1606 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1608 folder_view = modest_main_window_get_child_widget (main_window,
1609 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1613 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1615 /* Show an error if it's an account */
1616 if (!TNY_IS_FOLDER (folder)) {
1617 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1618 _("mail_in_ui_folder_delete_error"));
1623 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1624 tny_folder_get_name (TNY_FOLDER (folder)));
1625 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1626 (const gchar *) message);
1629 if (response == GTK_RESPONSE_OK) {
1630 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(main_window));
1632 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1634 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1636 /* Show error if happened */
1637 if (modest_mail_operation_get_error (mail_op))
1638 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1639 _("mail_in_ui_folder_delete_error"));
1641 g_object_unref (G_OBJECT (mail_op));
1644 g_object_unref (G_OBJECT (folder));
1648 modest_ui_actions_on_delete_folder (GtkAction *action,
1649 ModestMainWindow *main_window)
1651 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1653 delete_folder (main_window, FALSE);
1657 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1659 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1661 delete_folder (main_window, TRUE);
1665 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1666 const gchar* server_account_name,
1671 ModestMainWindow *main_window)
1673 g_return_if_fail(server_account_name);
1674 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1676 #ifdef MODEST_PLATFORM_MAEMO
1677 /* Maemo uses a different (awkward) button order,
1678 * It should probably just use gtk_alternative_dialog_button_order ().
1680 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1684 GTK_RESPONSE_ACCEPT,
1686 GTK_RESPONSE_REJECT,
1689 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1693 GTK_RESPONSE_REJECT,
1695 GTK_RESPONSE_ACCEPT,
1697 #endif /* MODEST_PLATFORM_MAEMO */
1699 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1701 gchar *server_name = modest_server_account_get_hostname (
1702 modest_runtime_get_account_mgr(), server_account_name);
1704 /* This causes a warning because the logical ID has no %s in it,
1705 * though the translation does, but there is not much we can do about that: */
1706 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1707 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1710 g_free (server_name);
1714 gchar *initial_username = modest_server_account_get_username (
1715 modest_runtime_get_account_mgr(), server_account_name);
1717 GtkWidget *entry_username = gtk_entry_new ();
1718 if (initial_username)
1719 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1720 /* Dim this if a connection has ever succeeded with this username,
1721 * as per the UI spec: */
1722 const gboolean username_known =
1723 modest_server_account_get_username_has_succeeded(
1724 modest_runtime_get_account_mgr(), server_account_name);
1725 gtk_widget_set_sensitive (entry_username, !username_known);
1727 #ifdef MODEST_PLATFORM_MAEMO
1728 /* Auto-capitalization is the default, so let's turn it off: */
1729 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1731 /* Create a size group to be used by all captions.
1732 * Note that HildonCaption does not create a default size group if we do not specify one.
1733 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1734 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1736 GtkWidget *caption = hildon_caption_new (sizegroup,
1737 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1738 gtk_widget_show (entry_username);
1739 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1740 FALSE, FALSE, MODEST_MARGIN_HALF);
1741 gtk_widget_show (caption);
1743 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1745 #endif /* MODEST_PLATFORM_MAEMO */
1748 GtkWidget *entry_password = gtk_entry_new ();
1749 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1750 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1752 #ifdef MODEST_PLATFORM_MAEMO
1753 /* Auto-capitalization is the default, so let's turn it off: */
1754 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1755 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1757 caption = hildon_caption_new (sizegroup,
1758 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1759 gtk_widget_show (entry_password);
1760 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1761 FALSE, FALSE, MODEST_MARGIN_HALF);
1762 gtk_widget_show (caption);
1763 g_object_unref (sizegroup);
1765 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1767 #endif /* MODEST_PLATFORM_MAEMO */
1769 /* This is not in the Maemo UI spec:
1770 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1771 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1775 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1777 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1779 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1781 modest_server_account_set_username (
1782 modest_runtime_get_account_mgr(), server_account_name,
1785 const gboolean username_was_changed =
1786 (strcmp (*username, initial_username) != 0);
1787 if (username_was_changed) {
1788 /* To actually use a changed username,
1789 * we must reset the connection, according to pvanhoof.
1790 * This _might_ be a sensible way to do that: */
1791 TnyDevice *device = modest_runtime_get_device();
1792 tny_device_force_offline (device);
1793 tny_device_force_online (device);
1798 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1800 /* We do not save the password in the configuration,
1801 * because this function is only called for passwords that should
1802 * not be remembered:
1803 modest_server_account_set_password (
1804 modest_runtime_get_account_mgr(), server_account_name,
1823 /* This is not in the Maemo UI spec:
1824 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1830 gtk_widget_destroy (dialog);
1834 modest_ui_actions_on_cut (GtkAction *action,
1835 ModestWindow *window)
1837 GtkWidget *focused_widget;
1839 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1840 if (GTK_IS_EDITABLE (focused_widget)) {
1841 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1842 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1843 GtkTextBuffer *buffer;
1844 GtkClipboard *clipboard;
1846 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1847 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1848 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1853 modest_ui_actions_on_copy (GtkAction *action,
1854 ModestWindow *window)
1856 GtkClipboard *clipboard;
1857 GtkWidget *focused_widget;
1859 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1860 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1861 if (GTK_IS_LABEL (focused_widget)) {
1862 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1863 } else if (GTK_IS_EDITABLE (focused_widget)) {
1864 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1865 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1866 GtkTextBuffer *buffer;
1868 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1869 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1874 modest_ui_actions_on_undo (GtkAction *action,
1875 ModestWindow *window)
1877 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1878 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1880 g_return_if_reached ();
1885 modest_ui_actions_on_paste (GtkAction *action,
1886 ModestWindow *window)
1888 GtkWidget *focused_widget;
1890 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1891 if (GTK_IS_EDITABLE (focused_widget)) {
1892 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1893 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1894 GtkTextBuffer *buffer;
1895 GtkClipboard *clipboard;
1897 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1898 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1899 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1904 modest_ui_actions_on_select_all (GtkAction *action,
1905 ModestWindow *window)
1907 GtkWidget *focused_widget;
1909 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1910 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
1911 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
1912 } else if (GTK_IS_LABEL (focused_widget)) {
1913 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1914 } else if (GTK_IS_EDITABLE (focused_widget)) {
1915 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1916 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1917 GtkTextBuffer *buffer;
1918 GtkTextIter start, end;
1920 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1921 gtk_text_buffer_get_start_iter (buffer, &start);
1922 gtk_text_buffer_get_end_iter (buffer, &end);
1923 gtk_text_buffer_select_range (buffer, &start, &end);
1928 modest_ui_actions_on_mark_as_read (GtkAction *action,
1929 ModestWindow *window)
1931 g_return_if_fail (MODEST_IS_WINDOW(window));
1933 /* Mark each header as read */
1934 do_headers_action (window, headers_action_mark_as_read, NULL);
1938 modest_ui_actions_on_mark_as_unread (GtkAction *action,
1939 ModestWindow *window)
1941 g_return_if_fail (MODEST_IS_WINDOW(window));
1943 /* Mark each header as read */
1944 do_headers_action (window, headers_action_mark_as_unread, NULL);
1948 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1949 GtkRadioAction *selected,
1950 ModestWindow *window)
1954 value = gtk_radio_action_get_current_value (selected);
1955 if (MODEST_IS_WINDOW (window)) {
1956 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1960 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1961 GtkRadioAction *selected,
1962 ModestWindow *window)
1964 TnyHeaderFlags flags;
1965 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1967 flags = gtk_radio_action_get_current_value (selected);
1968 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1971 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1972 GtkRadioAction *selected,
1973 ModestWindow *window)
1977 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1979 file_format = gtk_radio_action_get_current_value (selected);
1980 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1985 modest_ui_actions_on_zoom_plus (GtkAction *action,
1986 ModestWindow *window)
1988 g_return_if_fail (MODEST_IS_WINDOW (window));
1990 modest_window_zoom_plus (MODEST_WINDOW (window));
1994 modest_ui_actions_on_zoom_minus (GtkAction *action,
1995 ModestWindow *window)
1997 g_return_if_fail (MODEST_IS_WINDOW (window));
1999 modest_window_zoom_minus (MODEST_WINDOW (window));
2003 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2004 ModestWindow *window)
2006 ModestWindowMgr *mgr;
2007 gboolean fullscreen, active;
2008 g_return_if_fail (MODEST_IS_WINDOW (window));
2010 mgr = modest_runtime_get_window_mgr ();
2012 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2013 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2015 if (active != fullscreen) {
2016 modest_window_mgr_set_fullscreen_mode (mgr, active);
2017 gtk_window_present (GTK_WINDOW (window));
2022 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2023 ModestWindow *window)
2025 ModestWindowMgr *mgr;
2026 gboolean fullscreen;
2028 g_return_if_fail (MODEST_IS_WINDOW (window));
2030 mgr = modest_runtime_get_window_mgr ();
2031 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2032 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2034 gtk_window_present (GTK_WINDOW (window));
2038 * Used by modest_ui_actions_on_details to call do_headers_action
2041 headers_action_show_details (TnyHeader *header,
2042 ModestWindow *window,
2049 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2052 gtk_widget_show_all (dialog);
2053 gtk_dialog_run (GTK_DIALOG (dialog));
2055 gtk_widget_destroy (dialog);
2059 * Show the folder details in a ModestDetailsDialog widget
2062 show_folder_details (TnyFolder *folder,
2068 dialog = modest_details_dialog_new_with_folder (window, folder);
2071 gtk_widget_show_all (dialog);
2072 gtk_dialog_run (GTK_DIALOG (dialog));
2074 gtk_widget_destroy (dialog);
2078 * Show the header details in a ModestDetailsDialog widget
2081 modest_ui_actions_on_details (GtkAction *action,
2084 TnyList * headers_list;
2088 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2091 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2095 headers_list = get_selected_headers (win);
2099 iter = tny_list_create_iterator (headers_list);
2101 header = TNY_HEADER (tny_iterator_get_current (iter));
2102 headers_action_show_details (header, win, NULL);
2103 g_object_unref (header);
2105 g_object_unref (iter);
2107 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2108 GtkWidget *folder_view, *header_view;
2110 /* Check which widget has the focus */
2111 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2112 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2113 if (gtk_widget_is_focus (folder_view)) {
2116 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2118 /* Show only when it's a folder */
2119 if (!folder || !TNY_IS_FOLDER (folder))
2122 show_folder_details (folder, GTK_WINDOW (win));
2125 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2126 MODEST_WIDGET_TYPE_HEADER_VIEW);
2127 /* Show details of each header */
2128 do_headers_action (win, headers_action_show_details, header_view);
2134 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2135 ModestMsgEditWindow *window)
2137 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2139 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2143 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2144 ModestMsgEditWindow *window)
2146 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2148 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2152 modest_ui_actions_toggle_folders_view (GtkAction *action,
2153 ModestMainWindow *main_window)
2157 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2159 conf = modest_runtime_get_conf ();
2161 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2162 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2164 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2168 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2169 ModestWindow *window)
2171 gboolean active, fullscreen = FALSE;
2172 ModestWindowMgr *mgr;
2174 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2176 /* Check if we want to toggle the toolbar vuew in fullscreen
2178 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2179 "ViewShowToolbarFullScreen")) {
2183 /* Toggle toolbar */
2184 mgr = modest_runtime_get_window_mgr ();
2185 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2189 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2190 ModestMsgEditWindow *window)
2192 modest_msg_edit_window_select_font (window);
2196 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2197 const gchar *display_name,
2200 /* Do not change the application name if the widget has not
2201 the focus. This callback could be called even if the folder
2202 view has not the focus, because the handled signal could be
2203 emitted when the folder view is redrawn */
2204 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2206 gtk_window_set_title (window, display_name);
2208 gtk_window_set_title (window, " ");
2213 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2215 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2216 modest_msg_edit_window_select_contacts (window);
2220 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2222 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2223 modest_msg_edit_window_check_names (window);
2228 create_move_to_dialog (ModestWindow *win,
2229 GtkWidget *folder_view,
2230 GtkWidget **tree_view)
2232 GtkWidget *dialog, *scroll;
2234 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2236 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2238 GTK_RESPONSE_ACCEPT,
2240 GTK_RESPONSE_REJECT,
2243 /* Create scrolled window */
2244 scroll = gtk_scrolled_window_new (NULL, NULL);
2245 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2246 GTK_POLICY_AUTOMATIC,
2247 GTK_POLICY_AUTOMATIC);
2249 /* Create folder view */
2250 *tree_view = modest_folder_view_new (NULL);
2251 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2252 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2253 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2255 /* Add scroll to dialog */
2256 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2257 scroll, FALSE, FALSE, 0);
2259 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2265 * Returns TRUE if at least one of the headers of the list belongs to
2266 * a message that has been fully retrieved.
2269 has_retrieved_msgs (TnyList *list)
2272 gboolean found = FALSE;
2274 iter = tny_list_create_iterator (list);
2275 while (tny_iterator_is_done (iter) && !found) {
2277 TnyHeaderFlags flags;
2279 header = TNY_HEADER (tny_iterator_get_current (iter));
2280 flags = tny_header_get_flags (header);
2281 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2285 tny_iterator_next (iter);
2287 g_object_unref (iter);
2293 * Shows a confirmation dialog to the user when we're moving messages
2294 * from a remote server to the local storage. Returns the dialog
2295 * response. If it's other kind of movement the it always returns
2299 msgs_move_to_confirmation (GtkWindow *win,
2300 TnyFolder *dest_folder,
2303 gint response = GTK_RESPONSE_OK;
2305 /* If the destination is a local folder */
2306 if (modest_tny_folder_is_local_folder (dest_folder)) {
2307 TnyFolder *src_folder;
2311 /* Get source folder */
2312 iter = tny_list_create_iterator (headers);
2313 header = TNY_HEADER (tny_iterator_get_current (iter));
2314 src_folder = tny_header_get_folder (header);
2315 g_object_unref (header);
2316 g_object_unref (iter);
2318 /* If the source is a remote folder */
2319 if (!modest_tny_folder_is_local_folder (src_folder)) {
2320 const gchar *message;
2322 if (tny_list_get_length (headers) == 1)
2323 if (has_retrieved_msgs (headers))
2324 message = _("mcen_nc_move_retrieve");
2326 message = _("mcen_nc_move_header");
2328 if (has_retrieved_msgs (headers))
2329 message = _("mcen_nc_move_retrieves");
2331 message = _("mcen_nc_move_headers");
2333 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2334 (const gchar *) message);
2342 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2344 ModestMsgViewWindow *self = NULL;
2345 gboolean found = FALSE;
2347 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2348 self = MODEST_MSG_VIEW_WINDOW (object);
2350 found = modest_msg_view_window_select_first_message (self);
2351 g_return_if_fail (found);
2355 * UI handler for the "Move to" action when invoked from the
2359 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2360 ModestMainWindow *win)
2362 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2364 TnyFolderStore *folder_store;
2365 ModestMailOperation *mail_op = NULL;
2367 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2369 /* Get the folder view */
2370 folder_view = modest_main_window_get_child_widget (win,
2371 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2373 /* Create and run the dialog */
2374 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2375 result = gtk_dialog_run (GTK_DIALOG(dialog));
2376 g_object_ref (tree_view);
2378 /* We do this to save an indentation level ;-) */
2379 if (result != GTK_RESPONSE_ACCEPT)
2382 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2384 if (TNY_IS_ACCOUNT (folder_store))
2387 /* Get folder or messages to transfer */
2388 if (gtk_widget_is_focus (folder_view)) {
2389 TnyFolderStore *src_folder;
2390 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2392 if (TNY_IS_FOLDER (src_folder)) {
2393 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2394 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2397 modest_mail_operation_xfer_folder_async (mail_op,
2398 TNY_FOLDER (src_folder),
2401 g_object_unref (G_OBJECT (mail_op));
2405 g_object_unref (G_OBJECT (src_folder));
2407 GtkWidget *header_view;
2408 header_view = modest_main_window_get_child_widget (win,
2409 MODEST_WIDGET_TYPE_HEADER_VIEW);
2410 if (gtk_widget_is_focus (header_view)) {
2414 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2416 /* Ask for user confirmation */
2417 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2418 TNY_FOLDER (folder_store),
2421 /* Transfer messages */
2422 if (response == GTK_RESPONSE_OK) {
2423 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2424 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2427 modest_mail_operation_xfer_msgs (mail_op,
2429 TNY_FOLDER (folder_store),
2433 g_object_unref (G_OBJECT (mail_op));
2435 g_object_unref (headers);
2438 g_object_unref (folder_store);
2441 gtk_widget_destroy (dialog);
2446 * UI handler for the "Move to" action when invoked from the
2447 * ModestMsgViewWindow
2450 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2451 ModestMsgViewWindow *win)
2453 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2455 ModestMainWindow *main_window;
2459 /* Get the folder view */
2460 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2461 folder_view = modest_main_window_get_child_widget (main_window,
2462 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2464 /* Create and run the dialog */
2465 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2466 result = gtk_dialog_run (GTK_DIALOG(dialog));
2467 g_object_ref (tree_view);
2469 if (result == GTK_RESPONSE_ACCEPT) {
2470 TnyFolderStore *folder_store;
2473 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2475 /* Create header list */
2476 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2477 headers = tny_simple_list_new ();
2478 tny_list_prepend (headers, G_OBJECT (header));
2479 g_object_unref (header);
2481 /* Ask user for confirmation. MSG-NOT404 */
2482 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2483 TNY_FOLDER (folder_store),
2486 /* Transfer current msg */
2487 if (response == GTK_RESPONSE_OK) {
2488 ModestMailOperation *mail_op;
2490 /* Create mail op */
2491 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2492 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2495 /* Transfer messages */
2496 modest_mail_operation_xfer_msgs (mail_op,
2498 TNY_FOLDER (folder_store),
2500 tranasfer_msgs_from_viewer_cb,
2502 g_object_unref (G_OBJECT (mail_op));
2504 g_object_unref (headers);
2505 g_object_unref (folder_store);
2507 gtk_widget_destroy (dialog);
2511 modest_ui_actions_on_move_to (GtkAction *action,
2514 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2515 MODEST_IS_MSG_VIEW_WINDOW (win));
2517 if (MODEST_IS_MAIN_WINDOW (win))
2518 modest_ui_actions_on_main_window_move_to (action,
2519 MODEST_MAIN_WINDOW (win));
2521 modest_ui_actions_on_msg_view_window_move_to (action,
2522 MODEST_MSG_VIEW_WINDOW (win));
2526 * Calls #HeadersFunc for each header already selected in the main
2527 * window or the message currently being shown in the msg view window
2530 do_headers_action (ModestWindow *win,
2534 TnyList *headers_list;
2538 headers_list = get_selected_headers (win);
2542 /* Call the function for each header */
2543 iter = tny_list_create_iterator (headers_list);
2544 while (!tny_iterator_is_done (iter)) {
2547 header = TNY_HEADER (tny_iterator_get_current (iter));
2548 func (header, win, user_data);
2549 g_object_unref (header);
2550 tny_iterator_next (iter);
2552 g_object_unref (iter);
2556 modest_ui_actions_view_attachment (GtkAction *action,
2557 ModestWindow *window)
2559 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2560 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2562 /* not supported window for this action */
2563 g_return_if_reached ();
2568 modest_ui_actions_save_attachments (GtkAction *action,
2569 ModestWindow *window)
2571 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2572 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2574 /* not supported window for this action */
2575 g_return_if_reached ();
2580 modest_ui_actions_remove_attachments (GtkAction *action,
2581 ModestWindow *window)
2583 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2584 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2586 /* not supported window for this action */
2587 g_return_if_reached ();
2592 modest_ui_actions_on_settings (GtkAction *action,
2597 dialog = modest_platform_get_global_settings_dialog ();
2598 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2599 gtk_widget_show (dialog);
2601 gtk_dialog_run (GTK_DIALOG (dialog));
2603 gtk_widget_destroy (dialog);