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 #include "maemo/modest-maemo-utils.h"
52 #include "maemo/modest-hildon-includes.h"
53 #endif /* MODEST_PLATFORM_MAEMO */
55 #include "widgets/modest-ui-constants.h"
56 #include <widgets/modest-main-window.h>
57 #include <widgets/modest-msg-view-window.h>
58 #include <widgets/modest-account-view-window.h>
59 #include <widgets/modest-details-dialog.h>
60 #include <widgets/modest-attachments-view.h>
61 #include "widgets/modest-folder-view.h"
62 #include "widgets/modest-global-settings-dialog.h"
63 #include "modest-connection-specific-smtp-window.h"
64 #include "modest-account-mgr-helpers.h"
65 #include "modest-mail-operation.h"
66 #include "modest-text-utils.h"
68 #ifdef MODEST_HAVE_EASYSETUP
69 #include "easysetup/modest-easysetup-wizard.h"
70 #endif /* MODEST_HAVE_EASYSETUP */
72 #include <modest-widget-memory.h>
73 #include <tny-error.h>
74 #include <tny-simple-list.h>
75 #include <tny-msg-view.h>
76 #include <tny-device.h>
77 #include <tny-merge-folder.h>
79 #include <gtkhtml/gtkhtml.h>
81 typedef struct _GetMsgAsyncHelper {
83 ModestMailOperation *mail_op;
90 typedef enum _ReplyForwardAction {
96 typedef struct _ReplyForwardHelper {
97 guint reply_forward_type;
98 ReplyForwardAction action;
100 GtkWidget *parent_window;
101 } ReplyForwardHelper;
103 typedef struct _PasteAsAttachmentHelper {
104 ModestMsgEditWindow *window;
106 } PasteAsAttachmentHelper;
110 * The do_headers_action uses this kind of functions to perform some
111 * action to each member of a list of headers
113 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
115 static void do_headers_action (ModestWindow *win,
119 static void open_msg_cb (ModestMailOperation *mail_op,
124 static void reply_forward_cb (ModestMailOperation *mail_op,
129 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
131 static void folder_refreshed_cb (ModestMailOperation *mail_op,
135 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
136 ModestMailOperationState *state,
142 run_account_setup_wizard (ModestWindow *win)
144 ModestEasysetupWizardDialog *wizard;
146 g_return_if_fail (MODEST_IS_WINDOW(win));
148 wizard = modest_easysetup_wizard_dialog_new ();
149 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
150 gtk_dialog_run (GTK_DIALOG (wizard));
151 gtk_widget_destroy (GTK_WIDGET (wizard));
156 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
159 const gchar *authors[] = {
160 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
163 about = gtk_about_dialog_new ();
164 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
165 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
166 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
167 _("Copyright (c) 2006, Nokia Corporation\n"
168 "All rights reserved."));
169 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
170 _("a modest e-mail client\n\n"
171 "design and implementation: Dirk-Jan C. Binnema\n"
172 "contributions from the fine people at KC and Ig\n"
173 "uses the tinymail email framework written by Philip van Hoof"));
174 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
175 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
177 gtk_dialog_run (GTK_DIALOG (about));
178 gtk_widget_destroy(about);
182 * Gets the list of currently selected messages. If the win is the
183 * main window, then it returns a newly allocated list of the headers
184 * selected in the header view. If win is the msg view window, then
185 * the value returned is a list with just a single header.
187 * The caller of this funcion must free the list.
190 get_selected_headers (ModestWindow *win)
192 if (MODEST_IS_MAIN_WINDOW(win)) {
193 GtkWidget *header_view;
195 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
196 MODEST_WIDGET_TYPE_HEADER_VIEW);
197 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
199 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
200 /* for MsgViewWindows, we simply return a list with one element */
202 TnyList *list = NULL;
204 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
205 if (header != NULL) {
206 list = tny_simple_list_new ();
207 tny_list_prepend (list, G_OBJECT(header));
208 g_object_unref (G_OBJECT(header));
218 headers_action_mark_as_read (TnyHeader *header,
222 TnyHeaderFlags flags;
224 g_return_if_fail (TNY_IS_HEADER(header));
226 flags = tny_header_get_flags (header);
227 if (flags & TNY_HEADER_FLAG_SEEN) return;
228 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
232 headers_action_mark_as_unread (TnyHeader *header,
236 TnyHeaderFlags flags;
238 g_return_if_fail (TNY_IS_HEADER(header));
240 flags = tny_header_get_flags (header);
241 if (flags & TNY_HEADER_FLAG_SEEN) {
242 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
246 /** A convenience method, because deleting a message is
247 * otherwise complicated, and it's best to change it in one place
250 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
252 ModestMailOperation *mail_op = NULL;
253 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
254 win ? G_OBJECT(win) : NULL);
255 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
258 /* Always delete. TODO: Move to trash still not supported */
259 modest_mail_operation_remove_msg (mail_op, header, FALSE);
260 g_object_unref (G_OBJECT (mail_op));
264 headers_action_delete (TnyHeader *header,
268 modest_do_message_delete (header, win);
270 /* refilter treemodel to hide marked-as-deleted rows */
271 /* if (MODEST_IS_HEADER_VIEW (user_data)) */
272 /* modest_header_view_refilter (MODEST_HEADER_VIEW (user_data)); */
275 /** After deleing a message that is currently visible in a window,
276 * show the next message from the list, or close the window if there are no more messages.
278 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
280 /* Close msg view window or select next */
281 if (modest_msg_view_window_last_message_selected (win) &&
282 modest_msg_view_window_first_message_selected (win)) {
283 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
285 modest_msg_view_window_select_next_message (win);
290 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
292 TnyList *header_list = NULL;
293 TnyIterator *iter = NULL;
294 TnyHeader *header = NULL;
295 gchar *message = NULL;
298 ModestWindowMgr *mgr;
299 GtkWidget *header_view = NULL;
301 g_return_if_fail (MODEST_IS_WINDOW(win));
303 /* Check first if the header view has the focus */
304 if (MODEST_IS_MAIN_WINDOW (win)) {
306 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
307 MODEST_WIDGET_TYPE_HEADER_VIEW);
308 if (!gtk_widget_is_focus (header_view))
312 header_list = get_selected_headers (win);
313 if (!header_list) return;
315 /* Check if any of the headers are already opened, or in the process of being opened */
316 if (MODEST_IS_MAIN_WINDOW (win)) {
318 iter = tny_list_create_iterator (header_list);
320 mgr = modest_runtime_get_window_mgr ();
321 while (!tny_iterator_is_done (iter) && !found) {
322 header = TNY_HEADER (tny_iterator_get_current (iter));
324 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
325 g_object_unref (header);
328 tny_iterator_next (iter);
330 g_object_unref (iter);
335 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
336 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
338 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
342 g_object_unref (header_list);
348 if (tny_list_get_length(header_list) == 1) {
349 iter = tny_list_create_iterator (header_list);
350 header = TNY_HEADER (tny_iterator_get_current (iter));
352 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
353 g_object_unref (header);
356 g_object_unref (iter);
358 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
359 tny_list_get_length(header_list)), desc);
361 /* Confirmation dialog */
362 printf("DEBUG: %s\n", __FUNCTION__);
363 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
367 if (response == GTK_RESPONSE_OK) {
368 ModestWindow *main_window = NULL;
369 ModestWindowMgr *mgr = NULL;
370 GtkTreeModel *model = NULL;
371 GtkTreeSelection *sel = NULL;
372 GList *sel_list = NULL, *tmp = NULL;
373 GtkTreeRowReference *row_reference = NULL;
374 GtkTreePath *next_path = NULL;
376 /* Find last selected row */
377 if (MODEST_IS_MAIN_WINDOW (win)) {
378 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
379 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
380 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
381 for (tmp=sel_list; tmp; tmp=tmp->next) {
382 if (tmp->next == NULL) {
383 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
384 gtk_tree_path_next (next_path);
385 row_reference = gtk_tree_row_reference_new (model, next_path);
386 gtk_tree_path_free (next_path);
391 /* Remove each header. If it's a view window header_view == NULL */
392 do_headers_action (win, headers_action_delete, header_view);
394 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
395 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
397 /* Get main window */
398 mgr = modest_runtime_get_window_mgr ();
399 main_window = modest_window_mgr_get_main_window (mgr);
402 /* Move cursor to next row */
405 /* Select next row */
406 if (gtk_tree_row_reference_valid (row_reference)) {
407 next_path = gtk_tree_row_reference_get_path (row_reference);
408 gtk_tree_selection_select_path (sel, next_path);
409 gtk_tree_path_free (next_path);
411 if (row_reference != NULL)
412 gtk_tree_row_reference_free (row_reference);
415 /* Update toolbar dimming state */
416 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
419 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
420 g_list_free (sel_list);
426 g_object_unref (header_list);
432 /* delete either message or folder, based on where we are */
434 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
436 g_return_if_fail (MODEST_IS_WINDOW(win));
438 /* Check first if the header view has the focus */
439 if (MODEST_IS_MAIN_WINDOW (win)) {
441 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
442 MODEST_WIDGET_TYPE_FOLDER_VIEW);
443 if (gtk_widget_is_focus (w)) {
444 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
448 modest_ui_actions_on_delete_message (action, win);
454 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
456 #ifdef MODEST_PLATFORM_MAEMO
457 modest_osso_save_state();
458 #endif /* MODEST_PLATFORM_MAEMO */
460 g_debug ("closing down, clearing %d item(s) from operation queue",
461 modest_mail_operation_queue_num_elements
462 (modest_runtime_get_mail_operation_queue()));
464 /* cancel all outstanding operations */
465 modest_mail_operation_queue_cancel_all
466 (modest_runtime_get_mail_operation_queue());
468 g_debug ("queue has been cleared");
470 /* note: when modest-tny-account-store is finalized,
471 it will automatically set all network connections
478 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
482 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
484 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
485 /* gtk_widget_destroy (GTK_WIDGET (win)); */
486 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
487 /* gboolean ret_value; */
488 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
489 /* } else if (MODEST_IS_WINDOW (win)) { */
490 /* gtk_widget_destroy (GTK_WIDGET (win)); */
492 /* g_return_if_reached (); */
497 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
499 GtkClipboard *clipboard = NULL;
500 gchar *selection = NULL;
502 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
503 selection = gtk_clipboard_wait_for_text (clipboard);
505 /* Question: why is the clipboard being used here?
506 * It doesn't really make a lot of sense. */
510 modest_address_book_add_address (selection);
516 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
518 /* This is currently only implemented for Maemo */
519 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
520 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
521 run_account_setup_wizard (win);
524 /* Show the list of accounts: */
525 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
526 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
529 GtkWidget *dialog, *label;
531 /* Create the widgets */
533 dialog = gtk_dialog_new_with_buttons ("Message",
535 GTK_DIALOG_DESTROY_WITH_PARENT,
539 label = gtk_label_new ("Hello World!");
541 /* Ensure that the dialog box is destroyed when the user responds. */
543 g_signal_connect_swapped (dialog, "response",
544 G_CALLBACK (gtk_widget_destroy),
547 /* Add the label, and show everything we've added to the dialog. */
549 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
551 gtk_widget_show_all (dialog);
552 #endif /* MODEST_PLATFORM_MAEMO */
556 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
558 ModestWindow *main_window = MODEST_WINDOW (user_data);
560 /* Save any changes. */
561 modest_connection_specific_smtp_window_save_server_accounts (
562 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
563 modest_window_get_active_account (main_window));
564 gtk_widget_destroy (GTK_WIDGET (window));
570 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
572 /* This is currently only implemented for Maemo,
573 * because it requires an API (libconic) to detect different connection
576 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
578 /* Create the window if necessary: */
579 const gchar *active_account_name = modest_window_get_active_account (win);
581 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
582 * or show the default account?
583 * If we show the default account then the account name should be shown in
584 * the window when we show it. */
585 if (!active_account_name) {
586 g_warning ("%s: No account is active.", __FUNCTION__);
590 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
591 modest_connection_specific_smtp_window_fill_with_connections (
592 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
593 modest_runtime_get_account_mgr(),
594 active_account_name);
596 /* Show the window: */
597 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
598 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
599 gtk_widget_show (specific_window);
601 /* Save changes when the window is hidden: */
602 g_signal_connect (specific_window, "hide",
603 G_CALLBACK (on_smtp_servers_window_hide), win);
604 #endif /* MODEST_PLATFORM_MAEMO */
608 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
610 ModestWindow *msg_win = NULL;
612 TnyFolder *folder = NULL;
613 gchar *account_name = NULL;
614 gchar *from_str = NULL;
615 /* GError *err = NULL; */
616 TnyAccount *account = NULL;
617 ModestWindowMgr *mgr;
618 gchar *signature = NULL, *blank_and_signature = NULL;
620 /* if there are no accounts yet, just show the wizard */
621 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
622 run_account_setup_wizard (win);
626 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
628 account_name = g_strdup (modest_window_get_active_account (win));
630 g_printerr ("modest: no account found\n");
634 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
636 TNY_ACCOUNT_TYPE_STORE);
638 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
642 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
644 g_printerr ("modest: failed get from string for '%s'\n", account_name);
648 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
649 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
650 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
651 MODEST_ACCOUNT_SIGNATURE, FALSE);
652 blank_and_signature = g_strconcat ("\n", signature, NULL);
655 blank_and_signature = g_strdup ("");
658 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
660 g_printerr ("modest: failed to create new msg\n");
664 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
666 g_printerr ("modest: failed to find Drafts folder\n");
671 /* Create and register edit window */
672 /* This is destroyed by TOOD. */
673 msg_win = modest_msg_edit_window_new (msg, account_name);
674 mgr = modest_runtime_get_window_mgr ();
675 modest_window_mgr_register_window (mgr, msg_win);
678 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
680 gtk_widget_show_all (GTK_WIDGET (msg_win));
683 g_free (account_name);
685 g_free (blank_and_signature);
687 g_object_unref (msg_win);
689 g_object_unref (G_OBJECT(account));
691 g_object_unref (G_OBJECT(msg));
693 g_object_unref (G_OBJECT(folder));
697 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
701 ModestMailOperationStatus status;
703 /* If there is no message or the operation was not successful */
704 status = modest_mail_operation_get_status (mail_op);
705 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
707 /* Remove the header from the preregistered uids */
708 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
718 open_msg_cb (ModestMailOperation *mail_op,
723 ModestWindowMgr *mgr = NULL;
724 ModestWindow *parent_win = NULL;
725 ModestWindow *win = NULL;
726 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
727 gchar *account = NULL;
730 /* Do nothing if there was any problem with the mail
731 operation. The error will be shown by the error_handler of
732 the mail operation */
733 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
737 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
738 folder = tny_header_get_folder (header);
740 /* Mark header as read */
741 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
744 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
746 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
748 /* Gets folder type (OUTBOX headers will be opened in edit window */
749 if (modest_tny_folder_is_local_folder (folder))
750 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
752 /* If the header is in the drafts folder then open the editor,
753 else the message view window */
754 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
755 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
756 /* we cannot edit without a valid account... */
757 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
758 run_account_setup_wizard(parent_win);
761 win = modest_msg_edit_window_new (msg, account);
763 gchar *uid = modest_tny_folder_get_header_unique_id (header);
765 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
766 GtkWidget *header_view;
767 GtkTreeSelection *sel;
768 GList *sel_list = NULL;
771 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
772 MODEST_WIDGET_TYPE_HEADER_VIEW);
774 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
775 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
777 if (sel_list != NULL) {
778 GtkTreeRowReference *row_reference;
780 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
781 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
782 g_list_free (sel_list);
784 win = modest_msg_view_window_new_with_header_model (msg,
789 gtk_tree_row_reference_free (row_reference);
791 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
794 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
799 /* Register and show new window */
801 mgr = modest_runtime_get_window_mgr ();
802 modest_window_mgr_register_window (mgr, win);
803 g_object_unref (win);
804 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
805 gtk_widget_show_all (GTK_WIDGET(win));
808 /* Update toolbar dimming state */
809 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
810 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
816 g_object_unref (parent_win);
817 g_object_unref (folder);
821 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
825 GObject *win = modest_mail_operation_get_source (mail_op);
827 error = modest_mail_operation_get_error (mail_op);
828 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
830 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
832 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
835 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
836 _("mail_ni_ui_folder_get_msg_folder_error"));
840 g_object_unref (win);
844 * This function is used by both modest_ui_actions_on_open and
845 * modest_ui_actions_on_header_activated. This way we always do the
846 * same when trying to open messages.
849 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
851 ModestWindowMgr *mgr = NULL;
852 TnyIterator *iter = NULL;
853 ModestMailOperation *mail_op = NULL;
854 TnyList *not_opened_headers = NULL;
855 TnyHeaderFlags flags = 0;
857 /* Look if we already have a message view for each header. If
858 true, then remove the header from the list of headers to
860 mgr = modest_runtime_get_window_mgr ();
861 iter = tny_list_create_iterator (headers);
862 not_opened_headers = tny_simple_list_new ();
864 while (!tny_iterator_is_done (iter)) {
866 ModestWindow *window = NULL;
867 TnyHeader *header = NULL;
868 gboolean found = FALSE;
870 header = TNY_HEADER (tny_iterator_get_current (iter));
872 flags = tny_header_get_flags (header);
875 found = modest_window_mgr_find_registered_header (mgr, header, &window);
877 /* Do not open again the message and present the
878 window to the user */
881 gtk_window_present (GTK_WINDOW (window));
883 /* the header has been registered already, we don't do
884 * anything but wait for the window to come up*/
885 g_debug ("header %p already registered, waiting for window", header);
887 tny_list_append (not_opened_headers, G_OBJECT (header));
891 g_object_unref (header);
893 tny_iterator_next (iter);
895 g_object_unref (iter);
898 /* If some messages would have to be downloaded, ask the user to
899 * make a connection. It's generally easier to do this here (in the mainloop)
900 * than later in a thread:
902 if (tny_list_get_length (not_opened_headers) > 0) {
903 gboolean connected = modest_platform_connect_and_wait (GTK_WINDOW (win), NULL);
905 /* Don't go further if a connection would be necessary but none is available: */
907 g_object_unref (not_opened_headers);
912 /* Register the headers before actually creating the windows: */
913 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
914 while (!tny_iterator_is_done (iter_not_opened)) {
915 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
917 modest_window_mgr_register_header (mgr, header);
918 g_object_unref (header);
921 tny_iterator_next (iter_not_opened);
923 g_object_unref (iter_not_opened);
924 iter_not_opened = NULL;
926 /* Open each message */
927 if (tny_list_get_length (not_opened_headers) > 0) {
928 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
930 modest_ui_actions_get_msgs_full_error_handler,
932 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
933 if (tny_list_get_length (not_opened_headers) > 1) {
934 modest_mail_operation_get_msgs_full (mail_op,
940 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
941 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
942 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
943 g_object_unref (header);
944 g_object_unref (iter);
946 g_object_unref (mail_op);
950 if (not_opened_headers != NULL)
951 g_object_unref (not_opened_headers);
955 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
960 headers = get_selected_headers (win);
965 _modest_ui_actions_open (headers, win);
967 g_object_unref(headers);
972 free_reply_forward_helper (gpointer data)
974 ReplyForwardHelper *helper;
976 helper = (ReplyForwardHelper *) data;
977 g_free (helper->account_name);
978 g_slice_free (ReplyForwardHelper, helper);
982 reply_forward_cb (ModestMailOperation *mail_op,
988 ReplyForwardHelper *rf_helper;
989 ModestWindow *msg_win = NULL;
990 ModestEditType edit_type;
992 TnyAccount *account = NULL;
993 ModestWindowMgr *mgr = NULL;
994 gchar *signature = NULL;
996 /* If there was any error. The mail operation could be NULL,
997 this means that we already have the message downloaded and
998 that we didn't do a mail operation to retrieve it */
999 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1002 g_return_if_fail (user_data != NULL);
1003 rf_helper = (ReplyForwardHelper *) user_data;
1005 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1006 rf_helper->account_name);
1007 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1008 rf_helper->account_name,
1009 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1010 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1011 rf_helper->account_name,
1012 MODEST_ACCOUNT_SIGNATURE, FALSE);
1015 /* Create reply mail */
1016 switch (rf_helper->action) {
1019 modest_tny_msg_create_reply_msg (msg, from, signature,
1020 rf_helper->reply_forward_type,
1021 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1023 case ACTION_REPLY_TO_ALL:
1025 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
1026 MODEST_TNY_MSG_REPLY_MODE_ALL);
1027 edit_type = MODEST_EDIT_TYPE_REPLY;
1029 case ACTION_FORWARD:
1031 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1032 edit_type = MODEST_EDIT_TYPE_FORWARD;
1035 g_return_if_reached ();
1042 g_printerr ("modest: failed to create message\n");
1046 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1047 rf_helper->account_name,
1048 TNY_ACCOUNT_TYPE_STORE);
1050 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1054 /* Create and register the windows */
1055 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
1056 mgr = modest_runtime_get_window_mgr ();
1057 modest_window_mgr_register_window (mgr, msg_win);
1059 if (rf_helper->parent_window != NULL) {
1060 gdouble parent_zoom;
1062 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1063 modest_window_set_zoom (msg_win, parent_zoom);
1066 /* Show edit window */
1067 gtk_widget_show_all (GTK_WIDGET (msg_win));
1071 g_object_unref (msg_win);
1073 g_object_unref (G_OBJECT (new_msg));
1075 g_object_unref (G_OBJECT (account));
1076 /* g_object_unref (msg); */
1077 g_object_unref (header);
1078 free_reply_forward_helper (rf_helper);
1082 * Checks a list of headers. If any of them are not currently
1083 * downloaded (CACHED) then it asks the user for permission to
1086 * Returns FALSE if the user does not want to download the
1087 * messages. Returns TRUE if the user allowed the download or if all
1088 * of them are currently downloaded
1091 download_uncached_messages (TnyList *header_list, GtkWindow *win,
1096 gint uncached_messages = 0;
1098 iter = tny_list_create_iterator (header_list);
1099 while (!tny_iterator_is_done (iter)) {
1101 TnyHeaderFlags flags;
1103 header = TNY_HEADER (tny_iterator_get_current (iter));
1105 flags = tny_header_get_flags (header);
1106 /* TODO: is this the right flag?, it seems that some
1107 headers that have been previously downloaded do not
1109 if (! (flags & TNY_HEADER_FLAG_CACHED))
1110 uncached_messages ++;
1111 g_object_unref (header);
1114 tny_iterator_next (iter);
1116 g_object_unref (iter);
1118 /* Ask for user permission to download the messages */
1120 if (uncached_messages > 0) {
1121 GtkResponseType response;
1123 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1124 _("emev_nc_include_original"));
1127 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1128 ngettext("mcen_nc_get_msg",
1130 uncached_messages));
1131 if (response == GTK_RESPONSE_CANCEL)
1134 /* If a download will be necessary, make sure that we have a connection: */
1135 retval = modest_platform_connect_and_wait(win, NULL);
1143 * Common code for the reply and forward actions
1146 reply_forward (ReplyForwardAction action, ModestWindow *win)
1148 ModestMailOperation *mail_op = NULL;
1149 TnyList *header_list = NULL;
1150 ReplyForwardHelper *rf_helper = NULL;
1151 guint reply_forward_type;
1152 gboolean continue_download;
1154 g_return_if_fail (MODEST_IS_WINDOW(win));
1156 /* we need an account when editing */
1157 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1158 run_account_setup_wizard (win);
1162 header_list = get_selected_headers (win);
1166 /* Check that the messages have been previously downloaded */
1167 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1168 if (!continue_download) {
1169 g_object_unref (header_list);
1173 reply_forward_type =
1174 modest_conf_get_int (modest_runtime_get_conf (),
1175 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1177 /* We assume that we can only select messages of the
1178 same folder and that we reply all of them from the
1179 same account. In fact the interface currently only
1180 allows single selection */
1183 rf_helper = g_slice_new0 (ReplyForwardHelper);
1184 rf_helper->reply_forward_type = reply_forward_type;
1185 rf_helper->action = action;
1186 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1188 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1189 rf_helper->parent_window = GTK_WIDGET (win);
1190 if (!rf_helper->account_name)
1191 rf_helper->account_name =
1192 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1194 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1197 /* Get header and message. Do not free them here, the
1198 reply_forward_cb must do it */
1199 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1200 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1201 if (!msg || !header) {
1203 g_object_unref (msg);
1205 g_object_unref (header);
1206 g_printerr ("modest: no message found\n");
1209 reply_forward_cb (NULL, header, msg, rf_helper);
1215 /* Retrieve messages */
1216 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1218 modest_ui_actions_get_msgs_full_error_handler,
1220 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1222 /* Only reply/forward to one message */
1223 iter = tny_list_create_iterator (header_list);
1224 header = TNY_HEADER (tny_iterator_get_current (iter));
1225 g_object_unref (iter);
1228 modest_mail_operation_get_msg (mail_op,
1233 /* modest_mail_operation_get_msgs_full (mail_op, */
1235 /* reply_forward_cb, */
1237 /* free_reply_forward_helper); */
1239 g_object_unref (header);
1243 g_object_unref(mail_op);
1247 g_object_unref (header_list);
1251 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1253 g_return_if_fail (MODEST_IS_WINDOW(win));
1255 reply_forward (ACTION_REPLY, win);
1259 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1261 g_return_if_fail (MODEST_IS_WINDOW(win));
1263 reply_forward (ACTION_FORWARD, win);
1267 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1269 g_return_if_fail (MODEST_IS_WINDOW(win));
1271 reply_forward (ACTION_REPLY_TO_ALL, win);
1275 modest_ui_actions_on_next (GtkAction *action,
1276 ModestWindow *window)
1278 if (MODEST_IS_MAIN_WINDOW (window)) {
1279 GtkWidget *header_view;
1281 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1282 MODEST_WIDGET_TYPE_HEADER_VIEW);
1286 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1287 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1288 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1290 g_return_if_reached ();
1295 modest_ui_actions_on_prev (GtkAction *action,
1296 ModestWindow *window)
1298 g_return_if_fail (MODEST_IS_WINDOW(window));
1300 if (MODEST_IS_MAIN_WINDOW (window)) {
1301 GtkWidget *header_view;
1302 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1303 MODEST_WIDGET_TYPE_HEADER_VIEW);
1307 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1308 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1309 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1311 g_return_if_reached ();
1316 modest_ui_actions_on_sort (GtkAction *action,
1317 ModestWindow *window)
1319 g_return_if_fail (MODEST_IS_WINDOW(window));
1321 if (MODEST_IS_MAIN_WINDOW (window)) {
1322 GtkWidget *header_view;
1323 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1324 MODEST_WIDGET_TYPE_HEADER_VIEW);
1326 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1331 /* Show sorting dialog */
1332 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1337 new_messages_arrived (ModestMailOperation *self,
1341 if (new_messages == 0)
1344 modest_platform_on_new_msg ();
1348 * This function performs the send & receive required actions. The
1349 * window is used to create the mail operation. Typically it should
1350 * always be the main window, but we pass it as argument in order to
1354 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1356 gchar *acc_name = NULL;
1357 ModestMailOperation *mail_op;
1359 /* If no account name was provided then get the current account, and if
1360 there is no current account then pick the default one: */
1361 if (!account_name) {
1362 acc_name = g_strdup (modest_window_get_active_account(win));
1364 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1366 g_printerr ("modest: cannot get default account\n");
1370 acc_name = g_strdup (account_name);
1373 /* Set send/receive operation in progress */
1374 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1376 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1378 modest_ui_actions_send_receive_error_handler,
1381 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1382 G_CALLBACK (_on_send_receive_progress_changed),
1385 /* Send & receive. */
1386 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1387 /* Receive and then send. The operation is tagged initially as
1388 a receive operation because the account update performs a
1389 receive and then a send. The operation changes its type
1390 internally, so the progress objects will receive the proper
1391 progress information */
1392 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1393 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1394 g_object_unref (G_OBJECT (mail_op));
1402 modest_ui_actions_do_cancel_send (const gchar *account_name,
1405 TnyTransportAccount *transport_account;
1406 TnySendQueue *send_queue = NULL;
1407 GError *error = NULL;
1409 /* Get transport account */
1411 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1412 (modest_runtime_get_account_store(),
1414 TNY_ACCOUNT_TYPE_TRANSPORT));
1415 if (!transport_account) {
1416 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1421 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1422 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1423 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1424 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1425 "modest: could not find send queue for account\n");
1427 /* Keeep messages in outbox folder */
1428 tny_send_queue_cancel (send_queue, FALSE, &error);
1432 if (transport_account != NULL)
1433 g_object_unref (G_OBJECT (transport_account));
1437 modest_ui_actions_cancel_send_all (ModestWindow *win)
1439 GSList *account_names, *iter;
1441 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1444 iter = account_names;
1446 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1447 iter = g_slist_next (iter);
1450 modest_account_mgr_free_account_names (account_names);
1451 account_names = NULL;
1455 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1458 /* Check if accounts exist */
1459 gboolean accounts_exist =
1460 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1462 /* If not, allow the user to create an account before trying to send/receive. */
1463 if (!accounts_exist)
1464 modest_ui_actions_on_accounts (NULL, win);
1466 /* Cancel all sending operaitons */
1467 modest_ui_actions_cancel_send_all (win);
1471 * Refreshes all accounts. This function will be used by automatic
1475 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1477 GSList *account_names, *iter;
1479 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1482 iter = account_names;
1484 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1485 iter = g_slist_next (iter);
1488 modest_account_mgr_free_account_names (account_names);
1489 account_names = NULL;
1493 modest_do_refresh_current_folder(ModestWindow *win)
1495 /* Refresh currently selected folder. Note that if we only
1496 want to retreive the headers, then the refresh only will
1497 invoke a poke_status over all folders, i.e., only the
1498 total/unread count will be updated */
1499 if (MODEST_IS_MAIN_WINDOW (win)) {
1500 GtkWidget *header_view, *folder_view;
1501 TnyFolderStore *folder_store;
1503 /* Get folder and header view */
1505 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1506 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1508 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1510 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1512 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1513 MODEST_WIDGET_TYPE_HEADER_VIEW);
1515 /* We do not need to set the contents style
1516 because it hasn't changed. We also do not
1517 need to save the widget status. Just force
1519 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1520 TNY_FOLDER (folder_store),
1521 folder_refreshed_cb,
1522 MODEST_MAIN_WINDOW (win));
1526 g_object_unref (folder_store);
1532 * Handler of the click on Send&Receive button in the main toolbar
1535 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1537 /* Check if accounts exist */
1538 gboolean accounts_exist =
1539 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1541 /* If not, allow the user to create an account before trying to send/receive. */
1542 if (!accounts_exist)
1543 modest_ui_actions_on_accounts (NULL, win);
1545 modest_do_refresh_current_folder (win);
1547 /* Refresh the active account */
1548 modest_ui_actions_do_send_receive (NULL, win);
1553 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1556 GtkWidget *header_view;
1558 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1560 header_view = modest_main_window_get_child_widget (main_window,
1561 MODEST_WIDGET_TYPE_HEADER_VIEW);
1565 conf = modest_runtime_get_conf ();
1567 /* what is saved/restored is depending on the style; thus; we save with
1568 * old style, then update the style, and restore for this new style
1570 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1572 if (modest_header_view_get_style
1573 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1574 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1575 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1577 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1578 MODEST_HEADER_VIEW_STYLE_DETAILS);
1580 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1581 MODEST_CONF_HEADER_VIEW_KEY);
1586 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1588 ModestMainWindow *main_window)
1590 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1591 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1593 /* If no header has been selected then exit */
1598 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1599 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1601 /* Update Main window title */
1602 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1603 const gchar *subject = tny_header_get_subject (header);
1604 if (subject && strlen(subject) > 0)
1605 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1607 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1610 /* Update toolbar dimming state */
1611 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1615 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1617 ModestMainWindow *main_window)
1621 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1626 headers = tny_simple_list_new ();
1627 tny_list_prepend (headers, G_OBJECT (header));
1629 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1631 g_object_unref (headers);
1635 set_active_account_from_tny_account (TnyAccount *account,
1636 ModestWindow *window)
1638 const gchar *server_acc_name = tny_account_get_id (account);
1640 /* We need the TnyAccount provided by the
1641 account store because that is the one that
1642 knows the name of the Modest account */
1643 TnyAccount *modest_server_account = modest_server_account =
1644 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1645 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1648 const gchar *modest_acc_name =
1649 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1650 modest_window_set_active_account (window, modest_acc_name);
1651 g_object_unref (modest_server_account);
1656 folder_refreshed_cb (ModestMailOperation *mail_op,
1660 ModestMainWindow *win = NULL;
1661 GtkWidget *header_view;
1662 TnyFolder *current_folder;
1664 g_return_if_fail (TNY_IS_FOLDER (folder));
1666 win = MODEST_MAIN_WINDOW (user_data);
1668 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1671 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1672 if (current_folder != NULL && folder != current_folder) {
1677 /* Check if folder is empty and set headers view contents style */
1678 if (tny_folder_get_all_count (folder) == 0) {
1679 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1680 modest_main_window_set_contents_style (win,
1681 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1683 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1688 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1689 TnyFolderStore *folder_store,
1691 ModestMainWindow *main_window)
1694 GtkWidget *header_view;
1696 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1698 header_view = modest_main_window_get_child_widget(main_window,
1699 MODEST_WIDGET_TYPE_HEADER_VIEW);
1703 conf = modest_runtime_get_conf ();
1705 if (TNY_IS_ACCOUNT (folder_store)) {
1707 /* Update active account */
1708 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1709 /* Show account details */
1710 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1713 if (TNY_IS_FOLDER (folder_store) && selected) {
1715 /* Update the active account */
1716 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1718 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1719 g_object_unref (account);
1723 /* Set the header style by default, it could
1724 be changed later by the refresh callback to
1726 modest_main_window_set_contents_style (main_window,
1727 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1729 /* Set folder on header view. This function
1730 will call tny_folder_refresh_async so we
1731 pass a callback that will be called when
1732 finished. We use that callback to set the
1733 empty view if there are no messages */
1734 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1735 TNY_FOLDER (folder_store),
1736 folder_refreshed_cb,
1739 /* Restore configuration. We need to do this
1740 *after* the set_folder because the widget
1741 memory asks the header view about its
1743 modest_widget_memory_restore (modest_runtime_get_conf (),
1744 G_OBJECT(header_view),
1745 MODEST_CONF_HEADER_VIEW_KEY);
1747 /* Update the active account */
1748 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1749 /* Save only if we're seeing headers */
1750 if (modest_main_window_get_contents_style (main_window) ==
1751 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1752 modest_widget_memory_save (conf, G_OBJECT (header_view),
1753 MODEST_CONF_HEADER_VIEW_KEY);
1754 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1758 /* Update toolbar dimming state */
1759 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1763 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1770 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1772 online = tny_device_is_online (modest_runtime_get_device());
1775 /* already online -- the item is simply not there... */
1776 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1778 GTK_MESSAGE_WARNING,
1780 _("The %s you selected cannot be found"),
1782 gtk_dialog_run (GTK_DIALOG(dialog));
1784 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1788 GTK_RESPONSE_REJECT,
1790 GTK_RESPONSE_ACCEPT,
1792 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1793 "Do you want to get online?"), item);
1794 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1795 gtk_label_new (txt), FALSE, FALSE, 0);
1796 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1799 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1800 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1801 // modest_platform_connect_and_wait ();
1804 gtk_widget_destroy (dialog);
1808 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1811 /* g_message ("%s %s", __FUNCTION__, link); */
1816 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1819 modest_platform_activate_uri (link);
1823 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1826 modest_platform_show_uri_popup (link);
1830 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1833 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1837 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1838 const gchar *address,
1841 /* g_message ("%s %s", __FUNCTION__, address); */
1845 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1847 TnyTransportAccount *transport_account;
1848 ModestMailOperation *mail_operation;
1850 gchar *account_name, *from;
1851 ModestAccountMgr *account_mgr;
1852 gchar *info_text = NULL;
1854 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1856 data = modest_msg_edit_window_get_msg_data (edit_window);
1858 account_mgr = modest_runtime_get_account_mgr();
1859 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1861 account_name = modest_account_mgr_get_default_account (account_mgr);
1862 if (!account_name) {
1863 g_printerr ("modest: no account found\n");
1864 modest_msg_edit_window_free_msg_data (edit_window, data);
1868 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1869 account_name = g_strdup (data->account_name);
1873 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1874 (modest_runtime_get_account_store(),
1876 TNY_ACCOUNT_TYPE_TRANSPORT));
1877 if (!transport_account) {
1878 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1879 g_free (account_name);
1880 modest_msg_edit_window_free_msg_data (edit_window, data);
1883 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1885 /* Create the mail operation */
1886 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1887 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1889 modest_mail_operation_save_to_drafts (mail_operation,
1901 data->priority_flags);
1904 g_free (account_name);
1905 g_object_unref (G_OBJECT (transport_account));
1906 g_object_unref (G_OBJECT (mail_operation));
1908 modest_msg_edit_window_free_msg_data (edit_window, data);
1910 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1911 modest_platform_information_banner (NULL, NULL, info_text);
1915 /* For instance, when clicking the Send toolbar button when editing a message: */
1917 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1919 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1921 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
1924 /* Offer the connection dialog, if necessary: */
1925 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
1928 /* FIXME: Code added just for testing. The final version will
1929 use the send queue provided by tinymail and some
1931 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1932 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1934 account_name = modest_account_mgr_get_default_account (account_mgr);
1936 if (!account_name) {
1937 g_printerr ("modest: no account found\n");
1941 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1943 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1944 account_name = g_strdup (data->account_name);
1947 /* Get the currently-active transport account for this modest account: */
1948 TnyTransportAccount *transport_account =
1949 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1950 (modest_runtime_get_account_store(),
1952 if (!transport_account) {
1953 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1954 g_free (account_name);
1955 modest_msg_edit_window_free_msg_data (edit_window, data);
1959 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1961 /* mail content checks and dialogs */
1962 if (data->subject == NULL || data->subject[0] == '\0') {
1963 GtkResponseType response;
1964 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1965 _("mcen_nc_subject_is_empty_send"));
1966 if (response == GTK_RESPONSE_CANCEL) {
1967 g_free (account_name);
1972 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1973 GtkResponseType response;
1974 gchar *note_message;
1975 gchar *note_subject = data->subject;
1976 if (note_subject == NULL || note_subject[0] == '\0')
1977 note_subject = _("mail_va_no_subject");
1978 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1979 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1981 g_free (note_message);
1982 if (response == GTK_RESPONSE_CANCEL) {
1983 g_free (account_name);
1988 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1990 /* Create the mail operation */
1991 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1992 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1994 modest_mail_operation_send_new_mail (mail_operation,
2005 data->priority_flags);
2009 g_free (account_name);
2010 g_object_unref (G_OBJECT (transport_account));
2011 g_object_unref (G_OBJECT (mail_operation));
2013 modest_msg_edit_window_free_msg_data (edit_window, data);
2014 modest_msg_edit_window_set_sent (edit_window, TRUE);
2016 /* Save settings and close the window: */
2017 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2021 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2022 ModestMsgEditWindow *window)
2024 ModestMsgEditFormatState *format_state = NULL;
2026 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2027 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2029 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2032 format_state = modest_msg_edit_window_get_format_state (window);
2033 g_return_if_fail (format_state != NULL);
2035 format_state->bold = gtk_toggle_action_get_active (action);
2036 modest_msg_edit_window_set_format_state (window, format_state);
2037 g_free (format_state);
2042 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2043 ModestMsgEditWindow *window)
2045 ModestMsgEditFormatState *format_state = NULL;
2047 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2048 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2050 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2053 format_state = modest_msg_edit_window_get_format_state (window);
2054 g_return_if_fail (format_state != NULL);
2056 format_state->italics = gtk_toggle_action_get_active (action);
2057 modest_msg_edit_window_set_format_state (window, format_state);
2058 g_free (format_state);
2063 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2064 ModestMsgEditWindow *window)
2066 ModestMsgEditFormatState *format_state = NULL;
2068 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2069 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2071 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2074 format_state = modest_msg_edit_window_get_format_state (window);
2075 g_return_if_fail (format_state != NULL);
2077 format_state->bullet = gtk_toggle_action_get_active (action);
2078 modest_msg_edit_window_set_format_state (window, format_state);
2079 g_free (format_state);
2084 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2085 GtkRadioAction *selected,
2086 ModestMsgEditWindow *window)
2088 ModestMsgEditFormatState *format_state = NULL;
2089 GtkJustification value;
2091 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2093 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2096 value = gtk_radio_action_get_current_value (selected);
2098 format_state = modest_msg_edit_window_get_format_state (window);
2099 g_return_if_fail (format_state != NULL);
2101 format_state->justification = value;
2102 modest_msg_edit_window_set_format_state (window, format_state);
2103 g_free (format_state);
2107 modest_ui_actions_on_select_editor_color (GtkAction *action,
2108 ModestMsgEditWindow *window)
2110 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2111 g_return_if_fail (GTK_IS_ACTION (action));
2113 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2116 modest_msg_edit_window_select_color (window);
2120 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2121 ModestMsgEditWindow *window)
2123 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2124 g_return_if_fail (GTK_IS_ACTION (action));
2126 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2129 modest_msg_edit_window_select_background_color (window);
2133 modest_ui_actions_on_insert_image (GtkAction *action,
2134 ModestMsgEditWindow *window)
2136 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2137 g_return_if_fail (GTK_IS_ACTION (action));
2139 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2142 modest_msg_edit_window_insert_image (window);
2146 modest_ui_actions_on_attach_file (GtkAction *action,
2147 ModestMsgEditWindow *window)
2149 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2150 g_return_if_fail (GTK_IS_ACTION (action));
2152 modest_msg_edit_window_offer_attach_file (window);
2156 modest_ui_actions_on_remove_attachments (GtkAction *action,
2157 ModestMsgEditWindow *window)
2159 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2160 g_return_if_fail (GTK_IS_ACTION (action));
2162 modest_msg_edit_window_remove_attachments (window, NULL);
2166 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2169 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2170 const GError *error = modest_mail_operation_get_error (mail_op);
2174 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2175 modest_mail_operation_get_error (mail_op)->message);
2180 modest_ui_actions_create_folder(GtkWidget *parent_window,
2181 GtkWidget *folder_view)
2183 TnyFolderStore *parent_folder;
2185 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2187 if (parent_folder) {
2188 gboolean finished = FALSE;
2190 gchar *folder_name = NULL, *suggested_name = NULL;
2192 /* Run the new folder dialog */
2194 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2199 g_free (suggested_name);
2200 suggested_name = NULL;
2202 if (result == GTK_RESPONSE_REJECT) {
2205 ModestMailOperation *mail_op;
2206 TnyFolder *new_folder = NULL;
2208 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2209 G_OBJECT(parent_window),
2210 modest_ui_actions_new_folder_error_handler,
2213 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2215 new_folder = modest_mail_operation_create_folder (mail_op,
2217 (const gchar *) folder_name);
2219 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2222 g_object_unref (new_folder);
2225 g_object_unref (mail_op);
2228 suggested_name = folder_name;
2232 g_object_unref (parent_folder);
2237 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2239 GtkWidget *folder_view;
2241 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2243 folder_view = modest_main_window_get_child_widget (main_window,
2244 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2248 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2252 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2255 GObject *win = modest_mail_operation_get_source (mail_op);
2256 const GError *error = NULL;
2257 const gchar *message = NULL;
2259 /* Get error message */
2260 error = modest_mail_operation_get_error (mail_op);
2261 if (error != NULL && error->message != NULL) {
2262 message = error->message;
2264 message = _("!!! FIXME: Unable to rename");
2267 /* Show notification dialog */
2268 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2269 g_object_unref (win);
2273 modest_ui_actions_on_rename_folder (GtkAction *action,
2274 ModestMainWindow *main_window)
2276 TnyFolderStore *folder;
2277 GtkWidget *folder_view;
2278 GtkWidget *header_view;
2280 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2282 folder_view = modest_main_window_get_child_widget (main_window,
2283 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2287 header_view = modest_main_window_get_child_widget (main_window,
2288 MODEST_WIDGET_TYPE_HEADER_VIEW);
2293 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2297 /* Offer the connection dialog if necessary: */
2298 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2299 g_object_unref (G_OBJECT (folder));
2304 if (TNY_IS_FOLDER (folder)) {
2307 const gchar *current_name;
2309 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2310 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2311 current_name, &folder_name);
2313 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2314 ModestMailOperation *mail_op;
2317 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2318 G_OBJECT(main_window),
2319 modest_ui_actions_rename_folder_error_handler,
2323 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2326 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2328 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2329 TNY_FOLDER(folder), TRUE);
2332 modest_header_view_clear ((ModestHeaderView *) header_view);
2334 modest_mail_operation_rename_folder (mail_op,
2335 TNY_FOLDER (folder),
2336 (const gchar *) folder_name);
2338 g_object_unref (mail_op);
2339 g_free (folder_name);
2342 g_object_unref (folder);
2346 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2349 GObject *win = modest_mail_operation_get_source (mail_op);
2351 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2352 _("mail_in_ui_folder_delete_error"));
2353 g_object_unref (win);
2357 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2359 TnyFolderStore *folder;
2360 GtkWidget *folder_view;
2364 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2366 folder_view = modest_main_window_get_child_widget (main_window,
2367 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2371 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2373 /* Show an error if it's an account */
2374 if (!TNY_IS_FOLDER (folder)) {
2375 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2376 _("mail_in_ui_folder_delete_error"));
2377 g_object_unref (G_OBJECT (folder));
2381 /* Offer the connection dialog if necessary: */
2382 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2383 g_object_unref (G_OBJECT (folder));
2388 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2389 tny_folder_get_name (TNY_FOLDER (folder)));
2390 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2391 (const gchar *) message);
2394 if (response == GTK_RESPONSE_OK) {
2395 ModestMailOperation *mail_op =
2396 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2397 G_OBJECT(main_window),
2398 modest_ui_actions_delete_folder_error_handler,
2401 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2403 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2404 g_object_unref (G_OBJECT (mail_op));
2407 g_object_unref (G_OBJECT (folder));
2411 modest_ui_actions_on_delete_folder (GtkAction *action,
2412 ModestMainWindow *main_window)
2414 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2416 delete_folder (main_window, FALSE);
2420 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2422 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2424 delete_folder (main_window, TRUE);
2429 show_error (GtkWidget *parent_widget, const gchar* text)
2431 hildon_banner_show_information(parent_widget, NULL, text);
2434 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2436 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2443 gtk_dialog_run (dialog);
2444 gtk_widget_destroy (GTK_WIDGET (dialog));
2449 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2450 const gchar* server_account_name,
2455 ModestMainWindow *main_window)
2457 g_return_if_fail(server_account_name);
2458 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2460 /* Initalize output parameters: */
2467 #ifdef MODEST_PLATFORM_MAEMO
2468 /* Maemo uses a different (awkward) button order,
2469 * It should probably just use gtk_alternative_dialog_button_order ().
2471 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2475 GTK_RESPONSE_ACCEPT,
2477 GTK_RESPONSE_REJECT,
2480 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2484 GTK_RESPONSE_REJECT,
2486 GTK_RESPONSE_ACCEPT,
2488 #endif /* MODEST_PLATFORM_MAEMO */
2490 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2492 gchar *server_name = modest_server_account_get_hostname (
2493 modest_runtime_get_account_mgr(), server_account_name);
2494 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2495 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2500 /* This causes a warning because the logical ID has no %s in it,
2501 * though the translation does, but there is not much we can do about that: */
2502 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2503 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2506 g_free (server_name);
2510 gchar *initial_username = modest_server_account_get_username (
2511 modest_runtime_get_account_mgr(), server_account_name);
2513 GtkWidget *entry_username = gtk_entry_new ();
2514 if (initial_username)
2515 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2516 /* Dim this if a connection has ever succeeded with this username,
2517 * as per the UI spec: */
2518 const gboolean username_known =
2519 modest_server_account_get_username_has_succeeded(
2520 modest_runtime_get_account_mgr(), server_account_name);
2521 gtk_widget_set_sensitive (entry_username, !username_known);
2523 #ifdef MODEST_PLATFORM_MAEMO
2524 /* Auto-capitalization is the default, so let's turn it off: */
2525 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2527 /* Create a size group to be used by all captions.
2528 * Note that HildonCaption does not create a default size group if we do not specify one.
2529 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2530 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2532 GtkWidget *caption = hildon_caption_new (sizegroup,
2533 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2534 gtk_widget_show (entry_username);
2535 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2536 FALSE, FALSE, MODEST_MARGIN_HALF);
2537 gtk_widget_show (caption);
2539 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2541 #endif /* MODEST_PLATFORM_MAEMO */
2544 GtkWidget *entry_password = gtk_entry_new ();
2545 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2546 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2548 #ifdef MODEST_PLATFORM_MAEMO
2549 /* Auto-capitalization is the default, so let's turn it off: */
2550 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2551 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2553 caption = hildon_caption_new (sizegroup,
2554 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2555 gtk_widget_show (entry_password);
2556 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2557 FALSE, FALSE, MODEST_MARGIN_HALF);
2558 gtk_widget_show (caption);
2559 g_object_unref (sizegroup);
2561 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2563 #endif /* MODEST_PLATFORM_MAEMO */
2565 /* This is not in the Maemo UI spec:
2566 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2567 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2571 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2573 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2575 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2577 modest_server_account_set_username (
2578 modest_runtime_get_account_mgr(), server_account_name,
2581 const gboolean username_was_changed =
2582 (strcmp (*username, initial_username) != 0);
2583 if (username_was_changed) {
2584 g_warning ("%s: tinymail does not yet support changing the "
2585 "username in the get_password() callback.\n", __FUNCTION__);
2590 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2592 /* We do not save the password in the configuration,
2593 * because this function is only called for passwords that should
2594 * not be remembered:
2595 modest_server_account_set_password (
2596 modest_runtime_get_account_mgr(), server_account_name,
2605 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2617 /* This is not in the Maemo UI spec:
2618 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2624 gtk_widget_destroy (dialog);
2626 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2630 modest_ui_actions_on_cut (GtkAction *action,
2631 ModestWindow *window)
2633 GtkWidget *focused_widget;
2635 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2636 if (GTK_IS_EDITABLE (focused_widget)) {
2637 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2638 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2639 GtkTextBuffer *buffer;
2640 GtkClipboard *clipboard;
2642 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2643 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2644 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2645 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2646 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2647 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2648 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2649 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2654 modest_ui_actions_on_copy (GtkAction *action,
2655 ModestWindow *window)
2657 GtkClipboard *clipboard;
2658 GtkWidget *focused_widget;
2660 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2661 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2663 if (GTK_IS_LABEL (focused_widget)) {
2664 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2665 } else if (GTK_IS_EDITABLE (focused_widget)) {
2666 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2667 } else if (GTK_IS_HTML (focused_widget)) {
2668 gtk_html_copy (GTK_HTML (focused_widget));
2669 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2670 GtkTextBuffer *buffer;
2671 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2672 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2673 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2674 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2675 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2676 TnyIterator *iter = tny_list_create_iterator (header_list);
2677 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2679 gboolean ask = FALSE;
2681 TnyFolder *folder = tny_header_get_folder (header);
2682 TnyAccount *account = tny_folder_get_account (folder);
2683 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2684 /* If it's POP then ask */
2685 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2686 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2687 g_object_unref (account);
2688 g_object_unref (folder);
2689 g_object_unref (header);
2692 g_object_unref (iter);
2694 /* Check that the messages have been previously downloaded */
2695 gboolean continue_download = TRUE;
2697 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2698 if (continue_download)
2699 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2700 g_object_unref (header_list);
2701 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2702 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2705 /* Show information banner */
2706 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2711 modest_ui_actions_on_undo (GtkAction *action,
2712 ModestWindow *window)
2714 ModestEmailClipboard *clipboard = NULL;
2716 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2717 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2718 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2719 /* Clear clipboard source */
2720 clipboard = modest_runtime_get_email_clipboard ();
2721 modest_email_clipboard_clear (clipboard);
2724 g_return_if_reached ();
2729 modest_ui_actions_on_redo (GtkAction *action,
2730 ModestWindow *window)
2732 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2733 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2736 g_return_if_reached ();
2742 paste_msgs_cb (const GObject *object, gpointer user_data)
2744 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2745 g_return_if_fail (GTK_IS_WIDGET (user_data));
2747 /* destroy information note */
2748 gtk_widget_destroy (GTK_WIDGET(user_data));
2752 paste_as_attachment_free (gpointer data)
2754 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2756 gtk_widget_destroy (helper->banner);
2757 g_object_unref (helper->banner);
2762 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2767 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2768 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2773 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2778 modest_ui_actions_on_paste (GtkAction *action,
2779 ModestWindow *window)
2781 GtkWidget *focused_widget = NULL;
2782 GtkWidget *inf_note = NULL;
2783 ModestMailOperation *mail_op = NULL;
2785 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2786 if (GTK_IS_EDITABLE (focused_widget)) {
2787 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2788 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2789 ModestEmailClipboard *e_clipboard = NULL;
2790 e_clipboard = modest_runtime_get_email_clipboard ();
2791 if (modest_email_clipboard_cleared (e_clipboard)) {
2792 GtkTextBuffer *buffer;
2793 GtkClipboard *clipboard;
2795 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2796 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2797 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2798 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2799 ModestMailOperation *mail_op;
2800 TnyFolder *src_folder;
2803 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2804 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2805 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2806 _CS("ckct_nw_pasting"));
2807 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2808 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2810 if (helper->banner != NULL) {
2811 g_object_ref (G_OBJECT (helper->banner));
2812 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2813 gtk_widget_show (GTK_WIDGET (helper->banner));
2817 modest_mail_operation_get_msgs_full (mail_op,
2819 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2821 paste_as_attachment_free);
2824 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2825 ModestEmailClipboard *clipboard = NULL;
2826 TnyFolder *src_folder = NULL;
2827 TnyFolderStore *folder_store = NULL;
2828 TnyList *data = NULL;
2829 gboolean delete = FALSE;
2831 /* Check clipboard source */
2832 clipboard = modest_runtime_get_email_clipboard ();
2833 if (modest_email_clipboard_cleared (clipboard))
2836 /* Get elements to paste */
2837 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2839 /* Create a new mail operation */
2840 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2841 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2844 /* Get destination folder */
2845 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2847 /* Launch notification */
2848 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2849 _CS("ckct_nw_pasting"));
2850 if (inf_note != NULL) {
2851 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2852 gtk_widget_show (GTK_WIDGET(inf_note));
2855 /* transfer messages */
2857 modest_mail_operation_xfer_msgs (mail_op,
2859 TNY_FOLDER (folder_store),
2864 } else if (src_folder != NULL) {
2865 modest_mail_operation_xfer_folder (mail_op,
2875 g_object_unref (data);
2876 if (src_folder != NULL)
2877 g_object_unref (src_folder);
2878 if (folder_store != NULL)
2879 g_object_unref (folder_store);
2885 modest_ui_actions_on_select_all (GtkAction *action,
2886 ModestWindow *window)
2888 GtkWidget *focused_widget;
2890 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2891 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2892 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2893 } else if (GTK_IS_LABEL (focused_widget)) {
2894 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2895 } else if (GTK_IS_EDITABLE (focused_widget)) {
2896 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2897 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2898 GtkTextBuffer *buffer;
2899 GtkTextIter start, end;
2901 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2902 gtk_text_buffer_get_start_iter (buffer, &start);
2903 gtk_text_buffer_get_end_iter (buffer, &end);
2904 gtk_text_buffer_select_range (buffer, &start, &end);
2905 } else if (GTK_IS_HTML (focused_widget)) {
2906 gtk_html_select_all (GTK_HTML (focused_widget));
2907 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2908 GtkWidget *header_view = focused_widget;
2909 GtkTreeSelection *selection = NULL;
2911 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2912 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2913 MODEST_WIDGET_TYPE_HEADER_VIEW);
2915 /* Select all messages */
2916 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2917 gtk_tree_selection_select_all (selection);
2919 /* Set focuse on header view */
2920 gtk_widget_grab_focus (header_view);
2926 modest_ui_actions_on_mark_as_read (GtkAction *action,
2927 ModestWindow *window)
2929 g_return_if_fail (MODEST_IS_WINDOW(window));
2931 /* Mark each header as read */
2932 do_headers_action (window, headers_action_mark_as_read, NULL);
2936 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2937 ModestWindow *window)
2939 g_return_if_fail (MODEST_IS_WINDOW(window));
2941 /* Mark each header as read */
2942 do_headers_action (window, headers_action_mark_as_unread, NULL);
2946 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2947 GtkRadioAction *selected,
2948 ModestWindow *window)
2952 value = gtk_radio_action_get_current_value (selected);
2953 if (MODEST_IS_WINDOW (window)) {
2954 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2958 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2959 GtkRadioAction *selected,
2960 ModestWindow *window)
2962 TnyHeaderFlags flags;
2963 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2965 flags = gtk_radio_action_get_current_value (selected);
2966 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2969 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2970 GtkRadioAction *selected,
2971 ModestWindow *window)
2975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2977 file_format = gtk_radio_action_get_current_value (selected);
2978 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2983 modest_ui_actions_on_zoom_plus (GtkAction *action,
2984 ModestWindow *window)
2986 g_return_if_fail (MODEST_IS_WINDOW (window));
2988 modest_window_zoom_plus (MODEST_WINDOW (window));
2992 modest_ui_actions_on_zoom_minus (GtkAction *action,
2993 ModestWindow *window)
2995 g_return_if_fail (MODEST_IS_WINDOW (window));
2997 modest_window_zoom_minus (MODEST_WINDOW (window));
3001 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3002 ModestWindow *window)
3004 ModestWindowMgr *mgr;
3005 gboolean fullscreen, active;
3006 g_return_if_fail (MODEST_IS_WINDOW (window));
3008 mgr = modest_runtime_get_window_mgr ();
3010 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3011 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3013 if (active != fullscreen) {
3014 modest_window_mgr_set_fullscreen_mode (mgr, active);
3015 gtk_window_present (GTK_WINDOW (window));
3020 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3021 ModestWindow *window)
3023 ModestWindowMgr *mgr;
3024 gboolean fullscreen;
3026 g_return_if_fail (MODEST_IS_WINDOW (window));
3028 mgr = modest_runtime_get_window_mgr ();
3029 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3030 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3032 gtk_window_present (GTK_WINDOW (window));
3036 * Used by modest_ui_actions_on_details to call do_headers_action
3039 headers_action_show_details (TnyHeader *header,
3040 ModestWindow *window,
3047 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3050 gtk_widget_show_all (dialog);
3051 gtk_dialog_run (GTK_DIALOG (dialog));
3053 gtk_widget_destroy (dialog);
3057 * Show the folder details in a ModestDetailsDialog widget
3060 show_folder_details (TnyFolder *folder,
3066 dialog = modest_details_dialog_new_with_folder (window, folder);
3069 gtk_widget_show_all (dialog);
3070 gtk_dialog_run (GTK_DIALOG (dialog));
3072 gtk_widget_destroy (dialog);
3076 * Show the header details in a ModestDetailsDialog widget
3079 modest_ui_actions_on_details (GtkAction *action,
3082 TnyList * headers_list;
3086 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3089 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3092 g_object_unref (msg);
3094 headers_list = get_selected_headers (win);
3098 iter = tny_list_create_iterator (headers_list);
3100 header = TNY_HEADER (tny_iterator_get_current (iter));
3102 headers_action_show_details (header, win, NULL);
3103 g_object_unref (header);
3106 g_object_unref (iter);
3107 g_object_unref (headers_list);
3109 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3110 GtkWidget *folder_view, *header_view;
3112 /* Check which widget has the focus */
3113 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3114 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3115 if (gtk_widget_is_focus (folder_view)) {
3116 TnyFolderStore *folder_store
3117 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3118 if (!folder_store) {
3119 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3122 /* Show only when it's a folder */
3123 /* This function should not be called for account items,
3124 * because we dim the menu item for them. */
3125 if (TNY_IS_FOLDER (folder_store)) {
3126 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3129 g_object_unref (folder_store);
3132 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3133 MODEST_WIDGET_TYPE_HEADER_VIEW);
3134 /* Show details of each header */
3135 do_headers_action (win, headers_action_show_details, header_view);
3141 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3142 ModestMsgEditWindow *window)
3144 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3146 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3150 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3151 ModestMsgEditWindow *window)
3153 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3155 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3159 modest_ui_actions_toggle_folders_view (GtkAction *action,
3160 ModestMainWindow *main_window)
3162 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3164 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3165 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3167 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3171 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3172 ModestWindow *window)
3174 gboolean active, fullscreen = FALSE;
3175 ModestWindowMgr *mgr;
3177 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3179 /* Check if we want to toggle the toolbar vuew in fullscreen
3181 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3182 "ViewShowToolbarFullScreen")) {
3186 /* Toggle toolbar */
3187 mgr = modest_runtime_get_window_mgr ();
3188 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3192 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3193 ModestMsgEditWindow *window)
3195 modest_msg_edit_window_select_font (window);
3199 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3200 const gchar *display_name,
3203 /* Do not change the application name if the widget has not
3204 the focus. This callback could be called even if the folder
3205 view has not the focus, because the handled signal could be
3206 emitted when the folder view is redrawn */
3207 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3209 gtk_window_set_title (window, display_name);
3211 gtk_window_set_title (window, " ");
3216 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3218 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3219 modest_msg_edit_window_select_contacts (window);
3223 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3225 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3226 modest_msg_edit_window_check_names (window, FALSE);
3230 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3232 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3233 GTK_WIDGET (user_data));
3237 create_move_to_dialog (GtkWindow *win,
3238 GtkWidget *folder_view,
3239 GtkWidget **tree_view)
3241 GtkWidget *dialog, *scroll;
3242 GtkWidget *new_button;
3244 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3246 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3249 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3250 /* We do this manually so GTK+ does not associate a response ID for
3252 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3253 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3254 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3256 /* Create scrolled window */
3257 scroll = gtk_scrolled_window_new (NULL, NULL);
3258 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3259 GTK_POLICY_AUTOMATIC,
3260 GTK_POLICY_AUTOMATIC);
3262 /* Create folder view */
3263 *tree_view = modest_platform_create_folder_view (NULL);
3265 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3267 /* It could happen that we're trying to move a message from a
3268 window (msg window for example) after the main window was
3269 closed, so we can not just get the model of the folder
3271 if (MODEST_IS_FOLDER_VIEW (folder_view))
3272 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3273 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3275 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3276 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3278 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3280 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3282 /* Add scroll to dialog */
3283 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3284 scroll, TRUE, TRUE, 0);
3286 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3287 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3293 * Returns TRUE if at least one of the headers of the list belongs to
3294 * a message that has been fully retrieved.
3297 has_retrieved_msgs (TnyList *list)
3300 gboolean found = FALSE;
3302 iter = tny_list_create_iterator (list);
3303 while (tny_iterator_is_done (iter) && !found) {
3305 TnyHeaderFlags flags = 0;
3307 header = TNY_HEADER (tny_iterator_get_current (iter));
3309 flags = tny_header_get_flags (header);
3310 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3313 g_object_unref (header);
3317 tny_iterator_next (iter);
3319 g_object_unref (iter);
3325 * Shows a confirmation dialog to the user when we're moving messages
3326 * from a remote server to the local storage. Returns the dialog
3327 * response. If it's other kind of movement the it always returns
3331 msgs_move_to_confirmation (GtkWindow *win,
3332 TnyFolder *dest_folder,
3335 gint response = GTK_RESPONSE_OK;
3337 /* If the destination is a local folder */
3338 if (modest_tny_folder_is_local_folder (dest_folder)) {
3339 TnyFolder *src_folder = NULL;
3340 TnyIterator *iter = NULL;
3341 TnyHeader *header = NULL;
3343 /* Get source folder */
3344 iter = tny_list_create_iterator (headers);
3345 header = TNY_HEADER (tny_iterator_get_current (iter));
3347 src_folder = tny_header_get_folder (header);
3348 g_object_unref (header);
3351 g_object_unref (iter);
3353 /* if no src_folder, message may be an attahcment */
3354 if (src_folder == NULL)
3355 return GTK_RESPONSE_CANCEL;
3357 /* If the source is a remote folder */
3358 if (!modest_tny_folder_is_local_folder (src_folder)) {
3359 const gchar *message;
3361 if (has_retrieved_msgs (headers))
3362 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3363 tny_list_get_length (headers));
3365 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3366 tny_list_get_length (headers));
3368 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3369 (const gchar *) message);
3372 g_object_unref (src_folder);
3381 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3383 ModestMsgViewWindow *self = NULL;
3385 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3386 self = MODEST_MSG_VIEW_WINDOW (object);
3388 if (!modest_msg_view_window_select_next_message (self))
3389 if (!modest_msg_view_window_select_previous_message (self))
3390 /* No more messages to view, so close this window */
3391 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3395 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3398 GObject *win = modest_mail_operation_get_source (mail_op);
3399 const GError *error = NULL;
3400 const gchar *message = NULL;
3402 /* Get error message */
3403 error = modest_mail_operation_get_error (mail_op);
3404 if (error != NULL && error->message != NULL) {
3405 message = error->message;
3407 message = _("mail_in_ui_folder_move_target_error");
3410 /* Show notification dialog */
3411 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3412 g_object_unref (win);
3416 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3419 GObject *win = modest_mail_operation_get_source (mail_op);
3420 const GError *error = modest_mail_operation_get_error (mail_op);
3422 g_return_if_fail (error != NULL);
3423 if (error->message != NULL)
3424 g_printerr ("modest: %s\n", error->message);
3426 g_printerr ("modest: unkonw error on send&receive operation");
3428 /* Show error message */
3429 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3430 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3431 /* _CS("sfil_ib_unable_to_receive")); */
3433 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3434 /* _CS("sfil_ib_unable_to_send")); */
3435 g_object_unref (win);
3439 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3446 gint pending_purges = 0;
3447 gboolean some_purged = FALSE;
3448 ModestWindow *win = MODEST_WINDOW (user_data);
3449 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3451 /* If there was any error */
3452 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3453 modest_window_mgr_unregister_header (mgr, header);
3457 /* Once the message has been retrieved for purging, we check if
3458 * it's all ok for purging */
3460 parts = tny_simple_list_new ();
3461 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3462 iter = tny_list_create_iterator (parts);
3464 while (!tny_iterator_is_done (iter)) {
3466 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3467 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3468 if (tny_mime_part_is_purged (part))
3475 g_object_unref (part);
3477 tny_iterator_next (iter);
3480 if (pending_purges>0) {
3482 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3484 if (response == GTK_RESPONSE_OK) {
3485 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3486 tny_iterator_first (iter);
3487 while (!tny_iterator_is_done (iter)) {
3490 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3491 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3492 tny_mime_part_set_purged (part);
3495 g_object_unref (part);
3497 tny_iterator_next (iter);
3500 tny_msg_rewrite_cache (msg);
3503 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3506 /* remove attachments */
3507 tny_iterator_first (iter);
3508 while (!tny_iterator_is_done (iter)) {
3511 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3513 /* One for the reference given by tny_iterator_get_current(): */
3514 g_object_unref (part);
3516 /* TODO: Is this meant to remove the attachment by doing another unref()?
3517 * Otherwise, this seems useless. */
3520 tny_iterator_next (iter);
3522 modest_window_mgr_unregister_header (mgr, header);
3524 g_object_unref (iter);
3525 g_object_unref (parts);
3529 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3530 ModestMainWindow *win)
3532 GtkWidget *header_view;
3533 TnyList *header_list;
3536 TnyHeaderFlags flags;
3537 ModestWindow *msg_view_window = NULL;
3540 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3542 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3543 MODEST_WIDGET_TYPE_HEADER_VIEW);
3545 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3547 if (tny_list_get_length (header_list) == 1) {
3548 iter = tny_list_create_iterator (header_list);
3549 header = TNY_HEADER (tny_iterator_get_current (iter));
3550 g_object_unref (iter);
3555 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3556 header, &msg_view_window);
3557 flags = tny_header_get_flags (header);
3558 if (!(flags & TNY_HEADER_FLAG_CACHED))
3561 if (msg_view_window != NULL)
3562 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3564 /* do nothing; uid was registered before, so window is probably on it's way */
3565 g_warning ("debug: header %p has already been registered", header);
3568 ModestMailOperation *mail_op = NULL;
3569 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3570 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3572 modest_ui_actions_get_msgs_full_error_handler,
3574 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3575 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3577 g_object_unref (mail_op);
3580 g_object_unref (header);
3582 g_object_unref (header_list);
3586 * Utility function that transfer messages from both the main window
3587 * and the msg view window when using the "Move to" dialog
3590 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3593 TnyList *headers = NULL;
3596 if (!TNY_IS_FOLDER (dst_folder)) {
3597 modest_platform_information_banner (GTK_WIDGET (win),
3599 _CS("ckdg_ib_unable_to_move_to_current_location"));
3603 /* Get selected headers */
3604 headers = get_selected_headers (MODEST_WINDOW (win));
3606 /* Ask for user confirmation */
3607 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3608 TNY_FOLDER (dst_folder),
3611 /* Transfer messages */
3612 if (response == GTK_RESPONSE_OK) {
3613 ModestMailOperation *mail_op =
3614 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3616 modest_ui_actions_move_folder_error_handler,
3618 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3621 modest_mail_operation_xfer_msgs (mail_op,
3623 TNY_FOLDER (dst_folder),
3625 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3628 g_object_unref (G_OBJECT (mail_op));
3630 g_object_unref (headers);
3635 * UI handler for the "Move to" action when invoked from the
3639 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3640 GtkWidget *folder_view,
3641 TnyFolderStore *dst_folder,
3642 ModestMainWindow *win)
3644 GtkWidget *header_view = NULL;
3645 ModestMailOperation *mail_op = NULL;
3646 TnyFolderStore *src_folder;
3648 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3650 /* Get the source folder */
3651 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3653 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3654 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3658 /* Get header view */
3660 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3662 /* Get folder or messages to transfer */
3663 if (gtk_widget_is_focus (folder_view)) {
3665 /* Allow only to transfer folders to the local root folder */
3666 if (TNY_IS_ACCOUNT (dst_folder) &&
3667 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3670 /* Clean folder on header view before moving it */
3671 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3673 if (TNY_IS_FOLDER (src_folder)) {
3675 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3677 modest_ui_actions_move_folder_error_handler,
3679 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3682 modest_mail_operation_xfer_folder (mail_op,
3683 TNY_FOLDER (src_folder),
3686 /* Unref mail operation */
3687 g_object_unref (G_OBJECT (mail_op));
3689 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3691 } else if (gtk_widget_is_focus (header_view)) {
3692 /* Transfer messages */
3693 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3698 g_object_unref (src_folder);
3703 * UI handler for the "Move to" action when invoked from the
3704 * ModestMsgViewWindow
3707 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3708 TnyFolderStore *dst_folder,
3709 ModestMsgViewWindow *win)
3711 TnyHeader *header = NULL;
3712 TnyFolder *src_folder;
3714 /* Create header list */
3715 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3716 src_folder = tny_header_get_folder(header);
3717 g_object_unref (header);
3719 /* Transfer the message */
3720 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3721 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3723 g_object_unref (src_folder);
3727 modest_ui_actions_on_move_to (GtkAction *action,
3730 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3732 TnyFolderStore *dst_folder = NULL;
3733 ModestMainWindow *main_window;
3735 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3736 MODEST_IS_MSG_VIEW_WINDOW (win));
3738 /* Get the main window if exists */
3739 if (MODEST_IS_MAIN_WINDOW (win))
3740 main_window = MODEST_MAIN_WINDOW (win);
3743 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3745 /* Get the folder view widget if exists */
3747 folder_view = modest_main_window_get_child_widget (main_window,
3748 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3752 /* Create and run the dialog */
3753 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3754 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3755 result = gtk_dialog_run (GTK_DIALOG(dialog));
3756 g_object_ref (tree_view);
3757 gtk_widget_destroy (dialog);
3759 if (result != GTK_RESPONSE_ACCEPT)
3762 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3763 /* Offer the connection dialog if necessary: */
3764 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3767 /* Do window specific stuff */
3768 if (MODEST_IS_MAIN_WINDOW (win))
3769 modest_ui_actions_on_main_window_move_to (action,
3772 MODEST_MAIN_WINDOW (win));
3774 modest_ui_actions_on_msg_view_window_move_to (action,
3776 MODEST_MSG_VIEW_WINDOW (win));
3779 g_object_unref (dst_folder);
3783 * Calls #HeadersFunc for each header already selected in the main
3784 * window or the message currently being shown in the msg view window
3787 do_headers_action (ModestWindow *win,
3791 TnyList *headers_list = NULL;
3792 TnyIterator *iter = NULL;
3793 TnyHeader *header = NULL;
3794 TnyFolder *folder = NULL;
3797 headers_list = get_selected_headers (win);
3801 /* Get the folder */
3802 iter = tny_list_create_iterator (headers_list);
3803 header = TNY_HEADER (tny_iterator_get_current (iter));
3805 folder = tny_header_get_folder (header);
3806 g_object_unref (header);
3809 /* Call the function for each header */
3810 while (!tny_iterator_is_done (iter)) {
3811 header = TNY_HEADER (tny_iterator_get_current (iter));
3812 func (header, win, user_data);
3813 g_object_unref (header);
3814 tny_iterator_next (iter);
3817 /* Trick: do a poke status in order to speed up the signaling
3819 tny_folder_poke_status (folder);
3822 g_object_unref (folder);
3823 g_object_unref (iter);
3824 g_object_unref (headers_list);
3828 modest_ui_actions_view_attachment (GtkAction *action,
3829 ModestWindow *window)
3831 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3832 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3834 /* not supported window for this action */
3835 g_return_if_reached ();
3840 modest_ui_actions_save_attachments (GtkAction *action,
3841 ModestWindow *window)
3843 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3844 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3846 /* not supported window for this action */
3847 g_return_if_reached ();
3852 modest_ui_actions_remove_attachments (GtkAction *action,
3853 ModestWindow *window)
3855 if (MODEST_IS_MAIN_WINDOW (window)) {
3856 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3857 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3858 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3860 /* not supported window for this action */
3861 g_return_if_reached ();
3866 modest_ui_actions_on_settings (GtkAction *action,
3871 dialog = modest_platform_get_global_settings_dialog ();
3872 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3873 gtk_widget_show_all (dialog);
3875 gtk_dialog_run (GTK_DIALOG (dialog));
3877 gtk_widget_destroy (dialog);
3881 modest_ui_actions_on_help (GtkAction *action,
3884 const gchar *help_id = NULL;
3886 if (MODEST_IS_MAIN_WINDOW (win)) {
3887 const gchar *action_name;
3888 action_name = gtk_action_get_name (action);
3890 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3891 !strcmp (action_name, "HeaderViewCSMHelp")) {
3892 GtkWidget *folder_view;
3893 TnyFolderStore *folder_store;
3894 /* Get selected folder */
3895 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3896 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3897 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3899 /* Switch help_id */
3900 if (TNY_IS_FOLDER (folder_store)) {
3901 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
3902 case TNY_FOLDER_TYPE_NORMAL:
3903 help_id = "applications_email_managefolders";
3905 case TNY_FOLDER_TYPE_INBOX:
3906 help_id = "applications_email_inbox";
3908 case TNY_FOLDER_TYPE_OUTBOX:
3909 help_id = "applications_email_outbox";
3911 case TNY_FOLDER_TYPE_SENT:
3912 help_id = "applications_email_sent";
3914 case TNY_FOLDER_TYPE_DRAFTS:
3915 help_id = "applications_email_drafts";
3917 case TNY_FOLDER_TYPE_ARCHIVE:
3918 help_id = "applications_email_managefolders";
3921 help_id = "applications_email_managefolders";
3924 help_id = "applications_email_mainview";
3926 g_object_unref (folder_store);
3928 help_id = "applications_email_mainview";
3930 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3931 help_id = "applications_email_viewer";
3932 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3933 help_id = "applications_email_editor";
3935 modest_platform_show_help (GTK_WINDOW (win), help_id);
3939 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3940 ModestWindow *window)
3942 ModestMailOperation *mail_op;
3946 headers = get_selected_headers (window);
3950 /* Create mail operation */
3951 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3953 modest_ui_actions_get_msgs_full_error_handler,
3955 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3956 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3959 g_object_unref (headers);
3960 g_object_unref (mail_op);
3964 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3965 ModestWindow *window)
3967 g_return_if_fail (MODEST_IS_WINDOW (window));
3970 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3974 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3975 ModestWindow *window)
3977 g_return_if_fail (MODEST_IS_WINDOW (window));
3980 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3984 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3985 ModestWindow *window)
3987 g_return_if_fail (MODEST_IS_WINDOW (window));
3990 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3994 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3995 ModestWindow *window)
3997 g_return_if_fail (MODEST_IS_WINDOW (window));
4000 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4004 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4005 ModestWindow *window)
4007 g_return_if_fail (MODEST_IS_WINDOW (window));
4010 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4014 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4015 ModestWindow *window)
4017 g_return_if_fail (MODEST_IS_WINDOW (window));
4020 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4024 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4025 ModestWindow *window)
4027 g_return_if_fail (MODEST_IS_WINDOW (window));
4030 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4034 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4035 ModestWindow *window)
4037 g_return_if_fail (MODEST_IS_WINDOW (window));
4040 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4044 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4046 g_return_if_fail (MODEST_IS_WINDOW (window));
4049 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4053 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4055 g_return_if_fail (MODEST_IS_WINDOW (window));
4057 modest_platform_show_search_messages (GTK_WINDOW (window));
4061 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4063 g_return_if_fail (MODEST_IS_WINDOW (win));
4064 modest_platform_show_addressbook (GTK_WINDOW (win));
4069 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4070 ModestWindow *window)
4072 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4074 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4078 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4079 ModestMailOperationState *state,
4082 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4084 /* Set send/receive operation finished */
4085 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4086 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));