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)
1020 * Common code for the reply and forward actions
1023 reply_forward (ReplyForwardAction action, ModestWindow *win)
1025 ModestMailOperation *mail_op = NULL;
1026 TnyList *header_list = NULL;
1027 ReplyForwardHelper *rf_helper = NULL;
1028 guint reply_forward_type;
1029 gboolean continue_download;
1031 g_return_if_fail (MODEST_IS_WINDOW(win));
1033 /* we need an account when editing */
1034 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1035 run_account_setup_wizard (win);
1039 header_list = get_selected_headers (win);
1043 /* Check that the messages have been previously downloaded */
1044 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1045 if (!continue_download) {
1046 g_object_unref (header_list);
1050 reply_forward_type =
1051 modest_conf_get_int (modest_runtime_get_conf (),
1052 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1054 /* We assume that we can only select messages of the
1055 same folder and that we reply all of them from the
1056 same account. In fact the interface currently only
1057 allows single selection */
1060 rf_helper = g_slice_new0 (ReplyForwardHelper);
1061 rf_helper->reply_forward_type = reply_forward_type;
1062 rf_helper->action = action;
1063 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1064 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1065 rf_helper->parent_window = GTK_WIDGET (win);
1066 if (!rf_helper->account_name)
1067 rf_helper->account_name =
1068 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1070 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1073 /* Get header and message. Do not free them here, the
1074 reply_forward_cb must do it */
1075 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1076 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1077 if (!msg || !header) {
1079 g_object_unref (msg);
1081 g_object_unref (header);
1082 g_printerr ("modest: no message found\n");
1085 reply_forward_cb (NULL, header, msg, rf_helper);
1091 /* Retrieve messages */
1092 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1094 modest_ui_actions_get_msgs_full_error_handler,
1096 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1098 /* Only reply/forward to one message */
1099 iter = tny_list_create_iterator (header_list);
1100 header = TNY_HEADER (tny_iterator_get_current (iter));
1101 g_object_unref (iter);
1103 modest_mail_operation_get_msg (mail_op,
1108 /* modest_mail_operation_get_msgs_full (mail_op, */
1110 /* reply_forward_cb, */
1112 /* free_reply_forward_helper); */
1115 g_object_unref(mail_op);
1119 g_object_unref (header_list);
1123 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1125 g_return_if_fail (MODEST_IS_WINDOW(win));
1127 reply_forward (ACTION_REPLY, win);
1131 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1133 g_return_if_fail (MODEST_IS_WINDOW(win));
1135 reply_forward (ACTION_FORWARD, win);
1139 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1141 g_return_if_fail (MODEST_IS_WINDOW(win));
1143 reply_forward (ACTION_REPLY_TO_ALL, win);
1147 modest_ui_actions_on_next (GtkAction *action,
1148 ModestWindow *window)
1150 if (MODEST_IS_MAIN_WINDOW (window)) {
1151 GtkWidget *header_view;
1153 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1154 MODEST_WIDGET_TYPE_HEADER_VIEW);
1158 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1159 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1160 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1162 g_return_if_reached ();
1167 modest_ui_actions_on_prev (GtkAction *action,
1168 ModestWindow *window)
1170 g_return_if_fail (MODEST_IS_WINDOW(window));
1172 if (MODEST_IS_MAIN_WINDOW (window)) {
1173 GtkWidget *header_view;
1174 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1175 MODEST_WIDGET_TYPE_HEADER_VIEW);
1179 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1180 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1181 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1183 g_return_if_reached ();
1188 modest_ui_actions_on_sort (GtkAction *action,
1189 ModestWindow *window)
1191 g_return_if_fail (MODEST_IS_WINDOW(window));
1193 if (MODEST_IS_MAIN_WINDOW (window)) {
1194 GtkWidget *header_view;
1195 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1196 MODEST_WIDGET_TYPE_HEADER_VIEW);
1200 /* Show sorting dialog */
1201 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1206 new_messages_arrived (ModestMailOperation *self,
1210 if (new_messages == 0)
1213 modest_platform_on_new_msg ();
1217 * This function performs the send & receive required actions. The
1218 * window is used to create the mail operation. Typically it should
1219 * always be the main window, but we pass it as argument in order to
1223 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1225 gchar *acc_name = NULL;
1226 ModestMailOperation *mail_op;
1228 /* If no account name was provided then get the current account, and if
1229 there is no current account then pick the default one: */
1230 if (!account_name) {
1231 acc_name = g_strdup (modest_window_get_active_account(win));
1233 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1235 g_printerr ("modest: cannot get default account\n");
1239 acc_name = g_strdup (account_name);
1242 /* Set send/receive operation in progress */
1243 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1245 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1247 modest_ui_actions_send_receive_error_handler,
1250 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1251 G_CALLBACK (_on_send_receive_progress_changed),
1254 /* Send & receive. */
1255 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1256 /* Receive and then send. The operation is tagged initially as
1257 a receive operation because the account update performs a
1258 receive and then a send. The operation changes its type
1259 internally, so the progress objects will receive the proper
1260 progress information */
1261 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1262 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1263 g_object_unref (G_OBJECT (mail_op));
1270 * Refreshes all accounts. This function will be used by automatic
1274 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1276 GSList *account_names, *iter;
1278 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1281 iter = account_names;
1283 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1284 iter = g_slist_next (iter);
1287 modest_account_mgr_free_account_names (account_names);
1288 account_names = NULL;
1292 * Handler of the click on Send&Receive button in the main toolbar
1295 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1297 /* Check if accounts exist */
1298 gboolean accounts_exist =
1299 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1301 /* If not, allow the user to create an account before trying to send/receive. */
1302 if (!accounts_exist)
1303 modest_ui_actions_on_accounts (NULL, win);
1305 /* Refresh the active account */
1306 modest_ui_actions_do_send_receive (NULL, win);
1311 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1314 GtkWidget *header_view;
1316 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1318 header_view = modest_main_window_get_child_widget (main_window,
1319 MODEST_WIDGET_TYPE_HEADER_VIEW);
1323 conf = modest_runtime_get_conf ();
1325 /* what is saved/restored is depending on the style; thus; we save with
1326 * old style, then update the style, and restore for this new style
1328 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1330 if (modest_header_view_get_style
1331 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1332 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1333 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1335 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1336 MODEST_HEADER_VIEW_STYLE_DETAILS);
1338 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1339 MODEST_CONF_HEADER_VIEW_KEY);
1344 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1346 ModestMainWindow *main_window)
1348 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1349 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1351 /* If no header has been selected then exit */
1356 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1357 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1359 /* Update Main window title */
1360 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1361 const gchar *subject = tny_header_get_subject (header);
1362 if (subject && strlen(subject) > 0)
1363 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1365 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1368 /* Update toolbar dimming state */
1369 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1373 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1375 ModestMainWindow *main_window)
1379 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1384 headers = tny_simple_list_new ();
1385 tny_list_prepend (headers, G_OBJECT (header));
1387 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1389 g_object_unref (headers);
1393 set_active_account_from_tny_account (TnyAccount *account,
1394 ModestWindow *window)
1396 const gchar *server_acc_name = tny_account_get_id (account);
1398 /* We need the TnyAccount provided by the
1399 account store because that is the one that
1400 knows the name of the Modest account */
1401 TnyAccount *modest_server_account = modest_server_account =
1402 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1403 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1406 const gchar *modest_acc_name =
1407 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1408 modest_window_set_active_account (window, modest_acc_name);
1409 g_object_unref (modest_server_account);
1414 folder_refreshed_cb (const GObject *obj,
1418 ModestMainWindow *win = NULL;
1419 GtkWidget *header_view;
1421 g_return_if_fail (TNY_IS_FOLDER (folder));
1423 win = MODEST_MAIN_WINDOW (user_data);
1425 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1427 /* Check if folder is empty and set headers view contents style */
1428 if (tny_folder_get_all_count (folder) == 0) {
1429 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1430 modest_main_window_set_contents_style (win,
1431 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1433 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1438 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1439 TnyFolderStore *folder_store,
1441 ModestMainWindow *main_window)
1444 GtkWidget *header_view;
1446 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1448 header_view = modest_main_window_get_child_widget(main_window,
1449 MODEST_WIDGET_TYPE_HEADER_VIEW);
1453 conf = modest_runtime_get_conf ();
1455 if (TNY_IS_ACCOUNT (folder_store)) {
1457 /* Update active account */
1458 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1459 /* Show account details */
1460 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1463 if (TNY_IS_FOLDER (folder_store) && selected) {
1465 /* Update the active account */
1466 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1468 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1469 g_object_unref (account);
1473 /* Set the header style by default, it could
1474 be changed later by the refresh callback to
1476 modest_main_window_set_contents_style (main_window,
1477 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1479 /* Set folder on header view. This function
1480 will call tny_folder_refresh_async so we
1481 pass a callback that will be called when
1482 finished. We use that callback to set the
1483 empty view if there are no messages */
1484 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1485 TNY_FOLDER (folder_store),
1486 folder_refreshed_cb,
1489 /* Restore configuration. We need to do this
1490 *after* the set_folder because the widget
1491 memory asks the header view about its
1493 modest_widget_memory_restore (modest_runtime_get_conf (),
1494 G_OBJECT(header_view),
1495 MODEST_CONF_HEADER_VIEW_KEY);
1497 /* Update the active account */
1498 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1499 /* Save only if we're seeing headers */
1500 if (modest_main_window_get_contents_style (main_window) ==
1501 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1502 modest_widget_memory_save (conf, G_OBJECT (header_view),
1503 MODEST_CONF_HEADER_VIEW_KEY);
1504 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1508 /* Update toolbar dimming state */
1509 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1513 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1520 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1522 online = tny_device_is_online (modest_runtime_get_device());
1525 /* already online -- the item is simply not there... */
1526 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1528 GTK_MESSAGE_WARNING,
1530 _("The %s you selected cannot be found"),
1532 gtk_dialog_run (GTK_DIALOG(dialog));
1534 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1538 GTK_RESPONSE_REJECT,
1540 GTK_RESPONSE_ACCEPT,
1542 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1543 "Do you want to get online?"), item);
1544 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1545 gtk_label_new (txt), FALSE, FALSE, 0);
1546 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1549 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1550 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1551 // modest_platform_connect_and_wait ();
1554 gtk_widget_destroy (dialog);
1558 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1561 /* g_message ("%s %s", __FUNCTION__, link); */
1566 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1569 modest_platform_activate_uri (link);
1573 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1576 modest_platform_show_uri_popup (link);
1580 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1583 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1587 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1588 const gchar *address,
1591 /* g_message ("%s %s", __FUNCTION__, address); */
1595 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1597 TnyTransportAccount *transport_account;
1598 ModestMailOperation *mail_operation;
1600 gchar *account_name, *from;
1601 ModestAccountMgr *account_mgr;
1602 gchar *info_text = NULL;
1604 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1606 data = modest_msg_edit_window_get_msg_data (edit_window);
1608 account_mgr = modest_runtime_get_account_mgr();
1609 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1611 account_name = modest_account_mgr_get_default_account (account_mgr);
1612 if (!account_name) {
1613 g_printerr ("modest: no account found\n");
1614 modest_msg_edit_window_free_msg_data (edit_window, data);
1618 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1619 account_name = g_strdup (data->account_name);
1623 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1624 (modest_runtime_get_account_store(),
1626 TNY_ACCOUNT_TYPE_TRANSPORT));
1627 if (!transport_account) {
1628 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1629 g_free (account_name);
1630 modest_msg_edit_window_free_msg_data (edit_window, data);
1633 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1635 /* Create the mail operation */
1636 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1637 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1639 modest_mail_operation_save_to_drafts (mail_operation,
1650 data->priority_flags);
1653 g_free (account_name);
1654 g_object_unref (G_OBJECT (transport_account));
1655 g_object_unref (G_OBJECT (mail_operation));
1657 modest_msg_edit_window_free_msg_data (edit_window, data);
1659 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1660 modest_platform_information_banner (NULL, NULL, info_text);
1664 /* For instance, when clicking the Send toolbar button when editing a message: */
1666 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1668 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1670 if (!modest_msg_edit_window_check_names (edit_window))
1673 /* FIXME: Code added just for testing. The final version will
1674 use the send queue provided by tinymail and some
1676 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1677 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1679 account_name = modest_account_mgr_get_default_account (account_mgr);
1681 if (!account_name) {
1682 g_printerr ("modest: no account found\n");
1686 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1688 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1689 account_name = g_strdup (data->account_name);
1692 /* Get the currently-active transport account for this modest account: */
1693 TnyTransportAccount *transport_account =
1694 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1695 (modest_runtime_get_account_store(),
1697 if (!transport_account) {
1698 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1699 g_free (account_name);
1700 modest_msg_edit_window_free_msg_data (edit_window, data);
1704 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1706 /* mail content checks and dialogs */
1707 if (data->subject == NULL || data->subject[0] == '\0') {
1708 GtkResponseType response;
1709 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1710 _("mcen_nc_subject_is_empty_send"));
1711 if (response == GTK_RESPONSE_CANCEL) {
1712 g_free (account_name);
1717 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1718 GtkResponseType response;
1719 gchar *note_message;
1720 gchar *note_subject = data->subject;
1721 if (note_subject == NULL || note_subject[0] == '\0')
1722 note_subject = _("mail_va_no_subject");
1723 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1724 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1726 g_free (note_message);
1727 if (response == GTK_RESPONSE_CANCEL) {
1728 g_free (account_name);
1733 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1735 /* Create the mail operation */
1736 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1737 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1739 modest_mail_operation_send_new_mail (mail_operation,
1750 data->priority_flags);
1754 g_free (account_name);
1755 g_object_unref (G_OBJECT (transport_account));
1756 g_object_unref (G_OBJECT (mail_operation));
1758 modest_msg_edit_window_free_msg_data (edit_window, data);
1759 modest_msg_edit_window_set_sent (edit_window, TRUE);
1761 /* Save settings and close the window: */
1762 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
1766 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1767 ModestMsgEditWindow *window)
1769 ModestMsgEditFormatState *format_state = NULL;
1771 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1772 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1774 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1777 format_state = modest_msg_edit_window_get_format_state (window);
1778 g_return_if_fail (format_state != NULL);
1780 format_state->bold = gtk_toggle_action_get_active (action);
1781 modest_msg_edit_window_set_format_state (window, format_state);
1782 g_free (format_state);
1787 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1788 ModestMsgEditWindow *window)
1790 ModestMsgEditFormatState *format_state = NULL;
1792 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1793 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1795 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1798 format_state = modest_msg_edit_window_get_format_state (window);
1799 g_return_if_fail (format_state != NULL);
1801 format_state->italics = gtk_toggle_action_get_active (action);
1802 modest_msg_edit_window_set_format_state (window, format_state);
1803 g_free (format_state);
1808 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1809 ModestMsgEditWindow *window)
1811 ModestMsgEditFormatState *format_state = NULL;
1813 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1814 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1816 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1819 format_state = modest_msg_edit_window_get_format_state (window);
1820 g_return_if_fail (format_state != NULL);
1822 format_state->bullet = gtk_toggle_action_get_active (action);
1823 modest_msg_edit_window_set_format_state (window, format_state);
1824 g_free (format_state);
1829 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1830 GtkRadioAction *selected,
1831 ModestMsgEditWindow *window)
1833 ModestMsgEditFormatState *format_state = NULL;
1834 GtkJustification value;
1836 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1838 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1841 value = gtk_radio_action_get_current_value (selected);
1843 format_state = modest_msg_edit_window_get_format_state (window);
1844 g_return_if_fail (format_state != NULL);
1846 format_state->justification = value;
1847 modest_msg_edit_window_set_format_state (window, format_state);
1848 g_free (format_state);
1852 modest_ui_actions_on_select_editor_color (GtkAction *action,
1853 ModestMsgEditWindow *window)
1855 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1856 g_return_if_fail (GTK_IS_ACTION (action));
1858 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1861 modest_msg_edit_window_select_color (window);
1865 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1866 ModestMsgEditWindow *window)
1868 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1869 g_return_if_fail (GTK_IS_ACTION (action));
1871 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1874 modest_msg_edit_window_select_background_color (window);
1878 modest_ui_actions_on_insert_image (GtkAction *action,
1879 ModestMsgEditWindow *window)
1881 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1882 g_return_if_fail (GTK_IS_ACTION (action));
1884 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1887 modest_msg_edit_window_insert_image (window);
1891 modest_ui_actions_on_attach_file (GtkAction *action,
1892 ModestMsgEditWindow *window)
1894 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1895 g_return_if_fail (GTK_IS_ACTION (action));
1897 modest_msg_edit_window_attach_file (window);
1901 modest_ui_actions_on_remove_attachments (GtkAction *action,
1902 ModestMsgEditWindow *window)
1904 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1905 g_return_if_fail (GTK_IS_ACTION (action));
1907 modest_msg_edit_window_remove_attachments (window, NULL);
1911 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1913 TnyFolderStore *parent_folder;
1914 GtkWidget *folder_view;
1916 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1918 folder_view = modest_main_window_get_child_widget (main_window,
1919 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1923 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1925 if (parent_folder) {
1926 gboolean finished = FALSE;
1928 gchar *folder_name = NULL, *suggested_name = NULL;
1930 /* Run the new folder dialog */
1932 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1937 if (result == GTK_RESPONSE_REJECT) {
1940 ModestMailOperation *mail_op;
1941 TnyFolder *new_folder = NULL;
1943 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1944 G_OBJECT(main_window));
1945 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1947 new_folder = modest_mail_operation_create_folder (mail_op,
1949 (const gchar *) folder_name);
1951 g_object_unref (new_folder);
1954 g_object_unref (mail_op);
1956 g_free (folder_name);
1960 g_object_unref (parent_folder);
1965 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
1968 GObject *win = modest_mail_operation_get_source (mail_op);
1969 const GError *error = NULL;
1970 const gchar *message = NULL;
1972 /* Get error message */
1973 error = modest_mail_operation_get_error (mail_op);
1974 if (error != NULL && error->message != NULL) {
1975 message = error->message;
1977 message = _("!!! FIXME: Unable to rename");
1980 /* Show notification dialog */
1981 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
1982 g_object_unref (win);
1986 modest_ui_actions_on_rename_folder (GtkAction *action,
1987 ModestMainWindow *main_window)
1989 TnyFolderStore *folder;
1990 GtkWidget *folder_view;
1991 GtkWidget *header_view;
1993 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1995 folder_view = modest_main_window_get_child_widget (main_window,
1996 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2000 header_view = modest_main_window_get_child_widget (main_window,
2001 MODEST_WIDGET_TYPE_HEADER_VIEW);
2006 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2008 if (folder && TNY_IS_FOLDER (folder)) {
2011 const gchar *current_name;
2013 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2014 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2015 current_name, &folder_name);
2017 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2018 ModestMailOperation *mail_op;
2021 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2022 G_OBJECT(main_window),
2023 modest_ui_actions_rename_folder_error_handler,
2027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2030 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2032 modest_mail_operation_rename_folder (mail_op,
2033 TNY_FOLDER (folder),
2034 (const gchar *) folder_name);
2036 g_object_unref (mail_op);
2037 g_free (folder_name);
2039 g_object_unref (folder);
2044 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2047 GObject *win = modest_mail_operation_get_source (mail_op);
2049 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2050 _("mail_in_ui_folder_delete_error"));
2051 g_object_unref (win);
2055 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2057 TnyFolderStore *folder;
2058 GtkWidget *folder_view;
2062 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2064 folder_view = modest_main_window_get_child_widget (main_window,
2065 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2069 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2071 /* Show an error if it's an account */
2072 if (!TNY_IS_FOLDER (folder)) {
2073 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2074 _("mail_in_ui_folder_delete_error"));
2079 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2080 tny_folder_get_name (TNY_FOLDER (folder)));
2081 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2082 (const gchar *) message);
2085 if (response == GTK_RESPONSE_OK) {
2086 ModestMailOperation *mail_op =
2087 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2088 G_OBJECT(main_window),
2089 modest_ui_actions_delete_folder_error_handler,
2092 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2094 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2095 g_object_unref (G_OBJECT (mail_op));
2098 g_object_unref (G_OBJECT (folder));
2102 modest_ui_actions_on_delete_folder (GtkAction *action,
2103 ModestMainWindow *main_window)
2105 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2107 delete_folder (main_window, FALSE);
2111 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2113 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2115 delete_folder (main_window, TRUE);
2119 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2120 const gchar* server_account_name,
2125 ModestMainWindow *main_window)
2127 g_return_if_fail(server_account_name);
2128 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2130 /* Initalize output parameters: */
2137 #ifdef MODEST_PLATFORM_MAEMO
2138 /* Maemo uses a different (awkward) button order,
2139 * It should probably just use gtk_alternative_dialog_button_order ().
2141 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2145 GTK_RESPONSE_ACCEPT,
2147 GTK_RESPONSE_REJECT,
2150 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2154 GTK_RESPONSE_REJECT,
2156 GTK_RESPONSE_ACCEPT,
2158 #endif /* MODEST_PLATFORM_MAEMO */
2160 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2162 gchar *server_name = modest_server_account_get_hostname (
2163 modest_runtime_get_account_mgr(), server_account_name);
2164 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2165 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2170 /* This causes a warning because the logical ID has no %s in it,
2171 * though the translation does, but there is not much we can do about that: */
2172 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2173 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2176 g_free (server_name);
2180 gchar *initial_username = modest_server_account_get_username (
2181 modest_runtime_get_account_mgr(), server_account_name);
2183 GtkWidget *entry_username = gtk_entry_new ();
2184 if (initial_username)
2185 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2186 /* Dim this if a connection has ever succeeded with this username,
2187 * as per the UI spec: */
2188 const gboolean username_known =
2189 modest_server_account_get_username_has_succeeded(
2190 modest_runtime_get_account_mgr(), server_account_name);
2191 gtk_widget_set_sensitive (entry_username, !username_known);
2193 #ifdef MODEST_PLATFORM_MAEMO
2194 /* Auto-capitalization is the default, so let's turn it off: */
2195 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2197 /* Create a size group to be used by all captions.
2198 * Note that HildonCaption does not create a default size group if we do not specify one.
2199 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2200 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2202 GtkWidget *caption = hildon_caption_new (sizegroup,
2203 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2204 gtk_widget_show (entry_username);
2205 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2206 FALSE, FALSE, MODEST_MARGIN_HALF);
2207 gtk_widget_show (caption);
2209 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2211 #endif /* MODEST_PLATFORM_MAEMO */
2214 GtkWidget *entry_password = gtk_entry_new ();
2215 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2216 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2218 #ifdef MODEST_PLATFORM_MAEMO
2219 /* Auto-capitalization is the default, so let's turn it off: */
2220 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2221 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2223 caption = hildon_caption_new (sizegroup,
2224 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2225 gtk_widget_show (entry_password);
2226 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2227 FALSE, FALSE, MODEST_MARGIN_HALF);
2228 gtk_widget_show (caption);
2229 g_object_unref (sizegroup);
2231 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2233 #endif /* MODEST_PLATFORM_MAEMO */
2235 /* This is not in the Maemo UI spec:
2236 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2237 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2241 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2243 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2245 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2247 modest_server_account_set_username (
2248 modest_runtime_get_account_mgr(), server_account_name,
2251 const gboolean username_was_changed =
2252 (strcmp (*username, initial_username) != 0);
2253 if (username_was_changed) {
2254 g_warning ("%s: tinymail does not yet support changing the "
2255 "username in the get_password() callback.\n", __FUNCTION__);
2260 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2262 /* We do not save the password in the configuration,
2263 * because this function is only called for passwords that should
2264 * not be remembered:
2265 modest_server_account_set_password (
2266 modest_runtime_get_account_mgr(), server_account_name,
2285 /* This is not in the Maemo UI spec:
2286 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2292 gtk_widget_destroy (dialog);
2294 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2298 modest_ui_actions_on_cut (GtkAction *action,
2299 ModestWindow *window)
2301 GtkWidget *focused_widget;
2303 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2304 if (GTK_IS_EDITABLE (focused_widget)) {
2305 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2306 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2307 GtkTextBuffer *buffer;
2308 GtkClipboard *clipboard;
2310 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2311 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2312 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2313 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2314 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2315 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2316 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2321 modest_ui_actions_on_copy (GtkAction *action,
2322 ModestWindow *window)
2324 GtkClipboard *clipboard;
2325 GtkWidget *focused_widget;
2327 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2328 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2330 if (GTK_IS_LABEL (focused_widget)) {
2331 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2332 } else if (GTK_IS_EDITABLE (focused_widget)) {
2333 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2334 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2335 GtkTextBuffer *buffer;
2336 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2337 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2338 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2339 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2340 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2341 TnyIterator *iter = tny_list_create_iterator (header_list);
2342 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2343 TnyFolder *folder = tny_header_get_folder (header);
2344 TnyAccount *account = tny_folder_get_account (folder);
2345 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2346 /* If it's POP then ask */
2347 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2348 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2349 g_object_unref (account);
2350 g_object_unref (folder);
2351 g_object_unref (header);
2352 g_object_unref (iter);
2354 /* Check that the messages have been previously downloaded */
2355 gboolean continue_download = TRUE;
2357 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2358 if (continue_download)
2359 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2360 g_object_unref (header_list);
2361 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2362 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2365 /* Show information banner */
2366 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2371 modest_ui_actions_on_undo (GtkAction *action,
2372 ModestWindow *window)
2374 ModestEmailClipboard *clipboard = NULL;
2376 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2377 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2378 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2379 /* Clear clipboard source */
2380 clipboard = modest_runtime_get_email_clipboard ();
2381 modest_email_clipboard_clear (clipboard);
2384 g_return_if_reached ();
2390 paste_msgs_cb (const GObject *object, gpointer user_data)
2392 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2393 g_return_if_fail (GTK_IS_WIDGET (user_data));
2395 /* destroy information note */
2396 gtk_widget_destroy (GTK_WIDGET(user_data));
2400 modest_ui_actions_on_paste (GtkAction *action,
2401 ModestWindow *window)
2403 GtkWidget *focused_widget = NULL;
2404 GtkWidget *inf_note = NULL;
2405 ModestMailOperation *mail_op = NULL;
2407 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2408 if (GTK_IS_EDITABLE (focused_widget)) {
2409 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2410 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2411 GtkTextBuffer *buffer;
2412 GtkClipboard *clipboard;
2414 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2415 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2416 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2417 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2418 ModestEmailClipboard *clipboard = NULL;
2419 TnyFolder *src_folder = NULL;
2420 TnyFolderStore *folder_store = NULL;
2421 TnyList *data = NULL;
2422 gboolean delete = FALSE;
2424 /* Check clipboard source */
2425 clipboard = modest_runtime_get_email_clipboard ();
2426 if (modest_email_clipboard_cleared (clipboard))
2429 /* Get elements to paste */
2430 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2432 /* Create a new mail operation */
2433 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2434 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2437 /* Get destination folder */
2438 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2440 /* Launch notification */
2441 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2442 _CS("ckct_nw_pasting"));
2443 if (inf_note != NULL) {
2444 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2445 gtk_widget_show (GTK_WIDGET(inf_note));
2448 /* transfer messages */
2450 modest_mail_operation_xfer_msgs (mail_op,
2452 TNY_FOLDER (folder_store),
2457 } else if (src_folder != NULL) {
2458 modest_mail_operation_xfer_folder (mail_op,
2468 g_object_unref (data);
2469 if (src_folder != NULL)
2470 g_object_unref (src_folder);
2471 if (folder_store != NULL)
2472 g_object_unref (folder_store);
2478 modest_ui_actions_on_select_all (GtkAction *action,
2479 ModestWindow *window)
2481 GtkWidget *focused_widget;
2483 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2484 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2485 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2486 } else if (GTK_IS_LABEL (focused_widget)) {
2487 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2488 } else if (GTK_IS_EDITABLE (focused_widget)) {
2489 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2490 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2491 GtkTextBuffer *buffer;
2492 GtkTextIter start, end;
2494 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2495 gtk_text_buffer_get_start_iter (buffer, &start);
2496 gtk_text_buffer_get_end_iter (buffer, &end);
2497 gtk_text_buffer_select_range (buffer, &start, &end);
2498 } else if (GTK_IS_HTML (focused_widget)) {
2499 gtk_html_select_all (GTK_HTML (focused_widget));
2500 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2501 GtkWidget *header_view = focused_widget;
2502 GtkTreeSelection *selection = NULL;
2504 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2505 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2506 MODEST_WIDGET_TYPE_HEADER_VIEW);
2508 /* Select all messages */
2509 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2510 gtk_tree_selection_select_all (selection);
2512 /* Set focuse on header view */
2513 gtk_widget_grab_focus (header_view);
2519 modest_ui_actions_on_mark_as_read (GtkAction *action,
2520 ModestWindow *window)
2522 g_return_if_fail (MODEST_IS_WINDOW(window));
2524 /* Mark each header as read */
2525 do_headers_action (window, headers_action_mark_as_read, NULL);
2529 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2530 ModestWindow *window)
2532 g_return_if_fail (MODEST_IS_WINDOW(window));
2534 /* Mark each header as read */
2535 do_headers_action (window, headers_action_mark_as_unread, NULL);
2539 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2540 GtkRadioAction *selected,
2541 ModestWindow *window)
2545 value = gtk_radio_action_get_current_value (selected);
2546 if (MODEST_IS_WINDOW (window)) {
2547 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2551 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2552 GtkRadioAction *selected,
2553 ModestWindow *window)
2555 TnyHeaderFlags flags;
2556 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2558 flags = gtk_radio_action_get_current_value (selected);
2559 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2562 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2563 GtkRadioAction *selected,
2564 ModestWindow *window)
2568 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2570 file_format = gtk_radio_action_get_current_value (selected);
2571 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2576 modest_ui_actions_on_zoom_plus (GtkAction *action,
2577 ModestWindow *window)
2579 g_return_if_fail (MODEST_IS_WINDOW (window));
2581 modest_window_zoom_plus (MODEST_WINDOW (window));
2585 modest_ui_actions_on_zoom_minus (GtkAction *action,
2586 ModestWindow *window)
2588 g_return_if_fail (MODEST_IS_WINDOW (window));
2590 modest_window_zoom_minus (MODEST_WINDOW (window));
2594 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2595 ModestWindow *window)
2597 ModestWindowMgr *mgr;
2598 gboolean fullscreen, active;
2599 g_return_if_fail (MODEST_IS_WINDOW (window));
2601 mgr = modest_runtime_get_window_mgr ();
2603 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2604 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2606 if (active != fullscreen) {
2607 modest_window_mgr_set_fullscreen_mode (mgr, active);
2608 gtk_window_present (GTK_WINDOW (window));
2613 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2614 ModestWindow *window)
2616 ModestWindowMgr *mgr;
2617 gboolean fullscreen;
2619 g_return_if_fail (MODEST_IS_WINDOW (window));
2621 mgr = modest_runtime_get_window_mgr ();
2622 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2623 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2625 gtk_window_present (GTK_WINDOW (window));
2629 * Used by modest_ui_actions_on_details to call do_headers_action
2632 headers_action_show_details (TnyHeader *header,
2633 ModestWindow *window,
2640 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2643 gtk_widget_show_all (dialog);
2644 gtk_dialog_run (GTK_DIALOG (dialog));
2646 gtk_widget_destroy (dialog);
2650 * Show the folder details in a ModestDetailsDialog widget
2653 show_folder_details (TnyFolder *folder,
2659 dialog = modest_details_dialog_new_with_folder (window, folder);
2662 gtk_widget_show_all (dialog);
2663 gtk_dialog_run (GTK_DIALOG (dialog));
2665 gtk_widget_destroy (dialog);
2669 * Show the header details in a ModestDetailsDialog widget
2672 modest_ui_actions_on_details (GtkAction *action,
2675 TnyList * headers_list;
2679 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2682 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2685 g_object_unref (msg);
2687 headers_list = get_selected_headers (win);
2691 iter = tny_list_create_iterator (headers_list);
2693 header = TNY_HEADER (tny_iterator_get_current (iter));
2694 headers_action_show_details (header, win, NULL);
2695 g_object_unref (header);
2697 g_object_unref (iter);
2698 g_object_unref (headers_list);
2700 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2701 GtkWidget *folder_view, *header_view;
2703 /* Check which widget has the focus */
2704 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2705 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2706 if (gtk_widget_is_focus (folder_view)) {
2707 TnyFolderStore *folder_store
2708 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2709 if (!folder_store) {
2710 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2713 /* Show only when it's a folder */
2714 /* This function should not be called for account items,
2715 * because we dim the menu item for them. */
2716 if (TNY_IS_FOLDER (folder_store)) {
2717 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2720 g_object_unref (folder_store);
2723 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2724 MODEST_WIDGET_TYPE_HEADER_VIEW);
2725 /* Show details of each header */
2726 do_headers_action (win, headers_action_show_details, header_view);
2732 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2733 ModestMsgEditWindow *window)
2735 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2737 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2741 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2742 ModestMsgEditWindow *window)
2744 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2746 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2750 modest_ui_actions_toggle_folders_view (GtkAction *action,
2751 ModestMainWindow *main_window)
2755 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2757 conf = modest_runtime_get_conf ();
2759 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2760 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2762 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2766 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2767 ModestWindow *window)
2769 gboolean active, fullscreen = FALSE;
2770 ModestWindowMgr *mgr;
2772 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2774 /* Check if we want to toggle the toolbar vuew in fullscreen
2776 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2777 "ViewShowToolbarFullScreen")) {
2781 /* Toggle toolbar */
2782 mgr = modest_runtime_get_window_mgr ();
2783 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2787 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2788 ModestMsgEditWindow *window)
2790 modest_msg_edit_window_select_font (window);
2794 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2795 const gchar *display_name,
2798 /* Do not change the application name if the widget has not
2799 the focus. This callback could be called even if the folder
2800 view has not the focus, because the handled signal could be
2801 emitted when the folder view is redrawn */
2802 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2804 gtk_window_set_title (window, display_name);
2806 gtk_window_set_title (window, " ");
2811 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2813 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2814 modest_msg_edit_window_select_contacts (window);
2818 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2820 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2821 modest_msg_edit_window_check_names (window);
2826 create_move_to_dialog (ModestWindow *win,
2827 GtkWidget *folder_view,
2828 GtkWidget **tree_view)
2830 GtkWidget *dialog, *scroll;
2832 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2834 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2836 GTK_RESPONSE_ACCEPT,
2838 GTK_RESPONSE_REJECT,
2841 /* Create scrolled window */
2842 scroll = gtk_scrolled_window_new (NULL, NULL);
2843 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2844 GTK_POLICY_AUTOMATIC,
2845 GTK_POLICY_AUTOMATIC);
2847 /* Create folder view */
2848 *tree_view = modest_platform_create_folder_view (NULL);
2850 /* It could happen that we're trying to move a message from a
2851 window (msg window for example) after the main window was
2852 closed, so we can not just get the model of the folder
2854 if (MODEST_IS_FOLDER_VIEW (folder_view))
2855 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2856 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2858 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2859 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2861 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2863 /* Add scroll to dialog */
2864 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2865 scroll, FALSE, FALSE, 0);
2867 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2869 /* Select INBOX or local account */
2870 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2876 * Returns TRUE if at least one of the headers of the list belongs to
2877 * a message that has been fully retrieved.
2880 has_retrieved_msgs (TnyList *list)
2883 gboolean found = FALSE;
2885 iter = tny_list_create_iterator (list);
2886 while (tny_iterator_is_done (iter) && !found) {
2888 TnyHeaderFlags flags;
2890 header = TNY_HEADER (tny_iterator_get_current (iter));
2891 flags = tny_header_get_flags (header);
2892 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2896 tny_iterator_next (iter);
2898 g_object_unref (iter);
2904 * Shows a confirmation dialog to the user when we're moving messages
2905 * from a remote server to the local storage. Returns the dialog
2906 * response. If it's other kind of movement the it always returns
2910 msgs_move_to_confirmation (GtkWindow *win,
2911 TnyFolder *dest_folder,
2914 gint response = GTK_RESPONSE_OK;
2916 /* If the destination is a local folder */
2917 if (modest_tny_folder_is_local_folder (dest_folder)) {
2918 TnyFolder *src_folder;
2922 /* Get source folder */
2923 iter = tny_list_create_iterator (headers);
2924 header = TNY_HEADER (tny_iterator_get_current (iter));
2925 src_folder = tny_header_get_folder (header);
2926 g_object_unref (header);
2927 g_object_unref (iter);
2929 /* if no src_folder, message may be an attahcment */
2930 if (src_folder == NULL)
2931 return GTK_RESPONSE_CANCEL;
2933 /* If the source is a remote folder */
2934 if (!modest_tny_folder_is_local_folder (src_folder)) {
2935 const gchar *message;
2937 if (has_retrieved_msgs (headers))
2938 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
2939 tny_list_get_length (headers));
2941 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
2942 tny_list_get_length (headers));
2944 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2945 (const gchar *) message);
2947 g_object_unref (src_folder);
2955 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2957 ModestMsgViewWindow *self = NULL;
2958 gboolean last, first;
2960 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2961 self = MODEST_MSG_VIEW_WINDOW (object);
2963 last = modest_msg_view_window_last_message_selected (self);
2964 first = modest_msg_view_window_first_message_selected (self);
2966 /* No more messages to view, so close this window */
2967 /* gboolean ret_value; */
2968 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
2969 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
2971 modest_msg_view_window_select_previous_message (self);
2973 modest_msg_view_window_select_next_message (self);
2977 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2980 GObject *win = modest_mail_operation_get_source (mail_op);
2981 const GError *error = NULL;
2982 const gchar *message = NULL;
2984 /* Get error message */
2985 error = modest_mail_operation_get_error (mail_op);
2986 if (error != NULL && error->message != NULL) {
2987 message = error->message;
2989 message = _("mail_in_ui_folder_move_target_error");
2992 /* Show notification dialog */
2993 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2994 g_object_unref (win);
2998 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3001 GObject *win = modest_mail_operation_get_source (mail_op);
3002 const GError *error = modest_mail_operation_get_error (mail_op);
3004 g_return_if_fail (error != NULL);
3005 if (error->message != NULL)
3006 g_printerr ("modest: %s\n", error->message);
3008 g_printerr ("modest: unkonw error on send&receive operation");
3010 /* Show error message */
3011 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3012 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3013 /* _CS("sfil_ib_unable_to_receive")); */
3015 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3016 /* _CS("sfil_ib_unable_to_send")); */
3017 g_object_unref (win);
3021 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3028 gint pending_purges = 0;
3029 gboolean some_purged = FALSE;
3030 ModestWindow *win = MODEST_WINDOW (user_data);
3034 /* Once the message has been retrieved for purging, we check if
3035 * it's all ok for purging */
3037 parts = tny_simple_list_new ();
3038 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3039 iter = tny_list_create_iterator (parts);
3041 while (!tny_iterator_is_done (iter)) {
3043 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3044 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3045 if (tny_mime_part_is_purged (part))
3050 tny_iterator_next (iter);
3053 if (pending_purges>0) {
3055 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3057 if (response == GTK_RESPONSE_OK) {
3058 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3059 tny_iterator_first (iter);
3060 while (!tny_iterator_is_done (iter)) {
3063 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3064 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3065 tny_mime_part_set_purged (part);
3066 tny_iterator_next (iter);
3069 tny_msg_rewrite_cache (msg);
3072 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3075 /* remove attachments */
3076 tny_iterator_first (iter);
3077 while (!tny_iterator_is_done (iter)) {
3080 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3081 g_object_unref (part);
3082 tny_iterator_next (iter);
3085 g_object_unref (iter);
3086 g_object_unref (parts);
3090 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3091 ModestMainWindow *win)
3093 GtkWidget *header_view;
3094 TnyList *header_list;
3097 TnyHeaderFlags flags;
3098 ModestWindow *msg_view_window = NULL;
3101 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3103 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3104 MODEST_WIDGET_TYPE_HEADER_VIEW);
3106 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3108 if (tny_list_get_length (header_list) == 1) {
3109 iter = tny_list_create_iterator (header_list);
3110 header = TNY_HEADER (tny_iterator_get_current (iter));
3111 g_object_unref (iter);
3116 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3117 header, &msg_view_window);
3118 flags = tny_header_get_flags (header);
3119 if (!(flags & TNY_HEADER_FLAG_CACHED))
3122 if (msg_view_window != NULL)
3123 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3125 /* do nothing; uid was registered before, so window is probably on it's way */
3126 g_warning ("debug: header %p has already been registered", header);
3129 ModestMailOperation *mail_op = NULL;
3130 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3131 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3133 modest_ui_actions_get_msgs_full_error_handler,
3135 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3136 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3138 g_object_unref (mail_op);
3141 g_object_unref (header);
3143 g_object_unref (header_list);
3147 * UI handler for the "Move to" action when invoked from the
3151 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3152 ModestMainWindow *win)
3154 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3155 GtkWidget *header_view = NULL;
3157 TnyFolderStore *folder_store = NULL;
3158 ModestMailOperation *mail_op = NULL;
3160 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3162 /* Get the folder view */
3163 folder_view = modest_main_window_get_child_widget (win,
3164 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3166 /* Get header view */
3167 header_view = modest_main_window_get_child_widget (win,
3168 MODEST_WIDGET_TYPE_HEADER_VIEW);
3170 /* Create and run the dialog */
3171 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3172 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3173 result = gtk_dialog_run (GTK_DIALOG(dialog));
3174 g_object_ref (tree_view);
3176 /* We do this to save an indentation level ;-) */
3177 if (result != GTK_RESPONSE_ACCEPT)
3180 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3182 if (TNY_IS_ACCOUNT (folder_store) &&
3183 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3186 /* Get folder or messages to transfer */
3187 if (gtk_widget_is_focus (folder_view)) {
3188 TnyFolderStore *src_folder;
3189 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3191 /* Clean folder on header view before moving it */
3192 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3194 if (TNY_IS_FOLDER (src_folder)) {
3196 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3198 modest_ui_actions_move_folder_error_handler,
3200 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3202 modest_mail_operation_xfer_folder (mail_op,
3203 TNY_FOLDER (src_folder),
3208 /* Unref mail operation */
3209 g_object_unref (G_OBJECT (mail_op));
3213 g_object_unref (G_OBJECT (src_folder));
3215 if (gtk_widget_is_focus (header_view)) {
3219 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3221 /* Ask for user confirmation */
3222 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3223 TNY_FOLDER (folder_store),
3226 /* Transfer messages */
3227 if (response == GTK_RESPONSE_OK) {
3229 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3231 modest_ui_actions_move_folder_error_handler,
3233 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3236 modest_mail_operation_xfer_msgs (mail_op,
3238 TNY_FOLDER (folder_store),
3243 g_object_unref (G_OBJECT (mail_op));
3245 g_object_unref (headers);
3249 if (folder_store != NULL)
3250 g_object_unref (folder_store);
3251 gtk_widget_destroy (dialog);
3256 * UI handler for the "Move to" action when invoked from the
3257 * ModestMsgViewWindow
3260 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3261 ModestMsgViewWindow *win)
3263 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3265 ModestMainWindow *main_window;
3269 /* Get the folder view */
3270 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3272 folder_view = modest_main_window_get_child_widget (main_window,
3273 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3277 /* Create and run the dialog */
3278 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3279 result = gtk_dialog_run (GTK_DIALOG(dialog));
3281 if (result == GTK_RESPONSE_ACCEPT) {
3282 TnyFolderStore *folder_store;
3285 /* Create header list */
3286 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3287 g_return_if_fail (header != NULL);
3289 headers = tny_simple_list_new ();
3290 tny_list_prepend (headers, G_OBJECT (header));
3291 g_object_unref (header);
3293 /* Ask user for confirmation. MSG-NOT404 */
3294 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view)));
3295 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3296 TNY_FOLDER (folder_store),
3299 /* Transfer current msg */
3300 if (response == GTK_RESPONSE_OK) {
3301 ModestMailOperation *mail_op;
3303 /* Create mail op */
3304 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3305 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3308 /* Transfer messages */
3309 modest_mail_operation_xfer_msgs (mail_op,
3311 TNY_FOLDER (folder_store),
3313 transfer_msgs_from_viewer_cb,
3315 g_object_unref (G_OBJECT (mail_op));
3317 g_object_unref (headers);
3318 g_object_unref (folder_store);
3320 gtk_widget_destroy (dialog);
3324 modest_ui_actions_on_move_to (GtkAction *action,
3327 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3328 MODEST_IS_MSG_VIEW_WINDOW (win));
3330 if (MODEST_IS_MAIN_WINDOW (win))
3331 modest_ui_actions_on_main_window_move_to (action,
3332 MODEST_MAIN_WINDOW (win));
3334 modest_ui_actions_on_msg_view_window_move_to (action,
3335 MODEST_MSG_VIEW_WINDOW (win));
3339 * Calls #HeadersFunc for each header already selected in the main
3340 * window or the message currently being shown in the msg view window
3343 do_headers_action (ModestWindow *win,
3347 TnyList *headers_list;
3353 headers_list = get_selected_headers (win);
3357 /* Get the folder */
3358 iter = tny_list_create_iterator (headers_list);
3359 header = TNY_HEADER (tny_iterator_get_current (iter));
3360 folder = tny_header_get_folder (header);
3361 g_object_unref (header);
3363 /* Call the function for each header */
3364 while (!tny_iterator_is_done (iter)) {
3365 header = TNY_HEADER (tny_iterator_get_current (iter));
3366 func (header, win, user_data);
3367 g_object_unref (header);
3368 tny_iterator_next (iter);
3371 /* Trick: do a poke status in order to speed up the signaling
3373 tny_folder_poke_status (folder);
3376 g_object_unref (folder);
3377 g_object_unref (iter);
3378 g_object_unref (headers_list);
3382 modest_ui_actions_view_attachment (GtkAction *action,
3383 ModestWindow *window)
3385 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3386 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3388 /* not supported window for this action */
3389 g_return_if_reached ();
3394 modest_ui_actions_save_attachments (GtkAction *action,
3395 ModestWindow *window)
3397 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3398 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3400 /* not supported window for this action */
3401 g_return_if_reached ();
3406 modest_ui_actions_remove_attachments (GtkAction *action,
3407 ModestWindow *window)
3409 if (MODEST_IS_MAIN_WINDOW (window)) {
3410 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3411 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3412 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3414 /* not supported window for this action */
3415 g_return_if_reached ();
3420 modest_ui_actions_on_settings (GtkAction *action,
3425 dialog = modest_platform_get_global_settings_dialog ();
3426 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3427 gtk_widget_show_all (dialog);
3429 gtk_dialog_run (GTK_DIALOG (dialog));
3431 gtk_widget_destroy (dialog);
3435 modest_ui_actions_on_help (GtkAction *action,
3438 const gchar *help_id = NULL;
3440 if (MODEST_IS_MAIN_WINDOW (win)) {
3441 const gchar *action_name;
3442 action_name = gtk_action_get_name (action);
3444 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3445 !strcmp (action_name, "HeaderViewCSMHelp")) {
3446 GtkWidget *folder_view;
3447 TnyFolderStore *folder_store;
3448 /* Get selected folder */
3449 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3450 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3451 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3453 /* Switch help_id */
3454 if (TNY_IS_FOLDER (folder_store)) {
3455 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3456 case TNY_FOLDER_TYPE_NORMAL:
3457 help_id = "applications_email_userfolder";
3459 case TNY_FOLDER_TYPE_INBOX:
3460 help_id = "applications_email_inbox";
3462 case TNY_FOLDER_TYPE_OUTBOX:
3463 help_id = "applications_email_outbox";
3465 case TNY_FOLDER_TYPE_SENT:
3466 help_id = "applications_email_sent";
3468 case TNY_FOLDER_TYPE_DRAFTS:
3469 help_id = "applications_email_drafts";
3471 case TNY_FOLDER_TYPE_ARCHIVE:
3472 help_id = "applications_email_archive";
3478 g_object_unref (folder_store);
3480 help_id = "applications_email_mainview";
3482 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3483 help_id = "applications_email_viewer";
3484 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3485 help_id = "applications_email_editor";
3487 modest_platform_show_help (GTK_WINDOW (win), help_id);
3491 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3492 ModestWindow *window)
3494 ModestMailOperation *mail_op;
3498 headers = get_selected_headers (window);
3502 /* Create mail operation */
3503 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3505 modest_ui_actions_get_msgs_full_error_handler,
3507 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3508 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3511 g_object_unref (headers);
3512 g_object_unref (mail_op);
3516 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3517 ModestWindow *window)
3519 g_return_if_fail (MODEST_IS_WINDOW (window));
3522 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3526 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3527 ModestWindow *window)
3529 g_return_if_fail (MODEST_IS_WINDOW (window));
3532 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3536 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3537 ModestWindow *window)
3539 g_return_if_fail (MODEST_IS_WINDOW (window));
3542 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3546 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3547 ModestWindow *window)
3549 g_return_if_fail (MODEST_IS_WINDOW (window));
3552 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3556 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3557 ModestWindow *window)
3559 g_return_if_fail (MODEST_IS_WINDOW (window));
3562 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3566 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3567 ModestWindow *window)
3569 g_return_if_fail (MODEST_IS_WINDOW (window));
3572 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3576 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3577 ModestWindow *window)
3579 g_return_if_fail (MODEST_IS_WINDOW (window));
3582 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3586 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3587 ModestWindow *window)
3589 g_return_if_fail (MODEST_IS_WINDOW (window));
3592 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3596 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3598 g_return_if_fail (MODEST_IS_WINDOW (window));
3601 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3605 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3607 g_return_if_fail (MODEST_IS_WINDOW (window));
3609 modest_platform_show_search_messages (GTK_WINDOW (window));
3613 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3615 g_return_if_fail (MODEST_IS_WINDOW (win));
3616 modest_platform_show_addressbook (GTK_WINDOW (win));
3621 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3622 ModestWindow *window)
3624 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3626 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3630 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3631 ModestMailOperationState *state,
3634 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3636 /* Set send/receive operation finished */
3637 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3638 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));