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);
109 do_headers_action (ModestWindow *win,
114 static void open_msg_cb (ModestMailOperation *mail_op,
119 static void reply_forward_cb (ModestMailOperation *mail_op,
124 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
127 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
128 ModestMailOperationState *state,
134 run_account_setup_wizard (ModestWindow *win)
136 ModestEasysetupWizardDialog *wizard;
138 g_return_if_fail (MODEST_IS_WINDOW(win));
140 wizard = modest_easysetup_wizard_dialog_new ();
141 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
142 gtk_dialog_run (GTK_DIALOG (wizard));
143 gtk_widget_destroy (GTK_WIDGET (wizard));
148 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
151 const gchar *authors[] = {
152 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
155 about = gtk_about_dialog_new ();
156 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
157 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
158 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
159 _("Copyright (c) 2006, Nokia Corporation\n"
160 "All rights reserved."));
161 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
162 _("a modest e-mail client\n\n"
163 "design and implementation: Dirk-Jan C. Binnema\n"
164 "contributions from the fine people at KC and Ig\n"
165 "uses the tinymail email framework written by Philip van Hoof"));
166 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
167 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
169 gtk_dialog_run (GTK_DIALOG (about));
170 gtk_widget_destroy(about);
174 * Gets the list of currently selected messages. If the win is the
175 * main window, then it returns a newly allocated list of the headers
176 * selected in the header view. If win is the msg view window, then
177 * the value returned is a list with just a single header.
179 * The caller of this funcion must free the list.
182 get_selected_headers (ModestWindow *win)
184 if (MODEST_IS_MAIN_WINDOW(win)) {
185 GtkWidget *header_view;
187 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
188 MODEST_WIDGET_TYPE_HEADER_VIEW);
189 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
191 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
192 /* for MsgViewWindows, we simply return a list with one element */
194 TnyList *list = NULL;
196 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
197 if (header != NULL) {
198 list = tny_simple_list_new ();
199 tny_list_prepend (list, G_OBJECT(header));
200 g_object_unref (G_OBJECT(header));
210 headers_action_mark_as_read (TnyHeader *header,
214 TnyHeaderFlags flags;
216 g_return_if_fail (TNY_IS_HEADER(header));
218 flags = tny_header_get_flags (header);
219 if (flags & TNY_HEADER_FLAG_SEEN) return;
220 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
224 headers_action_mark_as_unread (TnyHeader *header,
228 TnyHeaderFlags flags;
230 g_return_if_fail (TNY_IS_HEADER(header));
232 flags = tny_header_get_flags (header);
233 if (flags & TNY_HEADER_FLAG_SEEN) {
234 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
240 headers_action_delete (TnyHeader *header,
244 ModestMailOperation *mail_op = NULL;
246 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
247 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
250 /* Always delete. TODO: Move to trash still not supported */
251 modest_mail_operation_remove_msg (mail_op, header, FALSE);
252 g_object_unref (G_OBJECT (mail_op));
254 /* refilter treemodel to hide marked-as-deleted rows */
255 if (MODEST_IS_HEADER_VIEW (user_data))
256 modest_header_view_refilter (MODEST_HEADER_VIEW (user_data));
260 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
262 TnyList *header_list = NULL;
263 TnyIterator *iter = NULL;
264 TnyHeader *header = NULL;
265 gchar *message = NULL;
268 ModestWindowMgr *mgr;
269 GtkWidget *header_view = NULL;
271 g_return_if_fail (MODEST_IS_WINDOW(win));
273 /* Check first if the header view has the focus */
274 if (MODEST_IS_MAIN_WINDOW (win)) {
276 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
277 MODEST_WIDGET_TYPE_HEADER_VIEW);
278 if (!gtk_widget_is_focus (header_view))
282 header_list = get_selected_headers (win);
283 if (!header_list) return;
285 /* Check if any of the headers is already opened, or in the process of being opened */
286 if (MODEST_IS_MAIN_WINDOW (win)) {
288 iter = tny_list_create_iterator (header_list);
290 mgr = modest_runtime_get_window_mgr ();
291 while (!tny_iterator_is_done (iter) && !found) {
292 header = TNY_HEADER (tny_iterator_get_current (iter));
293 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
294 g_object_unref (header);
295 tny_iterator_next (iter);
297 g_object_unref (iter);
302 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
303 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
305 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
309 g_object_unref (header_list);
315 if (tny_list_get_length(header_list) == 1) {
316 iter = tny_list_create_iterator (header_list);
317 header = TNY_HEADER (tny_iterator_get_current (iter));
318 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
319 g_object_unref (header);
320 g_object_unref (iter);
322 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
323 tny_list_get_length(header_list)), desc);
325 /* Confirmation dialog */
326 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
330 if (response == GTK_RESPONSE_OK) {
331 ModestMainWindow *main_window;
332 ModestWindowMgr *mgr;
334 /* Remove each header. If it's a view window header_view == NULL */
335 do_headers_action (win, headers_action_delete, header_view);
337 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
338 /* Close msg view window or select next */
339 if (modest_msg_view_window_last_message_selected (MODEST_MSG_VIEW_WINDOW (win)) &&
340 modest_msg_view_window_first_message_selected (MODEST_MSG_VIEW_WINDOW (win))) {
341 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
343 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (win));
347 /* Refilter header view model, if main window still exists */
348 mgr = modest_runtime_get_window_mgr ();
349 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
353 widget = modest_main_window_get_child_widget (main_window,
354 MODEST_WIDGET_TYPE_HEADER_VIEW);
355 modest_header_view_refilter (MODEST_HEADER_VIEW (widget));
358 /* Update toolbar dimming state */
359 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
365 g_object_unref (header_list);
370 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
372 #ifdef MODEST_PLATFORM_MAEMO
373 modest_osso_save_state();
374 #endif /* MODEST_PLATFORM_MAEMO */
376 g_debug ("closing down, clearing %d item(s) from operation queue",
377 modest_mail_operation_queue_num_elements
378 (modest_runtime_get_mail_operation_queue()));
380 /* cancel all outstanding operations */
381 modest_mail_operation_queue_cancel_all
382 (modest_runtime_get_mail_operation_queue());
384 g_debug ("queue has been cleared");
386 /* note: when modest-tny-account-store is finalized,
387 it will automatically set all network connections
394 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
397 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
399 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
400 /* gtk_widget_destroy (GTK_WIDGET (win)); */
401 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
402 /* gboolean ret_value; */
403 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
404 /* } else if (MODEST_IS_WINDOW (win)) { */
405 /* gtk_widget_destroy (GTK_WIDGET (win)); */
407 /* g_return_if_reached (); */
412 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
414 GtkClipboard *clipboard = NULL;
415 gchar *selection = NULL;
417 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
418 selection = gtk_clipboard_wait_for_text (clipboard);
420 /* Question: why is the clipboard being used here?
421 * It doesn't really make a lot of sense. */
425 modest_address_book_add_address (selection);
431 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
433 /* This is currently only implemented for Maemo */
434 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
435 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
436 run_account_setup_wizard (win);
439 /* Show the list of accounts: */
440 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
441 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
442 gtk_dialog_run (account_win);
443 gtk_widget_destroy (GTK_WIDGET(account_win));
446 GtkWidget *dialog, *label;
448 /* Create the widgets */
450 dialog = gtk_dialog_new_with_buttons ("Message",
452 GTK_DIALOG_DESTROY_WITH_PARENT,
456 label = gtk_label_new ("Hello World!");
458 /* Ensure that the dialog box is destroyed when the user responds. */
460 g_signal_connect_swapped (dialog, "response",
461 G_CALLBACK (gtk_widget_destroy),
464 /* Add the label, and show everything we've added to the dialog. */
466 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
468 gtk_widget_show_all (dialog);
469 #endif /* MODEST_PLATFORM_MAEMO */
473 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
475 ModestWindow *main_window = MODEST_WINDOW (user_data);
477 /* Save any changes. */
478 modest_connection_specific_smtp_window_save_server_accounts (
479 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
480 modest_window_get_active_account (main_window));
481 gtk_widget_destroy (GTK_WIDGET (window));
487 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
489 /* This is currently only implemented for Maemo,
490 * because it requires an API (libconic) to detect different connection
493 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
495 /* Create the window if necessary: */
496 const gchar *active_account_name = modest_window_get_active_account (win);
498 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
499 * or show the default account?
500 * If we show the default account then the account name should be shown in
501 * the window when we show it. */
502 if (!active_account_name) {
503 g_warning ("%s: No account is active.", __FUNCTION__);
507 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
508 modest_connection_specific_smtp_window_fill_with_connections (
509 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
510 modest_runtime_get_account_mgr(),
511 active_account_name);
513 /* Show the window: */
514 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
515 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
516 gtk_widget_show (specific_window);
518 /* Save changes when the window is hidden: */
519 g_signal_connect (specific_window, "hide",
520 G_CALLBACK (on_smtp_servers_window_hide), win);
521 #endif /* MODEST_PLATFORM_MAEMO */
525 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
527 ModestWindow *msg_win = NULL;
529 TnyFolder *folder = NULL;
530 gchar *account_name = NULL;
531 gchar *from_str = NULL;
532 /* GError *err = NULL; */
533 TnyAccount *account = NULL;
534 ModestWindowMgr *mgr;
535 gchar *signature = NULL, *blank_and_signature = NULL;
537 /* if there are no accounts yet, just show the wizard */
538 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
539 run_account_setup_wizard (win);
543 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
545 account_name = g_strdup (modest_window_get_active_account (win));
547 g_printerr ("modest: no account found\n");
551 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
553 TNY_ACCOUNT_TYPE_STORE);
555 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
559 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
561 g_printerr ("modest: failed get from string for '%s'\n", account_name);
565 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
566 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
567 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
568 MODEST_ACCOUNT_SIGNATURE, FALSE);
569 blank_and_signature = g_strconcat ("\n", signature, NULL);
572 blank_and_signature = g_strdup ("");
575 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
577 g_printerr ("modest: failed to create new msg\n");
581 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
583 g_printerr ("modest: failed to find Drafts folder\n");
588 /* Create and register edit window */
589 /* This is destroyed by TOOD. */
590 msg_win = modest_msg_edit_window_new (msg, account_name);
591 mgr = modest_runtime_get_window_mgr ();
592 modest_window_mgr_register_window (mgr, msg_win);
595 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
597 gtk_widget_show_all (GTK_WIDGET (msg_win));
600 g_free (account_name);
602 g_free (blank_and_signature);
604 g_object_unref (msg_win);
606 g_object_unref (G_OBJECT(account));
608 g_object_unref (G_OBJECT(msg));
610 g_object_unref (G_OBJECT(folder));
614 open_msg_cb (ModestMailOperation *mail_op,
619 ModestWindowMgr *mgr = NULL;
620 ModestWindow *parent_win = NULL;
621 ModestWindow *win = NULL;
622 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
623 gchar *account = NULL;
626 /* TODO: Show an error? (review the specs) */
630 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
631 folder = tny_header_get_folder (header);
633 /* Mark header as read */
634 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
637 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
639 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
641 /* Gets folder type (OUTBOX headers will be opened in edit window */
642 if (modest_tny_folder_is_local_folder (folder))
643 folder_type = modest_tny_folder_get_local_folder_type (folder);
645 /* If the header is in the drafts folder then open the editor,
646 else the message view window */
647 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
648 /* we cannot edit without a valid account... */
649 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
650 run_account_setup_wizard(parent_win);
653 win = modest_msg_edit_window_new (msg, account);
655 gchar *uid = modest_tny_folder_get_header_unique_id (header);
657 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
658 GtkWidget *header_view;
659 GtkTreeSelection *sel;
660 GList *sel_list = NULL;
663 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
664 MODEST_WIDGET_TYPE_HEADER_VIEW);
666 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
667 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
669 if (sel_list != NULL) {
670 GtkTreeRowReference *row_reference;
672 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
673 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
674 g_list_free (sel_list);
676 win = modest_msg_view_window_new_with_header_model (msg,
681 gtk_tree_row_reference_free (row_reference);
683 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
686 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
691 /* Register and show new window */
693 mgr = modest_runtime_get_window_mgr ();
694 modest_window_mgr_register_window (mgr, win);
695 g_object_unref (win);
696 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
697 gtk_widget_show_all (GTK_WIDGET(win));
700 /* Update toolbar dimming state */
701 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
702 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
708 g_object_unref (parent_win);
709 /* g_object_unref (msg); */
710 g_object_unref (folder);
714 * This function is the error handler of the
715 * modest_mail_operation_get_msgs_full operation
718 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
723 error = modest_mail_operation_get_error (mail_op);
724 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
725 GObject *win = modest_mail_operation_get_source (mail_op);
727 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
729 g_object_unref (win);
734 * This function is used by both modest_ui_actions_on_open and
735 * modest_ui_actions_on_header_activated. This way we always do the
736 * same when trying to open messages.
739 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
741 ModestWindowMgr *mgr = NULL;
742 TnyIterator *iter = NULL;
743 ModestMailOperation *mail_op1 = NULL;
744 ModestMailOperation *mail_op2 = NULL;
745 TnyList *not_opened_headers = NULL;
746 TnyList *not_opened_cached_headers = NULL;
747 TnyHeaderFlags flags;
749 /* Look if we already have a message view for each header. If
750 true, then remove the header from the list of headers to
752 mgr = modest_runtime_get_window_mgr ();
753 iter = tny_list_create_iterator (headers);
754 not_opened_headers = tny_simple_list_new ();
755 not_opened_cached_headers = tny_simple_list_new ();
756 while (!tny_iterator_is_done (iter)) {
758 ModestWindow *window;
762 header = TNY_HEADER (tny_iterator_get_current (iter));
763 flags = tny_header_get_flags (header);
766 found = modest_window_mgr_find_registered_header (mgr, header, &window);
768 /* Do not open again the message and present the
769 window to the user */
772 gtk_window_present (GTK_WINDOW (window));
774 /* the header has been registered already, we don't do
775 * anything but wait for the window to come up*/
776 g_warning ("debug: header %p already registered, waiting for window",
779 /* register the header before actually creating the window */
780 modest_window_mgr_register_header (mgr, header);
782 if (!(flags & TNY_HEADER_FLAG_CACHED))
783 tny_list_append (not_opened_headers, G_OBJECT (header));
784 /* Check if msg has already been retreived */
786 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
788 g_object_unref (header);
789 tny_iterator_next (iter);
792 /* Open each uncached message */
793 if (tny_list_get_length (not_opened_headers) > 0) {
794 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
796 modest_ui_actions_get_msgs_full_error_handler,
798 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
799 if (tny_list_get_length (not_opened_headers) > 1) {
800 modest_mail_operation_get_msgs_full (mail_op1,
806 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
807 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
808 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
809 g_object_unref (header);
810 g_object_unref (iter);
814 /* Open each cached message */
815 if (tny_list_get_length (not_opened_cached_headers) > 0) {
816 mail_op2 = 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_op2);
821 if (tny_list_get_length (not_opened_cached_headers) > 1) {
822 modest_mail_operation_get_msgs_full (mail_op2,
828 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
829 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
830 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
831 g_object_unref (header);
832 g_object_unref (iter);
837 if (not_opened_headers != NULL)
838 g_object_unref (not_opened_headers);
839 if (not_opened_cached_headers != NULL)
840 g_object_unref (not_opened_cached_headers);
842 g_object_unref (iter);
843 if (mail_op1 != NULL)
844 g_object_unref (mail_op1);
845 if (mail_op2 != NULL)
846 g_object_unref (mail_op2);
850 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
855 headers = get_selected_headers (win);
860 _modest_ui_actions_open (headers, win);
862 g_object_unref(headers);
867 free_reply_forward_helper (gpointer data)
869 ReplyForwardHelper *helper;
871 helper = (ReplyForwardHelper *) data;
872 g_free (helper->account_name);
873 g_slice_free (ReplyForwardHelper, helper);
877 reply_forward_cb (ModestMailOperation *mail_op,
883 ReplyForwardHelper *rf_helper;
884 ModestWindow *msg_win = NULL;
885 ModestEditType edit_type;
887 TnyAccount *account = NULL;
888 ModestWindowMgr *mgr = NULL;
889 gchar *signature = NULL;
891 g_return_if_fail (user_data != NULL);
892 rf_helper = (ReplyForwardHelper *) user_data;
894 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
895 rf_helper->account_name);
896 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
897 rf_helper->account_name,
898 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
899 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
900 rf_helper->account_name,
901 MODEST_ACCOUNT_SIGNATURE, FALSE);
904 /* Create reply mail */
905 switch (rf_helper->action) {
908 modest_tny_msg_create_reply_msg (msg, from, signature,
909 rf_helper->reply_forward_type,
910 MODEST_TNY_MSG_REPLY_MODE_SENDER);
912 case ACTION_REPLY_TO_ALL:
914 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
915 MODEST_TNY_MSG_REPLY_MODE_ALL);
916 edit_type = MODEST_EDIT_TYPE_REPLY;
920 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
921 edit_type = MODEST_EDIT_TYPE_FORWARD;
924 g_return_if_reached ();
931 g_printerr ("modest: failed to create message\n");
935 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
936 rf_helper->account_name,
937 TNY_ACCOUNT_TYPE_STORE);
939 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
943 /* Create and register the windows */
944 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
945 mgr = modest_runtime_get_window_mgr ();
946 modest_window_mgr_register_window (mgr, msg_win);
948 if (rf_helper->parent_window != NULL) {
951 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
952 modest_window_set_zoom (msg_win, parent_zoom);
955 /* Show edit window */
956 gtk_widget_show_all (GTK_WIDGET (msg_win));
960 g_object_unref (msg_win);
962 g_object_unref (G_OBJECT (new_msg));
964 g_object_unref (G_OBJECT (account));
965 /* g_object_unref (msg); */
966 g_object_unref (header);
967 free_reply_forward_helper (rf_helper);
971 * Checks a list of headers. If any of them are not currently
972 * downloaded (CACHED) then it asks the user for permission to
975 * Returns FALSE if the user does not want to download the
976 * messages. Returns TRUE if the user allowed the download or if all
977 * of them are currently downloaded
980 download_uncached_messages (TnyList *header_list, GtkWindow *win)
984 gint uncached_messages = 0;
986 iter = tny_list_create_iterator (header_list);
987 while (!tny_iterator_is_done (iter)) {
989 TnyHeaderFlags flags;
991 header = TNY_HEADER (tny_iterator_get_current (iter));
992 flags = tny_header_get_flags (header);
993 /* TODO: is this the right flag?, it seems that some
994 headers that have been previously downloaded do not
996 if (! (flags & TNY_HEADER_FLAG_CACHED))
997 uncached_messages ++;
998 g_object_unref (header);
999 tny_iterator_next (iter);
1001 g_object_unref (iter);
1003 /* Ask for user permission to download the messages */
1005 if (uncached_messages > 0) {
1006 GtkResponseType response;
1008 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1009 ngettext("mcen_nc_get_msg",
1011 uncached_messages));
1012 if (response == GTK_RESPONSE_CANCEL)
1015 /* If a download will be necessary, make sure that we have a connection: */
1016 retval = modest_platform_connect_and_wait(win);
1024 * Common code for the reply and forward actions
1027 reply_forward (ReplyForwardAction action, ModestWindow *win)
1029 ModestMailOperation *mail_op = NULL;
1030 TnyList *header_list = NULL;
1031 ReplyForwardHelper *rf_helper = NULL;
1032 guint reply_forward_type;
1033 gboolean continue_download;
1035 g_return_if_fail (MODEST_IS_WINDOW(win));
1037 /* we need an account when editing */
1038 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1039 run_account_setup_wizard (win);
1043 header_list = get_selected_headers (win);
1047 /* Check that the messages have been previously downloaded */
1048 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1049 if (!continue_download) {
1050 g_object_unref (header_list);
1054 reply_forward_type =
1055 modest_conf_get_int (modest_runtime_get_conf (),
1056 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1058 /* We assume that we can only select messages of the
1059 same folder and that we reply all of them from the
1060 same account. In fact the interface currently only
1061 allows single selection */
1064 rf_helper = g_slice_new0 (ReplyForwardHelper);
1065 rf_helper->reply_forward_type = reply_forward_type;
1066 rf_helper->action = action;
1067 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1068 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1069 rf_helper->parent_window = GTK_WIDGET (win);
1070 if (!rf_helper->account_name)
1071 rf_helper->account_name =
1072 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1074 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1077 /* Get header and message. Do not free them here, the
1078 reply_forward_cb must do it */
1079 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1080 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1081 if (!msg || !header) {
1083 g_object_unref (msg);
1085 g_object_unref (header);
1086 g_printerr ("modest: no message found\n");
1089 reply_forward_cb (NULL, header, msg, rf_helper);
1095 /* Retrieve messages */
1096 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1098 modest_ui_actions_get_msgs_full_error_handler,
1100 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1102 /* Only reply/forward to one message */
1103 iter = tny_list_create_iterator (header_list);
1104 header = TNY_HEADER (tny_iterator_get_current (iter));
1105 g_object_unref (iter);
1107 modest_mail_operation_get_msg (mail_op,
1112 /* modest_mail_operation_get_msgs_full (mail_op, */
1114 /* reply_forward_cb, */
1116 /* free_reply_forward_helper); */
1119 g_object_unref(mail_op);
1123 g_object_unref (header_list);
1127 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1129 g_return_if_fail (MODEST_IS_WINDOW(win));
1131 reply_forward (ACTION_REPLY, win);
1135 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1137 g_return_if_fail (MODEST_IS_WINDOW(win));
1139 reply_forward (ACTION_FORWARD, win);
1143 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1145 g_return_if_fail (MODEST_IS_WINDOW(win));
1147 reply_forward (ACTION_REPLY_TO_ALL, win);
1151 modest_ui_actions_on_next (GtkAction *action,
1152 ModestWindow *window)
1154 if (MODEST_IS_MAIN_WINDOW (window)) {
1155 GtkWidget *header_view;
1157 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1158 MODEST_WIDGET_TYPE_HEADER_VIEW);
1162 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1163 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1164 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1166 g_return_if_reached ();
1171 modest_ui_actions_on_prev (GtkAction *action,
1172 ModestWindow *window)
1174 g_return_if_fail (MODEST_IS_WINDOW(window));
1176 if (MODEST_IS_MAIN_WINDOW (window)) {
1177 GtkWidget *header_view;
1178 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1179 MODEST_WIDGET_TYPE_HEADER_VIEW);
1183 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1184 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1185 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1187 g_return_if_reached ();
1192 modest_ui_actions_on_sort (GtkAction *action,
1193 ModestWindow *window)
1195 g_return_if_fail (MODEST_IS_WINDOW(window));
1197 if (MODEST_IS_MAIN_WINDOW (window)) {
1198 GtkWidget *header_view;
1199 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1200 MODEST_WIDGET_TYPE_HEADER_VIEW);
1204 /* Show sorting dialog */
1205 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1210 new_messages_arrived (ModestMailOperation *self,
1214 if (new_messages == 0)
1217 modest_platform_on_new_msg ();
1221 * This function performs the send & receive required actions. The
1222 * window is used to create the mail operation. Typically it should
1223 * always be the main window, but we pass it as argument in order to
1227 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1229 gchar *acc_name = NULL;
1230 ModestMailOperation *mail_op;
1232 /* If no account name was provided then get the current account, and if
1233 there is no current account then pick the default one: */
1234 if (!account_name) {
1235 acc_name = g_strdup (modest_window_get_active_account(win));
1237 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1239 g_printerr ("modest: cannot get default account\n");
1243 acc_name = g_strdup (account_name);
1246 /* Set send/receive operation in progress */
1247 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1249 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1251 modest_ui_actions_send_receive_error_handler,
1254 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1255 G_CALLBACK (_on_send_receive_progress_changed),
1258 /* Send & receive. */
1259 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1260 /* Receive and then send. The operation is tagged initially as
1261 a receive operation because the account update performs a
1262 receive and then a send. The operation changes its type
1263 internally, so the progress objects will receive the proper
1264 progress information */
1265 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1266 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1267 g_object_unref (G_OBJECT (mail_op));
1274 * Refreshes all accounts. This function will be used by automatic
1278 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1280 GSList *account_names, *iter;
1282 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1285 iter = account_names;
1287 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1288 iter = g_slist_next (iter);
1291 modest_account_mgr_free_account_names (account_names);
1292 account_names = NULL;
1296 * Handler of the click on Send&Receive button in the main toolbar
1299 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1301 /* Check if accounts exist */
1302 gboolean accounts_exist =
1303 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1305 /* If not, allow the user to create an account before trying to send/receive. */
1306 if (!accounts_exist)
1307 modest_ui_actions_on_accounts (NULL, win);
1309 /* Refresh the active account */
1310 modest_ui_actions_do_send_receive (NULL, win);
1315 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1318 GtkWidget *header_view;
1320 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1322 header_view = modest_main_window_get_child_widget (main_window,
1323 MODEST_WIDGET_TYPE_HEADER_VIEW);
1327 conf = modest_runtime_get_conf ();
1329 /* what is saved/restored is depending on the style; thus; we save with
1330 * old style, then update the style, and restore for this new style
1332 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1334 if (modest_header_view_get_style
1335 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1336 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1337 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1339 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1340 MODEST_HEADER_VIEW_STYLE_DETAILS);
1342 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1343 MODEST_CONF_HEADER_VIEW_KEY);
1348 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1350 ModestMainWindow *main_window)
1352 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1353 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1355 /* If no header has been selected then exit */
1360 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1361 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1363 /* Update Main window title */
1364 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1365 const gchar *subject = tny_header_get_subject (header);
1366 if (subject && strlen(subject) > 0)
1367 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1369 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1372 /* Update toolbar dimming state */
1373 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1377 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1379 ModestMainWindow *main_window)
1383 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1388 headers = tny_simple_list_new ();
1389 tny_list_prepend (headers, G_OBJECT (header));
1391 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1393 g_object_unref (headers);
1397 set_active_account_from_tny_account (TnyAccount *account,
1398 ModestWindow *window)
1400 const gchar *server_acc_name = tny_account_get_id (account);
1402 /* We need the TnyAccount provided by the
1403 account store because that is the one that
1404 knows the name of the Modest account */
1405 TnyAccount *modest_server_account = modest_server_account =
1406 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1407 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1410 const gchar *modest_acc_name =
1411 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1412 modest_window_set_active_account (window, modest_acc_name);
1413 g_object_unref (modest_server_account);
1418 folder_refreshed_cb (const GObject *obj,
1422 ModestMainWindow *win = NULL;
1423 GtkWidget *header_view;
1425 g_return_if_fail (TNY_IS_FOLDER (folder));
1427 win = MODEST_MAIN_WINDOW (user_data);
1429 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1431 /* Check if folder is empty and set headers view contents style */
1432 if (tny_folder_get_all_count (folder) == 0) {
1433 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1434 modest_main_window_set_contents_style (win,
1435 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1437 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1442 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1443 TnyFolderStore *folder_store,
1445 ModestMainWindow *main_window)
1448 GtkWidget *header_view;
1450 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1452 header_view = modest_main_window_get_child_widget(main_window,
1453 MODEST_WIDGET_TYPE_HEADER_VIEW);
1457 conf = modest_runtime_get_conf ();
1459 if (TNY_IS_ACCOUNT (folder_store)) {
1461 /* Update active account */
1462 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1463 /* Show account details */
1464 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1467 if (TNY_IS_FOLDER (folder_store) && selected) {
1469 /* Update the active account */
1470 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1472 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1473 g_object_unref (account);
1477 /* Set the header style by default, it could
1478 be changed later by the refresh callback to
1480 modest_main_window_set_contents_style (main_window,
1481 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1483 /* Set folder on header view. This function
1484 will call tny_folder_refresh_async so we
1485 pass a callback that will be called when
1486 finished. We use that callback to set the
1487 empty view if there are no messages */
1488 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1489 TNY_FOLDER (folder_store),
1490 folder_refreshed_cb,
1493 /* Restore configuration. We need to do this
1494 *after* the set_folder because the widget
1495 memory asks the header view about its
1497 modest_widget_memory_restore (modest_runtime_get_conf (),
1498 G_OBJECT(header_view),
1499 MODEST_CONF_HEADER_VIEW_KEY);
1501 /* Update the active account */
1502 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1503 /* Save only if we're seeing headers */
1504 if (modest_main_window_get_contents_style (main_window) ==
1505 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1506 modest_widget_memory_save (conf, G_OBJECT (header_view),
1507 MODEST_CONF_HEADER_VIEW_KEY);
1508 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1512 /* Update toolbar dimming state */
1513 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1517 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1524 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1526 online = tny_device_is_online (modest_runtime_get_device());
1529 /* already online -- the item is simply not there... */
1530 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1532 GTK_MESSAGE_WARNING,
1534 _("The %s you selected cannot be found"),
1536 gtk_dialog_run (GTK_DIALOG(dialog));
1538 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1542 GTK_RESPONSE_REJECT,
1544 GTK_RESPONSE_ACCEPT,
1546 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1547 "Do you want to get online?"), item);
1548 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1549 gtk_label_new (txt), FALSE, FALSE, 0);
1550 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1553 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1554 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1555 // modest_platform_connect_and_wait ();
1558 gtk_widget_destroy (dialog);
1562 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1565 /* g_message ("%s %s", __FUNCTION__, link); */
1570 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1573 modest_platform_activate_uri (link);
1577 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1580 modest_platform_show_uri_popup (link);
1584 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1587 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1591 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1592 const gchar *address,
1595 /* g_message ("%s %s", __FUNCTION__, address); */
1599 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1601 TnyTransportAccount *transport_account;
1602 ModestMailOperation *mail_operation;
1604 gchar *account_name, *from;
1605 ModestAccountMgr *account_mgr;
1606 gchar *info_text = NULL;
1608 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1610 data = modest_msg_edit_window_get_msg_data (edit_window);
1612 account_mgr = modest_runtime_get_account_mgr();
1613 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1615 account_name = modest_account_mgr_get_default_account (account_mgr);
1616 if (!account_name) {
1617 g_printerr ("modest: no account found\n");
1618 modest_msg_edit_window_free_msg_data (edit_window, data);
1622 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1623 account_name = g_strdup (data->account_name);
1627 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1628 (modest_runtime_get_account_store(),
1630 TNY_ACCOUNT_TYPE_TRANSPORT));
1631 if (!transport_account) {
1632 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1633 g_free (account_name);
1634 modest_msg_edit_window_free_msg_data (edit_window, data);
1637 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1639 /* Create the mail operation */
1640 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1641 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1643 modest_mail_operation_save_to_drafts (mail_operation,
1654 data->priority_flags);
1657 g_free (account_name);
1658 g_object_unref (G_OBJECT (transport_account));
1659 g_object_unref (G_OBJECT (mail_operation));
1661 modest_msg_edit_window_free_msg_data (edit_window, data);
1663 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1664 modest_platform_information_banner (NULL, NULL, info_text);
1668 /* For instance, when clicking the Send toolbar button when editing a message: */
1670 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1672 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1674 if (!modest_msg_edit_window_check_names (edit_window))
1677 /* FIXME: Code added just for testing. The final version will
1678 use the send queue provided by tinymail and some
1680 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1681 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1683 account_name = modest_account_mgr_get_default_account (account_mgr);
1685 if (!account_name) {
1686 g_printerr ("modest: no account found\n");
1690 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1692 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1693 account_name = g_strdup (data->account_name);
1696 /* Get the currently-active transport account for this modest account: */
1697 TnyTransportAccount *transport_account =
1698 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1699 (modest_runtime_get_account_store(),
1701 if (!transport_account) {
1702 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1703 g_free (account_name);
1704 modest_msg_edit_window_free_msg_data (edit_window, data);
1708 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1710 /* mail content checks and dialogs */
1711 if (data->subject == NULL || data->subject[0] == '\0') {
1712 GtkResponseType response;
1713 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1714 _("mcen_nc_subject_is_empty_send"));
1715 if (response == GTK_RESPONSE_CANCEL) {
1716 g_free (account_name);
1721 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1722 GtkResponseType response;
1723 gchar *note_message;
1724 gchar *note_subject = data->subject;
1725 if (note_subject == NULL || note_subject[0] == '\0')
1726 note_subject = _("mail_va_no_subject");
1727 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1728 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1730 g_free (note_message);
1731 if (response == GTK_RESPONSE_CANCEL) {
1732 g_free (account_name);
1737 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1739 /* Create the mail operation */
1740 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1741 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1743 modest_mail_operation_send_new_mail (mail_operation,
1754 data->priority_flags);
1758 g_free (account_name);
1759 g_object_unref (G_OBJECT (transport_account));
1760 g_object_unref (G_OBJECT (mail_operation));
1762 modest_msg_edit_window_free_msg_data (edit_window, data);
1763 modest_msg_edit_window_set_sent (edit_window, TRUE);
1765 /* Save settings and close the window: */
1766 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
1770 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1771 ModestMsgEditWindow *window)
1773 ModestMsgEditFormatState *format_state = NULL;
1775 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1776 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1778 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1781 format_state = modest_msg_edit_window_get_format_state (window);
1782 g_return_if_fail (format_state != NULL);
1784 format_state->bold = gtk_toggle_action_get_active (action);
1785 modest_msg_edit_window_set_format_state (window, format_state);
1786 g_free (format_state);
1791 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1792 ModestMsgEditWindow *window)
1794 ModestMsgEditFormatState *format_state = NULL;
1796 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1797 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1799 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1802 format_state = modest_msg_edit_window_get_format_state (window);
1803 g_return_if_fail (format_state != NULL);
1805 format_state->italics = gtk_toggle_action_get_active (action);
1806 modest_msg_edit_window_set_format_state (window, format_state);
1807 g_free (format_state);
1812 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1813 ModestMsgEditWindow *window)
1815 ModestMsgEditFormatState *format_state = NULL;
1817 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1818 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1820 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1823 format_state = modest_msg_edit_window_get_format_state (window);
1824 g_return_if_fail (format_state != NULL);
1826 format_state->bullet = gtk_toggle_action_get_active (action);
1827 modest_msg_edit_window_set_format_state (window, format_state);
1828 g_free (format_state);
1833 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1834 GtkRadioAction *selected,
1835 ModestMsgEditWindow *window)
1837 ModestMsgEditFormatState *format_state = NULL;
1838 GtkJustification value;
1840 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1842 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1845 value = gtk_radio_action_get_current_value (selected);
1847 format_state = modest_msg_edit_window_get_format_state (window);
1848 g_return_if_fail (format_state != NULL);
1850 format_state->justification = value;
1851 modest_msg_edit_window_set_format_state (window, format_state);
1852 g_free (format_state);
1856 modest_ui_actions_on_select_editor_color (GtkAction *action,
1857 ModestMsgEditWindow *window)
1859 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1860 g_return_if_fail (GTK_IS_ACTION (action));
1862 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1865 modest_msg_edit_window_select_color (window);
1869 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1870 ModestMsgEditWindow *window)
1872 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1873 g_return_if_fail (GTK_IS_ACTION (action));
1875 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1878 modest_msg_edit_window_select_background_color (window);
1882 modest_ui_actions_on_insert_image (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_insert_image (window);
1895 modest_ui_actions_on_attach_file (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 modest_msg_edit_window_attach_file (window);
1905 modest_ui_actions_on_remove_attachments (GtkAction *action,
1906 ModestMsgEditWindow *window)
1908 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1909 g_return_if_fail (GTK_IS_ACTION (action));
1911 modest_msg_edit_window_remove_attachments (window, NULL);
1915 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1917 TnyFolderStore *parent_folder;
1918 GtkWidget *folder_view;
1920 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1922 folder_view = modest_main_window_get_child_widget (main_window,
1923 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1927 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1929 if (parent_folder) {
1930 gboolean finished = FALSE;
1932 gchar *folder_name = NULL, *suggested_name = NULL;
1934 /* Run the new folder dialog */
1936 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1941 if (result == GTK_RESPONSE_REJECT) {
1944 ModestMailOperation *mail_op;
1945 TnyFolder *new_folder = NULL;
1947 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1948 G_OBJECT(main_window));
1949 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1951 new_folder = modest_mail_operation_create_folder (mail_op,
1953 (const gchar *) folder_name);
1955 g_object_unref (new_folder);
1958 g_object_unref (mail_op);
1960 g_free (folder_name);
1964 g_object_unref (parent_folder);
1969 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1972 GObject *win = modest_mail_operation_get_source (mail_op);
1973 const GError *error = NULL;
1974 const gchar *message = NULL;
1976 /* Get error message */
1977 error = modest_mail_operation_get_error (mail_op);
1978 if (error != NULL && error->message != NULL) {
1979 message = error->message;
1981 message = _("!!! FIXME: Unable to rename");
1984 /* Show notification dialog */
1985 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
1986 g_object_unref (win);
1990 modest_ui_actions_on_rename_folder (GtkAction *action,
1991 ModestMainWindow *main_window)
1993 TnyFolderStore *folder;
1994 GtkWidget *folder_view;
1995 GtkWidget *header_view;
1997 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1999 folder_view = modest_main_window_get_child_widget (main_window,
2000 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2004 header_view = modest_main_window_get_child_widget (main_window,
2005 MODEST_WIDGET_TYPE_HEADER_VIEW);
2010 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2012 /* Offer the connection dialog if necessary: */
2013 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2014 g_object_unref (G_OBJECT (folder));
2019 if (folder && TNY_IS_FOLDER (folder)) {
2022 const gchar *current_name;
2024 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2025 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2026 current_name, &folder_name);
2028 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2029 ModestMailOperation *mail_op;
2032 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2033 G_OBJECT(main_window),
2034 modest_ui_actions_rename_folder_error_handler,
2038 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2041 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2043 modest_mail_operation_rename_folder (mail_op,
2044 TNY_FOLDER (folder),
2045 (const gchar *) folder_name);
2047 g_object_unref (mail_op);
2048 g_free (folder_name);
2050 g_object_unref (folder);
2055 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2058 GObject *win = modest_mail_operation_get_source (mail_op);
2060 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2061 _("mail_in_ui_folder_delete_error"));
2062 g_object_unref (win);
2066 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2068 TnyFolderStore *folder;
2069 GtkWidget *folder_view;
2073 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2075 folder_view = modest_main_window_get_child_widget (main_window,
2076 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2080 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2082 /* Show an error if it's an account */
2083 if (!TNY_IS_FOLDER (folder)) {
2084 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2085 _("mail_in_ui_folder_delete_error"));
2086 g_object_unref (G_OBJECT (folder));
2090 /* Offer the connection dialog if necessary: */
2091 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2092 g_object_unref (G_OBJECT (folder));
2097 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2098 tny_folder_get_name (TNY_FOLDER (folder)));
2099 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2100 (const gchar *) message);
2103 if (response == GTK_RESPONSE_OK) {
2104 ModestMailOperation *mail_op =
2105 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2106 G_OBJECT(main_window),
2107 modest_ui_actions_delete_folder_error_handler,
2110 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2112 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2113 g_object_unref (G_OBJECT (mail_op));
2116 g_object_unref (G_OBJECT (folder));
2120 modest_ui_actions_on_delete_folder (GtkAction *action,
2121 ModestMainWindow *main_window)
2123 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2125 delete_folder (main_window, FALSE);
2129 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2131 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2133 delete_folder (main_window, TRUE);
2137 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2138 const gchar* server_account_name,
2143 ModestMainWindow *main_window)
2145 g_return_if_fail(server_account_name);
2146 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2148 /* Initalize output parameters: */
2155 #ifdef MODEST_PLATFORM_MAEMO
2156 /* Maemo uses a different (awkward) button order,
2157 * It should probably just use gtk_alternative_dialog_button_order ().
2159 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2163 GTK_RESPONSE_ACCEPT,
2165 GTK_RESPONSE_REJECT,
2168 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2172 GTK_RESPONSE_REJECT,
2174 GTK_RESPONSE_ACCEPT,
2176 #endif /* MODEST_PLATFORM_MAEMO */
2178 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2180 gchar *server_name = modest_server_account_get_hostname (
2181 modest_runtime_get_account_mgr(), server_account_name);
2182 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2183 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2188 /* This causes a warning because the logical ID has no %s in it,
2189 * though the translation does, but there is not much we can do about that: */
2190 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2191 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2194 g_free (server_name);
2198 gchar *initial_username = modest_server_account_get_username (
2199 modest_runtime_get_account_mgr(), server_account_name);
2201 GtkWidget *entry_username = gtk_entry_new ();
2202 if (initial_username)
2203 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2204 /* Dim this if a connection has ever succeeded with this username,
2205 * as per the UI spec: */
2206 const gboolean username_known =
2207 modest_server_account_get_username_has_succeeded(
2208 modest_runtime_get_account_mgr(), server_account_name);
2209 gtk_widget_set_sensitive (entry_username, !username_known);
2211 #ifdef MODEST_PLATFORM_MAEMO
2212 /* Auto-capitalization is the default, so let's turn it off: */
2213 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2215 /* Create a size group to be used by all captions.
2216 * Note that HildonCaption does not create a default size group if we do not specify one.
2217 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2218 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2220 GtkWidget *caption = hildon_caption_new (sizegroup,
2221 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2222 gtk_widget_show (entry_username);
2223 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2224 FALSE, FALSE, MODEST_MARGIN_HALF);
2225 gtk_widget_show (caption);
2227 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2229 #endif /* MODEST_PLATFORM_MAEMO */
2232 GtkWidget *entry_password = gtk_entry_new ();
2233 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2234 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2236 #ifdef MODEST_PLATFORM_MAEMO
2237 /* Auto-capitalization is the default, so let's turn it off: */
2238 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2239 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2241 caption = hildon_caption_new (sizegroup,
2242 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2243 gtk_widget_show (entry_password);
2244 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2245 FALSE, FALSE, MODEST_MARGIN_HALF);
2246 gtk_widget_show (caption);
2247 g_object_unref (sizegroup);
2249 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2251 #endif /* MODEST_PLATFORM_MAEMO */
2253 /* This is not in the Maemo UI spec:
2254 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2255 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2259 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2261 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2263 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2265 modest_server_account_set_username (
2266 modest_runtime_get_account_mgr(), server_account_name,
2269 const gboolean username_was_changed =
2270 (strcmp (*username, initial_username) != 0);
2271 if (username_was_changed) {
2272 g_warning ("%s: tinymail does not yet support changing the "
2273 "username in the get_password() callback.\n", __FUNCTION__);
2278 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2280 /* We do not save the password in the configuration,
2281 * because this function is only called for passwords that should
2282 * not be remembered:
2283 modest_server_account_set_password (
2284 modest_runtime_get_account_mgr(), server_account_name,
2303 /* This is not in the Maemo UI spec:
2304 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2310 gtk_widget_destroy (dialog);
2312 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2316 modest_ui_actions_on_cut (GtkAction *action,
2317 ModestWindow *window)
2319 GtkWidget *focused_widget;
2321 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2322 if (GTK_IS_EDITABLE (focused_widget)) {
2323 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2324 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2325 GtkTextBuffer *buffer;
2326 GtkClipboard *clipboard;
2328 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2329 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2330 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2331 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2332 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2333 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2334 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2339 modest_ui_actions_on_copy (GtkAction *action,
2340 ModestWindow *window)
2342 GtkClipboard *clipboard;
2343 GtkWidget *focused_widget;
2345 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2346 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2348 if (GTK_IS_LABEL (focused_widget)) {
2349 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2350 } else if (GTK_IS_EDITABLE (focused_widget)) {
2351 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2352 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2353 GtkTextBuffer *buffer;
2354 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2355 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2356 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2357 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2358 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2359 TnyIterator *iter = tny_list_create_iterator (header_list);
2360 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2361 TnyFolder *folder = tny_header_get_folder (header);
2362 TnyAccount *account = tny_folder_get_account (folder);
2363 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2364 /* If it's POP then ask */
2365 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2366 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2367 g_object_unref (account);
2368 g_object_unref (folder);
2369 g_object_unref (header);
2370 g_object_unref (iter);
2372 /* Check that the messages have been previously downloaded */
2373 gboolean continue_download = TRUE;
2375 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2376 if (continue_download)
2377 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2378 g_object_unref (header_list);
2379 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2380 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2383 /* Show information banner */
2384 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2389 modest_ui_actions_on_undo (GtkAction *action,
2390 ModestWindow *window)
2392 ModestEmailClipboard *clipboard = NULL;
2394 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2395 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2396 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2397 /* Clear clipboard source */
2398 clipboard = modest_runtime_get_email_clipboard ();
2399 modest_email_clipboard_clear (clipboard);
2402 g_return_if_reached ();
2408 paste_msgs_cb (const GObject *object, gpointer user_data)
2410 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2411 g_return_if_fail (GTK_IS_WIDGET (user_data));
2413 /* destroy information note */
2414 gtk_widget_destroy (GTK_WIDGET(user_data));
2418 modest_ui_actions_on_paste (GtkAction *action,
2419 ModestWindow *window)
2421 GtkWidget *focused_widget = NULL;
2422 GtkWidget *inf_note = NULL;
2423 ModestMailOperation *mail_op = NULL;
2425 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2426 if (GTK_IS_EDITABLE (focused_widget)) {
2427 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2428 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2429 GtkTextBuffer *buffer;
2430 GtkClipboard *clipboard;
2432 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2433 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2434 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2435 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2436 ModestEmailClipboard *clipboard = NULL;
2437 TnyFolder *src_folder = NULL;
2438 TnyFolderStore *folder_store = NULL;
2439 TnyList *data = NULL;
2440 gboolean delete = FALSE;
2442 /* Check clipboard source */
2443 clipboard = modest_runtime_get_email_clipboard ();
2444 if (modest_email_clipboard_cleared (clipboard))
2447 /* Get elements to paste */
2448 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2450 /* Create a new mail operation */
2451 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2452 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2455 /* Get destination folder */
2456 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2458 /* Launch notification */
2459 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2460 _CS("ckct_nw_pasting"));
2461 if (inf_note != NULL) {
2462 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2463 gtk_widget_show (GTK_WIDGET(inf_note));
2466 /* transfer messages */
2468 modest_mail_operation_xfer_msgs (mail_op,
2470 TNY_FOLDER (folder_store),
2475 } else if (src_folder != NULL) {
2476 modest_mail_operation_xfer_folder (mail_op,
2486 g_object_unref (data);
2487 if (src_folder != NULL)
2488 g_object_unref (src_folder);
2489 if (folder_store != NULL)
2490 g_object_unref (folder_store);
2496 modest_ui_actions_on_select_all (GtkAction *action,
2497 ModestWindow *window)
2499 GtkWidget *focused_widget;
2501 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2502 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2503 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2504 } else if (GTK_IS_LABEL (focused_widget)) {
2505 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2506 } else if (GTK_IS_EDITABLE (focused_widget)) {
2507 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2508 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2509 GtkTextBuffer *buffer;
2510 GtkTextIter start, end;
2512 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2513 gtk_text_buffer_get_start_iter (buffer, &start);
2514 gtk_text_buffer_get_end_iter (buffer, &end);
2515 gtk_text_buffer_select_range (buffer, &start, &end);
2516 } else if (GTK_IS_HTML (focused_widget)) {
2517 gtk_html_select_all (GTK_HTML (focused_widget));
2518 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2519 GtkWidget *header_view = focused_widget;
2520 GtkTreeSelection *selection = NULL;
2522 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2523 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2524 MODEST_WIDGET_TYPE_HEADER_VIEW);
2526 /* Select all messages */
2527 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2528 gtk_tree_selection_select_all (selection);
2530 /* Set focuse on header view */
2531 gtk_widget_grab_focus (header_view);
2537 modest_ui_actions_on_mark_as_read (GtkAction *action,
2538 ModestWindow *window)
2540 g_return_if_fail (MODEST_IS_WINDOW(window));
2542 /* Mark each header as read */
2543 do_headers_action (window, headers_action_mark_as_read, NULL);
2547 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2548 ModestWindow *window)
2550 g_return_if_fail (MODEST_IS_WINDOW(window));
2552 /* Mark each header as read */
2553 do_headers_action (window, headers_action_mark_as_unread, NULL);
2557 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2558 GtkRadioAction *selected,
2559 ModestWindow *window)
2563 value = gtk_radio_action_get_current_value (selected);
2564 if (MODEST_IS_WINDOW (window)) {
2565 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2569 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2570 GtkRadioAction *selected,
2571 ModestWindow *window)
2573 TnyHeaderFlags flags;
2574 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2576 flags = gtk_radio_action_get_current_value (selected);
2577 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2580 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2581 GtkRadioAction *selected,
2582 ModestWindow *window)
2586 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2588 file_format = gtk_radio_action_get_current_value (selected);
2589 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2594 modest_ui_actions_on_zoom_plus (GtkAction *action,
2595 ModestWindow *window)
2597 g_return_if_fail (MODEST_IS_WINDOW (window));
2599 modest_window_zoom_plus (MODEST_WINDOW (window));
2603 modest_ui_actions_on_zoom_minus (GtkAction *action,
2604 ModestWindow *window)
2606 g_return_if_fail (MODEST_IS_WINDOW (window));
2608 modest_window_zoom_minus (MODEST_WINDOW (window));
2612 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2613 ModestWindow *window)
2615 ModestWindowMgr *mgr;
2616 gboolean fullscreen, active;
2617 g_return_if_fail (MODEST_IS_WINDOW (window));
2619 mgr = modest_runtime_get_window_mgr ();
2621 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2622 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2624 if (active != fullscreen) {
2625 modest_window_mgr_set_fullscreen_mode (mgr, active);
2626 gtk_window_present (GTK_WINDOW (window));
2631 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2632 ModestWindow *window)
2634 ModestWindowMgr *mgr;
2635 gboolean fullscreen;
2637 g_return_if_fail (MODEST_IS_WINDOW (window));
2639 mgr = modest_runtime_get_window_mgr ();
2640 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2641 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2643 gtk_window_present (GTK_WINDOW (window));
2647 * Used by modest_ui_actions_on_details to call do_headers_action
2650 headers_action_show_details (TnyHeader *header,
2651 ModestWindow *window,
2658 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2661 gtk_widget_show_all (dialog);
2662 gtk_dialog_run (GTK_DIALOG (dialog));
2664 gtk_widget_destroy (dialog);
2668 * Show the folder details in a ModestDetailsDialog widget
2671 show_folder_details (TnyFolder *folder,
2677 dialog = modest_details_dialog_new_with_folder (window, folder);
2680 gtk_widget_show_all (dialog);
2681 gtk_dialog_run (GTK_DIALOG (dialog));
2683 gtk_widget_destroy (dialog);
2687 * Show the header details in a ModestDetailsDialog widget
2690 modest_ui_actions_on_details (GtkAction *action,
2693 TnyList * headers_list;
2697 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2700 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2703 g_object_unref (msg);
2705 headers_list = get_selected_headers (win);
2709 iter = tny_list_create_iterator (headers_list);
2711 header = TNY_HEADER (tny_iterator_get_current (iter));
2712 headers_action_show_details (header, win, NULL);
2713 g_object_unref (header);
2715 g_object_unref (iter);
2716 g_object_unref (headers_list);
2718 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2719 GtkWidget *folder_view, *header_view;
2721 /* Check which widget has the focus */
2722 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2723 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2724 if (gtk_widget_is_focus (folder_view)) {
2725 TnyFolderStore *folder_store
2726 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2727 if (!folder_store) {
2728 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2731 /* Show only when it's a folder */
2732 /* This function should not be called for account items,
2733 * because we dim the menu item for them. */
2734 if (TNY_IS_FOLDER (folder_store)) {
2735 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2738 g_object_unref (folder_store);
2741 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2742 MODEST_WIDGET_TYPE_HEADER_VIEW);
2743 /* Show details of each header */
2744 do_headers_action (win, headers_action_show_details, header_view);
2750 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2751 ModestMsgEditWindow *window)
2753 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2755 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2759 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2760 ModestMsgEditWindow *window)
2762 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2764 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2768 modest_ui_actions_toggle_folders_view (GtkAction *action,
2769 ModestMainWindow *main_window)
2773 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2775 conf = modest_runtime_get_conf ();
2777 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2778 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2780 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2784 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2785 ModestWindow *window)
2787 gboolean active, fullscreen = FALSE;
2788 ModestWindowMgr *mgr;
2790 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2792 /* Check if we want to toggle the toolbar vuew in fullscreen
2794 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2795 "ViewShowToolbarFullScreen")) {
2799 /* Toggle toolbar */
2800 mgr = modest_runtime_get_window_mgr ();
2801 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2805 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2806 ModestMsgEditWindow *window)
2808 modest_msg_edit_window_select_font (window);
2812 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2813 const gchar *display_name,
2816 /* Do not change the application name if the widget has not
2817 the focus. This callback could be called even if the folder
2818 view has not the focus, because the handled signal could be
2819 emitted when the folder view is redrawn */
2820 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2822 gtk_window_set_title (window, display_name);
2824 gtk_window_set_title (window, " ");
2829 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2831 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2832 modest_msg_edit_window_select_contacts (window);
2836 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2838 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2839 modest_msg_edit_window_check_names (window);
2844 create_move_to_dialog (ModestWindow *win,
2845 GtkWidget *folder_view,
2846 GtkWidget **tree_view)
2848 GtkWidget *dialog, *scroll;
2850 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2852 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2854 GTK_RESPONSE_ACCEPT,
2856 GTK_RESPONSE_REJECT,
2859 /* Create scrolled window */
2860 scroll = gtk_scrolled_window_new (NULL, NULL);
2861 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2862 GTK_POLICY_AUTOMATIC,
2863 GTK_POLICY_AUTOMATIC);
2865 /* Create folder view */
2866 *tree_view = modest_platform_create_folder_view (NULL);
2868 /* It could happen that we're trying to move a message from a
2869 window (msg window for example) after the main window was
2870 closed, so we can not just get the model of the folder
2872 if (MODEST_IS_FOLDER_VIEW (folder_view))
2873 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2874 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2876 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2877 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2879 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2881 /* Add scroll to dialog */
2882 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2883 scroll, FALSE, FALSE, 0);
2885 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2887 /* Select INBOX or local account */
2888 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2894 * Returns TRUE if at least one of the headers of the list belongs to
2895 * a message that has been fully retrieved.
2898 has_retrieved_msgs (TnyList *list)
2901 gboolean found = FALSE;
2903 iter = tny_list_create_iterator (list);
2904 while (tny_iterator_is_done (iter) && !found) {
2906 TnyHeaderFlags flags;
2908 header = TNY_HEADER (tny_iterator_get_current (iter));
2909 flags = tny_header_get_flags (header);
2910 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2914 tny_iterator_next (iter);
2916 g_object_unref (iter);
2922 * Shows a confirmation dialog to the user when we're moving messages
2923 * from a remote server to the local storage. Returns the dialog
2924 * response. If it's other kind of movement the it always returns
2928 msgs_move_to_confirmation (GtkWindow *win,
2929 TnyFolder *dest_folder,
2932 gint response = GTK_RESPONSE_OK;
2934 /* If the destination is a local folder */
2935 if (modest_tny_folder_is_local_folder (dest_folder)) {
2936 TnyFolder *src_folder;
2940 /* Get source folder */
2941 iter = tny_list_create_iterator (headers);
2942 header = TNY_HEADER (tny_iterator_get_current (iter));
2943 src_folder = tny_header_get_folder (header);
2944 g_object_unref (header);
2945 g_object_unref (iter);
2947 /* if no src_folder, message may be an attahcment */
2948 if (src_folder == NULL)
2949 return GTK_RESPONSE_CANCEL;
2951 /* If the source is a remote folder */
2952 if (!modest_tny_folder_is_local_folder (src_folder)) {
2953 const gchar *message;
2955 if (has_retrieved_msgs (headers))
2956 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2957 tny_list_get_length (headers));
2959 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2960 tny_list_get_length (headers));
2962 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2963 (const gchar *) message);
2965 g_object_unref (src_folder);
2973 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2975 ModestMsgViewWindow *self = NULL;
2976 gboolean last, first;
2978 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2979 self = MODEST_MSG_VIEW_WINDOW (object);
2981 last = modest_msg_view_window_last_message_selected (self);
2982 first = modest_msg_view_window_first_message_selected (self);
2984 /* No more messages to view, so close this window */
2985 /* gboolean ret_value; */
2986 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2987 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
2989 modest_msg_view_window_select_previous_message (self);
2991 modest_msg_view_window_select_next_message (self);
2995 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2998 GObject *win = modest_mail_operation_get_source (mail_op);
2999 const GError *error = NULL;
3000 const gchar *message = NULL;
3002 /* Get error message */
3003 error = modest_mail_operation_get_error (mail_op);
3004 if (error != NULL && error->message != NULL) {
3005 message = error->message;
3007 message = _("mail_in_ui_folder_move_target_error");
3010 /* Show notification dialog */
3011 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3012 g_object_unref (win);
3016 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3019 GObject *win = modest_mail_operation_get_source (mail_op);
3020 const GError *error = modest_mail_operation_get_error (mail_op);
3022 g_return_if_fail (error != NULL);
3023 if (error->message != NULL)
3024 g_printerr ("modest: %s\n", error->message);
3026 g_printerr ("modest: unkonw error on send&receive operation");
3028 /* Show error message */
3029 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3030 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3031 /* _CS("sfil_ib_unable_to_receive")); */
3033 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3034 /* _CS("sfil_ib_unable_to_send")); */
3035 g_object_unref (win);
3039 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3046 gint pending_purges = 0;
3047 gboolean some_purged = FALSE;
3048 ModestWindow *win = MODEST_WINDOW (user_data);
3052 /* Once the message has been retrieved for purging, we check if
3053 * it's all ok for purging */
3055 parts = tny_simple_list_new ();
3056 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3057 iter = tny_list_create_iterator (parts);
3059 while (!tny_iterator_is_done (iter)) {
3061 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3062 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3063 if (tny_mime_part_is_purged (part))
3068 tny_iterator_next (iter);
3071 if (pending_purges>0) {
3073 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3075 if (response == GTK_RESPONSE_OK) {
3076 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3077 tny_iterator_first (iter);
3078 while (!tny_iterator_is_done (iter)) {
3081 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3082 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3083 tny_mime_part_set_purged (part);
3084 tny_iterator_next (iter);
3087 tny_msg_rewrite_cache (msg);
3090 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3093 /* remove attachments */
3094 tny_iterator_first (iter);
3095 while (!tny_iterator_is_done (iter)) {
3098 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3099 g_object_unref (part);
3100 tny_iterator_next (iter);
3103 g_object_unref (iter);
3104 g_object_unref (parts);
3108 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3109 ModestMainWindow *win)
3111 GtkWidget *header_view;
3112 TnyList *header_list;
3115 TnyHeaderFlags flags;
3116 ModestWindow *msg_view_window = NULL;
3119 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3121 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3122 MODEST_WIDGET_TYPE_HEADER_VIEW);
3124 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3126 if (tny_list_get_length (header_list) == 1) {
3127 iter = tny_list_create_iterator (header_list);
3128 header = TNY_HEADER (tny_iterator_get_current (iter));
3129 g_object_unref (iter);
3134 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3135 header, &msg_view_window);
3136 flags = tny_header_get_flags (header);
3137 if (!(flags & TNY_HEADER_FLAG_CACHED))
3140 if (msg_view_window != NULL)
3141 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3143 /* do nothing; uid was registered before, so window is probably on it's way */
3144 g_warning ("debug: header %p has already been registered", header);
3147 ModestMailOperation *mail_op = NULL;
3148 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3149 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3151 modest_ui_actions_get_msgs_full_error_handler,
3153 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3154 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3156 g_object_unref (mail_op);
3159 g_object_unref (header);
3161 g_object_unref (header_list);
3165 * UI handler for the "Move to" action when invoked from the
3169 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3170 ModestMainWindow *win)
3172 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3173 GtkWidget *header_view = NULL;
3175 TnyFolderStore *folder_store = NULL;
3176 ModestMailOperation *mail_op = NULL;
3178 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3180 /* Get the folder view */
3181 folder_view = modest_main_window_get_child_widget (win,
3182 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3184 /* Get header view */
3185 header_view = modest_main_window_get_child_widget (win,
3186 MODEST_WIDGET_TYPE_HEADER_VIEW);
3188 /* Create and run the dialog */
3189 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3190 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3191 result = gtk_dialog_run (GTK_DIALOG(dialog));
3192 g_object_ref (tree_view);
3194 /* We do this to save an indentation level ;-) */
3195 if (result != GTK_RESPONSE_ACCEPT)
3198 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3200 if (TNY_IS_ACCOUNT (folder_store) &&
3201 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3204 /* Offer the connection dialog if necessary: */
3205 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) {
3209 /* Get folder or messages to transfer */
3210 if (gtk_widget_is_focus (folder_view)) {
3211 TnyFolderStore *src_folder;
3212 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3214 /* Offer the connection dialog if necessary: */
3215 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) {
3217 /* Clean folder on header view before moving it */
3218 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3220 if (TNY_IS_FOLDER (src_folder)) {
3222 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3224 modest_ui_actions_move_folder_error_handler,
3226 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3228 modest_mail_operation_xfer_folder (mail_op,
3229 TNY_FOLDER (src_folder),
3232 /* Unref mail operation */
3233 g_object_unref (G_OBJECT (mail_op));
3237 g_object_unref (G_OBJECT (src_folder));
3240 if (gtk_widget_is_focus (header_view)) {
3241 TnyList *headers = NULL;
3244 /* TODO: Check for connection if the headers are on a network account. */
3245 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3247 /* Ask for user confirmation */
3248 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3249 TNY_FOLDER (folder_store),
3252 /* Transfer messages */
3253 if (response == GTK_RESPONSE_OK) {
3255 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3257 modest_ui_actions_move_folder_error_handler,
3259 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3262 modest_mail_operation_xfer_msgs (mail_op,
3264 TNY_FOLDER (folder_store),
3269 g_object_unref (G_OBJECT (mail_op));
3271 g_object_unref (headers);
3276 if (folder_store != NULL)
3277 g_object_unref (folder_store);
3279 gtk_widget_destroy (dialog);
3284 * UI handler for the "Move to" action when invoked from the
3285 * ModestMsgViewWindow
3288 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3289 ModestMsgViewWindow *win)
3291 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3293 ModestMainWindow *main_window = NULL;
3294 TnyHeader *header = NULL;
3295 TnyList *headers = NULL;
3297 /* Get the folder view */
3298 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3300 folder_view = modest_main_window_get_child_widget (main_window,
3301 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3305 /* Create and run the dialog */
3306 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3307 result = gtk_dialog_run (GTK_DIALOG(dialog));
3309 if (result == GTK_RESPONSE_ACCEPT) {
3310 TnyFolderStore *folder_store;
3313 /* Create header list */
3314 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3315 g_return_if_fail (header != NULL);
3317 /* Offer the connection dialog if necessary: */
3318 /* TODO: What's the extra g_object_ref() for? Isn't this leaking a ref? */
3319 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view)));
3320 TnyFolder *header_folder = tny_header_get_folder(header);
3321 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, folder_store) &&
3322 modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (header_folder))) {
3324 headers = tny_simple_list_new ();
3325 tny_list_prepend (headers, G_OBJECT (header));
3326 g_object_unref (header);
3328 /* Ask user for confirmation. MSG-NOT404 */
3329 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3330 TNY_FOLDER (folder_store),
3333 /* Transfer current msg */
3334 if (response == GTK_RESPONSE_OK) {
3335 ModestMailOperation *mail_op;
3337 /* Create mail op */
3338 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3339 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3342 /* Transfer messages */
3343 modest_mail_operation_xfer_msgs (mail_op,
3345 TNY_FOLDER (folder_store),
3347 transfer_msgs_from_viewer_cb,
3349 g_object_unref (G_OBJECT (mail_op));
3354 g_object_unref (header_folder);
3357 g_object_unref (headers);
3360 g_object_unref (folder_store);
3363 gtk_widget_destroy (dialog);
3367 modest_ui_actions_on_move_to (GtkAction *action,
3370 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3371 MODEST_IS_MSG_VIEW_WINDOW (win));
3373 if (MODEST_IS_MAIN_WINDOW (win))
3374 modest_ui_actions_on_main_window_move_to (action,
3375 MODEST_MAIN_WINDOW (win));
3377 modest_ui_actions_on_msg_view_window_move_to (action,
3378 MODEST_MSG_VIEW_WINDOW (win));
3382 * Calls #HeadersFunc for each header already selected in the main
3383 * window or the message currently being shown in the msg view window
3386 do_headers_action (ModestWindow *win,
3390 TnyList *headers_list;
3396 headers_list = get_selected_headers (win);
3400 /* Get the folder */
3401 iter = tny_list_create_iterator (headers_list);
3402 header = TNY_HEADER (tny_iterator_get_current (iter));
3403 folder = tny_header_get_folder (header);
3404 g_object_unref (header);
3406 /* Call the function for each header */
3407 while (!tny_iterator_is_done (iter)) {
3408 header = TNY_HEADER (tny_iterator_get_current (iter));
3409 func (header, win, user_data);
3410 g_object_unref (header);
3411 tny_iterator_next (iter);
3414 /* Trick: do a poke status in order to speed up the signaling
3416 tny_folder_poke_status (folder);
3419 g_object_unref (folder);
3420 g_object_unref (iter);
3421 g_object_unref (headers_list);
3425 modest_ui_actions_view_attachment (GtkAction *action,
3426 ModestWindow *window)
3428 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3429 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3431 /* not supported window for this action */
3432 g_return_if_reached ();
3437 modest_ui_actions_save_attachments (GtkAction *action,
3438 ModestWindow *window)
3440 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3441 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3443 /* not supported window for this action */
3444 g_return_if_reached ();
3449 modest_ui_actions_remove_attachments (GtkAction *action,
3450 ModestWindow *window)
3452 if (MODEST_IS_MAIN_WINDOW (window)) {
3453 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3454 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3455 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3457 /* not supported window for this action */
3458 g_return_if_reached ();
3463 modest_ui_actions_on_settings (GtkAction *action,
3468 dialog = modest_platform_get_global_settings_dialog ();
3469 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3470 gtk_widget_show_all (dialog);
3472 gtk_dialog_run (GTK_DIALOG (dialog));
3474 gtk_widget_destroy (dialog);
3478 modest_ui_actions_on_help (GtkAction *action,
3481 const gchar *help_id = NULL;
3483 if (MODEST_IS_MAIN_WINDOW (win)) {
3484 const gchar *action_name;
3485 action_name = gtk_action_get_name (action);
3487 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3488 !strcmp (action_name, "HeaderViewCSMHelp")) {
3489 GtkWidget *folder_view;
3490 TnyFolderStore *folder_store;
3491 /* Get selected folder */
3492 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3493 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3494 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3496 /* Switch help_id */
3497 if (TNY_IS_FOLDER (folder_store)) {
3498 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3499 case TNY_FOLDER_TYPE_NORMAL:
3500 help_id = "applications_email_userfolder";
3502 case TNY_FOLDER_TYPE_INBOX:
3503 help_id = "applications_email_inbox";
3505 case TNY_FOLDER_TYPE_OUTBOX:
3506 help_id = "applications_email_outbox";
3508 case TNY_FOLDER_TYPE_SENT:
3509 help_id = "applications_email_sent";
3511 case TNY_FOLDER_TYPE_DRAFTS:
3512 help_id = "applications_email_drafts";
3514 case TNY_FOLDER_TYPE_ARCHIVE:
3515 help_id = "applications_email_archive";
3521 g_object_unref (folder_store);
3523 help_id = "applications_email_mainview";
3525 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3526 help_id = "applications_email_viewer";
3527 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3528 help_id = "applications_email_editor";
3530 modest_platform_show_help (GTK_WINDOW (win), help_id);
3534 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3535 ModestWindow *window)
3537 ModestMailOperation *mail_op;
3541 headers = get_selected_headers (window);
3545 /* Create mail operation */
3546 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3548 modest_ui_actions_get_msgs_full_error_handler,
3550 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3551 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3554 g_object_unref (headers);
3555 g_object_unref (mail_op);
3559 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3560 ModestWindow *window)
3562 g_return_if_fail (MODEST_IS_WINDOW (window));
3565 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3569 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3570 ModestWindow *window)
3572 g_return_if_fail (MODEST_IS_WINDOW (window));
3575 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3579 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3580 ModestWindow *window)
3582 g_return_if_fail (MODEST_IS_WINDOW (window));
3585 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3589 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3590 ModestWindow *window)
3592 g_return_if_fail (MODEST_IS_WINDOW (window));
3595 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3599 modest_ui_actions_on_attachment_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_toolbar_csm_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_folder_view_csm_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_header_view_csm_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_check_toolbar_dimming_rules (ModestWindow *window)
3641 g_return_if_fail (MODEST_IS_WINDOW (window));
3644 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3648 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3650 g_return_if_fail (MODEST_IS_WINDOW (window));
3652 modest_platform_show_search_messages (GTK_WINDOW (window));
3656 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3658 g_return_if_fail (MODEST_IS_WINDOW (win));
3659 modest_platform_show_addressbook (GTK_WINDOW (win));
3664 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3665 ModestWindow *window)
3667 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3669 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3673 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3674 ModestMailOperationState *state,
3677 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3679 /* Set send/receive operation finished */
3680 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3681 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));