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 ();
2407 modest_ui_actions_on_redo (GtkAction *action,
2408 ModestWindow *window)
2410 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2411 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2414 g_return_if_reached ();
2420 paste_msgs_cb (const GObject *object, gpointer user_data)
2422 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2423 g_return_if_fail (GTK_IS_WIDGET (user_data));
2425 /* destroy information note */
2426 gtk_widget_destroy (GTK_WIDGET(user_data));
2430 modest_ui_actions_on_paste (GtkAction *action,
2431 ModestWindow *window)
2433 GtkWidget *focused_widget = NULL;
2434 GtkWidget *inf_note = NULL;
2435 ModestMailOperation *mail_op = NULL;
2437 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2438 if (GTK_IS_EDITABLE (focused_widget)) {
2439 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2440 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2441 GtkTextBuffer *buffer;
2442 GtkClipboard *clipboard;
2444 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2445 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2446 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2447 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2448 ModestEmailClipboard *clipboard = NULL;
2449 TnyFolder *src_folder = NULL;
2450 TnyFolderStore *folder_store = NULL;
2451 TnyList *data = NULL;
2452 gboolean delete = FALSE;
2454 /* Check clipboard source */
2455 clipboard = modest_runtime_get_email_clipboard ();
2456 if (modest_email_clipboard_cleared (clipboard))
2459 /* Get elements to paste */
2460 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2462 /* Create a new mail operation */
2463 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2464 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2467 /* Get destination folder */
2468 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2470 /* Launch notification */
2471 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2472 _CS("ckct_nw_pasting"));
2473 if (inf_note != NULL) {
2474 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2475 gtk_widget_show (GTK_WIDGET(inf_note));
2478 /* transfer messages */
2480 modest_mail_operation_xfer_msgs (mail_op,
2482 TNY_FOLDER (folder_store),
2487 } else if (src_folder != NULL) {
2488 modest_mail_operation_xfer_folder (mail_op,
2498 g_object_unref (data);
2499 if (src_folder != NULL)
2500 g_object_unref (src_folder);
2501 if (folder_store != NULL)
2502 g_object_unref (folder_store);
2508 modest_ui_actions_on_select_all (GtkAction *action,
2509 ModestWindow *window)
2511 GtkWidget *focused_widget;
2513 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2514 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2515 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2516 } else if (GTK_IS_LABEL (focused_widget)) {
2517 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2518 } else if (GTK_IS_EDITABLE (focused_widget)) {
2519 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2520 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2521 GtkTextBuffer *buffer;
2522 GtkTextIter start, end;
2524 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2525 gtk_text_buffer_get_start_iter (buffer, &start);
2526 gtk_text_buffer_get_end_iter (buffer, &end);
2527 gtk_text_buffer_select_range (buffer, &start, &end);
2528 } else if (GTK_IS_HTML (focused_widget)) {
2529 gtk_html_select_all (GTK_HTML (focused_widget));
2530 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2531 GtkWidget *header_view = focused_widget;
2532 GtkTreeSelection *selection = NULL;
2534 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2535 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2536 MODEST_WIDGET_TYPE_HEADER_VIEW);
2538 /* Select all messages */
2539 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2540 gtk_tree_selection_select_all (selection);
2542 /* Set focuse on header view */
2543 gtk_widget_grab_focus (header_view);
2549 modest_ui_actions_on_mark_as_read (GtkAction *action,
2550 ModestWindow *window)
2552 g_return_if_fail (MODEST_IS_WINDOW(window));
2554 /* Mark each header as read */
2555 do_headers_action (window, headers_action_mark_as_read, NULL);
2559 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2560 ModestWindow *window)
2562 g_return_if_fail (MODEST_IS_WINDOW(window));
2564 /* Mark each header as read */
2565 do_headers_action (window, headers_action_mark_as_unread, NULL);
2569 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2570 GtkRadioAction *selected,
2571 ModestWindow *window)
2575 value = gtk_radio_action_get_current_value (selected);
2576 if (MODEST_IS_WINDOW (window)) {
2577 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2581 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2582 GtkRadioAction *selected,
2583 ModestWindow *window)
2585 TnyHeaderFlags flags;
2586 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2588 flags = gtk_radio_action_get_current_value (selected);
2589 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2592 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2593 GtkRadioAction *selected,
2594 ModestWindow *window)
2598 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2600 file_format = gtk_radio_action_get_current_value (selected);
2601 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2606 modest_ui_actions_on_zoom_plus (GtkAction *action,
2607 ModestWindow *window)
2609 g_return_if_fail (MODEST_IS_WINDOW (window));
2611 modest_window_zoom_plus (MODEST_WINDOW (window));
2615 modest_ui_actions_on_zoom_minus (GtkAction *action,
2616 ModestWindow *window)
2618 g_return_if_fail (MODEST_IS_WINDOW (window));
2620 modest_window_zoom_minus (MODEST_WINDOW (window));
2624 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2625 ModestWindow *window)
2627 ModestWindowMgr *mgr;
2628 gboolean fullscreen, active;
2629 g_return_if_fail (MODEST_IS_WINDOW (window));
2631 mgr = modest_runtime_get_window_mgr ();
2633 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2634 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2636 if (active != fullscreen) {
2637 modest_window_mgr_set_fullscreen_mode (mgr, active);
2638 gtk_window_present (GTK_WINDOW (window));
2643 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2644 ModestWindow *window)
2646 ModestWindowMgr *mgr;
2647 gboolean fullscreen;
2649 g_return_if_fail (MODEST_IS_WINDOW (window));
2651 mgr = modest_runtime_get_window_mgr ();
2652 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2653 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2655 gtk_window_present (GTK_WINDOW (window));
2659 * Used by modest_ui_actions_on_details to call do_headers_action
2662 headers_action_show_details (TnyHeader *header,
2663 ModestWindow *window,
2670 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2673 gtk_widget_show_all (dialog);
2674 gtk_dialog_run (GTK_DIALOG (dialog));
2676 gtk_widget_destroy (dialog);
2680 * Show the folder details in a ModestDetailsDialog widget
2683 show_folder_details (TnyFolder *folder,
2689 dialog = modest_details_dialog_new_with_folder (window, folder);
2692 gtk_widget_show_all (dialog);
2693 gtk_dialog_run (GTK_DIALOG (dialog));
2695 gtk_widget_destroy (dialog);
2699 * Show the header details in a ModestDetailsDialog widget
2702 modest_ui_actions_on_details (GtkAction *action,
2705 TnyList * headers_list;
2709 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2712 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2715 g_object_unref (msg);
2717 headers_list = get_selected_headers (win);
2721 iter = tny_list_create_iterator (headers_list);
2723 header = TNY_HEADER (tny_iterator_get_current (iter));
2724 headers_action_show_details (header, win, NULL);
2725 g_object_unref (header);
2727 g_object_unref (iter);
2728 g_object_unref (headers_list);
2730 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2731 GtkWidget *folder_view, *header_view;
2733 /* Check which widget has the focus */
2734 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2735 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2736 if (gtk_widget_is_focus (folder_view)) {
2737 TnyFolderStore *folder_store
2738 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2739 if (!folder_store) {
2740 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2743 /* Show only when it's a folder */
2744 /* This function should not be called for account items,
2745 * because we dim the menu item for them. */
2746 if (TNY_IS_FOLDER (folder_store)) {
2747 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2750 g_object_unref (folder_store);
2753 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2754 MODEST_WIDGET_TYPE_HEADER_VIEW);
2755 /* Show details of each header */
2756 do_headers_action (win, headers_action_show_details, header_view);
2762 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2763 ModestMsgEditWindow *window)
2765 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2767 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2771 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2772 ModestMsgEditWindow *window)
2774 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2776 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2780 modest_ui_actions_toggle_folders_view (GtkAction *action,
2781 ModestMainWindow *main_window)
2785 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2787 conf = modest_runtime_get_conf ();
2789 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2790 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2792 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2796 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2797 ModestWindow *window)
2799 gboolean active, fullscreen = FALSE;
2800 ModestWindowMgr *mgr;
2802 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2804 /* Check if we want to toggle the toolbar vuew in fullscreen
2806 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2807 "ViewShowToolbarFullScreen")) {
2811 /* Toggle toolbar */
2812 mgr = modest_runtime_get_window_mgr ();
2813 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2817 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2818 ModestMsgEditWindow *window)
2820 modest_msg_edit_window_select_font (window);
2824 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2825 const gchar *display_name,
2828 /* Do not change the application name if the widget has not
2829 the focus. This callback could be called even if the folder
2830 view has not the focus, because the handled signal could be
2831 emitted when the folder view is redrawn */
2832 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2834 gtk_window_set_title (window, display_name);
2836 gtk_window_set_title (window, " ");
2841 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2843 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2844 modest_msg_edit_window_select_contacts (window);
2848 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2850 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2851 modest_msg_edit_window_check_names (window);
2856 create_move_to_dialog (ModestWindow *win,
2857 GtkWidget *folder_view,
2858 GtkWidget **tree_view)
2860 GtkWidget *dialog, *scroll;
2862 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2864 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2866 GTK_RESPONSE_ACCEPT,
2868 GTK_RESPONSE_REJECT,
2871 /* Create scrolled window */
2872 scroll = gtk_scrolled_window_new (NULL, NULL);
2873 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2874 GTK_POLICY_AUTOMATIC,
2875 GTK_POLICY_AUTOMATIC);
2877 /* Create folder view */
2878 *tree_view = modest_platform_create_folder_view (NULL);
2880 /* It could happen that we're trying to move a message from a
2881 window (msg window for example) after the main window was
2882 closed, so we can not just get the model of the folder
2884 if (MODEST_IS_FOLDER_VIEW (folder_view))
2885 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2886 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2888 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2889 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2891 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2893 /* Add scroll to dialog */
2894 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2895 scroll, FALSE, FALSE, 0);
2897 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2899 /* Select INBOX or local account */
2900 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2906 * Returns TRUE if at least one of the headers of the list belongs to
2907 * a message that has been fully retrieved.
2910 has_retrieved_msgs (TnyList *list)
2913 gboolean found = FALSE;
2915 iter = tny_list_create_iterator (list);
2916 while (tny_iterator_is_done (iter) && !found) {
2918 TnyHeaderFlags flags;
2920 header = TNY_HEADER (tny_iterator_get_current (iter));
2921 flags = tny_header_get_flags (header);
2922 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2926 tny_iterator_next (iter);
2928 g_object_unref (iter);
2934 * Shows a confirmation dialog to the user when we're moving messages
2935 * from a remote server to the local storage. Returns the dialog
2936 * response. If it's other kind of movement the it always returns
2940 msgs_move_to_confirmation (GtkWindow *win,
2941 TnyFolder *dest_folder,
2944 gint response = GTK_RESPONSE_OK;
2946 /* If the destination is a local folder */
2947 if (modest_tny_folder_is_local_folder (dest_folder)) {
2948 TnyFolder *src_folder;
2952 /* Get source folder */
2953 iter = tny_list_create_iterator (headers);
2954 header = TNY_HEADER (tny_iterator_get_current (iter));
2955 src_folder = tny_header_get_folder (header);
2956 g_object_unref (header);
2957 g_object_unref (iter);
2959 /* if no src_folder, message may be an attahcment */
2960 if (src_folder == NULL)
2961 return GTK_RESPONSE_CANCEL;
2963 /* If the source is a remote folder */
2964 if (!modest_tny_folder_is_local_folder (src_folder)) {
2965 const gchar *message;
2967 if (has_retrieved_msgs (headers))
2968 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2969 tny_list_get_length (headers));
2971 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2972 tny_list_get_length (headers));
2974 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2975 (const gchar *) message);
2977 g_object_unref (src_folder);
2985 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2987 ModestMsgViewWindow *self = NULL;
2988 gboolean last, first;
2990 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2991 self = MODEST_MSG_VIEW_WINDOW (object);
2993 last = modest_msg_view_window_last_message_selected (self);
2994 first = modest_msg_view_window_first_message_selected (self);
2996 /* No more messages to view, so close this window */
2997 /* gboolean ret_value; */
2998 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2999 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3001 modest_msg_view_window_select_previous_message (self);
3003 modest_msg_view_window_select_next_message (self);
3007 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3010 GObject *win = modest_mail_operation_get_source (mail_op);
3011 const GError *error = NULL;
3012 const gchar *message = NULL;
3014 /* Get error message */
3015 error = modest_mail_operation_get_error (mail_op);
3016 if (error != NULL && error->message != NULL) {
3017 message = error->message;
3019 message = _("mail_in_ui_folder_move_target_error");
3022 /* Show notification dialog */
3023 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3024 g_object_unref (win);
3028 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3031 GObject *win = modest_mail_operation_get_source (mail_op);
3032 const GError *error = modest_mail_operation_get_error (mail_op);
3034 g_return_if_fail (error != NULL);
3035 if (error->message != NULL)
3036 g_printerr ("modest: %s\n", error->message);
3038 g_printerr ("modest: unkonw error on send&receive operation");
3040 /* Show error message */
3041 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3042 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3043 /* _CS("sfil_ib_unable_to_receive")); */
3045 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3046 /* _CS("sfil_ib_unable_to_send")); */
3047 g_object_unref (win);
3051 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3058 gint pending_purges = 0;
3059 gboolean some_purged = FALSE;
3060 ModestWindow *win = MODEST_WINDOW (user_data);
3064 /* Once the message has been retrieved for purging, we check if
3065 * it's all ok for purging */
3067 parts = tny_simple_list_new ();
3068 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3069 iter = tny_list_create_iterator (parts);
3071 while (!tny_iterator_is_done (iter)) {
3073 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3074 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3075 if (tny_mime_part_is_purged (part))
3080 tny_iterator_next (iter);
3083 if (pending_purges>0) {
3085 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3087 if (response == GTK_RESPONSE_OK) {
3088 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3089 tny_iterator_first (iter);
3090 while (!tny_iterator_is_done (iter)) {
3093 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3094 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3095 tny_mime_part_set_purged (part);
3096 tny_iterator_next (iter);
3099 tny_msg_rewrite_cache (msg);
3102 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3105 /* remove attachments */
3106 tny_iterator_first (iter);
3107 while (!tny_iterator_is_done (iter)) {
3110 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3111 g_object_unref (part);
3112 tny_iterator_next (iter);
3115 g_object_unref (iter);
3116 g_object_unref (parts);
3120 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3121 ModestMainWindow *win)
3123 GtkWidget *header_view;
3124 TnyList *header_list;
3127 TnyHeaderFlags flags;
3128 ModestWindow *msg_view_window = NULL;
3131 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3133 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3134 MODEST_WIDGET_TYPE_HEADER_VIEW);
3136 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3138 if (tny_list_get_length (header_list) == 1) {
3139 iter = tny_list_create_iterator (header_list);
3140 header = TNY_HEADER (tny_iterator_get_current (iter));
3141 g_object_unref (iter);
3146 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3147 header, &msg_view_window);
3148 flags = tny_header_get_flags (header);
3149 if (!(flags & TNY_HEADER_FLAG_CACHED))
3152 if (msg_view_window != NULL)
3153 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3155 /* do nothing; uid was registered before, so window is probably on it's way */
3156 g_warning ("debug: header %p has already been registered", header);
3159 ModestMailOperation *mail_op = NULL;
3160 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3161 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3163 modest_ui_actions_get_msgs_full_error_handler,
3165 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3166 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3168 g_object_unref (mail_op);
3171 g_object_unref (header);
3173 g_object_unref (header_list);
3177 * UI handler for the "Move to" action when invoked from the
3181 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3182 ModestMainWindow *win)
3184 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3185 GtkWidget *header_view = NULL;
3187 TnyFolderStore *folder_store = NULL;
3188 ModestMailOperation *mail_op = NULL;
3190 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3192 /* Get the folder view */
3193 folder_view = modest_main_window_get_child_widget (win,
3194 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3196 /* Get header view */
3197 header_view = modest_main_window_get_child_widget (win,
3198 MODEST_WIDGET_TYPE_HEADER_VIEW);
3200 /* Create and run the dialog */
3201 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3202 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3203 result = gtk_dialog_run (GTK_DIALOG(dialog));
3204 g_object_ref (tree_view);
3206 /* We do this to save an indentation level ;-) */
3207 if (result != GTK_RESPONSE_ACCEPT)
3210 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3212 if (TNY_IS_ACCOUNT (folder_store) &&
3213 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3216 /* Offer the connection dialog if necessary: */
3217 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) {
3221 /* Get folder or messages to transfer */
3222 if (gtk_widget_is_focus (folder_view)) {
3223 TnyFolderStore *src_folder;
3224 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3226 /* Offer the connection dialog if necessary: */
3227 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) {
3229 /* Clean folder on header view before moving it */
3230 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3232 if (TNY_IS_FOLDER (src_folder)) {
3234 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3236 modest_ui_actions_move_folder_error_handler,
3238 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3240 modest_mail_operation_xfer_folder (mail_op,
3241 TNY_FOLDER (src_folder),
3244 /* Unref mail operation */
3245 g_object_unref (G_OBJECT (mail_op));
3249 g_object_unref (G_OBJECT (src_folder));
3252 if (gtk_widget_is_focus (header_view)) {
3253 TnyList *headers = NULL;
3256 /* TODO: Check for connection if the headers are on a network account. */
3257 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3259 /* Ask for user confirmation */
3260 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3261 TNY_FOLDER (folder_store),
3264 /* Transfer messages */
3265 if (response == GTK_RESPONSE_OK) {
3267 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3269 modest_ui_actions_move_folder_error_handler,
3271 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3274 modest_mail_operation_xfer_msgs (mail_op,
3276 TNY_FOLDER (folder_store),
3281 g_object_unref (G_OBJECT (mail_op));
3283 g_object_unref (headers);
3288 if (folder_store != NULL)
3289 g_object_unref (folder_store);
3291 gtk_widget_destroy (dialog);
3296 * UI handler for the "Move to" action when invoked from the
3297 * ModestMsgViewWindow
3300 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3301 ModestMsgViewWindow *win)
3303 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3305 ModestMainWindow *main_window = NULL;
3306 TnyHeader *header = NULL;
3307 TnyList *headers = NULL;
3309 /* Get the folder view */
3310 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3312 folder_view = modest_main_window_get_child_widget (main_window,
3313 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3317 /* Create and run the dialog */
3318 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3319 result = gtk_dialog_run (GTK_DIALOG(dialog));
3321 if (result == GTK_RESPONSE_ACCEPT) {
3322 TnyFolderStore *folder_store;
3325 /* Create header list */
3326 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3327 g_return_if_fail (header != NULL);
3329 /* Offer the connection dialog if necessary: */
3330 /* TODO: What's the extra g_object_ref() for? Isn't this leaking a ref? */
3331 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view)));
3332 TnyFolder *header_folder = tny_header_get_folder(header);
3333 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, folder_store) &&
3334 modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (header_folder))) {
3336 headers = tny_simple_list_new ();
3337 tny_list_prepend (headers, G_OBJECT (header));
3338 g_object_unref (header);
3340 /* Ask user for confirmation. MSG-NOT404 */
3341 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3342 TNY_FOLDER (folder_store),
3345 /* Transfer current msg */
3346 if (response == GTK_RESPONSE_OK) {
3347 ModestMailOperation *mail_op;
3349 /* Create mail op */
3350 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3351 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3354 /* Transfer messages */
3355 modest_mail_operation_xfer_msgs (mail_op,
3357 TNY_FOLDER (folder_store),
3359 transfer_msgs_from_viewer_cb,
3361 g_object_unref (G_OBJECT (mail_op));
3366 g_object_unref (header_folder);
3369 g_object_unref (headers);
3372 g_object_unref (folder_store);
3375 gtk_widget_destroy (dialog);
3379 modest_ui_actions_on_move_to (GtkAction *action,
3382 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3383 MODEST_IS_MSG_VIEW_WINDOW (win));
3385 if (MODEST_IS_MAIN_WINDOW (win))
3386 modest_ui_actions_on_main_window_move_to (action,
3387 MODEST_MAIN_WINDOW (win));
3389 modest_ui_actions_on_msg_view_window_move_to (action,
3390 MODEST_MSG_VIEW_WINDOW (win));
3394 * Calls #HeadersFunc for each header already selected in the main
3395 * window or the message currently being shown in the msg view window
3398 do_headers_action (ModestWindow *win,
3402 TnyList *headers_list;
3408 headers_list = get_selected_headers (win);
3412 /* Get the folder */
3413 iter = tny_list_create_iterator (headers_list);
3414 header = TNY_HEADER (tny_iterator_get_current (iter));
3415 folder = tny_header_get_folder (header);
3416 g_object_unref (header);
3418 /* Call the function for each header */
3419 while (!tny_iterator_is_done (iter)) {
3420 header = TNY_HEADER (tny_iterator_get_current (iter));
3421 func (header, win, user_data);
3422 g_object_unref (header);
3423 tny_iterator_next (iter);
3426 /* Trick: do a poke status in order to speed up the signaling
3428 tny_folder_poke_status (folder);
3431 g_object_unref (folder);
3432 g_object_unref (iter);
3433 g_object_unref (headers_list);
3437 modest_ui_actions_view_attachment (GtkAction *action,
3438 ModestWindow *window)
3440 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3441 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3443 /* not supported window for this action */
3444 g_return_if_reached ();
3449 modest_ui_actions_save_attachments (GtkAction *action,
3450 ModestWindow *window)
3452 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3453 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3455 /* not supported window for this action */
3456 g_return_if_reached ();
3461 modest_ui_actions_remove_attachments (GtkAction *action,
3462 ModestWindow *window)
3464 if (MODEST_IS_MAIN_WINDOW (window)) {
3465 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3466 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3467 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3469 /* not supported window for this action */
3470 g_return_if_reached ();
3475 modest_ui_actions_on_settings (GtkAction *action,
3480 dialog = modest_platform_get_global_settings_dialog ();
3481 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3482 gtk_widget_show_all (dialog);
3484 gtk_dialog_run (GTK_DIALOG (dialog));
3486 gtk_widget_destroy (dialog);
3490 modest_ui_actions_on_help (GtkAction *action,
3493 const gchar *help_id = NULL;
3495 if (MODEST_IS_MAIN_WINDOW (win)) {
3496 const gchar *action_name;
3497 action_name = gtk_action_get_name (action);
3499 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3500 !strcmp (action_name, "HeaderViewCSMHelp")) {
3501 GtkWidget *folder_view;
3502 TnyFolderStore *folder_store;
3503 /* Get selected folder */
3504 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3505 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3506 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3508 /* Switch help_id */
3509 if (TNY_IS_FOLDER (folder_store)) {
3510 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3511 case TNY_FOLDER_TYPE_NORMAL:
3512 help_id = "applications_email_userfolder";
3514 case TNY_FOLDER_TYPE_INBOX:
3515 help_id = "applications_email_inbox";
3517 case TNY_FOLDER_TYPE_OUTBOX:
3518 help_id = "applications_email_outbox";
3520 case TNY_FOLDER_TYPE_SENT:
3521 help_id = "applications_email_sent";
3523 case TNY_FOLDER_TYPE_DRAFTS:
3524 help_id = "applications_email_drafts";
3526 case TNY_FOLDER_TYPE_ARCHIVE:
3527 help_id = "applications_email_archive";
3533 g_object_unref (folder_store);
3535 help_id = "applications_email_mainview";
3537 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3538 help_id = "applications_email_viewer";
3539 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3540 help_id = "applications_email_editor";
3542 modest_platform_show_help (GTK_WINDOW (win), help_id);
3546 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3547 ModestWindow *window)
3549 ModestMailOperation *mail_op;
3553 headers = get_selected_headers (window);
3557 /* Create mail operation */
3558 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3560 modest_ui_actions_get_msgs_full_error_handler,
3562 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3563 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3566 g_object_unref (headers);
3567 g_object_unref (mail_op);
3571 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3572 ModestWindow *window)
3574 g_return_if_fail (MODEST_IS_WINDOW (window));
3577 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3581 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3582 ModestWindow *window)
3584 g_return_if_fail (MODEST_IS_WINDOW (window));
3587 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3591 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3592 ModestWindow *window)
3594 g_return_if_fail (MODEST_IS_WINDOW (window));
3597 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3601 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3602 ModestWindow *window)
3604 g_return_if_fail (MODEST_IS_WINDOW (window));
3607 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3611 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3612 ModestWindow *window)
3614 g_return_if_fail (MODEST_IS_WINDOW (window));
3617 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3621 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3622 ModestWindow *window)
3624 g_return_if_fail (MODEST_IS_WINDOW (window));
3627 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3631 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3632 ModestWindow *window)
3634 g_return_if_fail (MODEST_IS_WINDOW (window));
3637 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3641 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3642 ModestWindow *window)
3644 g_return_if_fail (MODEST_IS_WINDOW (window));
3647 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3651 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3653 g_return_if_fail (MODEST_IS_WINDOW (window));
3656 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3660 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3662 g_return_if_fail (MODEST_IS_WINDOW (window));
3664 modest_platform_show_search_messages (GTK_WINDOW (window));
3668 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3670 g_return_if_fail (MODEST_IS_WINDOW (win));
3671 modest_platform_show_addressbook (GTK_WINDOW (win));
3676 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3677 ModestWindow *window)
3679 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3681 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3685 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3686 ModestMailOperationState *state,
3689 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3691 /* Set send/receive operation finished */
3692 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3693 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));