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>
72 #include <tny-merge-folder.h>
74 typedef struct _GetMsgAsyncHelper {
76 ModestMailOperation *mail_op;
83 typedef enum _ReplyForwardAction {
89 typedef struct _ReplyForwardHelper {
90 guint reply_forward_type;
91 ReplyForwardAction action;
96 * The do_headers_action uses this kind of functions to perform some
97 * action to each member of a list of headers
99 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
102 do_headers_action (ModestWindow *win,
107 static void open_msg_cb (ModestMailOperation *mail_op,
112 static void reply_forward_cb (ModestMailOperation *mail_op,
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);
148 * Gets the list of currently selected messages. If the win is the
149 * main window, then it returns a newly allocated list of the headers
150 * selected in the header view. If win is the msg view window, then
151 * the value returned is a list with just a single header.
153 * The caller of this funcion must free the list.
156 get_selected_headers (ModestWindow *win)
158 if (MODEST_IS_MAIN_WINDOW(win)) {
159 GtkWidget *header_view;
161 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
162 MODEST_WIDGET_TYPE_HEADER_VIEW);
163 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
165 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
166 /* for MsgViewWindows, we simply return a list with one element */
168 TnyList *list = NULL;
170 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
171 if (header != NULL) {
172 list = tny_simple_list_new ();
173 tny_list_prepend (list, G_OBJECT(header));
174 g_object_unref (G_OBJECT(header));
184 headers_action_mark_as_read (TnyHeader *header,
188 TnyHeaderFlags flags;
190 g_return_if_fail (TNY_IS_HEADER(header));
192 flags = tny_header_get_flags (header);
193 if (flags & TNY_HEADER_FLAG_SEEN) return;
194 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
198 headers_action_mark_as_unread (TnyHeader *header,
202 TnyHeaderFlags flags;
204 g_return_if_fail (TNY_IS_HEADER(header));
206 flags = tny_header_get_flags (header);
207 if (flags & TNY_HEADER_FLAG_SEEN) {
208 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
214 headers_action_delete (TnyHeader *header,
218 ModestMailOperation *mail_op = NULL;
220 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
221 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
224 /* Always delete. TODO: Move to trash still not supported */
225 modest_mail_operation_remove_msg (mail_op, header, FALSE);
226 g_object_unref (G_OBJECT (mail_op));
230 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
232 TnyList *header_list = NULL;
233 TnyIterator *iter = NULL;
234 TnyHeader *header = NULL;
235 gchar *message = NULL;
239 g_return_if_fail (MODEST_IS_WINDOW(win));
241 header_list = get_selected_headers (win);
242 if (!header_list) return;
245 if (tny_list_get_length(header_list) > 1)
246 message = g_strdup(_("emev_nc_delete_messages"));
248 iter = tny_list_create_iterator (header_list);
249 header = TNY_HEADER (tny_iterator_get_current (iter));
250 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
251 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
254 /* Confirmation dialog */
255 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
259 if (response == GTK_RESPONSE_OK) {
260 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
262 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
266 /* Remove each header */
267 do_headers_action (win, headers_action_delete, NULL);
269 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
270 gtk_widget_destroy (GTK_WIDGET(win));
277 g_object_unref (header_list);
278 g_object_unref (iter);
283 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
285 #ifdef MODEST_PLATFORM_MAEMO
286 modest_osso_save_state();
287 #endif /* MODEST_PLATFORM_MAEMO */
293 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
295 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
296 gtk_widget_destroy (GTK_WIDGET (win));
297 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
299 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
300 } else if (MODEST_IS_WINDOW (win)) {
301 gtk_widget_destroy (GTK_WIDGET (win));
303 g_return_if_reached ();
308 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
310 GtkClipboard *clipboard = NULL;
311 gchar *selection = NULL;
313 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
314 selection = gtk_clipboard_wait_for_text (clipboard);
316 modest_address_book_add_address (selection);
321 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
323 /* This is currently only implemented for Maemo,
324 * because it requires a providers preset file which is not publically available.
326 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
327 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
328 TRUE /* enabled accounts only */);
329 gboolean accounts_exist = account_names != NULL;
330 g_slist_free (account_names);
332 if (!accounts_exist) {
333 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
334 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
335 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
336 gtk_dialog_run (GTK_DIALOG (wizard));
337 gtk_widget_destroy (GTK_WIDGET (wizard));
339 /* Show the list of accounts: */
340 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
341 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
342 gtk_dialog_run (account_win);
343 gtk_widget_destroy (GTK_WIDGET(account_win));
346 GtkWidget *dialog, *label;
348 /* Create the widgets */
350 dialog = gtk_dialog_new_with_buttons ("Message",
352 GTK_DIALOG_DESTROY_WITH_PARENT,
356 label = gtk_label_new ("Hello World!");
358 /* Ensure that the dialog box is destroyed when the user responds. */
360 g_signal_connect_swapped (dialog, "response",
361 G_CALLBACK (gtk_widget_destroy),
364 /* Add the label, and show everything we've added to the dialog. */
366 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
368 gtk_widget_show_all (dialog);
369 #endif /* MODEST_PLATFORM_MAEMO */
373 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
375 ModestWindow *main_window = MODEST_WINDOW (user_data);
377 /* Save any changes. */
378 modest_connection_specific_smtp_window_save_server_accounts (
379 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
380 modest_window_get_active_account (main_window));
381 gtk_widget_destroy (GTK_WIDGET (window));
385 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
387 /* This is currently only implemented for Maemo,
388 * because it requires an API (libconic) to detect different connection
391 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
393 /* Create the window if necessary: */
394 const gchar *active_account_name = modest_window_get_active_account (win);
396 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
397 * or show the default account?
398 * If we show the default account then the account name should be shown in
399 * the window when we show it. */
400 if (!active_account_name) {
401 g_warning ("%s: No account is active.", __FUNCTION__);
405 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
406 modest_connection_specific_smtp_window_fill_with_connections (
407 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
408 modest_runtime_get_account_mgr(),
409 active_account_name);
411 /* Show the window: */
412 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
413 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
414 gtk_widget_show (specific_window);
416 /* Save changes when the window is hidden: */
417 g_signal_connect (specific_window, "hide",
418 G_CALLBACK (on_smtp_servers_window_hide), win);
419 #endif /* MODEST_PLATFORM_MAEMO */
423 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
425 ModestWindow *msg_win;
427 TnyFolder *folder = NULL;
428 gchar *account_name = NULL;
429 gchar *from_str = NULL;
430 /* GError *err = NULL; */
431 TnyAccount *account = NULL;
432 ModestWindowMgr *mgr;
433 gchar *signature = NULL;
435 account_name = g_strdup(modest_window_get_active_account (win));
437 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
439 g_printerr ("modest: no account found\n");
443 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
445 TNY_ACCOUNT_TYPE_STORE);
447 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
451 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
453 g_printerr ("modest: failed get from string for '%s'\n", account_name);
457 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
458 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
459 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
460 MODEST_ACCOUNT_SIGNATURE, FALSE);
462 signature = g_strdup ("");
465 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
467 g_printerr ("modest: failed to create new msg\n");
471 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
473 g_printerr ("modest: failed to find Drafts folder\n");
477 /* tny_folder_add_msg (folder, msg, &err); */
479 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
481 /* g_error_free (err); */
485 /* Create and register edit window */
486 /* This is destroyed by TOOD. */
487 msg_win = modest_msg_edit_window_new (msg, account_name);
488 mgr = modest_runtime_get_window_mgr ();
489 modest_window_mgr_register_window (mgr, msg_win);
492 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
494 gtk_widget_show_all (GTK_WIDGET (msg_win));
497 g_free (account_name);
501 g_object_unref (G_OBJECT(account));
503 g_object_unref (G_OBJECT(msg));
505 g_object_unref (G_OBJECT(folder));
509 open_msg_cb (ModestMailOperation *mail_op,
514 ModestWindowMgr *mgr = NULL;
515 ModestWindow *parent_win = NULL;
516 ModestWindow *win = NULL;
517 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
518 gchar *account = NULL;
521 /* TODO: Show an error? (review the specs) */
525 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
526 folder = tny_header_get_folder (header);
528 /* Mark header as read */
529 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
532 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
534 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
536 /* Gets folder type (OUTBOX headers will be opened in edit window */
537 if (modest_tny_folder_is_local_folder (folder))
538 folder_type = modest_tny_folder_get_local_folder_type (folder);
540 /* If the header is in the drafts folder then open the editor,
541 else the message view window */
542 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
543 win = modest_msg_edit_window_new (msg, account);
545 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
546 GtkWidget *header_view;
547 GtkTreeSelection *sel;
548 GList *sel_list = NULL;
551 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
552 MODEST_WIDGET_TYPE_HEADER_VIEW);
554 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
555 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
557 if (sel_list != NULL) {
558 GtkTreeRowReference *row_reference;
560 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
561 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
562 g_list_free (sel_list);
564 win = modest_msg_view_window_new_with_header_model (msg,
568 gtk_tree_row_reference_free (row_reference);
570 win = modest_msg_view_window_new (msg, account);
573 win = modest_msg_view_window_new (msg, account);
577 /* Register and show new window */
579 mgr = modest_runtime_get_window_mgr ();
580 modest_window_mgr_register_window (mgr, win);
581 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
582 gtk_widget_show_all (GTK_WIDGET(win));
587 g_object_unref (msg);
588 g_object_unref (folder);
589 g_object_unref (header);
593 * This function is used by both modest_ui_actions_on_open and
594 * modest_ui_actions_on_header_activated. This way we always do the
595 * same when trying to open messages.
598 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
600 ModestWindowMgr *mgr;
602 ModestMailOperation *mail_op;
604 /* Look if we already have a message view for each header. If
605 true, then remove the header from the list of headers to
607 mgr = modest_runtime_get_window_mgr ();
608 iter = tny_list_create_iterator (headers);
609 while (!tny_iterator_is_done (iter)) {
610 ModestWindow *window;
613 header = TNY_HEADER (tny_iterator_get_current (iter));
614 window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
616 tny_list_remove (headers, G_OBJECT (header));
618 g_object_unref (header);
619 tny_iterator_next (iter);
622 /* Open each message */
623 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT (win));
624 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
625 modest_mail_operation_get_msgs_full (mail_op,
632 g_object_unref(mail_op);
636 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
641 headers = get_selected_headers (win);
646 _modest_ui_actions_open (headers, win);
648 g_object_unref(headers);
653 free_reply_forward_helper (gpointer data)
655 ReplyForwardHelper *helper;
657 helper = (ReplyForwardHelper *) data;
658 g_free (helper->account_name);
659 g_slice_free (ReplyForwardHelper, helper);
663 reply_forward_cb (ModestMailOperation *mail_op,
669 ReplyForwardHelper *rf_helper;
670 ModestWindow *msg_win;
671 ModestEditType edit_type;
674 TnyFolder *folder = NULL;
675 TnyAccount *account = NULL;
676 ModestWindowMgr *mgr;
677 gchar *signature = NULL;
679 g_return_if_fail (user_data != NULL);
680 rf_helper = (ReplyForwardHelper *) user_data;
682 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
683 rf_helper->account_name);
684 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
685 rf_helper->account_name,
686 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
687 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
688 rf_helper->account_name,
689 MODEST_ACCOUNT_SIGNATURE, FALSE);
692 /* Create reply mail */
693 switch (rf_helper->action) {
696 modest_tny_msg_create_reply_msg (msg, from, signature,
697 rf_helper->reply_forward_type,
698 MODEST_TNY_MSG_REPLY_MODE_SENDER);
700 case ACTION_REPLY_TO_ALL:
702 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
703 MODEST_TNY_MSG_REPLY_MODE_ALL);
704 edit_type = MODEST_EDIT_TYPE_REPLY;
708 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
709 edit_type = MODEST_EDIT_TYPE_FORWARD;
712 g_return_if_reached ();
719 g_printerr ("modest: failed to create message\n");
723 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
724 rf_helper->account_name,
725 TNY_ACCOUNT_TYPE_STORE);
727 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
731 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
733 g_printerr ("modest: failed to find Drafts folder\n");
737 tny_folder_add_msg (folder, msg, &err);
739 g_printerr ("modest: error adding msg to Drafts folder: %s",
745 /* Create and register the windows */
746 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
747 mgr = modest_runtime_get_window_mgr ();
748 modest_window_mgr_register_window (mgr, msg_win);
750 /* Show edit window */
751 gtk_widget_show_all (GTK_WIDGET (msg_win));
755 g_object_unref (G_OBJECT (new_msg));
757 g_object_unref (G_OBJECT (folder));
759 g_object_unref (G_OBJECT (account));
760 g_object_unref (msg);
761 g_object_unref (header);
765 * Checks a list of headers. If any of them are not currently
766 * downloaded (CACHED) then it asks the user for permission to
769 * Returns FALSE if the user does not want to download the
770 * messages. Returns TRUE if the user allowed the download or if all
771 * of them are currently downloaded
774 download_uncached_messages (TnyList *header_list, GtkWindow *win)
777 gboolean found, retval;
779 iter = tny_list_create_iterator (header_list);
781 while (!tny_iterator_is_done (iter) && !found) {
783 TnyHeaderFlags flags;
785 header = TNY_HEADER (tny_iterator_get_current (iter));
786 flags = tny_header_get_flags (header);
787 found = !(flags & TNY_HEADER_FLAG_CACHED);
788 g_object_unref (header);
789 tny_iterator_next (iter);
791 g_object_unref (iter);
793 /* Ask for user permission to download the messages */
796 GtkResponseType response;
798 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
799 _("mcen_nc_get_multi_msg_txt"));
800 if (response == GTK_RESPONSE_CANCEL)
808 * Common code for the reply and forward actions
811 reply_forward (ReplyForwardAction action, ModestWindow *win)
813 ModestMailOperation *mail_op = NULL;
814 TnyList *header_list = NULL;
815 ReplyForwardHelper *rf_helper = NULL;
816 guint reply_forward_type;
817 gboolean continue_download;
819 g_return_if_fail (MODEST_IS_WINDOW(win));
821 header_list = get_selected_headers (win);
825 /* Check that the messages have been previously downloaded */
826 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
827 if (!continue_download) {
828 g_object_unref (header_list);
833 modest_conf_get_int (modest_runtime_get_conf (),
834 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
836 /* We assume that we can only select messages of the
837 same folder and that we reply all of them from the
838 same account. In fact the interface currently only
839 allows single selection */
842 rf_helper = g_slice_new0 (ReplyForwardHelper);
843 rf_helper->reply_forward_type = reply_forward_type;
844 rf_helper->action = action;
845 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
846 if (!rf_helper->account_name)
847 rf_helper->account_name =
848 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
850 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
853 /* Get header and message. Do not free them here, the
854 reply_forward_cb must do it */
855 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
856 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
857 if (!msg || !header) {
859 g_object_unref (msg);
861 g_object_unref (header);
862 g_printerr ("modest: no message found\n");
865 reply_forward_cb (NULL, header, msg, rf_helper);
867 /* Retrieve messages */
868 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
869 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
870 modest_mail_operation_get_msgs_full (mail_op,
874 free_reply_forward_helper);
877 g_object_unref(mail_op);
881 g_object_unref (header_list);
885 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
887 g_return_if_fail (MODEST_IS_WINDOW(win));
889 reply_forward (ACTION_REPLY, win);
893 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
895 g_return_if_fail (MODEST_IS_WINDOW(win));
897 reply_forward (ACTION_FORWARD, win);
901 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
903 g_return_if_fail (MODEST_IS_WINDOW(win));
905 reply_forward (ACTION_REPLY_TO_ALL, win);
909 modest_ui_actions_on_next (GtkAction *action,
910 ModestWindow *window)
912 if (MODEST_IS_MAIN_WINDOW (window)) {
913 GtkWidget *header_view;
915 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
916 MODEST_WIDGET_TYPE_HEADER_VIEW);
920 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
921 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
922 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
924 g_return_if_reached ();
929 modest_ui_actions_on_prev (GtkAction *action,
930 ModestWindow *window)
932 g_return_if_fail (MODEST_IS_WINDOW(window));
934 if (MODEST_IS_MAIN_WINDOW (window)) {
935 GtkWidget *header_view;
936 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
937 MODEST_WIDGET_TYPE_HEADER_VIEW);
941 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
942 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
943 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
945 g_return_if_reached ();
950 modest_ui_actions_on_sort (GtkAction *action,
951 ModestWindow *window)
953 g_return_if_fail (MODEST_IS_WINDOW(window));
955 if (MODEST_IS_MAIN_WINDOW (window)) {
956 GtkWidget *header_view;
957 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
958 MODEST_WIDGET_TYPE_HEADER_VIEW);
962 /* Show sorting dialog */
963 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
967 /** Check that an appropriate connection is open.
969 gboolean check_for_connection (const gchar *account_name)
971 TnyDevice *device = modest_runtime_get_device ();
974 g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
976 TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
979 if (tny_device_is_online (device))
982 modest_platform_connect_and_wait (NULL);
984 /* TODO: Wait until a result. */
990 * This function performs the send & receive required actions. The
991 * window it's used to create the mail operation. Tipically it should
992 * be allways the main window, but we pass it as argument in order to
996 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
998 gchar *acc_name = NULL;
1000 /* If no account name was provided get the current account, if
1001 there is none either then pick the default one */
1002 if (!account_name) {
1003 acc_name = g_strdup (modest_window_get_active_account(win));
1005 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1007 g_printerr ("modest: cannot get default account\n");
1011 acc_name = g_strdup (account_name);
1014 /* Send & receive. */
1016 /* Do not continue if no suitable connection
1018 if (!check_for_connection (acc_name)) {
1023 /* TODO: Do not continue if an operation is already in progress:
1024 * Maybe there are some operations that tinymail allows to
1025 * happen simulatenously.
1026 * TODO: Maybe a simple global gboolean is_updating is enough?
1030 /* As per the UI spec,
1031 * for POP accounts, we should receive,
1032 * for IMAP we should synchronize everything, including receiving,
1033 * for SMTP we should send,
1034 * first receiving, then sending:
1036 /* Create the mail operation */
1037 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1038 ModestMailOperation *mail_op;
1039 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1040 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1041 modest_mail_operation_update_account (mail_op, acc_name);
1042 g_object_unref (G_OBJECT (mail_op));
1049 * Refreshes all accounts. This function will be used by automatic
1053 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1055 GSList *account_names, *iter;
1057 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1060 iter = account_names;
1062 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1063 iter = g_slist_next (iter);
1066 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1067 g_slist_free (account_names);
1071 * Handler of the click on Send&Receive button in the main toolbar
1074 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1076 /* Check that at least one account exists: */
1077 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1078 TRUE /* enabled accounts only */);
1079 gboolean accounts_exist = account_names != NULL;
1080 g_slist_free (account_names);
1082 /* If not, allow the user to create an account before trying to send/receive. */
1083 if (!accounts_exist)
1084 modest_ui_actions_on_accounts (NULL, win);
1086 /* Refresh the active account */
1087 modest_ui_actions_do_send_receive (NULL, win);
1092 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1095 GtkWidget *header_view;
1097 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1099 header_view = modest_main_window_get_child_widget (main_window,
1100 MODEST_WIDGET_TYPE_HEADER_VIEW);
1104 conf = modest_runtime_get_conf ();
1106 /* what is saved/restored is depending on the style; thus; we save with
1107 * old style, then update the style, and restore for this new style
1109 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1111 if (modest_header_view_get_style
1112 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1113 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1114 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1116 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1117 MODEST_HEADER_VIEW_STYLE_DETAILS);
1119 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1120 MODEST_CONF_HEADER_VIEW_KEY);
1125 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1127 ModestMainWindow *main_window)
1129 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1131 /* If no header has been selected then exit */
1135 /* Update Main window title */
1136 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1137 const gchar *subject = tny_header_get_subject (header);
1138 if (subject && strcmp (subject, ""))
1139 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1141 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1146 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1148 ModestMainWindow *main_window)
1152 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1157 headers = tny_simple_list_new ();
1158 tny_list_prepend (headers, G_OBJECT (header));
1160 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1162 g_object_unref (headers);
1166 set_active_account_from_tny_account (TnyAccount *account,
1167 ModestWindow *window)
1169 const gchar *server_acc_name = tny_account_get_id (account);
1171 /* We need the TnyAccount provided by the
1172 account store because that is the one that
1173 knows the name of the Modest account */
1174 TnyAccount *modest_server_account = modest_server_account =
1175 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1178 const gchar *modest_acc_name =
1179 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1180 modest_window_set_active_account (window, modest_acc_name);
1181 g_object_unref (modest_server_account);
1185 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1186 TnyFolderStore *folder_store,
1188 ModestMainWindow *main_window)
1191 GtkWidget *header_view;
1193 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1195 header_view = modest_main_window_get_child_widget(main_window,
1196 MODEST_WIDGET_TYPE_HEADER_VIEW);
1200 conf = modest_runtime_get_conf ();
1202 if (TNY_IS_ACCOUNT (folder_store)) {
1203 /* Update active account */
1204 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1205 /* Show account details */
1206 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1207 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1208 printf ("DEBUG: %s: folder store.\n", __FUNCTION__);
1209 //TODO: Set the virtual folder store as the "active account" somehow:
1210 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1212 if (TNY_IS_FOLDER (folder_store) && selected) {
1214 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1215 /* Update the active account */
1216 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1217 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1218 g_object_unref (account);
1221 /* Set folder on header view */
1222 modest_main_window_set_contents_style (main_window,
1223 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1224 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1225 TNY_FOLDER (folder_store));
1226 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1227 MODEST_CONF_HEADER_VIEW_KEY);
1229 /* Update the active account */
1230 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1231 /* Do not show folder */
1232 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1233 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1239 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1246 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1248 if (g_main_depth > 0)
1249 gdk_threads_enter ();
1250 online = tny_device_is_online (modest_runtime_get_device());
1253 /* already online -- the item is simply not there... */
1254 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1256 GTK_MESSAGE_WARNING,
1258 _("The %s you selected cannot be found"),
1260 gtk_dialog_run (GTK_DIALOG(dialog));
1262 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1266 GTK_RESPONSE_REJECT,
1268 GTK_RESPONSE_ACCEPT,
1270 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1271 "Do you want to get online?"), item);
1272 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1273 gtk_label_new (txt), FALSE, FALSE, 0);
1274 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1277 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1278 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1279 // modest_platform_connect_and_wait ();;
1282 gtk_widget_destroy (dialog);
1283 if (g_main_depth > 0)
1284 gdk_threads_leave ();
1288 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1291 /* g_message ("%s %s", __FUNCTION__, link); */
1296 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1299 modest_platform_activate_uri (link);
1303 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1306 modest_platform_show_uri_popup (link);
1310 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1313 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1317 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1318 const gchar *address,
1321 /* g_message ("%s %s", __FUNCTION__, address); */
1325 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1327 TnyTransportAccount *transport_account;
1328 ModestMailOperation *mail_operation;
1330 gchar *account_name, *from;
1331 ModestAccountMgr *account_mgr;
1333 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1335 data = modest_msg_edit_window_get_msg_data (edit_window);
1337 account_mgr = modest_runtime_get_account_mgr();
1338 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1340 account_name = modest_account_mgr_get_default_account (account_mgr);
1341 if (!account_name) {
1342 g_printerr ("modest: no account found\n");
1343 modest_msg_edit_window_free_msg_data (edit_window, data);
1347 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1348 (modest_runtime_get_account_store(),
1350 TNY_ACCOUNT_TYPE_TRANSPORT));
1351 if (!transport_account) {
1352 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1353 g_free (account_name);
1354 modest_msg_edit_window_free_msg_data (edit_window, data);
1357 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1359 /* Create the mail operation */
1360 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1361 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1363 modest_mail_operation_save_to_drafts (mail_operation,
1373 data->priority_flags);
1376 g_free (account_name);
1377 g_object_unref (G_OBJECT (transport_account));
1378 g_object_unref (G_OBJECT (mail_operation));
1380 modest_msg_edit_window_free_msg_data (edit_window, data);
1382 /* Save settings and close the window */
1383 gtk_widget_destroy (GTK_WIDGET (edit_window));
1386 /* For instance, when clicking the Send toolbar button when editing a message: */
1388 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1390 TnyTransportAccount *transport_account;
1391 ModestMailOperation *mail_operation;
1393 gchar *account_name, *from;
1394 ModestAccountMgr *account_mgr;
1396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1398 if (!modest_msg_edit_window_check_names (edit_window))
1401 data = modest_msg_edit_window_get_msg_data (edit_window);
1403 /* FIXME: Code added just for testing. The final version will
1404 use the send queue provided by tinymail and some
1406 account_mgr = modest_runtime_get_account_mgr();
1407 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1409 account_name = modest_account_mgr_get_default_account (account_mgr);
1410 if (!account_name) {
1411 g_printerr ("modest: no account found\n");
1412 modest_msg_edit_window_free_msg_data (edit_window, data);
1416 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1417 (modest_runtime_get_account_store(),
1419 if (!transport_account) {
1420 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1421 g_free (account_name);
1422 modest_msg_edit_window_free_msg_data (edit_window, data);
1425 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1427 /* Create the mail operation */
1428 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1429 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1431 modest_mail_operation_send_new_mail (mail_operation,
1441 data->priority_flags);
1444 g_free (account_name);
1445 g_object_unref (G_OBJECT (transport_account));
1446 g_object_unref (G_OBJECT (mail_operation));
1448 modest_msg_edit_window_free_msg_data (edit_window, data);
1450 /* Save settings and close the window */
1451 gtk_widget_destroy (GTK_WIDGET (edit_window));
1455 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1456 ModestMsgEditWindow *window)
1458 ModestMsgEditFormatState *format_state = NULL;
1460 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1461 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1463 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1466 format_state = modest_msg_edit_window_get_format_state (window);
1467 g_return_if_fail (format_state != NULL);
1469 format_state->bold = gtk_toggle_action_get_active (action);
1470 modest_msg_edit_window_set_format_state (window, format_state);
1471 g_free (format_state);
1476 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1477 ModestMsgEditWindow *window)
1479 ModestMsgEditFormatState *format_state = NULL;
1481 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1482 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1484 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1487 format_state = modest_msg_edit_window_get_format_state (window);
1488 g_return_if_fail (format_state != NULL);
1490 format_state->italics = gtk_toggle_action_get_active (action);
1491 modest_msg_edit_window_set_format_state (window, format_state);
1492 g_free (format_state);
1497 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1498 ModestMsgEditWindow *window)
1500 ModestMsgEditFormatState *format_state = NULL;
1502 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1503 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1505 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1508 format_state = modest_msg_edit_window_get_format_state (window);
1509 g_return_if_fail (format_state != NULL);
1511 format_state->bullet = gtk_toggle_action_get_active (action);
1512 modest_msg_edit_window_set_format_state (window, format_state);
1513 g_free (format_state);
1518 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1519 GtkRadioAction *selected,
1520 ModestMsgEditWindow *window)
1522 ModestMsgEditFormatState *format_state = NULL;
1523 GtkJustification value;
1525 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1527 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1530 value = gtk_radio_action_get_current_value (selected);
1532 format_state = modest_msg_edit_window_get_format_state (window);
1533 g_return_if_fail (format_state != NULL);
1535 format_state->justification = value;
1536 modest_msg_edit_window_set_format_state (window, format_state);
1537 g_free (format_state);
1541 modest_ui_actions_on_select_editor_color (GtkAction *action,
1542 ModestMsgEditWindow *window)
1544 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1545 g_return_if_fail (GTK_IS_ACTION (action));
1547 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1550 modest_msg_edit_window_select_color (window);
1554 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1555 ModestMsgEditWindow *window)
1557 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1558 g_return_if_fail (GTK_IS_ACTION (action));
1560 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1563 modest_msg_edit_window_select_background_color (window);
1567 modest_ui_actions_on_insert_image (GtkAction *action,
1568 ModestMsgEditWindow *window)
1570 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1571 g_return_if_fail (GTK_IS_ACTION (action));
1573 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1576 modest_msg_edit_window_insert_image (window);
1580 modest_ui_actions_on_attach_file (GtkAction *action,
1581 ModestMsgEditWindow *window)
1583 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1584 g_return_if_fail (GTK_IS_ACTION (action));
1586 modest_msg_edit_window_attach_file (window);
1590 modest_ui_actions_on_remove_attachments (GtkAction *action,
1591 ModestMsgEditWindow *window)
1593 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1594 g_return_if_fail (GTK_IS_ACTION (action));
1596 modest_msg_edit_window_remove_attachments (window, NULL);
1600 * Shows a dialog with an entry that asks for some text. The returned
1601 * value must be freed by the caller. The dialog window title will be
1605 ask_for_folder_name (GtkWindow *parent_window,
1608 GtkWidget *dialog, *entry;
1609 gchar *folder_name = NULL;
1611 /* Ask for folder name */
1612 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1616 GTK_RESPONSE_REJECT,
1618 GTK_RESPONSE_ACCEPT,
1620 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1621 gtk_label_new(title),
1624 entry = gtk_entry_new_with_max_length (40);
1625 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1629 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1631 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1632 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1634 gtk_widget_destroy (dialog);
1640 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1642 TnyFolderStore *parent_folder;
1643 GtkWidget *folder_view;
1645 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1647 folder_view = modest_main_window_get_child_widget (main_window,
1648 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1652 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1654 if (parent_folder) {
1655 gboolean finished = FALSE;
1657 gchar *folder_name = NULL, *suggested_name = NULL;
1659 /* Run the new folder dialog */
1661 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1666 if (result == GTK_RESPONSE_REJECT) {
1669 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1670 TnyFolder *new_folder = NULL;
1672 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1675 new_folder = modest_mail_operation_create_folder (mail_op,
1677 (const gchar *) folder_name);
1679 g_object_unref (new_folder);
1683 /* /\* TODO: check error and follow proper actions *\/ */
1684 /* /\* suggested_name = X; *\/ */
1685 /* /\* Show error to the user *\/ */
1686 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1687 /* _("mail_in_ui_folder_create_error")); */
1689 g_object_unref (mail_op);
1691 g_free (folder_name);
1695 g_object_unref (parent_folder);
1700 modest_ui_actions_on_rename_folder (GtkAction *action,
1701 ModestMainWindow *main_window)
1703 TnyFolderStore *folder;
1704 GtkWidget *folder_view;
1705 GtkWidget *header_view;
1707 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1709 folder_view = modest_main_window_get_child_widget (main_window,
1710 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1714 header_view = modest_main_window_get_child_widget (main_window,
1715 MODEST_WIDGET_TYPE_HEADER_VIEW);
1720 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1722 if (folder && TNY_IS_FOLDER (folder)) {
1724 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1725 _("Please enter a new name for the folder"));
1727 if (folder_name != NULL && strlen (folder_name) > 0) {
1728 ModestMailOperation *mail_op;
1730 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1731 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1734 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1736 modest_mail_operation_rename_folder (mail_op,
1737 TNY_FOLDER (folder),
1738 (const gchar *) folder_name);
1740 g_object_unref (mail_op);
1741 g_free (folder_name);
1743 g_object_unref (folder);
1748 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1750 TnyFolderStore *folder;
1751 GtkWidget *folder_view;
1755 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1757 folder_view = modest_main_window_get_child_widget (main_window,
1758 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1762 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1764 /* Show an error if it's an account */
1765 if (!TNY_IS_FOLDER (folder)) {
1766 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1767 _("mail_in_ui_folder_delete_error"));
1772 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1773 tny_folder_get_name (TNY_FOLDER (folder)));
1774 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1775 (const gchar *) message);
1778 if (response == GTK_RESPONSE_OK) {
1779 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(main_window));
1781 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1783 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1785 /* Show error if happened */
1786 if (modest_mail_operation_get_error (mail_op))
1787 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1788 _("mail_in_ui_folder_delete_error"));
1790 g_object_unref (G_OBJECT (mail_op));
1793 g_object_unref (G_OBJECT (folder));
1797 modest_ui_actions_on_delete_folder (GtkAction *action,
1798 ModestMainWindow *main_window)
1800 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1802 delete_folder (main_window, FALSE);
1806 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1808 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1810 delete_folder (main_window, TRUE);
1814 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1815 const gchar* server_account_name,
1820 ModestMainWindow *main_window)
1822 g_return_if_fail(server_account_name);
1823 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1825 /* Initalize output parameters: */
1832 #ifdef MODEST_PLATFORM_MAEMO
1833 /* Maemo uses a different (awkward) button order,
1834 * It should probably just use gtk_alternative_dialog_button_order ().
1836 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1840 GTK_RESPONSE_ACCEPT,
1842 GTK_RESPONSE_REJECT,
1845 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1849 GTK_RESPONSE_REJECT,
1851 GTK_RESPONSE_ACCEPT,
1853 #endif /* MODEST_PLATFORM_MAEMO */
1855 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1857 gchar *server_name = modest_server_account_get_hostname (
1858 modest_runtime_get_account_mgr(), server_account_name);
1860 /* This causes a warning because the logical ID has no %s in it,
1861 * though the translation does, but there is not much we can do about that: */
1862 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1863 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1866 g_free (server_name);
1870 gchar *initial_username = modest_server_account_get_username (
1871 modest_runtime_get_account_mgr(), server_account_name);
1873 GtkWidget *entry_username = gtk_entry_new ();
1874 if (initial_username)
1875 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1876 /* Dim this if a connection has ever succeeded with this username,
1877 * as per the UI spec: */
1878 const gboolean username_known =
1879 modest_server_account_get_username_has_succeeded(
1880 modest_runtime_get_account_mgr(), server_account_name);
1881 gtk_widget_set_sensitive (entry_username, !username_known);
1883 #ifdef MODEST_PLATFORM_MAEMO
1884 /* Auto-capitalization is the default, so let's turn it off: */
1885 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1887 /* Create a size group to be used by all captions.
1888 * Note that HildonCaption does not create a default size group if we do not specify one.
1889 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1890 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1892 GtkWidget *caption = hildon_caption_new (sizegroup,
1893 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1894 gtk_widget_show (entry_username);
1895 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1896 FALSE, FALSE, MODEST_MARGIN_HALF);
1897 gtk_widget_show (caption);
1899 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1901 #endif /* MODEST_PLATFORM_MAEMO */
1904 GtkWidget *entry_password = gtk_entry_new ();
1905 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1906 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1908 #ifdef MODEST_PLATFORM_MAEMO
1909 /* Auto-capitalization is the default, so let's turn it off: */
1910 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1911 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1913 caption = hildon_caption_new (sizegroup,
1914 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1915 gtk_widget_show (entry_password);
1916 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1917 FALSE, FALSE, MODEST_MARGIN_HALF);
1918 gtk_widget_show (caption);
1919 g_object_unref (sizegroup);
1921 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1923 #endif /* MODEST_PLATFORM_MAEMO */
1925 /* This is not in the Maemo UI spec:
1926 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1927 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1931 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1933 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1935 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1937 modest_server_account_set_username (
1938 modest_runtime_get_account_mgr(), server_account_name,
1941 const gboolean username_was_changed =
1942 (strcmp (*username, initial_username) != 0);
1943 if (username_was_changed) {
1944 /* To actually use a changed username,
1945 * we must reset the connection, according to pvanhoof.
1946 * This _might_ be a sensible way to do that: */
1947 TnyDevice *device = modest_runtime_get_device();
1948 tny_device_force_offline (device);
1949 tny_device_force_online (device);
1954 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1956 /* We do not save the password in the configuration,
1957 * because this function is only called for passwords that should
1958 * not be remembered:
1959 modest_server_account_set_password (
1960 modest_runtime_get_account_mgr(), server_account_name,
1979 /* This is not in the Maemo UI spec:
1980 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1986 gtk_widget_destroy (dialog);
1988 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
1992 modest_ui_actions_on_cut (GtkAction *action,
1993 ModestWindow *window)
1995 GtkWidget *focused_widget;
1997 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1998 if (GTK_IS_EDITABLE (focused_widget)) {
1999 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2000 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2001 GtkTextBuffer *buffer;
2002 GtkClipboard *clipboard;
2004 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2005 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2006 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2011 modest_ui_actions_on_copy (GtkAction *action,
2012 ModestWindow *window)
2014 GtkClipboard *clipboard;
2015 GtkWidget *focused_widget;
2017 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2018 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2019 if (GTK_IS_LABEL (focused_widget)) {
2020 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2021 } else if (GTK_IS_EDITABLE (focused_widget)) {
2022 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2023 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2024 GtkTextBuffer *buffer;
2026 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2027 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2032 modest_ui_actions_on_undo (GtkAction *action,
2033 ModestWindow *window)
2035 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2036 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2038 g_return_if_reached ();
2043 modest_ui_actions_on_paste (GtkAction *action,
2044 ModestWindow *window)
2046 GtkWidget *focused_widget;
2048 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2049 if (GTK_IS_EDITABLE (focused_widget)) {
2050 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2051 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2052 GtkTextBuffer *buffer;
2053 GtkClipboard *clipboard;
2055 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2056 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2057 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2062 modest_ui_actions_on_select_all (GtkAction *action,
2063 ModestWindow *window)
2065 GtkWidget *focused_widget;
2067 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2068 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2069 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2070 } else if (GTK_IS_LABEL (focused_widget)) {
2071 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2072 } else if (GTK_IS_EDITABLE (focused_widget)) {
2073 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2074 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2075 GtkTextBuffer *buffer;
2076 GtkTextIter start, end;
2078 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2079 gtk_text_buffer_get_start_iter (buffer, &start);
2080 gtk_text_buffer_get_end_iter (buffer, &end);
2081 gtk_text_buffer_select_range (buffer, &start, &end);
2086 modest_ui_actions_on_mark_as_read (GtkAction *action,
2087 ModestWindow *window)
2089 g_return_if_fail (MODEST_IS_WINDOW(window));
2091 /* Mark each header as read */
2092 do_headers_action (window, headers_action_mark_as_read, NULL);
2096 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2097 ModestWindow *window)
2099 g_return_if_fail (MODEST_IS_WINDOW(window));
2101 /* Mark each header as read */
2102 do_headers_action (window, headers_action_mark_as_unread, NULL);
2106 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2107 GtkRadioAction *selected,
2108 ModestWindow *window)
2112 value = gtk_radio_action_get_current_value (selected);
2113 if (MODEST_IS_WINDOW (window)) {
2114 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2118 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2119 GtkRadioAction *selected,
2120 ModestWindow *window)
2122 TnyHeaderFlags flags;
2123 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2125 flags = gtk_radio_action_get_current_value (selected);
2126 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2129 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2130 GtkRadioAction *selected,
2131 ModestWindow *window)
2135 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2137 file_format = gtk_radio_action_get_current_value (selected);
2138 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2143 modest_ui_actions_on_zoom_plus (GtkAction *action,
2144 ModestWindow *window)
2146 g_return_if_fail (MODEST_IS_WINDOW (window));
2148 modest_window_zoom_plus (MODEST_WINDOW (window));
2152 modest_ui_actions_on_zoom_minus (GtkAction *action,
2153 ModestWindow *window)
2155 g_return_if_fail (MODEST_IS_WINDOW (window));
2157 modest_window_zoom_minus (MODEST_WINDOW (window));
2161 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2162 ModestWindow *window)
2164 ModestWindowMgr *mgr;
2165 gboolean fullscreen, active;
2166 g_return_if_fail (MODEST_IS_WINDOW (window));
2168 mgr = modest_runtime_get_window_mgr ();
2170 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2171 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2173 if (active != fullscreen) {
2174 modest_window_mgr_set_fullscreen_mode (mgr, active);
2175 gtk_window_present (GTK_WINDOW (window));
2180 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2181 ModestWindow *window)
2183 ModestWindowMgr *mgr;
2184 gboolean fullscreen;
2186 g_return_if_fail (MODEST_IS_WINDOW (window));
2188 mgr = modest_runtime_get_window_mgr ();
2189 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2190 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2192 gtk_window_present (GTK_WINDOW (window));
2196 * Used by modest_ui_actions_on_details to call do_headers_action
2199 headers_action_show_details (TnyHeader *header,
2200 ModestWindow *window,
2207 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2210 gtk_widget_show_all (dialog);
2211 gtk_dialog_run (GTK_DIALOG (dialog));
2213 gtk_widget_destroy (dialog);
2217 * Show the folder details in a ModestDetailsDialog widget
2220 show_folder_details (TnyFolder *folder,
2226 dialog = modest_details_dialog_new_with_folder (window, folder);
2229 gtk_widget_show_all (dialog);
2230 gtk_dialog_run (GTK_DIALOG (dialog));
2232 gtk_widget_destroy (dialog);
2236 * Show the header details in a ModestDetailsDialog widget
2239 modest_ui_actions_on_details (GtkAction *action,
2242 TnyList * headers_list;
2246 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2249 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2252 g_object_unref (msg);
2254 headers_list = get_selected_headers (win);
2258 iter = tny_list_create_iterator (headers_list);
2260 header = TNY_HEADER (tny_iterator_get_current (iter));
2261 headers_action_show_details (header, win, NULL);
2262 g_object_unref (header);
2264 g_object_unref (iter);
2265 g_object_unref (headers_list);
2267 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2268 GtkWidget *folder_view, *header_view;
2270 /* Check which widget has the focus */
2271 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2272 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2273 if (gtk_widget_is_focus (folder_view)) {
2276 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2278 /* Show only when it's a folder */
2279 if (!folder || !TNY_IS_FOLDER (folder))
2282 show_folder_details (folder, GTK_WINDOW (win));
2285 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2286 MODEST_WIDGET_TYPE_HEADER_VIEW);
2287 /* Show details of each header */
2288 do_headers_action (win, headers_action_show_details, header_view);
2294 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2295 ModestMsgEditWindow *window)
2297 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2299 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2303 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2304 ModestMsgEditWindow *window)
2306 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2308 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2312 modest_ui_actions_toggle_folders_view (GtkAction *action,
2313 ModestMainWindow *main_window)
2317 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2319 conf = modest_runtime_get_conf ();
2321 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2322 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2324 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2328 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2329 ModestWindow *window)
2331 gboolean active, fullscreen = FALSE;
2332 ModestWindowMgr *mgr;
2334 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2336 /* Check if we want to toggle the toolbar vuew in fullscreen
2338 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2339 "ViewShowToolbarFullScreen")) {
2343 /* Toggle toolbar */
2344 mgr = modest_runtime_get_window_mgr ();
2345 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2349 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2350 ModestMsgEditWindow *window)
2352 modest_msg_edit_window_select_font (window);
2356 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2357 const gchar *display_name,
2360 /* Do not change the application name if the widget has not
2361 the focus. This callback could be called even if the folder
2362 view has not the focus, because the handled signal could be
2363 emitted when the folder view is redrawn */
2364 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2366 gtk_window_set_title (window, display_name);
2368 gtk_window_set_title (window, " ");
2373 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2375 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2376 modest_msg_edit_window_select_contacts (window);
2380 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2382 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2383 modest_msg_edit_window_check_names (window);
2388 create_move_to_dialog (ModestWindow *win,
2389 GtkWidget *folder_view,
2390 GtkWidget **tree_view)
2392 GtkWidget *dialog, *scroll;
2394 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2396 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2398 GTK_RESPONSE_ACCEPT,
2400 GTK_RESPONSE_REJECT,
2403 /* Create scrolled window */
2404 scroll = gtk_scrolled_window_new (NULL, NULL);
2405 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2406 GTK_POLICY_AUTOMATIC,
2407 GTK_POLICY_AUTOMATIC);
2409 /* Create folder view */
2410 *tree_view = modest_folder_view_new (NULL);
2411 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2412 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2413 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2415 /* Add scroll to dialog */
2416 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2417 scroll, FALSE, FALSE, 0);
2419 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2425 * Returns TRUE if at least one of the headers of the list belongs to
2426 * a message that has been fully retrieved.
2429 has_retrieved_msgs (TnyList *list)
2432 gboolean found = FALSE;
2434 iter = tny_list_create_iterator (list);
2435 while (tny_iterator_is_done (iter) && !found) {
2437 TnyHeaderFlags flags;
2439 header = TNY_HEADER (tny_iterator_get_current (iter));
2440 flags = tny_header_get_flags (header);
2441 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2445 tny_iterator_next (iter);
2447 g_object_unref (iter);
2453 * Shows a confirmation dialog to the user when we're moving messages
2454 * from a remote server to the local storage. Returns the dialog
2455 * response. If it's other kind of movement the it always returns
2459 msgs_move_to_confirmation (GtkWindow *win,
2460 TnyFolder *dest_folder,
2463 gint response = GTK_RESPONSE_OK;
2465 /* If the destination is a local folder */
2466 if (modest_tny_folder_is_local_folder (dest_folder)) {
2467 TnyFolder *src_folder;
2471 /* Get source folder */
2472 iter = tny_list_create_iterator (headers);
2473 header = TNY_HEADER (tny_iterator_get_current (iter));
2474 src_folder = tny_header_get_folder (header);
2475 g_object_unref (header);
2476 g_object_unref (iter);
2478 /* If the source is a remote folder */
2479 if (!modest_tny_folder_is_local_folder (src_folder)) {
2480 const gchar *message;
2482 if (tny_list_get_length (headers) == 1)
2483 if (has_retrieved_msgs (headers))
2484 message = _("mcen_nc_move_retrieve");
2486 message = _("mcen_nc_move_header");
2488 if (has_retrieved_msgs (headers))
2489 message = _("mcen_nc_move_retrieves");
2491 message = _("mcen_nc_move_headers");
2493 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2494 (const gchar *) message);
2496 g_object_unref (src_folder);
2503 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2505 ModestMsgViewWindow *self = NULL;
2506 gboolean found = FALSE;
2508 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2509 self = MODEST_MSG_VIEW_WINDOW (object);
2511 found = modest_msg_view_window_select_first_message (self);
2512 g_return_if_fail (found);
2516 move_to_error_checking (const GObject *obj, gpointer user_data)
2518 ModestWindow *win = NULL;
2520 g_return_if_fail (MODEST_IS_WINDOW (obj));
2521 win = MODEST_WINDOW (obj);
2523 /* TODO: show error message */
2524 /* modest_platform_run_information_dialog (GTK_WINDOW (win), */
2525 /* _("mail_in_ui_folder_move_target_error")); */
2529 * UI handler for the "Move to" action when invoked from the
2533 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2534 ModestMainWindow *win)
2536 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2537 GtkWidget *header_view = NULL;
2539 TnyFolderStore *folder_store = NULL;
2540 ModestMailOperation *mail_op = NULL;
2542 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2544 /* Get the folder view */
2545 folder_view = modest_main_window_get_child_widget (win,
2546 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2548 /* Get header view */
2549 header_view = modest_main_window_get_child_widget (win,
2550 MODEST_WIDGET_TYPE_HEADER_VIEW);
2552 /* Create and run the dialog */
2553 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2554 result = gtk_dialog_run (GTK_DIALOG(dialog));
2555 g_object_ref (tree_view);
2557 /* We do this to save an indentation level ;-) */
2558 if (result != GTK_RESPONSE_ACCEPT)
2561 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2563 if (TNY_IS_ACCOUNT (folder_store))
2566 /* Get folder or messages to transfer */
2567 if (gtk_widget_is_focus (folder_view)) {
2568 TnyFolderStore *src_folder;
2569 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2571 /* Clean folder on header view before moving it */
2572 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2574 if (TNY_IS_FOLDER (src_folder)) {
2575 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2577 move_to_error_checking);
2578 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2581 modest_mail_operation_xfer_folder (mail_op,
2582 TNY_FOLDER (src_folder),
2585 g_object_unref (G_OBJECT (mail_op));
2590 g_object_unref (G_OBJECT (src_folder));
2592 if (gtk_widget_is_focus (header_view)) {
2596 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2598 /* Ask for user confirmation */
2599 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2600 TNY_FOLDER (folder_store),
2603 /* Transfer messages */
2604 if (response == GTK_RESPONSE_OK) {
2605 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2606 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2609 modest_mail_operation_xfer_msgs (mail_op,
2611 TNY_FOLDER (folder_store),
2615 g_object_unref (G_OBJECT (mail_op));
2617 g_object_unref (headers);
2620 g_object_unref (folder_store);
2623 gtk_widget_destroy (dialog);
2628 * UI handler for the "Move to" action when invoked from the
2629 * ModestMsgViewWindow
2632 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2633 ModestMsgViewWindow *win)
2635 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2637 ModestMainWindow *main_window;
2641 /* Get the folder view */
2642 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2643 folder_view = modest_main_window_get_child_widget (main_window,
2644 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2646 /* Create and run the dialog */
2647 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2648 result = gtk_dialog_run (GTK_DIALOG(dialog));
2649 g_object_ref (tree_view);
2651 if (result == GTK_RESPONSE_ACCEPT) {
2652 TnyFolderStore *folder_store;
2655 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2657 /* Create header list */
2658 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2659 headers = tny_simple_list_new ();
2660 tny_list_prepend (headers, G_OBJECT (header));
2661 g_object_unref (header);
2663 /* Ask user for confirmation. MSG-NOT404 */
2664 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2665 TNY_FOLDER (folder_store),
2668 /* Transfer current msg */
2669 if (response == GTK_RESPONSE_OK) {
2670 ModestMailOperation *mail_op;
2672 /* Create mail op */
2673 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2674 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2677 /* Transfer messages */
2678 modest_mail_operation_xfer_msgs (mail_op,
2680 TNY_FOLDER (folder_store),
2682 tranasfer_msgs_from_viewer_cb,
2684 g_object_unref (G_OBJECT (mail_op));
2686 g_object_unref (headers);
2687 g_object_unref (folder_store);
2689 gtk_widget_destroy (dialog);
2693 modest_ui_actions_on_move_to (GtkAction *action,
2696 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2697 MODEST_IS_MSG_VIEW_WINDOW (win));
2699 if (MODEST_IS_MAIN_WINDOW (win))
2700 modest_ui_actions_on_main_window_move_to (action,
2701 MODEST_MAIN_WINDOW (win));
2703 modest_ui_actions_on_msg_view_window_move_to (action,
2704 MODEST_MSG_VIEW_WINDOW (win));
2708 * Calls #HeadersFunc for each header already selected in the main
2709 * window or the message currently being shown in the msg view window
2712 do_headers_action (ModestWindow *win,
2716 TnyList *headers_list;
2720 headers_list = get_selected_headers (win);
2724 /* Call the function for each header */
2725 iter = tny_list_create_iterator (headers_list);
2726 while (!tny_iterator_is_done (iter)) {
2729 header = TNY_HEADER (tny_iterator_get_current (iter));
2730 func (header, win, user_data);
2731 g_object_unref (header);
2732 tny_iterator_next (iter);
2734 g_object_unref (iter);
2735 g_object_unref (headers_list);
2739 modest_ui_actions_view_attachment (GtkAction *action,
2740 ModestWindow *window)
2742 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2743 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2745 /* not supported window for this action */
2746 g_return_if_reached ();
2751 modest_ui_actions_save_attachments (GtkAction *action,
2752 ModestWindow *window)
2754 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2755 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2757 /* not supported window for this action */
2758 g_return_if_reached ();
2763 modest_ui_actions_remove_attachments (GtkAction *action,
2764 ModestWindow *window)
2766 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2767 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2769 /* not supported window for this action */
2770 g_return_if_reached ();
2775 modest_ui_actions_on_settings (GtkAction *action,
2780 dialog = modest_platform_get_global_settings_dialog ();
2781 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2782 gtk_widget_show (dialog);
2784 gtk_dialog_run (GTK_DIALOG (dialog));
2786 gtk_widget_destroy (dialog);
2790 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2791 ModestWindow *window)
2793 ModestMailOperation *mail_op;
2797 headers = get_selected_headers (window);
2801 /* Create mail operation */
2802 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT (window));
2803 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2804 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2807 g_object_unref (headers);
2808 g_object_unref (mail_op);