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 is used to create the mail operation. Typically it should
992 * always be 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 then get the current account, and if
1001 there is no current account 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,
1032 * - for POP accounts, we should receive,
1033 * - for IMAP we should synchronize everything, including receiving,
1035 * - for SMTP we should send.
1036 * First receiving (store), then sending (transport):
1038 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1040 /* Receive and then send:
1041 * TODO: This API is strange: We create a receive operation, which is then converted to
1042 * a send operation. But we don't even seem to monitor the operation, so we maybe don't
1043 * even need to create it here.
1044 * Also, do we use the window parameter at all?
1046 ModestMailOperation *mail_op;
1047 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1048 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1049 modest_mail_operation_update_account (mail_op, acc_name);
1050 g_object_unref (G_OBJECT (mail_op));
1057 * Refreshes all accounts. This function will be used by automatic
1061 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1063 GSList *account_names, *iter;
1065 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1068 iter = account_names;
1070 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1071 iter = g_slist_next (iter);
1074 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1075 g_slist_free (account_names);
1079 * Handler of the click on Send&Receive button in the main toolbar
1082 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1084 /* Check that at least one account exists: */
1085 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1086 TRUE /* enabled accounts only */);
1087 gboolean accounts_exist = account_names != NULL;
1088 g_slist_free (account_names);
1090 /* If not, allow the user to create an account before trying to send/receive. */
1091 if (!accounts_exist)
1092 modest_ui_actions_on_accounts (NULL, win);
1094 /* Refresh the active account */
1095 modest_ui_actions_do_send_receive (NULL, win);
1100 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1103 GtkWidget *header_view;
1105 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1107 header_view = modest_main_window_get_child_widget (main_window,
1108 MODEST_WIDGET_TYPE_HEADER_VIEW);
1112 conf = modest_runtime_get_conf ();
1114 /* what is saved/restored is depending on the style; thus; we save with
1115 * old style, then update the style, and restore for this new style
1117 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1119 if (modest_header_view_get_style
1120 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1121 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1122 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1124 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1125 MODEST_HEADER_VIEW_STYLE_DETAILS);
1127 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1128 MODEST_CONF_HEADER_VIEW_KEY);
1133 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1135 ModestMainWindow *main_window)
1137 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1139 /* If no header has been selected then exit */
1143 /* Update Main window title */
1144 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1145 const gchar *subject = tny_header_get_subject (header);
1146 if (subject && strcmp (subject, ""))
1147 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1149 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1154 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1156 ModestMainWindow *main_window)
1160 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1165 headers = tny_simple_list_new ();
1166 tny_list_prepend (headers, G_OBJECT (header));
1168 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1170 g_object_unref (headers);
1174 set_active_account_from_tny_account (TnyAccount *account,
1175 ModestWindow *window)
1177 const gchar *server_acc_name = tny_account_get_id (account);
1179 /* We need the TnyAccount provided by the
1180 account store because that is the one that
1181 knows the name of the Modest account */
1182 TnyAccount *modest_server_account = modest_server_account =
1183 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1186 const gchar *modest_acc_name =
1187 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1188 modest_window_set_active_account (window, modest_acc_name);
1189 g_object_unref (modest_server_account);
1193 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1194 TnyFolderStore *folder_store,
1196 ModestMainWindow *main_window)
1199 GtkWidget *header_view;
1201 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1203 header_view = modest_main_window_get_child_widget(main_window,
1204 MODEST_WIDGET_TYPE_HEADER_VIEW);
1208 conf = modest_runtime_get_conf ();
1210 if (TNY_IS_ACCOUNT (folder_store)) {
1211 /* Update active account */
1212 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1213 /* Show account details */
1214 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1215 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1216 printf ("DEBUG: %s: folder store.\n", __FUNCTION__);
1217 //TODO: Set the virtual folder store as the "active account" somehow:
1218 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1220 if (TNY_IS_FOLDER (folder_store) && selected) {
1222 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1223 /* Update the active account */
1224 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1225 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1226 g_object_unref (account);
1229 /* Set folder on header view */
1230 modest_main_window_set_contents_style (main_window,
1231 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1232 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1233 TNY_FOLDER (folder_store));
1234 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1235 MODEST_CONF_HEADER_VIEW_KEY);
1237 /* Update the active account */
1238 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1239 /* Do not show folder */
1240 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1241 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1247 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1254 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1256 if (g_main_depth > 0)
1257 gdk_threads_enter ();
1258 online = tny_device_is_online (modest_runtime_get_device());
1261 /* already online -- the item is simply not there... */
1262 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1264 GTK_MESSAGE_WARNING,
1266 _("The %s you selected cannot be found"),
1268 gtk_dialog_run (GTK_DIALOG(dialog));
1270 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1274 GTK_RESPONSE_REJECT,
1276 GTK_RESPONSE_ACCEPT,
1278 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1279 "Do you want to get online?"), item);
1280 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1281 gtk_label_new (txt), FALSE, FALSE, 0);
1282 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1285 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1286 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1287 // modest_platform_connect_and_wait ();;
1290 gtk_widget_destroy (dialog);
1291 if (g_main_depth > 0)
1292 gdk_threads_leave ();
1296 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1299 /* g_message ("%s %s", __FUNCTION__, link); */
1304 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1307 modest_platform_activate_uri (link);
1311 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1314 modest_platform_show_uri_popup (link);
1318 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1321 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1325 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1326 const gchar *address,
1329 /* g_message ("%s %s", __FUNCTION__, address); */
1333 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1335 TnyTransportAccount *transport_account;
1336 ModestMailOperation *mail_operation;
1338 gchar *account_name, *from;
1339 ModestAccountMgr *account_mgr;
1341 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1343 data = modest_msg_edit_window_get_msg_data (edit_window);
1345 account_mgr = modest_runtime_get_account_mgr();
1346 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1348 account_name = modest_account_mgr_get_default_account (account_mgr);
1349 if (!account_name) {
1350 g_printerr ("modest: no account found\n");
1351 modest_msg_edit_window_free_msg_data (edit_window, data);
1355 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1356 (modest_runtime_get_account_store(),
1358 TNY_ACCOUNT_TYPE_TRANSPORT));
1359 if (!transport_account) {
1360 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1361 g_free (account_name);
1362 modest_msg_edit_window_free_msg_data (edit_window, data);
1365 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1367 /* Create the mail operation */
1368 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1369 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1371 modest_mail_operation_save_to_drafts (mail_operation,
1381 data->priority_flags);
1384 g_free (account_name);
1385 g_object_unref (G_OBJECT (transport_account));
1386 g_object_unref (G_OBJECT (mail_operation));
1388 modest_msg_edit_window_free_msg_data (edit_window, data);
1390 /* Save settings and close the window */
1391 gtk_widget_destroy (GTK_WIDGET (edit_window));
1394 /* For instance, when clicking the Send toolbar button when editing a message: */
1396 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1398 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1400 if (!modest_msg_edit_window_check_names (edit_window))
1403 /* FIXME: Code added just for testing. The final version will
1404 use the send queue provided by tinymail and some
1406 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1407 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1409 account_name = modest_account_mgr_get_default_account (account_mgr);
1411 if (!account_name) {
1412 g_printerr ("modest: no account found\n");
1416 /* Get the currently-active transport account for this modest account: */
1417 TnyTransportAccount *transport_account =
1418 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1419 (modest_runtime_get_account_store(),
1421 if (!transport_account) {
1422 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1423 g_free (account_name);
1427 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1429 /* Create the mail operation */
1430 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1431 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1433 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1434 modest_mail_operation_send_new_mail (mail_operation,
1444 data->priority_flags);
1448 g_free (account_name);
1449 g_object_unref (G_OBJECT (transport_account));
1450 g_object_unref (G_OBJECT (mail_operation));
1452 modest_msg_edit_window_free_msg_data (edit_window, data);
1454 /* Save settings and close the window: */
1455 gtk_widget_destroy (GTK_WIDGET (edit_window));
1459 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1460 ModestMsgEditWindow *window)
1462 ModestMsgEditFormatState *format_state = NULL;
1464 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1465 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1467 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1470 format_state = modest_msg_edit_window_get_format_state (window);
1471 g_return_if_fail (format_state != NULL);
1473 format_state->bold = gtk_toggle_action_get_active (action);
1474 modest_msg_edit_window_set_format_state (window, format_state);
1475 g_free (format_state);
1480 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1481 ModestMsgEditWindow *window)
1483 ModestMsgEditFormatState *format_state = NULL;
1485 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1486 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1488 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1491 format_state = modest_msg_edit_window_get_format_state (window);
1492 g_return_if_fail (format_state != NULL);
1494 format_state->italics = gtk_toggle_action_get_active (action);
1495 modest_msg_edit_window_set_format_state (window, format_state);
1496 g_free (format_state);
1501 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1502 ModestMsgEditWindow *window)
1504 ModestMsgEditFormatState *format_state = NULL;
1506 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1507 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1509 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1512 format_state = modest_msg_edit_window_get_format_state (window);
1513 g_return_if_fail (format_state != NULL);
1515 format_state->bullet = gtk_toggle_action_get_active (action);
1516 modest_msg_edit_window_set_format_state (window, format_state);
1517 g_free (format_state);
1522 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1523 GtkRadioAction *selected,
1524 ModestMsgEditWindow *window)
1526 ModestMsgEditFormatState *format_state = NULL;
1527 GtkJustification value;
1529 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1531 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1534 value = gtk_radio_action_get_current_value (selected);
1536 format_state = modest_msg_edit_window_get_format_state (window);
1537 g_return_if_fail (format_state != NULL);
1539 format_state->justification = value;
1540 modest_msg_edit_window_set_format_state (window, format_state);
1541 g_free (format_state);
1545 modest_ui_actions_on_select_editor_color (GtkAction *action,
1546 ModestMsgEditWindow *window)
1548 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1549 g_return_if_fail (GTK_IS_ACTION (action));
1551 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1554 modest_msg_edit_window_select_color (window);
1558 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1559 ModestMsgEditWindow *window)
1561 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1562 g_return_if_fail (GTK_IS_ACTION (action));
1564 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1567 modest_msg_edit_window_select_background_color (window);
1571 modest_ui_actions_on_insert_image (GtkAction *action,
1572 ModestMsgEditWindow *window)
1574 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1575 g_return_if_fail (GTK_IS_ACTION (action));
1577 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1580 modest_msg_edit_window_insert_image (window);
1584 modest_ui_actions_on_attach_file (GtkAction *action,
1585 ModestMsgEditWindow *window)
1587 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1588 g_return_if_fail (GTK_IS_ACTION (action));
1590 modest_msg_edit_window_attach_file (window);
1594 modest_ui_actions_on_remove_attachments (GtkAction *action,
1595 ModestMsgEditWindow *window)
1597 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1598 g_return_if_fail (GTK_IS_ACTION (action));
1600 modest_msg_edit_window_remove_attachments (window, NULL);
1604 * Shows a dialog with an entry that asks for some text. The returned
1605 * value must be freed by the caller. The dialog window title will be
1609 ask_for_folder_name (GtkWindow *parent_window,
1612 GtkWidget *dialog, *entry;
1613 gchar *folder_name = NULL;
1615 /* Ask for folder name */
1616 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1620 GTK_RESPONSE_REJECT,
1622 GTK_RESPONSE_ACCEPT,
1624 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1625 gtk_label_new(title),
1628 entry = gtk_entry_new_with_max_length (40);
1629 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1633 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1635 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1636 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1638 gtk_widget_destroy (dialog);
1644 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1646 TnyFolderStore *parent_folder;
1647 GtkWidget *folder_view;
1649 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1651 folder_view = modest_main_window_get_child_widget (main_window,
1652 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1656 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1658 if (parent_folder) {
1659 gboolean finished = FALSE;
1661 gchar *folder_name = NULL, *suggested_name = NULL;
1663 /* Run the new folder dialog */
1665 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1670 if (result == GTK_RESPONSE_REJECT) {
1673 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1674 TnyFolder *new_folder = NULL;
1676 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1679 new_folder = modest_mail_operation_create_folder (mail_op,
1681 (const gchar *) folder_name);
1683 g_object_unref (new_folder);
1687 /* /\* TODO: check error and follow proper actions *\/ */
1688 /* /\* suggested_name = X; *\/ */
1689 /* /\* Show error to the user *\/ */
1690 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1691 /* _("mail_in_ui_folder_create_error")); */
1693 g_object_unref (mail_op);
1695 g_free (folder_name);
1699 g_object_unref (parent_folder);
1704 modest_ui_actions_on_rename_folder (GtkAction *action,
1705 ModestMainWindow *main_window)
1707 TnyFolderStore *folder;
1708 GtkWidget *folder_view;
1709 GtkWidget *header_view;
1711 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1713 folder_view = modest_main_window_get_child_widget (main_window,
1714 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1718 header_view = modest_main_window_get_child_widget (main_window,
1719 MODEST_WIDGET_TYPE_HEADER_VIEW);
1724 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1726 if (folder && TNY_IS_FOLDER (folder)) {
1728 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1729 _("Please enter a new name for the folder"));
1731 if (folder_name != NULL && strlen (folder_name) > 0) {
1732 ModestMailOperation *mail_op;
1734 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1735 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1738 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1740 modest_mail_operation_rename_folder (mail_op,
1741 TNY_FOLDER (folder),
1742 (const gchar *) folder_name);
1744 g_object_unref (mail_op);
1745 g_free (folder_name);
1747 g_object_unref (folder);
1752 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1754 TnyFolderStore *folder;
1755 GtkWidget *folder_view;
1759 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1761 folder_view = modest_main_window_get_child_widget (main_window,
1762 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1766 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1768 /* Show an error if it's an account */
1769 if (!TNY_IS_FOLDER (folder)) {
1770 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1771 _("mail_in_ui_folder_delete_error"));
1776 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1777 tny_folder_get_name (TNY_FOLDER (folder)));
1778 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1779 (const gchar *) message);
1782 if (response == GTK_RESPONSE_OK) {
1783 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(main_window));
1785 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1787 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1789 /* Show error if happened */
1790 if (modest_mail_operation_get_error (mail_op))
1791 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1792 _("mail_in_ui_folder_delete_error"));
1794 g_object_unref (G_OBJECT (mail_op));
1797 g_object_unref (G_OBJECT (folder));
1801 modest_ui_actions_on_delete_folder (GtkAction *action,
1802 ModestMainWindow *main_window)
1804 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1806 delete_folder (main_window, FALSE);
1810 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1812 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1814 delete_folder (main_window, TRUE);
1818 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1819 const gchar* server_account_name,
1824 ModestMainWindow *main_window)
1826 g_return_if_fail(server_account_name);
1827 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1829 /* Initalize output parameters: */
1836 #ifdef MODEST_PLATFORM_MAEMO
1837 /* Maemo uses a different (awkward) button order,
1838 * It should probably just use gtk_alternative_dialog_button_order ().
1840 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1844 GTK_RESPONSE_ACCEPT,
1846 GTK_RESPONSE_REJECT,
1849 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1853 GTK_RESPONSE_REJECT,
1855 GTK_RESPONSE_ACCEPT,
1857 #endif /* MODEST_PLATFORM_MAEMO */
1859 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1861 gchar *server_name = modest_server_account_get_hostname (
1862 modest_runtime_get_account_mgr(), server_account_name);
1864 /* This causes a warning because the logical ID has no %s in it,
1865 * though the translation does, but there is not much we can do about that: */
1866 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1867 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1870 g_free (server_name);
1874 gchar *initial_username = modest_server_account_get_username (
1875 modest_runtime_get_account_mgr(), server_account_name);
1877 GtkWidget *entry_username = gtk_entry_new ();
1878 if (initial_username)
1879 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1880 /* Dim this if a connection has ever succeeded with this username,
1881 * as per the UI spec: */
1882 const gboolean username_known =
1883 modest_server_account_get_username_has_succeeded(
1884 modest_runtime_get_account_mgr(), server_account_name);
1885 gtk_widget_set_sensitive (entry_username, !username_known);
1887 #ifdef MODEST_PLATFORM_MAEMO
1888 /* Auto-capitalization is the default, so let's turn it off: */
1889 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1891 /* Create a size group to be used by all captions.
1892 * Note that HildonCaption does not create a default size group if we do not specify one.
1893 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1894 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1896 GtkWidget *caption = hildon_caption_new (sizegroup,
1897 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1898 gtk_widget_show (entry_username);
1899 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1900 FALSE, FALSE, MODEST_MARGIN_HALF);
1901 gtk_widget_show (caption);
1903 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1905 #endif /* MODEST_PLATFORM_MAEMO */
1908 GtkWidget *entry_password = gtk_entry_new ();
1909 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1910 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1912 #ifdef MODEST_PLATFORM_MAEMO
1913 /* Auto-capitalization is the default, so let's turn it off: */
1914 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1915 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1917 caption = hildon_caption_new (sizegroup,
1918 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1919 gtk_widget_show (entry_password);
1920 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1921 FALSE, FALSE, MODEST_MARGIN_HALF);
1922 gtk_widget_show (caption);
1923 g_object_unref (sizegroup);
1925 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1927 #endif /* MODEST_PLATFORM_MAEMO */
1929 /* This is not in the Maemo UI spec:
1930 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1931 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1935 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1937 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1939 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1941 modest_server_account_set_username (
1942 modest_runtime_get_account_mgr(), server_account_name,
1945 const gboolean username_was_changed =
1946 (strcmp (*username, initial_username) != 0);
1947 if (username_was_changed) {
1948 /* To actually use a changed username,
1949 * we must reset the connection, according to pvanhoof.
1950 * This _might_ be a sensible way to do that: */
1951 TnyDevice *device = modest_runtime_get_device();
1952 tny_device_force_offline (device);
1953 tny_device_force_online (device);
1958 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
1960 /* We do not save the password in the configuration,
1961 * because this function is only called for passwords that should
1962 * not be remembered:
1963 modest_server_account_set_password (
1964 modest_runtime_get_account_mgr(), server_account_name,
1983 /* This is not in the Maemo UI spec:
1984 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1990 gtk_widget_destroy (dialog);
1992 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
1996 modest_ui_actions_on_cut (GtkAction *action,
1997 ModestWindow *window)
1999 GtkWidget *focused_widget;
2001 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2002 if (GTK_IS_EDITABLE (focused_widget)) {
2003 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2004 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2005 GtkTextBuffer *buffer;
2006 GtkClipboard *clipboard;
2008 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2009 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2010 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2015 modest_ui_actions_on_copy (GtkAction *action,
2016 ModestWindow *window)
2018 GtkClipboard *clipboard;
2019 GtkWidget *focused_widget;
2021 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2022 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2023 if (GTK_IS_LABEL (focused_widget)) {
2024 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2025 } else if (GTK_IS_EDITABLE (focused_widget)) {
2026 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2027 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2028 GtkTextBuffer *buffer;
2030 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2031 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2036 modest_ui_actions_on_undo (GtkAction *action,
2037 ModestWindow *window)
2039 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2040 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2042 g_return_if_reached ();
2047 modest_ui_actions_on_paste (GtkAction *action,
2048 ModestWindow *window)
2050 GtkWidget *focused_widget;
2052 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2053 if (GTK_IS_EDITABLE (focused_widget)) {
2054 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2055 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2056 GtkTextBuffer *buffer;
2057 GtkClipboard *clipboard;
2059 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2060 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2061 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2066 modest_ui_actions_on_select_all (GtkAction *action,
2067 ModestWindow *window)
2069 GtkWidget *focused_widget;
2071 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2072 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2073 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2074 } else if (GTK_IS_LABEL (focused_widget)) {
2075 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2076 } else if (GTK_IS_EDITABLE (focused_widget)) {
2077 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2078 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2079 GtkTextBuffer *buffer;
2080 GtkTextIter start, end;
2082 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2083 gtk_text_buffer_get_start_iter (buffer, &start);
2084 gtk_text_buffer_get_end_iter (buffer, &end);
2085 gtk_text_buffer_select_range (buffer, &start, &end);
2090 modest_ui_actions_on_mark_as_read (GtkAction *action,
2091 ModestWindow *window)
2093 g_return_if_fail (MODEST_IS_WINDOW(window));
2095 /* Mark each header as read */
2096 do_headers_action (window, headers_action_mark_as_read, NULL);
2100 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2101 ModestWindow *window)
2103 g_return_if_fail (MODEST_IS_WINDOW(window));
2105 /* Mark each header as read */
2106 do_headers_action (window, headers_action_mark_as_unread, NULL);
2110 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2111 GtkRadioAction *selected,
2112 ModestWindow *window)
2116 value = gtk_radio_action_get_current_value (selected);
2117 if (MODEST_IS_WINDOW (window)) {
2118 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2122 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2123 GtkRadioAction *selected,
2124 ModestWindow *window)
2126 TnyHeaderFlags flags;
2127 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2129 flags = gtk_radio_action_get_current_value (selected);
2130 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2133 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2134 GtkRadioAction *selected,
2135 ModestWindow *window)
2139 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2141 file_format = gtk_radio_action_get_current_value (selected);
2142 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2147 modest_ui_actions_on_zoom_plus (GtkAction *action,
2148 ModestWindow *window)
2150 g_return_if_fail (MODEST_IS_WINDOW (window));
2152 modest_window_zoom_plus (MODEST_WINDOW (window));
2156 modest_ui_actions_on_zoom_minus (GtkAction *action,
2157 ModestWindow *window)
2159 g_return_if_fail (MODEST_IS_WINDOW (window));
2161 modest_window_zoom_minus (MODEST_WINDOW (window));
2165 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2166 ModestWindow *window)
2168 ModestWindowMgr *mgr;
2169 gboolean fullscreen, active;
2170 g_return_if_fail (MODEST_IS_WINDOW (window));
2172 mgr = modest_runtime_get_window_mgr ();
2174 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2175 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2177 if (active != fullscreen) {
2178 modest_window_mgr_set_fullscreen_mode (mgr, active);
2179 gtk_window_present (GTK_WINDOW (window));
2184 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2185 ModestWindow *window)
2187 ModestWindowMgr *mgr;
2188 gboolean fullscreen;
2190 g_return_if_fail (MODEST_IS_WINDOW (window));
2192 mgr = modest_runtime_get_window_mgr ();
2193 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2194 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2196 gtk_window_present (GTK_WINDOW (window));
2200 * Used by modest_ui_actions_on_details to call do_headers_action
2203 headers_action_show_details (TnyHeader *header,
2204 ModestWindow *window,
2211 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2214 gtk_widget_show_all (dialog);
2215 gtk_dialog_run (GTK_DIALOG (dialog));
2217 gtk_widget_destroy (dialog);
2221 * Show the folder details in a ModestDetailsDialog widget
2224 show_folder_details (TnyFolder *folder,
2230 dialog = modest_details_dialog_new_with_folder (window, folder);
2233 gtk_widget_show_all (dialog);
2234 gtk_dialog_run (GTK_DIALOG (dialog));
2236 gtk_widget_destroy (dialog);
2240 * Show the header details in a ModestDetailsDialog widget
2243 modest_ui_actions_on_details (GtkAction *action,
2246 TnyList * headers_list;
2250 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2253 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2256 g_object_unref (msg);
2258 headers_list = get_selected_headers (win);
2262 iter = tny_list_create_iterator (headers_list);
2264 header = TNY_HEADER (tny_iterator_get_current (iter));
2265 headers_action_show_details (header, win, NULL);
2266 g_object_unref (header);
2268 g_object_unref (iter);
2269 g_object_unref (headers_list);
2271 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2272 GtkWidget *folder_view, *header_view;
2274 /* Check which widget has the focus */
2275 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2276 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2277 if (gtk_widget_is_focus (folder_view)) {
2280 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2282 /* Show only when it's a folder */
2283 if (!folder || !TNY_IS_FOLDER (folder))
2286 show_folder_details (folder, GTK_WINDOW (win));
2289 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2290 MODEST_WIDGET_TYPE_HEADER_VIEW);
2291 /* Show details of each header */
2292 do_headers_action (win, headers_action_show_details, header_view);
2298 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2299 ModestMsgEditWindow *window)
2301 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2303 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2307 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2308 ModestMsgEditWindow *window)
2310 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2312 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2316 modest_ui_actions_toggle_folders_view (GtkAction *action,
2317 ModestMainWindow *main_window)
2321 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2323 conf = modest_runtime_get_conf ();
2325 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2326 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2328 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2332 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2333 ModestWindow *window)
2335 gboolean active, fullscreen = FALSE;
2336 ModestWindowMgr *mgr;
2338 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2340 /* Check if we want to toggle the toolbar vuew in fullscreen
2342 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2343 "ViewShowToolbarFullScreen")) {
2347 /* Toggle toolbar */
2348 mgr = modest_runtime_get_window_mgr ();
2349 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2353 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2354 ModestMsgEditWindow *window)
2356 modest_msg_edit_window_select_font (window);
2360 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2361 const gchar *display_name,
2364 /* Do not change the application name if the widget has not
2365 the focus. This callback could be called even if the folder
2366 view has not the focus, because the handled signal could be
2367 emitted when the folder view is redrawn */
2368 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2370 gtk_window_set_title (window, display_name);
2372 gtk_window_set_title (window, " ");
2377 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2379 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2380 modest_msg_edit_window_select_contacts (window);
2384 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2387 modest_msg_edit_window_check_names (window);
2392 create_move_to_dialog (ModestWindow *win,
2393 GtkWidget *folder_view,
2394 GtkWidget **tree_view)
2396 GtkWidget *dialog, *scroll;
2398 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2400 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2402 GTK_RESPONSE_ACCEPT,
2404 GTK_RESPONSE_REJECT,
2407 /* Create scrolled window */
2408 scroll = gtk_scrolled_window_new (NULL, NULL);
2409 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2410 GTK_POLICY_AUTOMATIC,
2411 GTK_POLICY_AUTOMATIC);
2413 /* Create folder view */
2414 *tree_view = modest_folder_view_new (NULL);
2415 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2416 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2417 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2419 /* Add scroll to dialog */
2420 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2421 scroll, FALSE, FALSE, 0);
2423 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2429 * Returns TRUE if at least one of the headers of the list belongs to
2430 * a message that has been fully retrieved.
2433 has_retrieved_msgs (TnyList *list)
2436 gboolean found = FALSE;
2438 iter = tny_list_create_iterator (list);
2439 while (tny_iterator_is_done (iter) && !found) {
2441 TnyHeaderFlags flags;
2443 header = TNY_HEADER (tny_iterator_get_current (iter));
2444 flags = tny_header_get_flags (header);
2445 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2449 tny_iterator_next (iter);
2451 g_object_unref (iter);
2457 * Shows a confirmation dialog to the user when we're moving messages
2458 * from a remote server to the local storage. Returns the dialog
2459 * response. If it's other kind of movement the it always returns
2463 msgs_move_to_confirmation (GtkWindow *win,
2464 TnyFolder *dest_folder,
2467 gint response = GTK_RESPONSE_OK;
2469 /* If the destination is a local folder */
2470 if (modest_tny_folder_is_local_folder (dest_folder)) {
2471 TnyFolder *src_folder;
2475 /* Get source folder */
2476 iter = tny_list_create_iterator (headers);
2477 header = TNY_HEADER (tny_iterator_get_current (iter));
2478 src_folder = tny_header_get_folder (header);
2479 g_object_unref (header);
2480 g_object_unref (iter);
2482 /* If the source is a remote folder */
2483 if (!modest_tny_folder_is_local_folder (src_folder)) {
2484 const gchar *message;
2486 if (tny_list_get_length (headers) == 1)
2487 if (has_retrieved_msgs (headers))
2488 message = _("mcen_nc_move_retrieve");
2490 message = _("mcen_nc_move_header");
2492 if (has_retrieved_msgs (headers))
2493 message = _("mcen_nc_move_retrieves");
2495 message = _("mcen_nc_move_headers");
2497 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2498 (const gchar *) message);
2500 g_object_unref (src_folder);
2507 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2509 ModestMsgViewWindow *self = NULL;
2510 gboolean found = FALSE;
2512 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2513 self = MODEST_MSG_VIEW_WINDOW (object);
2515 found = modest_msg_view_window_select_first_message (self);
2516 g_return_if_fail (found);
2520 move_to_error_checking (const GObject *obj, gpointer user_data)
2522 ModestWindow *win = NULL;
2524 g_return_if_fail (MODEST_IS_WINDOW (obj));
2525 win = MODEST_WINDOW (obj);
2527 /* TODO: show error message */
2528 /* modest_platform_run_information_dialog (GTK_WINDOW (win), */
2529 /* _("mail_in_ui_folder_move_target_error")); */
2533 * UI handler for the "Move to" action when invoked from the
2537 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2538 ModestMainWindow *win)
2540 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2541 GtkWidget *header_view = NULL;
2543 TnyFolderStore *folder_store = NULL;
2544 ModestMailOperation *mail_op = NULL;
2546 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2548 /* Get the folder view */
2549 folder_view = modest_main_window_get_child_widget (win,
2550 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2552 /* Get header view */
2553 header_view = modest_main_window_get_child_widget (win,
2554 MODEST_WIDGET_TYPE_HEADER_VIEW);
2556 /* Create and run the dialog */
2557 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2558 result = gtk_dialog_run (GTK_DIALOG(dialog));
2559 g_object_ref (tree_view);
2561 /* We do this to save an indentation level ;-) */
2562 if (result != GTK_RESPONSE_ACCEPT)
2565 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2567 if (TNY_IS_ACCOUNT (folder_store))
2570 /* Get folder or messages to transfer */
2571 if (gtk_widget_is_focus (folder_view)) {
2572 TnyFolderStore *src_folder;
2573 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2575 /* Clean folder on header view before moving it */
2576 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2578 if (TNY_IS_FOLDER (src_folder)) {
2579 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2581 move_to_error_checking);
2582 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2585 modest_mail_operation_xfer_folder (mail_op,
2586 TNY_FOLDER (src_folder),
2589 g_object_unref (G_OBJECT (mail_op));
2594 g_object_unref (G_OBJECT (src_folder));
2596 if (gtk_widget_is_focus (header_view)) {
2600 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2602 /* Ask for user confirmation */
2603 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2604 TNY_FOLDER (folder_store),
2607 /* Transfer messages */
2608 if (response == GTK_RESPONSE_OK) {
2609 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2610 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2613 modest_mail_operation_xfer_msgs (mail_op,
2615 TNY_FOLDER (folder_store),
2619 g_object_unref (G_OBJECT (mail_op));
2621 g_object_unref (headers);
2624 g_object_unref (folder_store);
2627 gtk_widget_destroy (dialog);
2632 * UI handler for the "Move to" action when invoked from the
2633 * ModestMsgViewWindow
2636 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2637 ModestMsgViewWindow *win)
2639 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2641 ModestMainWindow *main_window;
2645 /* Get the folder view */
2646 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2647 folder_view = modest_main_window_get_child_widget (main_window,
2648 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2650 /* Create and run the dialog */
2651 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2652 result = gtk_dialog_run (GTK_DIALOG(dialog));
2653 g_object_ref (tree_view);
2655 if (result == GTK_RESPONSE_ACCEPT) {
2656 TnyFolderStore *folder_store;
2659 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2661 /* Create header list */
2662 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2663 headers = tny_simple_list_new ();
2664 tny_list_prepend (headers, G_OBJECT (header));
2665 g_object_unref (header);
2667 /* Ask user for confirmation. MSG-NOT404 */
2668 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2669 TNY_FOLDER (folder_store),
2672 /* Transfer current msg */
2673 if (response == GTK_RESPONSE_OK) {
2674 ModestMailOperation *mail_op;
2676 /* Create mail op */
2677 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2678 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2681 /* Transfer messages */
2682 modest_mail_operation_xfer_msgs (mail_op,
2684 TNY_FOLDER (folder_store),
2686 tranasfer_msgs_from_viewer_cb,
2688 g_object_unref (G_OBJECT (mail_op));
2690 g_object_unref (headers);
2691 g_object_unref (folder_store);
2693 gtk_widget_destroy (dialog);
2697 modest_ui_actions_on_move_to (GtkAction *action,
2700 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2701 MODEST_IS_MSG_VIEW_WINDOW (win));
2703 if (MODEST_IS_MAIN_WINDOW (win))
2704 modest_ui_actions_on_main_window_move_to (action,
2705 MODEST_MAIN_WINDOW (win));
2707 modest_ui_actions_on_msg_view_window_move_to (action,
2708 MODEST_MSG_VIEW_WINDOW (win));
2712 * Calls #HeadersFunc for each header already selected in the main
2713 * window or the message currently being shown in the msg view window
2716 do_headers_action (ModestWindow *win,
2720 TnyList *headers_list;
2724 headers_list = get_selected_headers (win);
2728 /* Call the function for each header */
2729 iter = tny_list_create_iterator (headers_list);
2730 while (!tny_iterator_is_done (iter)) {
2733 header = TNY_HEADER (tny_iterator_get_current (iter));
2734 func (header, win, user_data);
2735 g_object_unref (header);
2736 tny_iterator_next (iter);
2738 g_object_unref (iter);
2739 g_object_unref (headers_list);
2743 modest_ui_actions_view_attachment (GtkAction *action,
2744 ModestWindow *window)
2746 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2747 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2749 /* not supported window for this action */
2750 g_return_if_reached ();
2755 modest_ui_actions_save_attachments (GtkAction *action,
2756 ModestWindow *window)
2758 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2759 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2761 /* not supported window for this action */
2762 g_return_if_reached ();
2767 modest_ui_actions_remove_attachments (GtkAction *action,
2768 ModestWindow *window)
2770 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2771 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2773 /* not supported window for this action */
2774 g_return_if_reached ();
2779 modest_ui_actions_on_settings (GtkAction *action,
2784 dialog = modest_platform_get_global_settings_dialog ();
2785 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2786 gtk_widget_show (dialog);
2788 gtk_dialog_run (GTK_DIALOG (dialog));
2790 gtk_widget_destroy (dialog);
2794 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2795 ModestWindow *window)
2797 ModestMailOperation *mail_op;
2801 headers = get_selected_headers (window);
2805 /* Create mail operation */
2806 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT (window));
2807 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2808 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2811 g_object_unref (headers);
2812 g_object_unref (mail_op);