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>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
49 #ifdef MODEST_PLATFORM_MAEMO
50 #include "maemo/modest-osso-state-saving.h"
51 #endif /* MODEST_PLATFORM_MAEMO */
53 #include "widgets/modest-ui-constants.h"
54 #include <widgets/modest-main-window.h>
55 #include <widgets/modest-msg-view-window.h>
56 #include <widgets/modest-account-view-window.h>
57 #include <widgets/modest-details-dialog.h>
58 #include <widgets/modest-attachments-view.h>
59 #include "widgets/modest-folder-view.h"
60 #include "widgets/modest-global-settings-dialog.h"
61 #include "modest-connection-specific-smtp-window.h"
62 #include "modest-account-mgr-helpers.h"
63 #include "modest-mail-operation.h"
64 #include "modest-text-utils.h"
66 #ifdef MODEST_HAVE_EASYSETUP
67 #include "easysetup/modest-easysetup-wizard.h"
68 #endif /* MODEST_HAVE_EASYSETUP */
70 #include <modest-widget-memory.h>
71 #include <tny-error.h>
72 #include <tny-simple-list.h>
73 #include <tny-msg-view.h>
74 #include <tny-device.h>
75 #include <tny-merge-folder.h>
77 #include <gtkhtml/gtkhtml.h>
79 typedef struct _GetMsgAsyncHelper {
81 ModestMailOperation *mail_op;
88 typedef enum _ReplyForwardAction {
94 typedef struct _ReplyForwardHelper {
95 guint reply_forward_type;
96 ReplyForwardAction action;
98 GtkWidget *parent_window;
103 * The do_headers_action uses this kind of functions to perform some
104 * action to each member of a list of headers
106 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
108 static void do_headers_action (ModestWindow *win,
112 static void open_msg_cb (ModestMailOperation *mail_op,
117 static void reply_forward_cb (ModestMailOperation *mail_op,
122 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
125 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
126 ModestMailOperationState *state,
132 run_account_setup_wizard (ModestWindow *win)
134 ModestEasysetupWizardDialog *wizard;
136 g_return_if_fail (MODEST_IS_WINDOW(win));
138 wizard = modest_easysetup_wizard_dialog_new ();
139 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
140 gtk_dialog_run (GTK_DIALOG (wizard));
141 gtk_widget_destroy (GTK_WIDGET (wizard));
146 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
149 const gchar *authors[] = {
150 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
153 about = gtk_about_dialog_new ();
154 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
155 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
156 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
157 _("Copyright (c) 2006, Nokia Corporation\n"
158 "All rights reserved."));
159 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
160 _("a modest e-mail client\n\n"
161 "design and implementation: Dirk-Jan C. Binnema\n"
162 "contributions from the fine people at KC and Ig\n"
163 "uses the tinymail email framework written by Philip van Hoof"));
164 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
165 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
167 gtk_dialog_run (GTK_DIALOG (about));
168 gtk_widget_destroy(about);
172 * Gets the list of currently selected messages. If the win is the
173 * main window, then it returns a newly allocated list of the headers
174 * selected in the header view. If win is the msg view window, then
175 * the value returned is a list with just a single header.
177 * The caller of this funcion must free the list.
180 get_selected_headers (ModestWindow *win)
182 if (MODEST_IS_MAIN_WINDOW(win)) {
183 GtkWidget *header_view;
185 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
186 MODEST_WIDGET_TYPE_HEADER_VIEW);
187 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
189 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
190 /* for MsgViewWindows, we simply return a list with one element */
192 TnyList *list = NULL;
194 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
195 if (header != NULL) {
196 list = tny_simple_list_new ();
197 tny_list_prepend (list, G_OBJECT(header));
198 g_object_unref (G_OBJECT(header));
208 headers_action_mark_as_read (TnyHeader *header,
212 TnyHeaderFlags flags;
214 g_return_if_fail (TNY_IS_HEADER(header));
216 flags = tny_header_get_flags (header);
217 if (flags & TNY_HEADER_FLAG_SEEN) return;
218 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
222 headers_action_mark_as_unread (TnyHeader *header,
226 TnyHeaderFlags flags;
228 g_return_if_fail (TNY_IS_HEADER(header));
230 flags = tny_header_get_flags (header);
231 if (flags & TNY_HEADER_FLAG_SEEN) {
232 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
238 headers_action_delete (TnyHeader *header,
242 ModestMailOperation *mail_op = NULL;
244 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
245 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
248 /* Always delete. TODO: Move to trash still not supported */
249 modest_mail_operation_remove_msg (mail_op, header, FALSE);
250 g_object_unref (G_OBJECT (mail_op));
252 /* refilter treemodel to hide marked-as-deleted rows */
253 if (MODEST_IS_HEADER_VIEW (user_data))
254 modest_header_view_refilter (MODEST_HEADER_VIEW (user_data));
258 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
260 TnyList *header_list = NULL;
261 TnyIterator *iter = NULL;
262 TnyHeader *header = NULL;
263 gchar *message = NULL;
266 ModestWindowMgr *mgr;
267 GtkWidget *header_view = NULL;
269 g_return_if_fail (MODEST_IS_WINDOW(win));
271 /* Check first if the header view has the focus */
272 if (MODEST_IS_MAIN_WINDOW (win)) {
274 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
275 MODEST_WIDGET_TYPE_HEADER_VIEW);
276 if (!gtk_widget_is_focus (header_view))
280 header_list = get_selected_headers (win);
281 if (!header_list) return;
283 /* Check if any of the headers is already opened, or in the process of being opened */
284 if (MODEST_IS_MAIN_WINDOW (win)) {
286 iter = tny_list_create_iterator (header_list);
288 mgr = modest_runtime_get_window_mgr ();
289 while (!tny_iterator_is_done (iter) && !found) {
290 header = TNY_HEADER (tny_iterator_get_current (iter));
291 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
292 g_object_unref (header);
293 tny_iterator_next (iter);
295 g_object_unref (iter);
300 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
301 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
303 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
307 g_object_unref (header_list);
313 if (tny_list_get_length(header_list) == 1) {
314 iter = tny_list_create_iterator (header_list);
315 header = TNY_HEADER (tny_iterator_get_current (iter));
316 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
317 g_object_unref (header);
318 g_object_unref (iter);
320 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
321 tny_list_get_length(header_list)), desc);
323 /* Confirmation dialog */
324 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
328 if (response == GTK_RESPONSE_OK) {
329 ModestMainWindow *main_window;
330 ModestWindowMgr *mgr;
332 /* Remove each header. If it's a view window header_view == NULL */
333 do_headers_action (win, headers_action_delete, header_view);
335 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 /* Close msg view window or select next */
337 if (modest_msg_view_window_last_message_selected (MODEST_MSG_VIEW_WINDOW (win)) &&
338 modest_msg_view_window_first_message_selected (MODEST_MSG_VIEW_WINDOW (win))) {
339 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
341 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (win));
345 /* Refilter header view model, if main window still exists */
346 mgr = modest_runtime_get_window_mgr ();
347 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
351 widget = modest_main_window_get_child_widget (main_window,
352 MODEST_WIDGET_TYPE_HEADER_VIEW);
353 modest_header_view_refilter (MODEST_HEADER_VIEW (widget));
356 /* Update toolbar dimming state */
357 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
363 g_object_unref (header_list);
368 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
370 #ifdef MODEST_PLATFORM_MAEMO
371 modest_osso_save_state();
372 #endif /* MODEST_PLATFORM_MAEMO */
374 g_debug ("closing down, clearing %d item(s) from operation queue",
375 modest_mail_operation_queue_num_elements
376 (modest_runtime_get_mail_operation_queue()));
378 /* cancel all outstanding operations */
379 modest_mail_operation_queue_cancel_all
380 (modest_runtime_get_mail_operation_queue());
382 g_debug ("queue has been cleared");
384 /* note: when modest-tny-account-store is finalized,
385 it will automatically set all network connections
392 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
395 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
397 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
398 /* gtk_widget_destroy (GTK_WIDGET (win)); */
399 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
400 /* gboolean ret_value; */
401 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
402 /* } else if (MODEST_IS_WINDOW (win)) { */
403 /* gtk_widget_destroy (GTK_WIDGET (win)); */
405 /* g_return_if_reached (); */
410 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
412 GtkClipboard *clipboard = NULL;
413 gchar *selection = NULL;
415 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
416 selection = gtk_clipboard_wait_for_text (clipboard);
418 /* Question: why is the clipboard being used here?
419 * It doesn't really make a lot of sense. */
423 modest_address_book_add_address (selection);
429 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
431 /* This is currently only implemented for Maemo */
432 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
433 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
434 run_account_setup_wizard (win);
437 /* Show the list of accounts: */
438 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
439 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
440 gtk_dialog_run (account_win);
441 gtk_widget_destroy (GTK_WIDGET(account_win));
444 GtkWidget *dialog, *label;
446 /* Create the widgets */
448 dialog = gtk_dialog_new_with_buttons ("Message",
450 GTK_DIALOG_DESTROY_WITH_PARENT,
454 label = gtk_label_new ("Hello World!");
456 /* Ensure that the dialog box is destroyed when the user responds. */
458 g_signal_connect_swapped (dialog, "response",
459 G_CALLBACK (gtk_widget_destroy),
462 /* Add the label, and show everything we've added to the dialog. */
464 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
466 gtk_widget_show_all (dialog);
467 #endif /* MODEST_PLATFORM_MAEMO */
471 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
473 ModestWindow *main_window = MODEST_WINDOW (user_data);
475 /* Save any changes. */
476 modest_connection_specific_smtp_window_save_server_accounts (
477 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
478 modest_window_get_active_account (main_window));
479 gtk_widget_destroy (GTK_WIDGET (window));
485 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
487 /* This is currently only implemented for Maemo,
488 * because it requires an API (libconic) to detect different connection
491 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
493 /* Create the window if necessary: */
494 const gchar *active_account_name = modest_window_get_active_account (win);
496 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
497 * or show the default account?
498 * If we show the default account then the account name should be shown in
499 * the window when we show it. */
500 if (!active_account_name) {
501 g_warning ("%s: No account is active.", __FUNCTION__);
505 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
506 modest_connection_specific_smtp_window_fill_with_connections (
507 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
508 modest_runtime_get_account_mgr(),
509 active_account_name);
511 /* Show the window: */
512 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
513 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
514 gtk_widget_show (specific_window);
516 /* Save changes when the window is hidden: */
517 g_signal_connect (specific_window, "hide",
518 G_CALLBACK (on_smtp_servers_window_hide), win);
519 #endif /* MODEST_PLATFORM_MAEMO */
523 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
525 ModestWindow *msg_win = NULL;
527 TnyFolder *folder = NULL;
528 gchar *account_name = NULL;
529 gchar *from_str = NULL;
530 /* GError *err = NULL; */
531 TnyAccount *account = NULL;
532 ModestWindowMgr *mgr;
533 gchar *signature = NULL, *blank_and_signature = NULL;
535 /* if there are no accounts yet, just show the wizard */
536 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
537 run_account_setup_wizard (win);
541 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
543 account_name = g_strdup (modest_window_get_active_account (win));
545 g_printerr ("modest: no account found\n");
549 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
551 TNY_ACCOUNT_TYPE_STORE);
553 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
557 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
559 g_printerr ("modest: failed get from string for '%s'\n", account_name);
563 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
564 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
565 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
566 MODEST_ACCOUNT_SIGNATURE, FALSE);
567 blank_and_signature = g_strconcat ("\n", signature, NULL);
570 blank_and_signature = g_strdup ("");
573 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
575 g_printerr ("modest: failed to create new msg\n");
579 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
581 g_printerr ("modest: failed to find Drafts folder\n");
586 /* Create and register edit window */
587 /* This is destroyed by TOOD. */
588 msg_win = modest_msg_edit_window_new (msg, account_name);
589 mgr = modest_runtime_get_window_mgr ();
590 modest_window_mgr_register_window (mgr, msg_win);
593 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
595 gtk_widget_show_all (GTK_WIDGET (msg_win));
598 g_free (account_name);
600 g_free (blank_and_signature);
602 g_object_unref (msg_win);
604 g_object_unref (G_OBJECT(account));
606 g_object_unref (G_OBJECT(msg));
608 g_object_unref (G_OBJECT(folder));
612 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
616 ModestMailOperationStatus status;
618 /* If there is no message or the operation was not successful */
619 status = modest_mail_operation_get_status (mail_op);
620 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
622 /* Remove the header from the preregistered uids */
623 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
633 open_msg_cb (ModestMailOperation *mail_op,
638 ModestWindowMgr *mgr = NULL;
639 ModestWindow *parent_win = NULL;
640 ModestWindow *win = NULL;
641 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
642 gchar *account = NULL;
645 /* Do nothing if there was any problem with the mail
646 operation. The error will be shown by the error_handler of
647 the mail operation */
648 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
651 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
652 folder = tny_header_get_folder (header);
654 /* Mark header as read */
655 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
658 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
660 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
662 /* Gets folder type (OUTBOX headers will be opened in edit window */
663 if (modest_tny_folder_is_local_folder (folder))
664 folder_type = modest_tny_folder_get_local_folder_type (folder);
666 /* If the header is in the drafts folder then open the editor,
667 else the message view window */
668 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
669 /* we cannot edit without a valid account... */
670 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
671 run_account_setup_wizard(parent_win);
674 win = modest_msg_edit_window_new (msg, account);
676 gchar *uid = modest_tny_folder_get_header_unique_id (header);
678 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
679 GtkWidget *header_view;
680 GtkTreeSelection *sel;
681 GList *sel_list = NULL;
684 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
685 MODEST_WIDGET_TYPE_HEADER_VIEW);
687 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
688 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
690 if (sel_list != NULL) {
691 GtkTreeRowReference *row_reference;
693 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
694 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
695 g_list_free (sel_list);
697 win = modest_msg_view_window_new_with_header_model (msg,
702 gtk_tree_row_reference_free (row_reference);
704 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
707 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
712 /* Register and show new window */
714 mgr = modest_runtime_get_window_mgr ();
715 modest_window_mgr_register_window (mgr, win);
716 g_object_unref (win);
717 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
718 gtk_widget_show_all (GTK_WIDGET(win));
721 /* Update toolbar dimming state */
722 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
723 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
729 g_object_unref (parent_win);
730 /* g_object_unref (msg); */
731 g_object_unref (folder);
735 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
739 GObject *win = modest_mail_operation_get_source (mail_op);
741 error = modest_mail_operation_get_error (mail_op);
742 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
744 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
747 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
748 _("mail_ni_ui_folder_get_msg_folder_error"));
752 g_object_unref (win);
756 * This function is used by both modest_ui_actions_on_open and
757 * modest_ui_actions_on_header_activated. This way we always do the
758 * same when trying to open messages.
761 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
763 ModestWindowMgr *mgr = NULL;
764 TnyIterator *iter = NULL;
765 ModestMailOperation *mail_op1 = NULL;
766 ModestMailOperation *mail_op2 = NULL;
767 TnyList *not_opened_headers = NULL;
768 TnyList *not_opened_cached_headers = NULL;
769 TnyHeaderFlags flags;
771 /* Look if we already have a message view for each header. If
772 true, then remove the header from the list of headers to
774 mgr = modest_runtime_get_window_mgr ();
775 iter = tny_list_create_iterator (headers);
776 not_opened_headers = tny_simple_list_new ();
777 not_opened_cached_headers = tny_simple_list_new ();
778 while (!tny_iterator_is_done (iter)) {
780 ModestWindow *window;
784 header = TNY_HEADER (tny_iterator_get_current (iter));
785 flags = tny_header_get_flags (header);
788 found = modest_window_mgr_find_registered_header (mgr, header, &window);
790 /* Do not open again the message and present the
791 window to the user */
794 gtk_window_present (GTK_WINDOW (window));
796 /* the header has been registered already, we don't do
797 * anything but wait for the window to come up*/
798 g_warning ("debug: header %p already registered, waiting for window",
801 /* register the header before actually creating the window */
802 modest_window_mgr_register_header (mgr, header);
804 if (!(flags & TNY_HEADER_FLAG_CACHED))
805 tny_list_append (not_opened_headers, G_OBJECT (header));
806 /* Check if msg has already been retreived */
808 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
810 g_object_unref (header);
811 tny_iterator_next (iter);
814 /* Open each uncached message */
815 if (tny_list_get_length (not_opened_headers) > 0) {
816 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
818 modest_ui_actions_get_msgs_full_error_handler,
820 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
821 if (tny_list_get_length (not_opened_headers) > 1) {
822 modest_mail_operation_get_msgs_full (mail_op1,
828 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
829 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
830 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
831 g_object_unref (header);
832 g_object_unref (iter);
836 /* Open each cached message */
837 if (tny_list_get_length (not_opened_cached_headers) > 0) {
838 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
840 modest_ui_actions_get_msgs_full_error_handler,
842 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
843 if (tny_list_get_length (not_opened_cached_headers) > 1) {
844 modest_mail_operation_get_msgs_full (mail_op2,
850 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
851 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
852 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
853 g_object_unref (header);
854 g_object_unref (iter);
859 if (not_opened_headers != NULL)
860 g_object_unref (not_opened_headers);
861 if (not_opened_cached_headers != NULL)
862 g_object_unref (not_opened_cached_headers);
864 g_object_unref (iter);
865 if (mail_op1 != NULL)
866 g_object_unref (mail_op1);
867 if (mail_op2 != NULL)
868 g_object_unref (mail_op2);
872 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
877 headers = get_selected_headers (win);
882 _modest_ui_actions_open (headers, win);
884 g_object_unref(headers);
889 free_reply_forward_helper (gpointer data)
891 ReplyForwardHelper *helper;
893 helper = (ReplyForwardHelper *) data;
894 g_free (helper->account_name);
895 g_slice_free (ReplyForwardHelper, helper);
899 reply_forward_cb (ModestMailOperation *mail_op,
905 ReplyForwardHelper *rf_helper;
906 ModestWindow *msg_win = NULL;
907 ModestEditType edit_type;
909 TnyAccount *account = NULL;
910 ModestWindowMgr *mgr = NULL;
911 gchar *signature = NULL;
913 /* If there was any error */
914 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
917 g_return_if_fail (user_data != NULL);
918 rf_helper = (ReplyForwardHelper *) user_data;
920 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
921 rf_helper->account_name);
922 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
923 rf_helper->account_name,
924 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
925 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
926 rf_helper->account_name,
927 MODEST_ACCOUNT_SIGNATURE, FALSE);
930 /* Create reply mail */
931 switch (rf_helper->action) {
934 modest_tny_msg_create_reply_msg (msg, from, signature,
935 rf_helper->reply_forward_type,
936 MODEST_TNY_MSG_REPLY_MODE_SENDER);
938 case ACTION_REPLY_TO_ALL:
940 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
941 MODEST_TNY_MSG_REPLY_MODE_ALL);
942 edit_type = MODEST_EDIT_TYPE_REPLY;
946 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
947 edit_type = MODEST_EDIT_TYPE_FORWARD;
950 g_return_if_reached ();
957 g_printerr ("modest: failed to create message\n");
961 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
962 rf_helper->account_name,
963 TNY_ACCOUNT_TYPE_STORE);
965 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
969 /* Create and register the windows */
970 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
971 mgr = modest_runtime_get_window_mgr ();
972 modest_window_mgr_register_window (mgr, msg_win);
974 if (rf_helper->parent_window != NULL) {
977 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
978 modest_window_set_zoom (msg_win, parent_zoom);
981 /* Show edit window */
982 gtk_widget_show_all (GTK_WIDGET (msg_win));
986 g_object_unref (msg_win);
988 g_object_unref (G_OBJECT (new_msg));
990 g_object_unref (G_OBJECT (account));
991 /* g_object_unref (msg); */
992 g_object_unref (header);
993 free_reply_forward_helper (rf_helper);
997 * Checks a list of headers. If any of them are not currently
998 * downloaded (CACHED) then it asks the user for permission to
1001 * Returns FALSE if the user does not want to download the
1002 * messages. Returns TRUE if the user allowed the download or if all
1003 * of them are currently downloaded
1006 download_uncached_messages (TnyList *header_list, GtkWindow *win)
1010 gint uncached_messages = 0;
1012 iter = tny_list_create_iterator (header_list);
1013 while (!tny_iterator_is_done (iter)) {
1015 TnyHeaderFlags flags;
1017 header = TNY_HEADER (tny_iterator_get_current (iter));
1018 flags = tny_header_get_flags (header);
1019 /* TODO: is this the right flag?, it seems that some
1020 headers that have been previously downloaded do not
1022 if (! (flags & TNY_HEADER_FLAG_CACHED))
1023 uncached_messages ++;
1024 g_object_unref (header);
1025 tny_iterator_next (iter);
1027 g_object_unref (iter);
1029 /* Ask for user permission to download the messages */
1031 if (uncached_messages > 0) {
1032 GtkResponseType response;
1034 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1035 ngettext("mcen_nc_get_msg",
1037 uncached_messages));
1038 if (response == GTK_RESPONSE_CANCEL)
1041 /* If a download will be necessary, make sure that we have a connection: */
1042 retval = modest_platform_connect_and_wait(win);
1050 * Common code for the reply and forward actions
1053 reply_forward (ReplyForwardAction action, ModestWindow *win)
1055 ModestMailOperation *mail_op = NULL;
1056 TnyList *header_list = NULL;
1057 ReplyForwardHelper *rf_helper = NULL;
1058 guint reply_forward_type;
1059 gboolean continue_download;
1061 g_return_if_fail (MODEST_IS_WINDOW(win));
1063 /* we need an account when editing */
1064 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1065 run_account_setup_wizard (win);
1069 header_list = get_selected_headers (win);
1073 /* Check that the messages have been previously downloaded */
1074 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1075 if (!continue_download) {
1076 g_object_unref (header_list);
1080 reply_forward_type =
1081 modest_conf_get_int (modest_runtime_get_conf (),
1082 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1084 /* We assume that we can only select messages of the
1085 same folder and that we reply all of them from the
1086 same account. In fact the interface currently only
1087 allows single selection */
1090 rf_helper = g_slice_new0 (ReplyForwardHelper);
1091 rf_helper->reply_forward_type = reply_forward_type;
1092 rf_helper->action = action;
1093 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1094 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1095 rf_helper->parent_window = GTK_WIDGET (win);
1096 if (!rf_helper->account_name)
1097 rf_helper->account_name =
1098 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1100 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1103 /* Get header and message. Do not free them here, the
1104 reply_forward_cb must do it */
1105 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1106 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1107 if (!msg || !header) {
1109 g_object_unref (msg);
1111 g_object_unref (header);
1112 g_printerr ("modest: no message found\n");
1115 reply_forward_cb (NULL, header, msg, rf_helper);
1121 /* Retrieve messages */
1122 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1124 modest_ui_actions_get_msgs_full_error_handler,
1126 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1128 /* Only reply/forward to one message */
1129 iter = tny_list_create_iterator (header_list);
1130 header = TNY_HEADER (tny_iterator_get_current (iter));
1131 g_object_unref (iter);
1133 modest_mail_operation_get_msg (mail_op,
1138 /* modest_mail_operation_get_msgs_full (mail_op, */
1140 /* reply_forward_cb, */
1142 /* free_reply_forward_helper); */
1145 g_object_unref(mail_op);
1149 g_object_unref (header_list);
1153 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1155 g_return_if_fail (MODEST_IS_WINDOW(win));
1157 reply_forward (ACTION_REPLY, win);
1161 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1163 g_return_if_fail (MODEST_IS_WINDOW(win));
1165 reply_forward (ACTION_FORWARD, win);
1169 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1171 g_return_if_fail (MODEST_IS_WINDOW(win));
1173 reply_forward (ACTION_REPLY_TO_ALL, win);
1177 modest_ui_actions_on_next (GtkAction *action,
1178 ModestWindow *window)
1180 if (MODEST_IS_MAIN_WINDOW (window)) {
1181 GtkWidget *header_view;
1183 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1184 MODEST_WIDGET_TYPE_HEADER_VIEW);
1188 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1189 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1190 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1192 g_return_if_reached ();
1197 modest_ui_actions_on_prev (GtkAction *action,
1198 ModestWindow *window)
1200 g_return_if_fail (MODEST_IS_WINDOW(window));
1202 if (MODEST_IS_MAIN_WINDOW (window)) {
1203 GtkWidget *header_view;
1204 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1205 MODEST_WIDGET_TYPE_HEADER_VIEW);
1209 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1210 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1211 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1213 g_return_if_reached ();
1218 modest_ui_actions_on_sort (GtkAction *action,
1219 ModestWindow *window)
1221 g_return_if_fail (MODEST_IS_WINDOW(window));
1223 if (MODEST_IS_MAIN_WINDOW (window)) {
1224 GtkWidget *header_view;
1225 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1226 MODEST_WIDGET_TYPE_HEADER_VIEW);
1230 /* Show sorting dialog */
1231 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1236 new_messages_arrived (ModestMailOperation *self,
1240 if (new_messages == 0)
1243 modest_platform_on_new_msg ();
1247 * This function performs the send & receive required actions. The
1248 * window is used to create the mail operation. Typically it should
1249 * always be the main window, but we pass it as argument in order to
1253 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1255 gchar *acc_name = NULL;
1256 ModestMailOperation *mail_op;
1258 /* If no account name was provided then get the current account, and if
1259 there is no current account then pick the default one: */
1260 if (!account_name) {
1261 acc_name = g_strdup (modest_window_get_active_account(win));
1263 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1265 g_printerr ("modest: cannot get default account\n");
1269 acc_name = g_strdup (account_name);
1272 /* Set send/receive operation in progress */
1273 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1275 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1277 modest_ui_actions_send_receive_error_handler,
1280 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1281 G_CALLBACK (_on_send_receive_progress_changed),
1284 /* Send & receive. */
1285 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1286 /* Receive and then send. The operation is tagged initially as
1287 a receive operation because the account update performs a
1288 receive and then a send. The operation changes its type
1289 internally, so the progress objects will receive the proper
1290 progress information */
1291 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1292 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1293 g_object_unref (G_OBJECT (mail_op));
1300 * Refreshes all accounts. This function will be used by automatic
1304 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1306 GSList *account_names, *iter;
1308 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1311 iter = account_names;
1313 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1314 iter = g_slist_next (iter);
1317 modest_account_mgr_free_account_names (account_names);
1318 account_names = NULL;
1322 * Handler of the click on Send&Receive button in the main toolbar
1325 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1327 /* Check if accounts exist */
1328 gboolean accounts_exist =
1329 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1331 /* If not, allow the user to create an account before trying to send/receive. */
1332 if (!accounts_exist)
1333 modest_ui_actions_on_accounts (NULL, win);
1335 /* Refresh the active account */
1336 modest_ui_actions_do_send_receive (NULL, win);
1341 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1344 GtkWidget *header_view;
1346 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1348 header_view = modest_main_window_get_child_widget (main_window,
1349 MODEST_WIDGET_TYPE_HEADER_VIEW);
1353 conf = modest_runtime_get_conf ();
1355 /* what is saved/restored is depending on the style; thus; we save with
1356 * old style, then update the style, and restore for this new style
1358 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1360 if (modest_header_view_get_style
1361 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1362 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1363 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1365 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1366 MODEST_HEADER_VIEW_STYLE_DETAILS);
1368 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1369 MODEST_CONF_HEADER_VIEW_KEY);
1374 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1376 ModestMainWindow *main_window)
1378 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1379 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1381 /* If no header has been selected then exit */
1386 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1387 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1389 /* Update Main window title */
1390 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1391 const gchar *subject = tny_header_get_subject (header);
1392 if (subject && strlen(subject) > 0)
1393 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1395 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1398 /* Update toolbar dimming state */
1399 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1403 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1405 ModestMainWindow *main_window)
1409 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1414 headers = tny_simple_list_new ();
1415 tny_list_prepend (headers, G_OBJECT (header));
1417 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1419 g_object_unref (headers);
1423 set_active_account_from_tny_account (TnyAccount *account,
1424 ModestWindow *window)
1426 const gchar *server_acc_name = tny_account_get_id (account);
1428 /* We need the TnyAccount provided by the
1429 account store because that is the one that
1430 knows the name of the Modest account */
1431 TnyAccount *modest_server_account = modest_server_account =
1432 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1433 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1436 const gchar *modest_acc_name =
1437 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1438 modest_window_set_active_account (window, modest_acc_name);
1439 g_object_unref (modest_server_account);
1444 folder_refreshed_cb (const GObject *obj,
1448 ModestMainWindow *win = NULL;
1449 GtkWidget *header_view;
1451 g_return_if_fail (TNY_IS_FOLDER (folder));
1453 win = MODEST_MAIN_WINDOW (user_data);
1455 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1457 /* Check if folder is empty and set headers view contents style */
1458 if (tny_folder_get_all_count (folder) == 0) {
1459 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1460 modest_main_window_set_contents_style (win,
1461 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1463 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1468 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1469 TnyFolderStore *folder_store,
1471 ModestMainWindow *main_window)
1474 GtkWidget *header_view;
1476 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1478 header_view = modest_main_window_get_child_widget(main_window,
1479 MODEST_WIDGET_TYPE_HEADER_VIEW);
1483 conf = modest_runtime_get_conf ();
1485 if (TNY_IS_ACCOUNT (folder_store)) {
1487 /* Update active account */
1488 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1489 /* Show account details */
1490 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1493 if (TNY_IS_FOLDER (folder_store) && selected) {
1495 /* Update the active account */
1496 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1498 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1499 g_object_unref (account);
1503 /* Set the header style by default, it could
1504 be changed later by the refresh callback to
1506 modest_main_window_set_contents_style (main_window,
1507 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1509 /* Set folder on header view. This function
1510 will call tny_folder_refresh_async so we
1511 pass a callback that will be called when
1512 finished. We use that callback to set the
1513 empty view if there are no messages */
1514 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1515 TNY_FOLDER (folder_store),
1516 folder_refreshed_cb,
1519 /* Restore configuration. We need to do this
1520 *after* the set_folder because the widget
1521 memory asks the header view about its
1523 modest_widget_memory_restore (modest_runtime_get_conf (),
1524 G_OBJECT(header_view),
1525 MODEST_CONF_HEADER_VIEW_KEY);
1527 /* Update the active account */
1528 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1529 /* Save only if we're seeing headers */
1530 if (modest_main_window_get_contents_style (main_window) ==
1531 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1532 modest_widget_memory_save (conf, G_OBJECT (header_view),
1533 MODEST_CONF_HEADER_VIEW_KEY);
1534 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1538 /* Update toolbar dimming state */
1539 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1543 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1550 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1552 online = tny_device_is_online (modest_runtime_get_device());
1555 /* already online -- the item is simply not there... */
1556 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1558 GTK_MESSAGE_WARNING,
1560 _("The %s you selected cannot be found"),
1562 gtk_dialog_run (GTK_DIALOG(dialog));
1564 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1568 GTK_RESPONSE_REJECT,
1570 GTK_RESPONSE_ACCEPT,
1572 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1573 "Do you want to get online?"), item);
1574 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1575 gtk_label_new (txt), FALSE, FALSE, 0);
1576 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1579 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1580 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1581 // modest_platform_connect_and_wait ();
1584 gtk_widget_destroy (dialog);
1588 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1591 /* g_message ("%s %s", __FUNCTION__, link); */
1596 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1599 modest_platform_activate_uri (link);
1603 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1606 modest_platform_show_uri_popup (link);
1610 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1613 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1617 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1618 const gchar *address,
1621 /* g_message ("%s %s", __FUNCTION__, address); */
1625 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1627 TnyTransportAccount *transport_account;
1628 ModestMailOperation *mail_operation;
1630 gchar *account_name, *from;
1631 ModestAccountMgr *account_mgr;
1632 gchar *info_text = NULL;
1634 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1636 data = modest_msg_edit_window_get_msg_data (edit_window);
1638 account_mgr = modest_runtime_get_account_mgr();
1639 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1641 account_name = modest_account_mgr_get_default_account (account_mgr);
1642 if (!account_name) {
1643 g_printerr ("modest: no account found\n");
1644 modest_msg_edit_window_free_msg_data (edit_window, data);
1648 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1649 account_name = g_strdup (data->account_name);
1653 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1654 (modest_runtime_get_account_store(),
1656 TNY_ACCOUNT_TYPE_TRANSPORT));
1657 if (!transport_account) {
1658 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1659 g_free (account_name);
1660 modest_msg_edit_window_free_msg_data (edit_window, data);
1663 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1665 /* Create the mail operation */
1666 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1667 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1669 modest_mail_operation_save_to_drafts (mail_operation,
1680 data->priority_flags);
1683 g_free (account_name);
1684 g_object_unref (G_OBJECT (transport_account));
1685 g_object_unref (G_OBJECT (mail_operation));
1687 modest_msg_edit_window_free_msg_data (edit_window, data);
1689 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1690 modest_platform_information_banner (NULL, NULL, info_text);
1694 /* For instance, when clicking the Send toolbar button when editing a message: */
1696 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1698 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1700 if (!modest_msg_edit_window_check_names (edit_window))
1703 /* FIXME: Code added just for testing. The final version will
1704 use the send queue provided by tinymail and some
1706 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1707 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1709 account_name = modest_account_mgr_get_default_account (account_mgr);
1711 if (!account_name) {
1712 g_printerr ("modest: no account found\n");
1716 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1718 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1719 account_name = g_strdup (data->account_name);
1722 /* Get the currently-active transport account for this modest account: */
1723 TnyTransportAccount *transport_account =
1724 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1725 (modest_runtime_get_account_store(),
1727 if (!transport_account) {
1728 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1729 g_free (account_name);
1730 modest_msg_edit_window_free_msg_data (edit_window, data);
1734 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1736 /* mail content checks and dialogs */
1737 if (data->subject == NULL || data->subject[0] == '\0') {
1738 GtkResponseType response;
1739 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1740 _("mcen_nc_subject_is_empty_send"));
1741 if (response == GTK_RESPONSE_CANCEL) {
1742 g_free (account_name);
1747 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1748 GtkResponseType response;
1749 gchar *note_message;
1750 gchar *note_subject = data->subject;
1751 if (note_subject == NULL || note_subject[0] == '\0')
1752 note_subject = _("mail_va_no_subject");
1753 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1754 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1756 g_free (note_message);
1757 if (response == GTK_RESPONSE_CANCEL) {
1758 g_free (account_name);
1763 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1765 /* Create the mail operation */
1766 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1767 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1769 modest_mail_operation_send_new_mail (mail_operation,
1780 data->priority_flags);
1784 g_free (account_name);
1785 g_object_unref (G_OBJECT (transport_account));
1786 g_object_unref (G_OBJECT (mail_operation));
1788 modest_msg_edit_window_free_msg_data (edit_window, data);
1789 modest_msg_edit_window_set_sent (edit_window, TRUE);
1791 /* Save settings and close the window: */
1792 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
1796 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1797 ModestMsgEditWindow *window)
1799 ModestMsgEditFormatState *format_state = NULL;
1801 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1802 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1804 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1807 format_state = modest_msg_edit_window_get_format_state (window);
1808 g_return_if_fail (format_state != NULL);
1810 format_state->bold = gtk_toggle_action_get_active (action);
1811 modest_msg_edit_window_set_format_state (window, format_state);
1812 g_free (format_state);
1817 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1818 ModestMsgEditWindow *window)
1820 ModestMsgEditFormatState *format_state = NULL;
1822 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1823 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1825 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1828 format_state = modest_msg_edit_window_get_format_state (window);
1829 g_return_if_fail (format_state != NULL);
1831 format_state->italics = gtk_toggle_action_get_active (action);
1832 modest_msg_edit_window_set_format_state (window, format_state);
1833 g_free (format_state);
1838 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1839 ModestMsgEditWindow *window)
1841 ModestMsgEditFormatState *format_state = NULL;
1843 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1844 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1846 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1849 format_state = modest_msg_edit_window_get_format_state (window);
1850 g_return_if_fail (format_state != NULL);
1852 format_state->bullet = gtk_toggle_action_get_active (action);
1853 modest_msg_edit_window_set_format_state (window, format_state);
1854 g_free (format_state);
1859 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1860 GtkRadioAction *selected,
1861 ModestMsgEditWindow *window)
1863 ModestMsgEditFormatState *format_state = NULL;
1864 GtkJustification value;
1866 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1868 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1871 value = gtk_radio_action_get_current_value (selected);
1873 format_state = modest_msg_edit_window_get_format_state (window);
1874 g_return_if_fail (format_state != NULL);
1876 format_state->justification = value;
1877 modest_msg_edit_window_set_format_state (window, format_state);
1878 g_free (format_state);
1882 modest_ui_actions_on_select_editor_color (GtkAction *action,
1883 ModestMsgEditWindow *window)
1885 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1886 g_return_if_fail (GTK_IS_ACTION (action));
1888 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1891 modest_msg_edit_window_select_color (window);
1895 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1896 ModestMsgEditWindow *window)
1898 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1899 g_return_if_fail (GTK_IS_ACTION (action));
1901 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1904 modest_msg_edit_window_select_background_color (window);
1908 modest_ui_actions_on_insert_image (GtkAction *action,
1909 ModestMsgEditWindow *window)
1911 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1912 g_return_if_fail (GTK_IS_ACTION (action));
1914 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1917 modest_msg_edit_window_insert_image (window);
1921 modest_ui_actions_on_attach_file (GtkAction *action,
1922 ModestMsgEditWindow *window)
1924 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1925 g_return_if_fail (GTK_IS_ACTION (action));
1927 modest_msg_edit_window_attach_file (window);
1931 modest_ui_actions_on_remove_attachments (GtkAction *action,
1932 ModestMsgEditWindow *window)
1934 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1935 g_return_if_fail (GTK_IS_ACTION (action));
1937 modest_msg_edit_window_remove_attachments (window, NULL);
1941 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1943 TnyFolderStore *parent_folder;
1944 GtkWidget *folder_view;
1946 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1948 folder_view = modest_main_window_get_child_widget (main_window,
1949 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1953 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1955 if (parent_folder) {
1956 gboolean finished = FALSE;
1958 gchar *folder_name = NULL, *suggested_name = NULL;
1960 /* Run the new folder dialog */
1962 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1967 if (result == GTK_RESPONSE_REJECT) {
1970 ModestMailOperation *mail_op;
1971 TnyFolder *new_folder = NULL;
1973 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1974 G_OBJECT(main_window));
1975 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1977 new_folder = modest_mail_operation_create_folder (mail_op,
1979 (const gchar *) folder_name);
1981 g_object_unref (new_folder);
1984 g_object_unref (mail_op);
1986 g_free (folder_name);
1990 g_object_unref (parent_folder);
1995 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1998 GObject *win = modest_mail_operation_get_source (mail_op);
1999 const GError *error = NULL;
2000 const gchar *message = NULL;
2002 /* Get error message */
2003 error = modest_mail_operation_get_error (mail_op);
2004 if (error != NULL && error->message != NULL) {
2005 message = error->message;
2007 message = _("!!! FIXME: Unable to rename");
2010 /* Show notification dialog */
2011 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2012 g_object_unref (win);
2016 modest_ui_actions_on_rename_folder (GtkAction *action,
2017 ModestMainWindow *main_window)
2019 TnyFolderStore *folder;
2020 GtkWidget *folder_view;
2021 GtkWidget *header_view;
2023 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2025 folder_view = modest_main_window_get_child_widget (main_window,
2026 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2030 header_view = modest_main_window_get_child_widget (main_window,
2031 MODEST_WIDGET_TYPE_HEADER_VIEW);
2036 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2038 /* Offer the connection dialog if necessary: */
2039 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2040 g_object_unref (G_OBJECT (folder));
2045 if (folder && TNY_IS_FOLDER (folder)) {
2048 const gchar *current_name;
2050 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2051 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2052 current_name, &folder_name);
2054 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2055 ModestMailOperation *mail_op;
2058 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2059 G_OBJECT(main_window),
2060 modest_ui_actions_rename_folder_error_handler,
2064 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2067 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2069 modest_mail_operation_rename_folder (mail_op,
2070 TNY_FOLDER (folder),
2071 (const gchar *) folder_name);
2073 g_object_unref (mail_op);
2074 g_free (folder_name);
2076 g_object_unref (folder);
2081 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2084 GObject *win = modest_mail_operation_get_source (mail_op);
2086 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2087 _("mail_in_ui_folder_delete_error"));
2088 g_object_unref (win);
2092 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2094 TnyFolderStore *folder;
2095 GtkWidget *folder_view;
2099 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2101 folder_view = modest_main_window_get_child_widget (main_window,
2102 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2106 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2108 /* Show an error if it's an account */
2109 if (!TNY_IS_FOLDER (folder)) {
2110 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2111 _("mail_in_ui_folder_delete_error"));
2112 g_object_unref (G_OBJECT (folder));
2116 /* Offer the connection dialog if necessary: */
2117 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2118 g_object_unref (G_OBJECT (folder));
2123 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2124 tny_folder_get_name (TNY_FOLDER (folder)));
2125 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2126 (const gchar *) message);
2129 if (response == GTK_RESPONSE_OK) {
2130 ModestMailOperation *mail_op =
2131 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2132 G_OBJECT(main_window),
2133 modest_ui_actions_delete_folder_error_handler,
2136 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2138 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2139 g_object_unref (G_OBJECT (mail_op));
2142 g_object_unref (G_OBJECT (folder));
2146 modest_ui_actions_on_delete_folder (GtkAction *action,
2147 ModestMainWindow *main_window)
2149 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2151 delete_folder (main_window, FALSE);
2155 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2157 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2159 delete_folder (main_window, TRUE);
2163 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2164 const gchar* server_account_name,
2169 ModestMainWindow *main_window)
2171 g_return_if_fail(server_account_name);
2172 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2174 /* Initalize output parameters: */
2181 #ifdef MODEST_PLATFORM_MAEMO
2182 /* Maemo uses a different (awkward) button order,
2183 * It should probably just use gtk_alternative_dialog_button_order ().
2185 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2189 GTK_RESPONSE_ACCEPT,
2191 GTK_RESPONSE_REJECT,
2194 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2198 GTK_RESPONSE_REJECT,
2200 GTK_RESPONSE_ACCEPT,
2202 #endif /* MODEST_PLATFORM_MAEMO */
2204 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2206 gchar *server_name = modest_server_account_get_hostname (
2207 modest_runtime_get_account_mgr(), server_account_name);
2208 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2209 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2214 /* This causes a warning because the logical ID has no %s in it,
2215 * though the translation does, but there is not much we can do about that: */
2216 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2217 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2220 g_free (server_name);
2224 gchar *initial_username = modest_server_account_get_username (
2225 modest_runtime_get_account_mgr(), server_account_name);
2227 GtkWidget *entry_username = gtk_entry_new ();
2228 if (initial_username)
2229 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2230 /* Dim this if a connection has ever succeeded with this username,
2231 * as per the UI spec: */
2232 const gboolean username_known =
2233 modest_server_account_get_username_has_succeeded(
2234 modest_runtime_get_account_mgr(), server_account_name);
2235 gtk_widget_set_sensitive (entry_username, !username_known);
2237 #ifdef MODEST_PLATFORM_MAEMO
2238 /* Auto-capitalization is the default, so let's turn it off: */
2239 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2241 /* Create a size group to be used by all captions.
2242 * Note that HildonCaption does not create a default size group if we do not specify one.
2243 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2244 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2246 GtkWidget *caption = hildon_caption_new (sizegroup,
2247 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2248 gtk_widget_show (entry_username);
2249 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2250 FALSE, FALSE, MODEST_MARGIN_HALF);
2251 gtk_widget_show (caption);
2253 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2255 #endif /* MODEST_PLATFORM_MAEMO */
2258 GtkWidget *entry_password = gtk_entry_new ();
2259 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2260 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2262 #ifdef MODEST_PLATFORM_MAEMO
2263 /* Auto-capitalization is the default, so let's turn it off: */
2264 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2265 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2267 caption = hildon_caption_new (sizegroup,
2268 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2269 gtk_widget_show (entry_password);
2270 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2271 FALSE, FALSE, MODEST_MARGIN_HALF);
2272 gtk_widget_show (caption);
2273 g_object_unref (sizegroup);
2275 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2277 #endif /* MODEST_PLATFORM_MAEMO */
2279 /* This is not in the Maemo UI spec:
2280 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2281 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2285 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2287 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2289 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2291 modest_server_account_set_username (
2292 modest_runtime_get_account_mgr(), server_account_name,
2295 const gboolean username_was_changed =
2296 (strcmp (*username, initial_username) != 0);
2297 if (username_was_changed) {
2298 g_warning ("%s: tinymail does not yet support changing the "
2299 "username in the get_password() callback.\n", __FUNCTION__);
2304 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2306 /* We do not save the password in the configuration,
2307 * because this function is only called for passwords that should
2308 * not be remembered:
2309 modest_server_account_set_password (
2310 modest_runtime_get_account_mgr(), server_account_name,
2329 /* This is not in the Maemo UI spec:
2330 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2336 gtk_widget_destroy (dialog);
2338 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2342 modest_ui_actions_on_cut (GtkAction *action,
2343 ModestWindow *window)
2345 GtkWidget *focused_widget;
2347 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2348 if (GTK_IS_EDITABLE (focused_widget)) {
2349 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2350 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2351 GtkTextBuffer *buffer;
2352 GtkClipboard *clipboard;
2354 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2355 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2356 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2357 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2358 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2359 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2360 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2365 modest_ui_actions_on_copy (GtkAction *action,
2366 ModestWindow *window)
2368 GtkClipboard *clipboard;
2369 GtkWidget *focused_widget;
2371 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2372 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2374 if (GTK_IS_LABEL (focused_widget)) {
2375 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2376 } else if (GTK_IS_EDITABLE (focused_widget)) {
2377 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2378 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2379 GtkTextBuffer *buffer;
2380 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2381 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2382 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2383 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2384 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2385 TnyIterator *iter = tny_list_create_iterator (header_list);
2386 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2387 TnyFolder *folder = tny_header_get_folder (header);
2388 TnyAccount *account = tny_folder_get_account (folder);
2389 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2390 /* If it's POP then ask */
2391 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2392 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2393 g_object_unref (account);
2394 g_object_unref (folder);
2395 g_object_unref (header);
2396 g_object_unref (iter);
2398 /* Check that the messages have been previously downloaded */
2399 gboolean continue_download = TRUE;
2401 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2402 if (continue_download)
2403 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2404 g_object_unref (header_list);
2405 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2406 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2409 /* Show information banner */
2410 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2415 modest_ui_actions_on_undo (GtkAction *action,
2416 ModestWindow *window)
2418 ModestEmailClipboard *clipboard = NULL;
2420 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2421 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2422 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2423 /* Clear clipboard source */
2424 clipboard = modest_runtime_get_email_clipboard ();
2425 modest_email_clipboard_clear (clipboard);
2428 g_return_if_reached ();
2433 modest_ui_actions_on_redo (GtkAction *action,
2434 ModestWindow *window)
2436 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2437 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2440 g_return_if_reached ();
2446 paste_msgs_cb (const GObject *object, gpointer user_data)
2448 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2449 g_return_if_fail (GTK_IS_WIDGET (user_data));
2451 /* destroy information note */
2452 gtk_widget_destroy (GTK_WIDGET(user_data));
2456 modest_ui_actions_on_paste (GtkAction *action,
2457 ModestWindow *window)
2459 GtkWidget *focused_widget = NULL;
2460 GtkWidget *inf_note = NULL;
2461 ModestMailOperation *mail_op = NULL;
2463 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2464 if (GTK_IS_EDITABLE (focused_widget)) {
2465 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2466 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2467 GtkTextBuffer *buffer;
2468 GtkClipboard *clipboard;
2470 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2471 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2472 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2473 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2474 ModestEmailClipboard *clipboard = NULL;
2475 TnyFolder *src_folder = NULL;
2476 TnyFolderStore *folder_store = NULL;
2477 TnyList *data = NULL;
2478 gboolean delete = FALSE;
2480 /* Check clipboard source */
2481 clipboard = modest_runtime_get_email_clipboard ();
2482 if (modest_email_clipboard_cleared (clipboard))
2485 /* Get elements to paste */
2486 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2488 /* Create a new mail operation */
2489 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2490 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2493 /* Get destination folder */
2494 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2496 /* Launch notification */
2497 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2498 _CS("ckct_nw_pasting"));
2499 if (inf_note != NULL) {
2500 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2501 gtk_widget_show (GTK_WIDGET(inf_note));
2504 /* transfer messages */
2506 modest_mail_operation_xfer_msgs (mail_op,
2508 TNY_FOLDER (folder_store),
2513 } else if (src_folder != NULL) {
2514 modest_mail_operation_xfer_folder (mail_op,
2524 g_object_unref (data);
2525 if (src_folder != NULL)
2526 g_object_unref (src_folder);
2527 if (folder_store != NULL)
2528 g_object_unref (folder_store);
2534 modest_ui_actions_on_select_all (GtkAction *action,
2535 ModestWindow *window)
2537 GtkWidget *focused_widget;
2539 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2540 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2541 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2542 } else if (GTK_IS_LABEL (focused_widget)) {
2543 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2544 } else if (GTK_IS_EDITABLE (focused_widget)) {
2545 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2546 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2547 GtkTextBuffer *buffer;
2548 GtkTextIter start, end;
2550 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2551 gtk_text_buffer_get_start_iter (buffer, &start);
2552 gtk_text_buffer_get_end_iter (buffer, &end);
2553 gtk_text_buffer_select_range (buffer, &start, &end);
2554 } else if (GTK_IS_HTML (focused_widget)) {
2555 gtk_html_select_all (GTK_HTML (focused_widget));
2556 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2557 GtkWidget *header_view = focused_widget;
2558 GtkTreeSelection *selection = NULL;
2560 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2561 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2562 MODEST_WIDGET_TYPE_HEADER_VIEW);
2564 /* Select all messages */
2565 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2566 gtk_tree_selection_select_all (selection);
2568 /* Set focuse on header view */
2569 gtk_widget_grab_focus (header_view);
2575 modest_ui_actions_on_mark_as_read (GtkAction *action,
2576 ModestWindow *window)
2578 g_return_if_fail (MODEST_IS_WINDOW(window));
2580 /* Mark each header as read */
2581 do_headers_action (window, headers_action_mark_as_read, NULL);
2585 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2586 ModestWindow *window)
2588 g_return_if_fail (MODEST_IS_WINDOW(window));
2590 /* Mark each header as read */
2591 do_headers_action (window, headers_action_mark_as_unread, NULL);
2595 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2596 GtkRadioAction *selected,
2597 ModestWindow *window)
2601 value = gtk_radio_action_get_current_value (selected);
2602 if (MODEST_IS_WINDOW (window)) {
2603 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2607 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2608 GtkRadioAction *selected,
2609 ModestWindow *window)
2611 TnyHeaderFlags flags;
2612 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2614 flags = gtk_radio_action_get_current_value (selected);
2615 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2618 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2619 GtkRadioAction *selected,
2620 ModestWindow *window)
2624 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2626 file_format = gtk_radio_action_get_current_value (selected);
2627 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2632 modest_ui_actions_on_zoom_plus (GtkAction *action,
2633 ModestWindow *window)
2635 g_return_if_fail (MODEST_IS_WINDOW (window));
2637 modest_window_zoom_plus (MODEST_WINDOW (window));
2641 modest_ui_actions_on_zoom_minus (GtkAction *action,
2642 ModestWindow *window)
2644 g_return_if_fail (MODEST_IS_WINDOW (window));
2646 modest_window_zoom_minus (MODEST_WINDOW (window));
2650 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2651 ModestWindow *window)
2653 ModestWindowMgr *mgr;
2654 gboolean fullscreen, active;
2655 g_return_if_fail (MODEST_IS_WINDOW (window));
2657 mgr = modest_runtime_get_window_mgr ();
2659 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2660 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2662 if (active != fullscreen) {
2663 modest_window_mgr_set_fullscreen_mode (mgr, active);
2664 gtk_window_present (GTK_WINDOW (window));
2669 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2670 ModestWindow *window)
2672 ModestWindowMgr *mgr;
2673 gboolean fullscreen;
2675 g_return_if_fail (MODEST_IS_WINDOW (window));
2677 mgr = modest_runtime_get_window_mgr ();
2678 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2679 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2681 gtk_window_present (GTK_WINDOW (window));
2685 * Used by modest_ui_actions_on_details to call do_headers_action
2688 headers_action_show_details (TnyHeader *header,
2689 ModestWindow *window,
2696 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2699 gtk_widget_show_all (dialog);
2700 gtk_dialog_run (GTK_DIALOG (dialog));
2702 gtk_widget_destroy (dialog);
2706 * Show the folder details in a ModestDetailsDialog widget
2709 show_folder_details (TnyFolder *folder,
2715 dialog = modest_details_dialog_new_with_folder (window, folder);
2718 gtk_widget_show_all (dialog);
2719 gtk_dialog_run (GTK_DIALOG (dialog));
2721 gtk_widget_destroy (dialog);
2725 * Show the header details in a ModestDetailsDialog widget
2728 modest_ui_actions_on_details (GtkAction *action,
2731 TnyList * headers_list;
2735 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2738 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2741 g_object_unref (msg);
2743 headers_list = get_selected_headers (win);
2747 iter = tny_list_create_iterator (headers_list);
2749 header = TNY_HEADER (tny_iterator_get_current (iter));
2750 headers_action_show_details (header, win, NULL);
2751 g_object_unref (header);
2753 g_object_unref (iter);
2754 g_object_unref (headers_list);
2756 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2757 GtkWidget *folder_view, *header_view;
2759 /* Check which widget has the focus */
2760 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2761 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2762 if (gtk_widget_is_focus (folder_view)) {
2763 TnyFolderStore *folder_store
2764 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2765 if (!folder_store) {
2766 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2769 /* Show only when it's a folder */
2770 /* This function should not be called for account items,
2771 * because we dim the menu item for them. */
2772 if (TNY_IS_FOLDER (folder_store)) {
2773 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2776 g_object_unref (folder_store);
2779 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2780 MODEST_WIDGET_TYPE_HEADER_VIEW);
2781 /* Show details of each header */
2782 do_headers_action (win, headers_action_show_details, header_view);
2788 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2789 ModestMsgEditWindow *window)
2791 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2793 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2797 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2798 ModestMsgEditWindow *window)
2800 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2802 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2806 modest_ui_actions_toggle_folders_view (GtkAction *action,
2807 ModestMainWindow *main_window)
2811 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2813 conf = modest_runtime_get_conf ();
2815 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2816 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2818 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2822 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2823 ModestWindow *window)
2825 gboolean active, fullscreen = FALSE;
2826 ModestWindowMgr *mgr;
2828 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2830 /* Check if we want to toggle the toolbar vuew in fullscreen
2832 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2833 "ViewShowToolbarFullScreen")) {
2837 /* Toggle toolbar */
2838 mgr = modest_runtime_get_window_mgr ();
2839 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2843 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2844 ModestMsgEditWindow *window)
2846 modest_msg_edit_window_select_font (window);
2850 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2851 const gchar *display_name,
2854 /* Do not change the application name if the widget has not
2855 the focus. This callback could be called even if the folder
2856 view has not the focus, because the handled signal could be
2857 emitted when the folder view is redrawn */
2858 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2860 gtk_window_set_title (window, display_name);
2862 gtk_window_set_title (window, " ");
2867 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2869 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2870 modest_msg_edit_window_select_contacts (window);
2874 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2876 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2877 modest_msg_edit_window_check_names (window);
2882 create_move_to_dialog (ModestWindow *win,
2883 GtkWidget *folder_view,
2884 GtkWidget **tree_view)
2886 GtkWidget *dialog, *scroll;
2888 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2890 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2892 GTK_RESPONSE_ACCEPT,
2894 GTK_RESPONSE_REJECT,
2897 /* Create scrolled window */
2898 scroll = gtk_scrolled_window_new (NULL, NULL);
2899 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2900 GTK_POLICY_AUTOMATIC,
2901 GTK_POLICY_AUTOMATIC);
2903 /* Create folder view */
2904 *tree_view = modest_platform_create_folder_view (NULL);
2906 /* It could happen that we're trying to move a message from a
2907 window (msg window for example) after the main window was
2908 closed, so we can not just get the model of the folder
2910 if (MODEST_IS_FOLDER_VIEW (folder_view))
2911 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2912 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2914 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2915 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2917 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2919 /* Add scroll to dialog */
2920 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2921 scroll, FALSE, FALSE, 0);
2923 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2925 /* Select INBOX or local account */
2926 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2932 * Returns TRUE if at least one of the headers of the list belongs to
2933 * a message that has been fully retrieved.
2936 has_retrieved_msgs (TnyList *list)
2939 gboolean found = FALSE;
2941 iter = tny_list_create_iterator (list);
2942 while (tny_iterator_is_done (iter) && !found) {
2944 TnyHeaderFlags flags;
2946 header = TNY_HEADER (tny_iterator_get_current (iter));
2947 flags = tny_header_get_flags (header);
2948 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2952 tny_iterator_next (iter);
2954 g_object_unref (iter);
2960 * Shows a confirmation dialog to the user when we're moving messages
2961 * from a remote server to the local storage. Returns the dialog
2962 * response. If it's other kind of movement the it always returns
2966 msgs_move_to_confirmation (GtkWindow *win,
2967 TnyFolder *dest_folder,
2970 gint response = GTK_RESPONSE_OK;
2972 /* If the destination is a local folder */
2973 if (modest_tny_folder_is_local_folder (dest_folder)) {
2974 TnyFolder *src_folder;
2978 /* Get source folder */
2979 iter = tny_list_create_iterator (headers);
2980 header = TNY_HEADER (tny_iterator_get_current (iter));
2981 src_folder = tny_header_get_folder (header);
2982 g_object_unref (header);
2983 g_object_unref (iter);
2985 /* if no src_folder, message may be an attahcment */
2986 if (src_folder == NULL)
2987 return GTK_RESPONSE_CANCEL;
2989 /* If the source is a remote folder */
2990 if (!modest_tny_folder_is_local_folder (src_folder)) {
2991 const gchar *message;
2993 if (has_retrieved_msgs (headers))
2994 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2995 tny_list_get_length (headers));
2997 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2998 tny_list_get_length (headers));
3000 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3001 (const gchar *) message);
3003 g_object_unref (src_folder);
3011 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3013 ModestMsgViewWindow *self = NULL;
3014 gboolean last, first;
3016 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3017 self = MODEST_MSG_VIEW_WINDOW (object);
3019 last = modest_msg_view_window_last_message_selected (self);
3020 first = modest_msg_view_window_first_message_selected (self);
3022 /* No more messages to view, so close this window */
3023 /* gboolean ret_value; */
3024 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
3025 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3027 modest_msg_view_window_select_previous_message (self);
3029 modest_msg_view_window_select_next_message (self);
3033 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3036 GObject *win = modest_mail_operation_get_source (mail_op);
3037 const GError *error = NULL;
3038 const gchar *message = NULL;
3040 /* Get error message */
3041 error = modest_mail_operation_get_error (mail_op);
3042 if (error != NULL && error->message != NULL) {
3043 message = error->message;
3045 message = _("mail_in_ui_folder_move_target_error");
3048 /* Show notification dialog */
3049 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3050 g_object_unref (win);
3054 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3057 GObject *win = modest_mail_operation_get_source (mail_op);
3058 const GError *error = modest_mail_operation_get_error (mail_op);
3060 g_return_if_fail (error != NULL);
3061 if (error->message != NULL)
3062 g_printerr ("modest: %s\n", error->message);
3064 g_printerr ("modest: unkonw error on send&receive operation");
3066 /* Show error message */
3067 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3068 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3069 /* _CS("sfil_ib_unable_to_receive")); */
3071 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3072 /* _CS("sfil_ib_unable_to_send")); */
3073 g_object_unref (win);
3077 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3084 gint pending_purges = 0;
3085 gboolean some_purged = FALSE;
3086 ModestWindow *win = MODEST_WINDOW (user_data);
3088 /* If there was any error */
3089 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
3092 /* Once the message has been retrieved for purging, we check if
3093 * it's all ok for purging */
3095 parts = tny_simple_list_new ();
3096 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3097 iter = tny_list_create_iterator (parts);
3099 while (!tny_iterator_is_done (iter)) {
3101 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3102 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3103 if (tny_mime_part_is_purged (part))
3108 tny_iterator_next (iter);
3111 if (pending_purges>0) {
3113 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3115 if (response == GTK_RESPONSE_OK) {
3116 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3117 tny_iterator_first (iter);
3118 while (!tny_iterator_is_done (iter)) {
3121 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3122 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3123 tny_mime_part_set_purged (part);
3124 tny_iterator_next (iter);
3127 tny_msg_rewrite_cache (msg);
3130 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3133 /* remove attachments */
3134 tny_iterator_first (iter);
3135 while (!tny_iterator_is_done (iter)) {
3138 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3139 g_object_unref (part);
3140 tny_iterator_next (iter);
3143 g_object_unref (iter);
3144 g_object_unref (parts);
3148 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3149 ModestMainWindow *win)
3151 GtkWidget *header_view;
3152 TnyList *header_list;
3155 TnyHeaderFlags flags;
3156 ModestWindow *msg_view_window = NULL;
3159 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3161 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3162 MODEST_WIDGET_TYPE_HEADER_VIEW);
3164 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3166 if (tny_list_get_length (header_list) == 1) {
3167 iter = tny_list_create_iterator (header_list);
3168 header = TNY_HEADER (tny_iterator_get_current (iter));
3169 g_object_unref (iter);
3174 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3175 header, &msg_view_window);
3176 flags = tny_header_get_flags (header);
3177 if (!(flags & TNY_HEADER_FLAG_CACHED))
3180 if (msg_view_window != NULL)
3181 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3183 /* do nothing; uid was registered before, so window is probably on it's way */
3184 g_warning ("debug: header %p has already been registered", header);
3187 ModestMailOperation *mail_op = NULL;
3188 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3189 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3191 modest_ui_actions_get_msgs_full_error_handler,
3193 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3194 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3196 g_object_unref (mail_op);
3199 g_object_unref (header);
3201 g_object_unref (header_list);
3205 * UI handler for the "Move to" action when invoked from the
3209 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3210 ModestMainWindow *win)
3212 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3213 GtkWidget *header_view = NULL;
3215 TnyFolderStore *folder_store = NULL;
3216 ModestMailOperation *mail_op = NULL;
3218 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3220 /* Get the folder view */
3221 folder_view = modest_main_window_get_child_widget (win,
3222 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3224 /* Get header view */
3225 header_view = modest_main_window_get_child_widget (win,
3226 MODEST_WIDGET_TYPE_HEADER_VIEW);
3228 /* Create and run the dialog */
3229 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3230 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3231 result = gtk_dialog_run (GTK_DIALOG(dialog));
3232 g_object_ref (tree_view);
3234 /* We do this to save an indentation level ;-) */
3235 if (result != GTK_RESPONSE_ACCEPT)
3238 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3240 if (TNY_IS_ACCOUNT (folder_store) &&
3241 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3244 /* Offer the connection dialog if necessary: */
3245 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) {
3249 /* Get folder or messages to transfer */
3250 if (gtk_widget_is_focus (folder_view)) {
3251 TnyFolderStore *src_folder;
3252 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3254 /* Offer the connection dialog if necessary: */
3255 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) {
3257 /* Clean folder on header view before moving it */
3258 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3260 if (TNY_IS_FOLDER (src_folder)) {
3262 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3264 modest_ui_actions_move_folder_error_handler,
3266 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3268 modest_mail_operation_xfer_folder (mail_op,
3269 TNY_FOLDER (src_folder),
3272 /* Unref mail operation */
3273 g_object_unref (G_OBJECT (mail_op));
3277 g_object_unref (G_OBJECT (src_folder));
3280 if (gtk_widget_is_focus (header_view)) {
3281 TnyList *headers = NULL;
3284 /* TODO: Check for connection if the headers are on a network account. */
3285 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3287 /* Ask for user confirmation */
3288 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3289 TNY_FOLDER (folder_store),
3292 /* Transfer messages */
3293 if (response == GTK_RESPONSE_OK) {
3295 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3297 modest_ui_actions_move_folder_error_handler,
3299 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3302 modest_mail_operation_xfer_msgs (mail_op,
3304 TNY_FOLDER (folder_store),
3309 g_object_unref (G_OBJECT (mail_op));
3311 g_object_unref (headers);
3316 if (folder_store != NULL)
3317 g_object_unref (folder_store);
3319 gtk_widget_destroy (dialog);
3324 * UI handler for the "Move to" action when invoked from the
3325 * ModestMsgViewWindow
3328 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3329 ModestMsgViewWindow *win)
3331 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3333 ModestMainWindow *main_window = NULL;
3334 TnyHeader *header = NULL;
3335 TnyList *headers = NULL;
3337 /* Get the folder view */
3338 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3340 folder_view = modest_main_window_get_child_widget (main_window,
3341 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3345 /* Create and run the dialog */
3346 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3347 result = gtk_dialog_run (GTK_DIALOG(dialog));
3349 if (result == GTK_RESPONSE_ACCEPT) {
3350 TnyFolderStore *folder_store;
3353 /* Create header list */
3354 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3355 g_return_if_fail (header != NULL);
3357 /* Offer the connection dialog if necessary: */
3358 /* TODO: What's the extra g_object_ref() for? Isn't this leaking a ref? */
3359 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view)));
3360 TnyFolder *header_folder = tny_header_get_folder(header);
3361 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, folder_store) &&
3362 modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (header_folder))) {
3364 headers = tny_simple_list_new ();
3365 tny_list_prepend (headers, G_OBJECT (header));
3366 g_object_unref (header);
3368 /* Ask user for confirmation. MSG-NOT404 */
3369 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3370 TNY_FOLDER (folder_store),
3373 /* Transfer current msg */
3374 if (response == GTK_RESPONSE_OK) {
3375 ModestMailOperation *mail_op;
3377 /* Create mail op */
3378 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3379 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3382 /* Transfer messages */
3383 modest_mail_operation_xfer_msgs (mail_op,
3385 TNY_FOLDER (folder_store),
3387 transfer_msgs_from_viewer_cb,
3389 g_object_unref (G_OBJECT (mail_op));
3394 g_object_unref (header_folder);
3397 g_object_unref (headers);
3400 g_object_unref (folder_store);
3403 gtk_widget_destroy (dialog);
3407 modest_ui_actions_on_move_to (GtkAction *action,
3410 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3411 MODEST_IS_MSG_VIEW_WINDOW (win));
3413 if (MODEST_IS_MAIN_WINDOW (win))
3414 modest_ui_actions_on_main_window_move_to (action,
3415 MODEST_MAIN_WINDOW (win));
3417 modest_ui_actions_on_msg_view_window_move_to (action,
3418 MODEST_MSG_VIEW_WINDOW (win));
3422 * Calls #HeadersFunc for each header already selected in the main
3423 * window or the message currently being shown in the msg view window
3426 do_headers_action (ModestWindow *win,
3430 TnyList *headers_list;
3436 headers_list = get_selected_headers (win);
3440 /* Get the folder */
3441 iter = tny_list_create_iterator (headers_list);
3442 header = TNY_HEADER (tny_iterator_get_current (iter));
3443 folder = tny_header_get_folder (header);
3444 g_object_unref (header);
3446 /* Call the function for each header */
3447 while (!tny_iterator_is_done (iter)) {
3448 header = TNY_HEADER (tny_iterator_get_current (iter));
3449 func (header, win, user_data);
3450 g_object_unref (header);
3451 tny_iterator_next (iter);
3454 /* Trick: do a poke status in order to speed up the signaling
3456 tny_folder_poke_status (folder);
3459 g_object_unref (folder);
3460 g_object_unref (iter);
3461 g_object_unref (headers_list);
3465 modest_ui_actions_view_attachment (GtkAction *action,
3466 ModestWindow *window)
3468 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3469 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3471 /* not supported window for this action */
3472 g_return_if_reached ();
3477 modest_ui_actions_save_attachments (GtkAction *action,
3478 ModestWindow *window)
3480 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3481 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3483 /* not supported window for this action */
3484 g_return_if_reached ();
3489 modest_ui_actions_remove_attachments (GtkAction *action,
3490 ModestWindow *window)
3492 if (MODEST_IS_MAIN_WINDOW (window)) {
3493 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3494 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3495 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3497 /* not supported window for this action */
3498 g_return_if_reached ();
3503 modest_ui_actions_on_settings (GtkAction *action,
3508 dialog = modest_platform_get_global_settings_dialog ();
3509 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3510 gtk_widget_show_all (dialog);
3512 gtk_dialog_run (GTK_DIALOG (dialog));
3514 gtk_widget_destroy (dialog);
3518 modest_ui_actions_on_help (GtkAction *action,
3521 const gchar *help_id = NULL;
3523 if (MODEST_IS_MAIN_WINDOW (win)) {
3524 const gchar *action_name;
3525 action_name = gtk_action_get_name (action);
3527 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3528 !strcmp (action_name, "HeaderViewCSMHelp")) {
3529 GtkWidget *folder_view;
3530 TnyFolderStore *folder_store;
3531 /* Get selected folder */
3532 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3533 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3534 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3536 /* Switch help_id */
3537 if (TNY_IS_FOLDER (folder_store)) {
3538 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3539 case TNY_FOLDER_TYPE_NORMAL:
3540 help_id = "applications_email_userfolder";
3542 case TNY_FOLDER_TYPE_INBOX:
3543 help_id = "applications_email_inbox";
3545 case TNY_FOLDER_TYPE_OUTBOX:
3546 help_id = "applications_email_outbox";
3548 case TNY_FOLDER_TYPE_SENT:
3549 help_id = "applications_email_sent";
3551 case TNY_FOLDER_TYPE_DRAFTS:
3552 help_id = "applications_email_drafts";
3554 case TNY_FOLDER_TYPE_ARCHIVE:
3555 help_id = "applications_email_archive";
3561 g_object_unref (folder_store);
3563 help_id = "applications_email_mainview";
3565 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3566 help_id = "applications_email_viewer";
3567 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3568 help_id = "applications_email_editor";
3570 modest_platform_show_help (GTK_WINDOW (win), help_id);
3574 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3575 ModestWindow *window)
3577 ModestMailOperation *mail_op;
3581 headers = get_selected_headers (window);
3585 /* Create mail operation */
3586 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3588 modest_ui_actions_get_msgs_full_error_handler,
3590 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3591 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3594 g_object_unref (headers);
3595 g_object_unref (mail_op);
3599 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3600 ModestWindow *window)
3602 g_return_if_fail (MODEST_IS_WINDOW (window));
3605 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3609 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3610 ModestWindow *window)
3612 g_return_if_fail (MODEST_IS_WINDOW (window));
3615 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3619 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3620 ModestWindow *window)
3622 g_return_if_fail (MODEST_IS_WINDOW (window));
3625 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3629 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3630 ModestWindow *window)
3632 g_return_if_fail (MODEST_IS_WINDOW (window));
3635 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3639 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3640 ModestWindow *window)
3642 g_return_if_fail (MODEST_IS_WINDOW (window));
3645 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3649 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3650 ModestWindow *window)
3652 g_return_if_fail (MODEST_IS_WINDOW (window));
3655 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3659 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3660 ModestWindow *window)
3662 g_return_if_fail (MODEST_IS_WINDOW (window));
3665 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3669 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3670 ModestWindow *window)
3672 g_return_if_fail (MODEST_IS_WINDOW (window));
3675 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3679 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3681 g_return_if_fail (MODEST_IS_WINDOW (window));
3684 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3688 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3690 g_return_if_fail (MODEST_IS_WINDOW (window));
3692 modest_platform_show_search_messages (GTK_WINDOW (window));
3696 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3698 g_return_if_fail (MODEST_IS_WINDOW (win));
3699 modest_platform_show_addressbook (GTK_WINDOW (win));
3704 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3705 ModestWindow *window)
3707 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3709 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3713 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3714 ModestMailOperationState *state,
3717 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3719 /* Set send/receive operation finished */
3720 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3721 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));