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>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _PasteAsAttachmentHelper {
107 ModestMsgEditWindow *window;
109 } PasteAsAttachmentHelper;
113 * The do_headers_action uses this kind of functions to perform some
114 * action to each member of a list of headers
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
118 static void do_headers_action (ModestWindow *win,
122 static void open_msg_cb (ModestMailOperation *mail_op,
127 static void reply_forward_cb (ModestMailOperation *mail_op,
132 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
134 static void folder_refreshed_cb (ModestMailOperation *mail_op,
138 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
139 ModestMailOperationState *state,
143 download_uncached_messages (TnyList *header_list, GtkWindow *win);
147 msgs_move_to_confirmation (GtkWindow *win,
148 TnyFolder *dest_folder,
153 /* Show the account creation wizard dialog.
154 * returns: TRUE if an account was created. FALSE if the user cancelled.
157 modest_run_account_setup_wizard (ModestWindow *win)
159 gboolean result = FALSE;
160 ModestEasysetupWizardDialog *wizard;
163 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
165 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
167 wizard = modest_easysetup_wizard_dialog_new ();
168 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
170 /* Don't make this a modal window, because secondary windows will then
171 * be unusable, freezing the UI: */
172 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
174 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
175 if (dialog_response == GTK_RESPONSE_CANCEL)
178 /* Check whether an account was created: */
179 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
182 gtk_widget_destroy (GTK_WIDGET (wizard));
189 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
192 const gchar *authors[] = {
193 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
196 about = gtk_about_dialog_new ();
197 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
198 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
199 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
200 _("Copyright (c) 2006, Nokia Corporation\n"
201 "All rights reserved."));
202 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
203 _("a modest e-mail client\n\n"
204 "design and implementation: Dirk-Jan C. Binnema\n"
205 "contributions from the fine people at KC and Ig\n"
206 "uses the tinymail email framework written by Philip van Hoof"));
207 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
208 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
209 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
210 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
212 gtk_dialog_run (GTK_DIALOG (about));
213 gtk_widget_destroy(about);
217 * Gets the list of currently selected messages. If the win is the
218 * main window, then it returns a newly allocated list of the headers
219 * selected in the header view. If win is the msg view window, then
220 * the value returned is a list with just a single header.
222 * The caller of this funcion must free the list.
225 get_selected_headers (ModestWindow *win)
227 if (MODEST_IS_MAIN_WINDOW(win)) {
228 GtkWidget *header_view;
230 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
231 MODEST_WIDGET_TYPE_HEADER_VIEW);
232 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
234 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
235 /* for MsgViewWindows, we simply return a list with one element */
237 TnyList *list = NULL;
239 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
240 if (header != NULL) {
241 list = tny_simple_list_new ();
242 tny_list_prepend (list, G_OBJECT(header));
243 g_object_unref (G_OBJECT(header));
253 headers_action_mark_as_read (TnyHeader *header,
257 TnyHeaderFlags flags;
259 g_return_if_fail (TNY_IS_HEADER(header));
261 flags = tny_header_get_flags (header);
262 if (flags & TNY_HEADER_FLAG_SEEN) return;
263 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
267 headers_action_mark_as_unread (TnyHeader *header,
271 TnyHeaderFlags flags;
273 g_return_if_fail (TNY_IS_HEADER(header));
275 flags = tny_header_get_flags (header);
276 if (flags & TNY_HEADER_FLAG_SEEN) {
277 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
281 /** A convenience method, because deleting a message is
282 * otherwise complicated, and it's best to change it in one place
285 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
287 ModestMailOperation *mail_op = NULL;
288 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
289 win ? G_OBJECT(win) : NULL);
290 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
293 /* Always delete. TODO: Move to trash still not supported */
294 modest_mail_operation_remove_msg (mail_op, header, FALSE);
295 g_object_unref (G_OBJECT (mail_op));
299 headers_action_delete (TnyHeader *header,
303 modest_do_message_delete (header, win);
306 /** After deleing a message that is currently visible in a window,
307 * show the next message from the list, or close the window if there are no more messages.
309 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
311 /* Close msg view window or select next */
312 if (modest_msg_view_window_last_message_selected (win) &&
313 modest_msg_view_window_first_message_selected (win)) {
314 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
316 if (!modest_msg_view_window_select_next_message (win)) {
318 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
324 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
326 TnyList *header_list = NULL;
327 TnyIterator *iter = NULL;
328 TnyHeader *header = NULL;
329 gchar *message = NULL;
332 ModestWindowMgr *mgr;
333 GtkWidget *header_view = NULL;
335 g_return_if_fail (MODEST_IS_WINDOW(win));
337 /* Check first if the header view has the focus */
338 if (MODEST_IS_MAIN_WINDOW (win)) {
340 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
341 MODEST_WIDGET_TYPE_HEADER_VIEW);
342 if (!gtk_widget_is_focus (header_view))
346 /* Get the headers, either from the header view (if win is the main window),
347 * or from the message view window: */
348 header_list = get_selected_headers (win);
349 if (!header_list) return;
351 /* Check if any of the headers are already opened, or in the process of being opened */
352 if (MODEST_IS_MAIN_WINDOW (win)) {
354 iter = tny_list_create_iterator (header_list);
356 mgr = modest_runtime_get_window_mgr ();
357 while (!tny_iterator_is_done (iter) && !found) {
358 header = TNY_HEADER (tny_iterator_get_current (iter));
360 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
361 g_object_unref (header);
364 tny_iterator_next (iter);
366 g_object_unref (iter);
371 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
372 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
374 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
378 g_object_unref (header_list);
384 if (tny_list_get_length(header_list) == 1) {
385 iter = tny_list_create_iterator (header_list);
386 header = TNY_HEADER (tny_iterator_get_current (iter));
388 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
389 g_object_unref (header);
392 g_object_unref (iter);
394 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
395 tny_list_get_length(header_list)), desc);
397 /* Confirmation dialog */
398 printf("DEBUG: %s\n", __FUNCTION__);
399 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
403 if (response == GTK_RESPONSE_OK) {
404 ModestWindow *main_window = NULL;
405 ModestWindowMgr *mgr = NULL;
406 GtkTreeModel *model = NULL;
407 GtkTreeSelection *sel = NULL;
408 GList *sel_list = NULL, *tmp = NULL;
409 GtkTreeRowReference *row_reference = NULL;
410 GtkTreePath *next_path = NULL;
411 TnyFolder *folder = NULL;
414 /* Find last selected row */
415 if (MODEST_IS_MAIN_WINDOW (win)) {
416 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
417 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
418 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
419 for (tmp=sel_list; tmp; tmp=tmp->next) {
420 if (tmp->next == NULL) {
421 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
422 gtk_tree_path_next (next_path);
423 row_reference = gtk_tree_row_reference_new (model, next_path);
424 gtk_tree_path_free (next_path);
429 /* Remove each header. If it's a view window header_view == NULL */
430 do_headers_action (win, headers_action_delete, header_view);
432 /* refresh the header view (removing marked-as-deleted)*/
433 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
435 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
436 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
438 /* Get main window */
439 mgr = modest_runtime_get_window_mgr ();
440 main_window = modest_window_mgr_get_main_window (mgr);
443 /* Move cursor to next row */
446 /* Select next row */
447 if (gtk_tree_row_reference_valid (row_reference)) {
448 next_path = gtk_tree_row_reference_get_path (row_reference);
449 gtk_tree_selection_select_path (sel, next_path);
450 gtk_tree_path_free (next_path);
452 if (row_reference != NULL)
453 gtk_tree_row_reference_free (row_reference);
456 /* Get folder from first header and sync it */
457 iter = tny_list_create_iterator (header_list);
458 header = TNY_HEADER (tny_iterator_get_current (iter));
459 folder = tny_header_get_folder (header);
460 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
461 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
462 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
463 else if (TNY_IS_CAMEL_POP_FOLDER (folder))
464 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
465 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
468 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
469 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
472 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
476 g_object_unref (header);
477 g_object_unref (iter);
478 g_object_unref (folder);
480 /* Update toolbar dimming state */
481 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
484 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
485 g_list_free (sel_list);
491 g_object_unref (header_list);
497 /* delete either message or folder, based on where we are */
499 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
501 g_return_if_fail (MODEST_IS_WINDOW(win));
503 /* Check first if the header view has the focus */
504 if (MODEST_IS_MAIN_WINDOW (win)) {
506 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
507 MODEST_WIDGET_TYPE_FOLDER_VIEW);
508 if (gtk_widget_is_focus (w)) {
509 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
513 modest_ui_actions_on_delete_message (action, win);
519 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
521 #ifdef MODEST_PLATFORM_MAEMO
522 modest_osso_save_state();
523 #endif /* MODEST_PLATFORM_MAEMO */
525 g_debug ("closing down, clearing %d item(s) from operation queue",
526 modest_mail_operation_queue_num_elements
527 (modest_runtime_get_mail_operation_queue()));
529 /* cancel all outstanding operations */
530 modest_mail_operation_queue_cancel_all
531 (modest_runtime_get_mail_operation_queue());
533 g_debug ("queue has been cleared");
535 /* note: when modest-tny-account-store is finalized,
536 it will automatically set all network connections
543 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
547 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
549 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
550 /* gtk_widget_destroy (GTK_WIDGET (win)); */
551 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
552 /* gboolean ret_value; */
553 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
554 /* } else if (MODEST_IS_WINDOW (win)) { */
555 /* gtk_widget_destroy (GTK_WIDGET (win)); */
557 /* g_return_if_reached (); */
562 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
564 GtkClipboard *clipboard = NULL;
565 gchar *selection = NULL;
567 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
568 selection = gtk_clipboard_wait_for_text (clipboard);
570 /* Question: why is the clipboard being used here?
571 * It doesn't really make a lot of sense. */
575 modest_address_book_add_address (selection);
581 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
583 /* This is currently only implemented for Maemo */
584 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
585 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
586 modest_run_account_setup_wizard (win);
589 /* Show the list of accounts: */
590 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
591 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
593 /* Don't make this a modal window, because secondary windows will then
594 * be unusable, freezing the UI: */
595 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
596 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
599 GtkWidget *dialog, *label;
601 /* Create the widgets */
603 dialog = gtk_dialog_new_with_buttons ("Message",
605 GTK_DIALOG_DESTROY_WITH_PARENT,
609 label = gtk_label_new ("Hello World!");
611 /* Ensure that the dialog box is destroyed when the user responds. */
613 g_signal_connect_swapped (dialog, "response",
614 G_CALLBACK (gtk_widget_destroy),
617 /* Add the label, and show everything we've added to the dialog. */
619 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
621 gtk_widget_show_all (dialog);
622 #endif /* MODEST_PLATFORM_MAEMO */
626 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
628 ModestWindow *main_window = MODEST_WINDOW (user_data);
630 /* Save any changes. */
631 modest_connection_specific_smtp_window_save_server_accounts (
632 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
633 modest_window_get_active_account (main_window));
634 gtk_widget_destroy (GTK_WIDGET (window));
640 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
642 /* This is currently only implemented for Maemo,
643 * because it requires an API (libconic) to detect different connection
646 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
648 /* Create the window if necessary: */
649 const gchar *active_account_name = modest_window_get_active_account (win);
651 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
652 * or show the default account?
653 * If we show the default account then the account name should be shown in
654 * the window when we show it. */
655 if (!active_account_name) {
656 g_warning ("%s: No account is active.", __FUNCTION__);
660 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
661 modest_connection_specific_smtp_window_fill_with_connections (
662 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
663 modest_runtime_get_account_mgr(),
664 active_account_name);
666 /* Show the window: */
667 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
668 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
669 gtk_widget_show (specific_window);
671 /* Save changes when the window is hidden: */
672 g_signal_connect (specific_window, "hide",
673 G_CALLBACK (on_smtp_servers_window_hide), win);
674 #endif /* MODEST_PLATFORM_MAEMO */
678 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
680 ModestWindow *msg_win = NULL;
682 TnyFolder *folder = NULL;
683 gchar *account_name = NULL;
684 gchar *from_str = NULL;
685 /* GError *err = NULL; */
686 TnyAccount *account = NULL;
687 ModestWindowMgr *mgr;
688 gchar *signature = NULL, *blank_and_signature = NULL;
690 /* if there are no accounts yet, just show the wizard */
691 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
692 const gboolean created = modest_run_account_setup_wizard (win);
697 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
699 account_name = g_strdup (modest_window_get_active_account (win));
701 g_printerr ("modest: no account found\n");
705 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
707 TNY_ACCOUNT_TYPE_STORE);
709 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
713 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
715 g_printerr ("modest: failed get from string for '%s'\n", account_name);
719 gboolean use_signature = FALSE;
720 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
723 blank_and_signature = g_strconcat ("\n", signature, NULL);
725 blank_and_signature = g_strdup ("");
730 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
732 g_printerr ("modest: failed to create new msg\n");
736 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
738 g_printerr ("modest: failed to find Drafts folder\n");
743 /* Create and register edit window */
744 /* This is destroyed by TODO. */
745 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
746 mgr = modest_runtime_get_window_mgr ();
747 modest_window_mgr_register_window (mgr, msg_win);
750 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
752 gtk_widget_show_all (GTK_WIDGET (msg_win));
755 g_free (account_name);
757 g_free (blank_and_signature);
759 g_object_unref (msg_win);
761 g_object_unref (G_OBJECT(account));
763 g_object_unref (G_OBJECT(msg));
765 g_object_unref (G_OBJECT(folder));
769 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
773 ModestMailOperationStatus status;
775 /* If there is no message or the operation was not successful */
776 status = modest_mail_operation_get_status (mail_op);
777 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
779 /* Remove the header from the preregistered uids */
780 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
790 open_msg_cb (ModestMailOperation *mail_op,
795 ModestWindowMgr *mgr = NULL;
796 ModestWindow *parent_win = NULL;
797 ModestWindow *win = NULL;
798 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
799 gchar *account = NULL;
802 /* Do nothing if there was any problem with the mail
803 operation. The error will be shown by the error_handler of
804 the mail operation */
805 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
809 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
810 folder = tny_header_get_folder (header);
812 /* Mark header as read */
813 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
816 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
818 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
820 /* Gets folder type (OUTBOX headers will be opened in edit window */
821 if (modest_tny_folder_is_local_folder (folder))
822 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
824 /* If the header is in the drafts folder then open the editor,
825 else the message view window */
826 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
827 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
828 /* we cannot edit without a valid account... */
829 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
830 const gboolean created = modest_run_account_setup_wizard(parent_win);
834 win = modest_msg_edit_window_new (msg, account, TRUE);
837 gchar *uid = modest_tny_folder_get_header_unique_id (header);
839 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
840 GtkWidget *header_view;
841 GtkTreeSelection *sel;
842 GList *sel_list = NULL;
845 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
846 MODEST_WIDGET_TYPE_HEADER_VIEW);
848 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
849 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
851 if (sel_list != NULL) {
852 GtkTreeRowReference *row_reference;
854 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
855 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
856 g_list_free (sel_list);
858 win = modest_msg_view_window_new_with_header_model (
859 msg, account, (const gchar*) uid,
860 model, row_reference);
861 gtk_tree_row_reference_free (row_reference);
863 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
866 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
871 /* Register and show new window */
873 mgr = modest_runtime_get_window_mgr ();
874 modest_window_mgr_register_window (mgr, win);
875 g_object_unref (win);
876 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
877 gtk_widget_show_all (GTK_WIDGET(win));
880 /* Update toolbar dimming state */
881 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
882 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
888 g_object_unref (parent_win);
889 g_object_unref (folder);
893 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
897 GObject *win = modest_mail_operation_get_source (mail_op);
899 error = modest_mail_operation_get_error (mail_op);
900 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
902 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
904 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
907 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
908 _("mail_ni_ui_folder_get_msg_folder_error"));
912 g_object_unref (win);
916 * This function is used by both modest_ui_actions_on_open and
917 * modest_ui_actions_on_header_activated. This way we always do the
918 * same when trying to open messages.
921 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
923 ModestWindowMgr *mgr = NULL;
924 TnyIterator *iter = NULL;
925 ModestMailOperation *mail_op = NULL;
926 TnyList *not_opened_headers = NULL;
927 TnyHeaderFlags flags = 0;
929 /* Look if we already have a message view for each header. If
930 true, then remove the header from the list of headers to
932 mgr = modest_runtime_get_window_mgr ();
933 iter = tny_list_create_iterator (headers);
934 not_opened_headers = tny_simple_list_new ();
936 while (!tny_iterator_is_done (iter)) {
938 ModestWindow *window = NULL;
939 TnyHeader *header = NULL;
940 gboolean found = FALSE;
942 header = TNY_HEADER (tny_iterator_get_current (iter));
944 flags = tny_header_get_flags (header);
947 found = modest_window_mgr_find_registered_header (mgr, header, &window);
949 /* Do not open again the message and present the
950 window to the user */
953 gtk_window_present (GTK_WINDOW (window));
955 /* the header has been registered already, we don't do
956 * anything but wait for the window to come up*/
957 g_debug ("header %p already registered, waiting for window", header);
959 tny_list_append (not_opened_headers, G_OBJECT (header));
963 g_object_unref (header);
965 tny_iterator_next (iter);
967 g_object_unref (iter);
970 /* If some messages would have to be downloaded, ask the user to
971 * make a connection. It's generally easier to do this here (in the mainloop)
972 * than later in a thread:
974 if (tny_list_get_length (not_opened_headers) > 0) {
976 gboolean found = FALSE;
978 iter = tny_list_create_iterator (not_opened_headers);
979 while (!tny_iterator_is_done (iter) && !found) {
980 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
981 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
984 tny_iterator_next (iter);
986 g_object_unref (header);
988 g_object_unref (iter);
990 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
991 g_object_unref (not_opened_headers);
996 /* Register the headers before actually creating the windows: */
997 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
998 while (!tny_iterator_is_done (iter_not_opened)) {
999 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1001 modest_window_mgr_register_header (mgr, header);
1002 g_object_unref (header);
1005 tny_iterator_next (iter_not_opened);
1007 g_object_unref (iter_not_opened);
1008 iter_not_opened = NULL;
1010 /* Open each message */
1011 if (tny_list_get_length (not_opened_headers) > 0) {
1012 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1014 modest_ui_actions_get_msgs_full_error_handler,
1016 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1017 if (tny_list_get_length (not_opened_headers) > 1) {
1018 modest_mail_operation_get_msgs_full (mail_op,
1024 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1025 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1026 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1027 g_object_unref (header);
1028 g_object_unref (iter);
1030 g_object_unref (mail_op);
1034 if (not_opened_headers != NULL)
1035 g_object_unref (not_opened_headers);
1039 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1044 headers = get_selected_headers (win);
1049 _modest_ui_actions_open (headers, win);
1051 g_object_unref(headers);
1056 free_reply_forward_helper (gpointer data)
1058 ReplyForwardHelper *helper;
1060 helper = (ReplyForwardHelper *) data;
1061 g_free (helper->account_name);
1062 g_slice_free (ReplyForwardHelper, helper);
1066 reply_forward_cb (ModestMailOperation *mail_op,
1072 ReplyForwardHelper *rf_helper;
1073 ModestWindow *msg_win = NULL;
1074 ModestEditType edit_type;
1076 TnyAccount *account = NULL;
1077 ModestWindowMgr *mgr = NULL;
1078 gchar *signature = NULL;
1080 /* If there was any error. The mail operation could be NULL,
1081 this means that we already have the message downloaded and
1082 that we didn't do a mail operation to retrieve it */
1083 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1086 g_return_if_fail (user_data != NULL);
1087 rf_helper = (ReplyForwardHelper *) user_data;
1089 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1090 rf_helper->account_name);
1091 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1092 rf_helper->account_name,
1093 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1094 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1095 rf_helper->account_name,
1096 MODEST_ACCOUNT_SIGNATURE, FALSE);
1099 /* Create reply mail */
1100 switch (rf_helper->action) {
1103 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1104 rf_helper->reply_forward_type,
1105 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1107 case ACTION_REPLY_TO_ALL:
1109 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1110 MODEST_TNY_MSG_REPLY_MODE_ALL);
1111 edit_type = MODEST_EDIT_TYPE_REPLY;
1113 case ACTION_FORWARD:
1115 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1116 edit_type = MODEST_EDIT_TYPE_FORWARD;
1119 g_return_if_reached ();
1126 g_printerr ("modest: failed to create message\n");
1130 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1131 rf_helper->account_name,
1132 TNY_ACCOUNT_TYPE_STORE);
1134 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1138 /* Create and register the windows */
1139 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1140 mgr = modest_runtime_get_window_mgr ();
1141 modest_window_mgr_register_window (mgr, msg_win);
1143 if (rf_helper->parent_window != NULL) {
1144 gdouble parent_zoom;
1146 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1147 modest_window_set_zoom (msg_win, parent_zoom);
1150 /* Show edit window */
1151 gtk_widget_show_all (GTK_WIDGET (msg_win));
1155 g_object_unref (msg_win);
1157 g_object_unref (G_OBJECT (new_msg));
1159 g_object_unref (G_OBJECT (account));
1160 /* g_object_unref (msg); */
1161 free_reply_forward_helper (rf_helper);
1165 * Checks a list of headers. If any of them are not currently
1166 * downloaded (CACHED) then it asks the user for permission to
1169 * Returns FALSE if the user does not want to download the
1170 * messages. Returns TRUE if the user allowed the download or if all
1171 * of them are currently downloaded
1174 download_uncached_messages (TnyList *header_list,
1179 gint uncached_messages = 0;
1181 iter = tny_list_create_iterator (header_list);
1182 while (!tny_iterator_is_done (iter)) {
1185 header = TNY_HEADER (tny_iterator_get_current (iter));
1187 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1188 uncached_messages ++;
1189 g_object_unref (header);
1192 tny_iterator_next (iter);
1194 g_object_unref (iter);
1196 /* Ask for user permission to download the messages */
1198 if (uncached_messages > 0) {
1199 gboolean download = TRUE;
1200 if (!tny_device_is_online (modest_runtime_get_device())) {
1201 GtkResponseType response =
1202 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1203 ngettext("mcen_nc_get_msg",
1205 uncached_messages));
1206 if (response == GTK_RESPONSE_CANCEL) download = FALSE;
1209 /* If a download will be necessary, make sure that we have a connection: */
1210 retval = modest_platform_connect_and_wait(win, NULL);
1220 * Common code for the reply and forward actions
1223 reply_forward (ReplyForwardAction action, ModestWindow *win)
1225 ModestMailOperation *mail_op = NULL;
1226 TnyList *header_list = NULL;
1227 ReplyForwardHelper *rf_helper = NULL;
1228 guint reply_forward_type;
1229 gboolean continue_download = TRUE;
1230 gboolean do_retrieve = TRUE;
1232 g_return_if_fail (MODEST_IS_WINDOW(win));
1234 /* we need an account when editing */
1235 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1236 const gboolean created = modest_run_account_setup_wizard (win);
1241 header_list = get_selected_headers (win);
1245 reply_forward_type =
1246 modest_conf_get_int (modest_runtime_get_conf (),
1247 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1250 /* Check that the messages have been previously downloaded */
1251 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1253 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1254 if (!continue_download) {
1255 g_object_unref (header_list);
1259 /* We assume that we can only select messages of the
1260 same folder and that we reply all of them from the
1261 same account. In fact the interface currently only
1262 allows single selection */
1265 rf_helper = g_slice_new0 (ReplyForwardHelper);
1266 rf_helper->reply_forward_type = reply_forward_type;
1267 rf_helper->action = action;
1268 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1270 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1271 rf_helper->parent_window = GTK_WIDGET (win);
1272 if (!rf_helper->account_name)
1273 rf_helper->account_name =
1274 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1276 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1279 /* Get header and message. Do not free them here, the
1280 reply_forward_cb must do it */
1281 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1282 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1283 if (!msg || !header) {
1285 g_object_unref (msg);
1286 g_printerr ("modest: no message found\n");
1289 reply_forward_cb (NULL, header, msg, rf_helper);
1292 g_object_unref (header);
1297 /* Only reply/forward to one message */
1298 iter = tny_list_create_iterator (header_list);
1299 header = TNY_HEADER (tny_iterator_get_current (iter));
1300 g_object_unref (iter);
1303 /* Retrieve messages */
1305 mail_op = modest_mail_operation_new_with_error_handling (
1306 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1308 modest_ui_actions_get_msgs_full_error_handler,
1310 modest_mail_operation_queue_add (
1311 modest_runtime_get_mail_operation_queue (), mail_op);
1313 modest_mail_operation_get_msg (mail_op,
1318 g_object_unref(mail_op);
1320 /* we put a ref here to prevent double unref as the reply
1321 * forward callback unrefs the header at its end */
1322 reply_forward_cb (NULL, header, NULL, rf_helper);
1326 g_object_unref (header);
1332 g_object_unref (header_list);
1336 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1338 g_return_if_fail (MODEST_IS_WINDOW(win));
1340 reply_forward (ACTION_REPLY, win);
1344 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1346 g_return_if_fail (MODEST_IS_WINDOW(win));
1348 reply_forward (ACTION_FORWARD, win);
1352 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1354 g_return_if_fail (MODEST_IS_WINDOW(win));
1356 reply_forward (ACTION_REPLY_TO_ALL, win);
1360 modest_ui_actions_on_next (GtkAction *action,
1361 ModestWindow *window)
1363 if (MODEST_IS_MAIN_WINDOW (window)) {
1364 GtkWidget *header_view;
1366 header_view = modest_main_window_get_child_widget (
1367 MODEST_MAIN_WINDOW(window),
1368 MODEST_WIDGET_TYPE_HEADER_VIEW);
1372 modest_header_view_select_next (
1373 MODEST_HEADER_VIEW(header_view));
1374 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1375 modest_msg_view_window_select_next_message (
1376 MODEST_MSG_VIEW_WINDOW (window));
1378 g_return_if_reached ();
1383 modest_ui_actions_on_prev (GtkAction *action,
1384 ModestWindow *window)
1386 g_return_if_fail (MODEST_IS_WINDOW(window));
1388 if (MODEST_IS_MAIN_WINDOW (window)) {
1389 GtkWidget *header_view;
1390 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1391 MODEST_WIDGET_TYPE_HEADER_VIEW);
1395 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1396 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1397 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1399 g_return_if_reached ();
1404 modest_ui_actions_on_sort (GtkAction *action,
1405 ModestWindow *window)
1407 g_return_if_fail (MODEST_IS_WINDOW(window));
1409 if (MODEST_IS_MAIN_WINDOW (window)) {
1410 GtkWidget *header_view;
1411 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1412 MODEST_WIDGET_TYPE_HEADER_VIEW);
1414 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1419 /* Show sorting dialog */
1420 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1425 new_messages_arrived (ModestMailOperation *self,
1429 ModestMainWindow *win = NULL;
1430 GtkWidget *folder_view = NULL;
1431 TnyFolderStore *folder = NULL;
1432 gboolean folder_empty = FALSE;
1434 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1435 win = MODEST_MAIN_WINDOW (user_data);
1437 /* Set contents style of headers view */
1438 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1439 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1440 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1441 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1444 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1447 modest_main_window_set_contents_style (win,
1448 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1451 /* Notify new messages have been downloaded */
1452 if (new_messages > 0)
1453 modest_platform_on_new_msg ();
1457 * This function performs the send & receive required actions. The
1458 * window is used to create the mail operation. Typically it should
1459 * always be the main window, but we pass it as argument in order to
1463 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1465 gchar *acc_name = NULL;
1466 ModestMailOperation *mail_op;
1468 /* If no account name was provided then get the current account, and if
1469 there is no current account then pick the default one: */
1470 if (!account_name) {
1471 acc_name = g_strdup (modest_window_get_active_account(win));
1473 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1475 g_printerr ("modest: cannot get default account\n");
1479 acc_name = g_strdup (account_name);
1482 /* Set send/receive operation in progress */
1483 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1485 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1487 modest_ui_actions_send_receive_error_handler,
1490 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1491 G_CALLBACK (_on_send_receive_progress_changed),
1494 /* Send & receive. */
1495 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1496 /* Receive and then send. The operation is tagged initially as
1497 a receive operation because the account update performs a
1498 receive and then a send. The operation changes its type
1499 internally, so the progress objects will receive the proper
1500 progress information */
1501 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1502 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1503 g_object_unref (G_OBJECT (mail_op));
1511 modest_ui_actions_do_cancel_send (const gchar *account_name,
1514 TnyTransportAccount *transport_account;
1515 TnySendQueue *send_queue = NULL;
1516 GError *error = NULL;
1518 /* Get transport account */
1520 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1521 (modest_runtime_get_account_store(),
1523 TNY_ACCOUNT_TYPE_TRANSPORT));
1524 if (!transport_account) {
1525 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1530 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1531 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1532 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1533 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1534 "modest: could not find send queue for account\n");
1536 /* Keeep messages in outbox folder */
1537 tny_send_queue_cancel (send_queue, FALSE, &error);
1541 if (transport_account != NULL)
1542 g_object_unref (G_OBJECT (transport_account));
1546 modest_ui_actions_cancel_send_all (ModestWindow *win)
1548 GSList *account_names, *iter;
1550 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1553 iter = account_names;
1555 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1556 iter = g_slist_next (iter);
1559 modest_account_mgr_free_account_names (account_names);
1560 account_names = NULL;
1564 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1567 /* Check if accounts exist */
1568 gboolean accounts_exist =
1569 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1571 /* If not, allow the user to create an account before trying to send/receive. */
1572 if (!accounts_exist)
1573 modest_ui_actions_on_accounts (NULL, win);
1575 /* Cancel all sending operaitons */
1576 modest_ui_actions_cancel_send_all (win);
1580 * Refreshes all accounts. This function will be used by automatic
1584 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1586 GSList *account_names, *iter;
1588 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1591 iter = account_names;
1593 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1594 iter = g_slist_next (iter);
1597 modest_account_mgr_free_account_names (account_names);
1598 account_names = NULL;
1602 modest_do_refresh_current_folder(ModestWindow *win)
1604 /* Refresh currently selected folder. Note that if we only
1605 want to retreive the headers, then the refresh only will
1606 invoke a poke_status over all folders, i.e., only the
1607 total/unread count will be updated */
1608 if (MODEST_IS_MAIN_WINDOW (win)) {
1609 GtkWidget *header_view, *folder_view;
1610 TnyFolderStore *folder_store;
1612 /* Get folder and header view */
1614 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1615 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1617 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1619 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1621 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1622 MODEST_WIDGET_TYPE_HEADER_VIEW);
1624 /* We do not need to set the contents style
1625 because it hasn't changed. We also do not
1626 need to save the widget status. Just force
1628 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1629 TNY_FOLDER (folder_store),
1630 folder_refreshed_cb,
1631 MODEST_MAIN_WINDOW (win));
1635 g_object_unref (folder_store);
1641 * Handler of the click on Send&Receive button in the main toolbar
1644 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1646 /* Check if accounts exist */
1647 gboolean accounts_exist =
1648 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1650 /* If not, allow the user to create an account before trying to send/receive. */
1651 if (!accounts_exist)
1652 modest_ui_actions_on_accounts (NULL, win);
1654 modest_do_refresh_current_folder (win);
1656 /* Refresh the active account */
1657 modest_ui_actions_do_send_receive (NULL, win);
1662 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1665 GtkWidget *header_view;
1667 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1669 header_view = modest_main_window_get_child_widget (main_window,
1670 MODEST_WIDGET_TYPE_HEADER_VIEW);
1674 conf = modest_runtime_get_conf ();
1676 /* what is saved/restored is depending on the style; thus; we save with
1677 * old style, then update the style, and restore for this new style
1679 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1681 if (modest_header_view_get_style
1682 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1683 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1684 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1686 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1687 MODEST_HEADER_VIEW_STYLE_DETAILS);
1689 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1690 MODEST_CONF_HEADER_VIEW_KEY);
1695 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1697 ModestMainWindow *main_window)
1699 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1700 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1702 /* in the case the folder is empty, show the empty folder message and focus
1704 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1705 if (modest_header_view_is_empty (header_view)) {
1706 TnyFolder *folder = modest_header_view_get_folder (header_view);
1707 GtkWidget *folder_view =
1708 modest_main_window_get_child_widget (main_window,
1709 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1711 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1712 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1716 /* If no header has been selected then exit */
1721 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1722 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1724 /* Update Main window title */
1725 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1726 const gchar *subject = tny_header_get_subject (header);
1727 if (subject && strlen(subject) > 0)
1728 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1730 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1733 /* Update toolbar dimming state */
1734 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1738 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1740 ModestMainWindow *main_window)
1744 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1749 headers = tny_simple_list_new ();
1750 tny_list_prepend (headers, G_OBJECT (header));
1752 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1754 g_object_unref (headers);
1758 set_active_account_from_tny_account (TnyAccount *account,
1759 ModestWindow *window)
1761 const gchar *server_acc_name = tny_account_get_id (account);
1763 /* We need the TnyAccount provided by the
1764 account store because that is the one that
1765 knows the name of the Modest account */
1766 TnyAccount *modest_server_account = modest_server_account =
1767 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1768 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1771 const gchar *modest_acc_name =
1772 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1773 modest_window_set_active_account (window, modest_acc_name);
1774 g_object_unref (modest_server_account);
1779 folder_refreshed_cb (ModestMailOperation *mail_op,
1783 ModestMainWindow *win = NULL;
1784 GtkWidget *header_view;
1785 TnyFolder *current_folder;
1786 gboolean folder_empty = TRUE;
1787 gboolean all_marked_as_deleted = TRUE;
1789 g_return_if_fail (TNY_IS_FOLDER (folder));
1791 win = MODEST_MAIN_WINDOW (user_data);
1793 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1796 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1797 if (current_folder != NULL && folder != current_folder) {
1802 /* Check if folder is empty and set headers view contents style */
1803 folder_empty = (tny_folder_get_all_count (folder) == 0);
1804 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1805 folder_empty = folder_empty || all_marked_as_deleted ;
1808 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1809 modest_main_window_set_contents_style (win,
1810 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1812 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1817 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1818 TnyFolderStore *folder_store,
1820 ModestMainWindow *main_window)
1823 GtkWidget *header_view;
1825 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1827 header_view = modest_main_window_get_child_widget(main_window,
1828 MODEST_WIDGET_TYPE_HEADER_VIEW);
1832 conf = modest_runtime_get_conf ();
1834 if (TNY_IS_ACCOUNT (folder_store)) {
1836 /* Update active account */
1837 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1838 /* Show account details */
1839 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1842 if (TNY_IS_FOLDER (folder_store) && selected) {
1844 /* Update the active account */
1845 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1847 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1848 g_object_unref (account);
1852 /* Set the header style by default, it could
1853 be changed later by the refresh callback to
1855 modest_main_window_set_contents_style (main_window,
1856 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1858 /* Set folder on header view. This function
1859 will call tny_folder_refresh_async so we
1860 pass a callback that will be called when
1861 finished. We use that callback to set the
1862 empty view if there are no messages */
1863 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1864 TNY_FOLDER (folder_store),
1865 folder_refreshed_cb,
1868 /* Restore configuration. We need to do this
1869 *after* the set_folder because the widget
1870 memory asks the header view about its
1872 modest_widget_memory_restore (modest_runtime_get_conf (),
1873 G_OBJECT(header_view),
1874 MODEST_CONF_HEADER_VIEW_KEY);
1876 /* Update the active account */
1877 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1878 /* Save only if we're seeing headers */
1879 if (modest_main_window_get_contents_style (main_window) ==
1880 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1881 modest_widget_memory_save (conf, G_OBJECT (header_view),
1882 MODEST_CONF_HEADER_VIEW_KEY);
1883 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1887 /* Update toolbar dimming state */
1888 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1892 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1899 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1901 online = tny_device_is_online (modest_runtime_get_device());
1904 /* already online -- the item is simply not there... */
1905 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1907 GTK_MESSAGE_WARNING,
1909 _("The %s you selected cannot be found"),
1911 gtk_dialog_run (GTK_DIALOG(dialog));
1913 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1917 GTK_RESPONSE_REJECT,
1919 GTK_RESPONSE_ACCEPT,
1921 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1922 "Do you want to get online?"), item);
1923 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1924 gtk_label_new (txt), FALSE, FALSE, 0);
1925 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1928 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1929 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1930 /* TODO: Comment about why is this commented out: */
1931 /* modest_platform_connect_and_wait (); */
1934 gtk_widget_destroy (dialog);
1938 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1941 /* g_message ("%s %s", __FUNCTION__, link); */
1946 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1949 modest_platform_activate_uri (link);
1953 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1956 modest_platform_show_uri_popup (link);
1960 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1963 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1967 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1968 const gchar *address,
1971 /* g_message ("%s %s", __FUNCTION__, address); */
1975 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1977 TnyTransportAccount *transport_account;
1978 ModestMailOperation *mail_operation;
1980 gchar *account_name, *from;
1981 ModestAccountMgr *account_mgr;
1982 gchar *info_text = NULL;
1984 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1986 data = modest_msg_edit_window_get_msg_data (edit_window);
1988 account_mgr = modest_runtime_get_account_mgr();
1989 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1991 account_name = modest_account_mgr_get_default_account (account_mgr);
1992 if (!account_name) {
1993 g_printerr ("modest: no account found\n");
1994 modest_msg_edit_window_free_msg_data (edit_window, data);
1998 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1999 account_name = g_strdup (data->account_name);
2003 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2004 (modest_runtime_get_account_store(),
2006 TNY_ACCOUNT_TYPE_TRANSPORT));
2007 if (!transport_account) {
2008 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2009 g_free (account_name);
2010 modest_msg_edit_window_free_msg_data (edit_window, data);
2013 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2015 /* Create the mail operation */
2016 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2017 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2019 modest_mail_operation_save_to_drafts (mail_operation,
2031 data->priority_flags);
2034 g_free (account_name);
2035 g_object_unref (G_OBJECT (transport_account));
2036 g_object_unref (G_OBJECT (mail_operation));
2038 modest_msg_edit_window_free_msg_data (edit_window, data);
2040 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2041 modest_platform_information_banner (NULL, NULL, info_text);
2045 /* For instance, when clicking the Send toolbar button when editing a message: */
2047 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2049 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2051 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2054 /* Offer the connection dialog, if necessary: */
2055 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2058 /* FIXME: Code added just for testing. The final version will
2059 use the send queue provided by tinymail and some
2061 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2062 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2064 account_name = modest_account_mgr_get_default_account (account_mgr);
2066 if (!account_name) {
2067 /* Run account setup wizard */
2068 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2073 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2075 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2076 account_name = g_strdup (data->account_name);
2079 /* Get the currently-active transport account for this modest account: */
2080 TnyTransportAccount *transport_account =
2081 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2082 (modest_runtime_get_account_store(),
2084 if (!transport_account) {
2085 /* Run account setup wizard */
2086 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2091 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2093 /* mail content checks and dialogs */
2094 if (data->subject == NULL || data->subject[0] == '\0') {
2095 GtkResponseType response;
2096 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2097 _("mcen_nc_subject_is_empty_send"));
2098 if (response == GTK_RESPONSE_CANCEL) {
2099 g_free (account_name);
2104 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2105 GtkResponseType response;
2106 gchar *note_message;
2107 gchar *note_subject = data->subject;
2108 if (note_subject == NULL || note_subject[0] == '\0')
2109 note_subject = _("mail_va_no_subject");
2110 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2111 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2113 g_free (note_message);
2114 if (response == GTK_RESPONSE_CANCEL) {
2115 g_free (account_name);
2120 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2122 /* Create the mail operation */
2123 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2124 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2126 modest_mail_operation_send_new_mail (mail_operation,
2137 data->priority_flags);
2141 g_free (account_name);
2142 g_object_unref (G_OBJECT (transport_account));
2143 g_object_unref (G_OBJECT (mail_operation));
2145 modest_msg_edit_window_free_msg_data (edit_window, data);
2146 modest_msg_edit_window_set_sent (edit_window, TRUE);
2148 /* Save settings and close the window: */
2149 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2153 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2154 ModestMsgEditWindow *window)
2156 ModestMsgEditFormatState *format_state = NULL;
2158 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2159 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2161 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2164 format_state = modest_msg_edit_window_get_format_state (window);
2165 g_return_if_fail (format_state != NULL);
2167 format_state->bold = gtk_toggle_action_get_active (action);
2168 modest_msg_edit_window_set_format_state (window, format_state);
2169 g_free (format_state);
2174 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2175 ModestMsgEditWindow *window)
2177 ModestMsgEditFormatState *format_state = NULL;
2179 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2180 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2182 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2185 format_state = modest_msg_edit_window_get_format_state (window);
2186 g_return_if_fail (format_state != NULL);
2188 format_state->italics = gtk_toggle_action_get_active (action);
2189 modest_msg_edit_window_set_format_state (window, format_state);
2190 g_free (format_state);
2195 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2196 ModestMsgEditWindow *window)
2198 ModestMsgEditFormatState *format_state = NULL;
2200 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2201 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2203 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2206 format_state = modest_msg_edit_window_get_format_state (window);
2207 g_return_if_fail (format_state != NULL);
2209 format_state->bullet = gtk_toggle_action_get_active (action);
2210 modest_msg_edit_window_set_format_state (window, format_state);
2211 g_free (format_state);
2216 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2217 GtkRadioAction *selected,
2218 ModestMsgEditWindow *window)
2220 ModestMsgEditFormatState *format_state = NULL;
2221 GtkJustification value;
2223 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2225 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2228 value = gtk_radio_action_get_current_value (selected);
2230 format_state = modest_msg_edit_window_get_format_state (window);
2231 g_return_if_fail (format_state != NULL);
2233 format_state->justification = value;
2234 modest_msg_edit_window_set_format_state (window, format_state);
2235 g_free (format_state);
2239 modest_ui_actions_on_select_editor_color (GtkAction *action,
2240 ModestMsgEditWindow *window)
2242 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2243 g_return_if_fail (GTK_IS_ACTION (action));
2245 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2248 modest_msg_edit_window_select_color (window);
2252 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2253 ModestMsgEditWindow *window)
2255 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2256 g_return_if_fail (GTK_IS_ACTION (action));
2258 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2261 modest_msg_edit_window_select_background_color (window);
2265 modest_ui_actions_on_insert_image (GtkAction *action,
2266 ModestMsgEditWindow *window)
2268 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2269 g_return_if_fail (GTK_IS_ACTION (action));
2271 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2274 modest_msg_edit_window_insert_image (window);
2278 modest_ui_actions_on_attach_file (GtkAction *action,
2279 ModestMsgEditWindow *window)
2281 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2282 g_return_if_fail (GTK_IS_ACTION (action));
2284 modest_msg_edit_window_offer_attach_file (window);
2288 modest_ui_actions_on_remove_attachments (GtkAction *action,
2289 ModestMsgEditWindow *window)
2291 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2292 g_return_if_fail (GTK_IS_ACTION (action));
2294 modest_msg_edit_window_remove_attachments (window, NULL);
2298 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2301 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2302 const GError *error = modest_mail_operation_get_error (mail_op);
2306 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2307 modest_mail_operation_get_error (mail_op)->message);
2312 modest_ui_actions_create_folder(GtkWidget *parent_window,
2313 GtkWidget *folder_view)
2315 TnyFolderStore *parent_folder;
2317 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2319 if (parent_folder) {
2320 gboolean finished = FALSE;
2322 gchar *folder_name = NULL, *suggested_name = NULL;
2323 const gchar *proto_str = NULL;
2324 TnyAccount *account;
2326 if (TNY_IS_ACCOUNT (parent_folder))
2327 account = g_object_ref (parent_folder);
2329 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2330 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2332 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2333 MODEST_PROTOCOL_STORE_POP) {
2335 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2337 g_object_unref (account);
2339 /* Run the new folder dialog */
2341 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2346 g_free (suggested_name);
2347 suggested_name = NULL;
2349 if (result == GTK_RESPONSE_REJECT) {
2352 ModestMailOperation *mail_op;
2353 TnyFolder *new_folder = NULL;
2355 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2356 G_OBJECT(parent_window),
2357 modest_ui_actions_new_folder_error_handler,
2360 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2362 new_folder = modest_mail_operation_create_folder (mail_op,
2364 (const gchar *) folder_name);
2366 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2369 g_object_unref (new_folder);
2372 g_object_unref (mail_op);
2375 suggested_name = folder_name;
2379 g_object_unref (parent_folder);
2384 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2386 GtkWidget *folder_view;
2388 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2390 folder_view = modest_main_window_get_child_widget (main_window,
2391 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2395 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2399 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2402 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2403 const GError *error = NULL;
2404 const gchar *message = NULL;
2406 /* Get error message */
2407 error = modest_mail_operation_get_error (mail_op);
2408 if (error != NULL && error->message != NULL) {
2409 message = error->message;
2411 message = _("!!! FIXME: Unable to rename");
2414 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2419 modest_ui_actions_on_rename_folder (GtkAction *action,
2420 ModestMainWindow *main_window)
2422 TnyFolderStore *folder;
2423 GtkWidget *folder_view;
2424 GtkWidget *header_view;
2426 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2428 folder_view = modest_main_window_get_child_widget (main_window,
2429 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2433 header_view = modest_main_window_get_child_widget (main_window,
2434 MODEST_WIDGET_TYPE_HEADER_VIEW);
2439 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2443 /* Offer the connection dialog if necessary: */
2444 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2445 g_object_unref (G_OBJECT (folder));
2450 if (TNY_IS_FOLDER (folder)) {
2453 const gchar *current_name;
2455 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2456 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2457 current_name, &folder_name);
2459 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2460 ModestMailOperation *mail_op;
2463 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2464 G_OBJECT(main_window),
2465 modest_ui_actions_rename_folder_error_handler,
2468 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2471 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2473 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2474 TNY_FOLDER(folder), TRUE);
2476 modest_header_view_clear ((ModestHeaderView *) header_view);
2478 modest_mail_operation_rename_folder (mail_op,
2479 TNY_FOLDER (folder),
2480 (const gchar *) folder_name);
2482 g_object_unref (mail_op);
2483 g_free (folder_name);
2486 g_object_unref (folder);
2490 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2493 GObject *win = modest_mail_operation_get_source (mail_op);
2495 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2496 _("mail_in_ui_folder_delete_error"));
2497 g_object_unref (win);
2501 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2503 TnyFolderStore *folder;
2504 GtkWidget *folder_view;
2508 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2510 folder_view = modest_main_window_get_child_widget (main_window,
2511 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2515 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2517 /* Show an error if it's an account */
2518 if (!TNY_IS_FOLDER (folder)) {
2519 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2520 _("mail_in_ui_folder_delete_error"));
2521 g_object_unref (G_OBJECT (folder));
2525 /* Offer the connection dialog if necessary: */
2526 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2527 g_object_unref (G_OBJECT (folder));
2532 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2533 tny_folder_get_name (TNY_FOLDER (folder)));
2534 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2535 (const gchar *) message);
2538 if (response == GTK_RESPONSE_OK) {
2539 ModestMailOperation *mail_op =
2540 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2541 G_OBJECT(main_window),
2542 modest_ui_actions_delete_folder_error_handler,
2545 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2547 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2548 g_object_unref (G_OBJECT (mail_op));
2551 g_object_unref (G_OBJECT (folder));
2555 modest_ui_actions_on_delete_folder (GtkAction *action,
2556 ModestMainWindow *main_window)
2558 GtkWidget *folder_view;
2559 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2561 delete_folder (main_window, FALSE);
2562 folder_view = modest_main_window_get_child_widget (main_window,
2563 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2566 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2570 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2572 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2574 delete_folder (main_window, TRUE);
2579 show_error (GtkWidget *parent_widget, const gchar* text)
2581 hildon_banner_show_information(parent_widget, NULL, text);
2584 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2586 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2593 gtk_dialog_run (dialog);
2594 gtk_widget_destroy (GTK_WIDGET (dialog));
2599 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2600 const gchar* server_account_name,
2605 ModestMainWindow *main_window)
2607 g_return_if_fail(server_account_name);
2608 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2610 /* Initalize output parameters: */
2617 #ifdef MODEST_PLATFORM_MAEMO
2618 /* Maemo uses a different (awkward) button order,
2619 * It should probably just use gtk_alternative_dialog_button_order ().
2621 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2625 GTK_RESPONSE_ACCEPT,
2627 GTK_RESPONSE_REJECT,
2630 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2634 GTK_RESPONSE_REJECT,
2636 GTK_RESPONSE_ACCEPT,
2638 #endif /* MODEST_PLATFORM_MAEMO */
2640 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2642 gchar *server_name = modest_server_account_get_hostname (
2643 modest_runtime_get_account_mgr(), server_account_name);
2644 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2645 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2650 /* This causes a warning because the logical ID has no %s in it,
2651 * though the translation does, but there is not much we can do about that: */
2652 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2653 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2656 g_free (server_name);
2660 gchar *initial_username = modest_server_account_get_username (
2661 modest_runtime_get_account_mgr(), server_account_name);
2663 GtkWidget *entry_username = gtk_entry_new ();
2664 if (initial_username)
2665 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2666 /* Dim this if a connection has ever succeeded with this username,
2667 * as per the UI spec: */
2668 const gboolean username_known =
2669 modest_server_account_get_username_has_succeeded(
2670 modest_runtime_get_account_mgr(), server_account_name);
2671 gtk_widget_set_sensitive (entry_username, !username_known);
2673 #ifdef MODEST_PLATFORM_MAEMO
2674 /* Auto-capitalization is the default, so let's turn it off: */
2675 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2677 /* Create a size group to be used by all captions.
2678 * Note that HildonCaption does not create a default size group if we do not specify one.
2679 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2680 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2682 GtkWidget *caption = hildon_caption_new (sizegroup,
2683 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2684 gtk_widget_show (entry_username);
2685 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2686 FALSE, FALSE, MODEST_MARGIN_HALF);
2687 gtk_widget_show (caption);
2689 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2691 #endif /* MODEST_PLATFORM_MAEMO */
2694 GtkWidget *entry_password = gtk_entry_new ();
2695 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2696 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2698 #ifdef MODEST_PLATFORM_MAEMO
2699 /* Auto-capitalization is the default, so let's turn it off: */
2700 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2701 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2703 caption = hildon_caption_new (sizegroup,
2704 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2705 gtk_widget_show (entry_password);
2706 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2707 FALSE, FALSE, MODEST_MARGIN_HALF);
2708 gtk_widget_show (caption);
2709 g_object_unref (sizegroup);
2711 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2713 #endif /* MODEST_PLATFORM_MAEMO */
2715 /* This is not in the Maemo UI spec:
2716 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2717 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2721 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2723 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2725 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2727 modest_server_account_set_username (
2728 modest_runtime_get_account_mgr(), server_account_name,
2731 const gboolean username_was_changed =
2732 (strcmp (*username, initial_username) != 0);
2733 if (username_was_changed) {
2734 g_warning ("%s: tinymail does not yet support changing the "
2735 "username in the get_password() callback.\n", __FUNCTION__);
2740 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2742 /* We do not save the password in the configuration,
2743 * because this function is only called for passwords that should
2744 * not be remembered:
2745 modest_server_account_set_password (
2746 modest_runtime_get_account_mgr(), server_account_name,
2755 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2767 /* This is not in the Maemo UI spec:
2768 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2774 gtk_widget_destroy (dialog);
2776 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2780 modest_ui_actions_on_cut (GtkAction *action,
2781 ModestWindow *window)
2783 GtkWidget *focused_widget;
2784 GtkClipboard *clipboard;
2786 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2787 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2788 if (GTK_IS_EDITABLE (focused_widget)) {
2789 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2790 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2791 gtk_clipboard_store (clipboard);
2792 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2793 GtkTextBuffer *buffer;
2795 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2796 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2797 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2798 gtk_clipboard_store (clipboard);
2799 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2800 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2801 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2802 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2807 modest_ui_actions_on_copy (GtkAction *action,
2808 ModestWindow *window)
2810 GtkClipboard *clipboard;
2811 GtkWidget *focused_widget;
2813 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2814 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2816 if (GTK_IS_LABEL (focused_widget)) {
2817 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2818 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2819 gtk_clipboard_store (clipboard);
2820 } else if (GTK_IS_EDITABLE (focused_widget)) {
2821 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2822 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2823 gtk_clipboard_store (clipboard);
2824 } else if (GTK_IS_HTML (focused_widget)) {
2825 gtk_html_copy (GTK_HTML (focused_widget));
2826 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2827 gtk_clipboard_store (clipboard);
2828 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2829 GtkTextBuffer *buffer;
2830 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2831 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2832 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2833 gtk_clipboard_store (clipboard);
2834 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2835 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2836 TnyIterator *iter = tny_list_create_iterator (header_list);
2837 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2839 gboolean ask = FALSE;
2841 TnyFolder *folder = tny_header_get_folder (header);
2842 TnyAccount *account = tny_folder_get_account (folder);
2843 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2844 /* If it's POP then ask */
2845 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2846 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2847 g_object_unref (account);
2848 g_object_unref (folder);
2849 g_object_unref (header);
2852 g_object_unref (iter);
2854 /* Check that the messages have been previously downloaded */
2855 gboolean continue_download = TRUE;
2857 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2858 if (continue_download)
2859 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2860 g_object_unref (header_list);
2861 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2862 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2865 /* Show information banner */
2866 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2871 modest_ui_actions_on_undo (GtkAction *action,
2872 ModestWindow *window)
2874 ModestEmailClipboard *clipboard = NULL;
2876 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2877 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2878 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2879 /* Clear clipboard source */
2880 clipboard = modest_runtime_get_email_clipboard ();
2881 modest_email_clipboard_clear (clipboard);
2884 g_return_if_reached ();
2889 modest_ui_actions_on_redo (GtkAction *action,
2890 ModestWindow *window)
2892 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2893 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2896 g_return_if_reached ();
2902 paste_msgs_cb (const GObject *object, gpointer user_data)
2904 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2905 g_return_if_fail (GTK_IS_WIDGET (user_data));
2907 /* destroy information note */
2908 gtk_widget_destroy (GTK_WIDGET(user_data));
2912 paste_as_attachment_free (gpointer data)
2914 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2916 gtk_widget_destroy (helper->banner);
2917 g_object_unref (helper->banner);
2922 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2927 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2928 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2933 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2938 modest_ui_actions_on_paste (GtkAction *action,
2939 ModestWindow *window)
2941 GtkWidget *focused_widget = NULL;
2942 GtkWidget *inf_note = NULL;
2943 ModestMailOperation *mail_op = NULL;
2945 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2946 if (GTK_IS_EDITABLE (focused_widget)) {
2947 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2948 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2949 ModestEmailClipboard *e_clipboard = NULL;
2950 e_clipboard = modest_runtime_get_email_clipboard ();
2951 if (modest_email_clipboard_cleared (e_clipboard)) {
2952 GtkTextBuffer *buffer;
2953 GtkClipboard *clipboard;
2955 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2956 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2957 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2958 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2959 ModestMailOperation *mail_op;
2960 TnyFolder *src_folder;
2963 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2964 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2965 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2966 _CS("ckct_nw_pasting"));
2967 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2968 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2970 if (helper->banner != NULL) {
2971 g_object_ref (G_OBJECT (helper->banner));
2972 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2973 gtk_widget_show (GTK_WIDGET (helper->banner));
2977 modest_mail_operation_get_msgs_full (mail_op,
2979 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2981 paste_as_attachment_free);
2984 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2985 ModestEmailClipboard *clipboard = NULL;
2986 TnyFolder *src_folder = NULL;
2987 TnyFolderStore *folder_store = NULL;
2988 TnyList *data = NULL;
2989 gboolean delete = FALSE;
2991 /* Check clipboard source */
2992 clipboard = modest_runtime_get_email_clipboard ();
2993 if (modest_email_clipboard_cleared (clipboard))
2996 /* Get elements to paste */
2997 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2999 /* Create a new mail operation */
3000 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3002 /* Get destination folder */
3003 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3005 /* transfer messages */
3009 /* Ask for user confirmation */
3010 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3011 TNY_FOLDER (folder_store),
3015 if (response == GTK_RESPONSE_OK) {
3016 /* Launch notification */
3017 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3018 _CS("ckct_nw_pasting"));
3019 if (inf_note != NULL) {
3020 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3021 gtk_widget_show (GTK_WIDGET(inf_note));
3024 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3025 modest_mail_operation_xfer_msgs (mail_op,
3027 TNY_FOLDER (folder_store),
3032 g_object_unref (mail_op);
3035 } else if (src_folder != NULL) {
3036 /* Launch notification */
3037 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3038 _CS("ckct_nw_pasting"));
3039 if (inf_note != NULL) {
3040 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3041 gtk_widget_show (GTK_WIDGET(inf_note));
3044 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3045 modest_mail_operation_xfer_folder (mail_op,
3055 g_object_unref (data);
3056 if (src_folder != NULL)
3057 g_object_unref (src_folder);
3058 if (folder_store != NULL)
3059 g_object_unref (folder_store);
3065 modest_ui_actions_on_select_all (GtkAction *action,
3066 ModestWindow *window)
3068 GtkWidget *focused_widget;
3070 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3071 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3072 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3073 } else if (GTK_IS_LABEL (focused_widget)) {
3074 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3075 } else if (GTK_IS_EDITABLE (focused_widget)) {
3076 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3077 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3078 GtkTextBuffer *buffer;
3079 GtkTextIter start, end;
3081 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3082 gtk_text_buffer_get_start_iter (buffer, &start);
3083 gtk_text_buffer_get_end_iter (buffer, &end);
3084 gtk_text_buffer_select_range (buffer, &start, &end);
3085 } else if (GTK_IS_HTML (focused_widget)) {
3086 gtk_html_select_all (GTK_HTML (focused_widget));
3087 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3088 GtkWidget *header_view = focused_widget;
3089 GtkTreeSelection *selection = NULL;
3091 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3092 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3093 MODEST_WIDGET_TYPE_HEADER_VIEW);
3095 /* Select all messages */
3096 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3097 gtk_tree_selection_select_all (selection);
3099 /* Set focuse on header view */
3100 gtk_widget_grab_focus (header_view);
3106 modest_ui_actions_on_mark_as_read (GtkAction *action,
3107 ModestWindow *window)
3109 g_return_if_fail (MODEST_IS_WINDOW(window));
3111 /* Mark each header as read */
3112 do_headers_action (window, headers_action_mark_as_read, NULL);
3116 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3117 ModestWindow *window)
3119 g_return_if_fail (MODEST_IS_WINDOW(window));
3121 /* Mark each header as read */
3122 do_headers_action (window, headers_action_mark_as_unread, NULL);
3126 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3127 GtkRadioAction *selected,
3128 ModestWindow *window)
3132 value = gtk_radio_action_get_current_value (selected);
3133 if (MODEST_IS_WINDOW (window)) {
3134 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3138 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3139 GtkRadioAction *selected,
3140 ModestWindow *window)
3142 TnyHeaderFlags flags;
3143 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3145 flags = gtk_radio_action_get_current_value (selected);
3146 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3149 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3150 GtkRadioAction *selected,
3151 ModestWindow *window)
3155 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3157 file_format = gtk_radio_action_get_current_value (selected);
3158 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3163 modest_ui_actions_on_zoom_plus (GtkAction *action,
3164 ModestWindow *window)
3166 g_return_if_fail (MODEST_IS_WINDOW (window));
3168 modest_window_zoom_plus (MODEST_WINDOW (window));
3172 modest_ui_actions_on_zoom_minus (GtkAction *action,
3173 ModestWindow *window)
3175 g_return_if_fail (MODEST_IS_WINDOW (window));
3177 modest_window_zoom_minus (MODEST_WINDOW (window));
3181 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3182 ModestWindow *window)
3184 ModestWindowMgr *mgr;
3185 gboolean fullscreen, active;
3186 g_return_if_fail (MODEST_IS_WINDOW (window));
3188 mgr = modest_runtime_get_window_mgr ();
3190 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3191 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3193 if (active != fullscreen) {
3194 modest_window_mgr_set_fullscreen_mode (mgr, active);
3195 gtk_window_present (GTK_WINDOW (window));
3200 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3201 ModestWindow *window)
3203 ModestWindowMgr *mgr;
3204 gboolean fullscreen;
3206 g_return_if_fail (MODEST_IS_WINDOW (window));
3208 mgr = modest_runtime_get_window_mgr ();
3209 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3210 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3212 gtk_window_present (GTK_WINDOW (window));
3216 * Used by modest_ui_actions_on_details to call do_headers_action
3219 headers_action_show_details (TnyHeader *header,
3220 ModestWindow *window,
3227 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3230 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3231 gtk_widget_show_all (dialog);
3232 gtk_dialog_run (GTK_DIALOG (dialog));
3234 gtk_widget_destroy (dialog);
3238 * Show the folder details in a ModestDetailsDialog widget
3241 show_folder_details (TnyFolder *folder,
3247 dialog = modest_details_dialog_new_with_folder (window, folder);
3250 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3251 gtk_widget_show_all (dialog);
3252 gtk_dialog_run (GTK_DIALOG (dialog));
3254 gtk_widget_destroy (dialog);
3258 * Show the header details in a ModestDetailsDialog widget
3261 modest_ui_actions_on_details (GtkAction *action,
3264 TnyList * headers_list;
3268 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3271 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3274 g_object_unref (msg);
3276 headers_list = get_selected_headers (win);
3280 iter = tny_list_create_iterator (headers_list);
3282 header = TNY_HEADER (tny_iterator_get_current (iter));
3284 headers_action_show_details (header, win, NULL);
3285 g_object_unref (header);
3288 g_object_unref (iter);
3289 g_object_unref (headers_list);
3291 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3292 GtkWidget *folder_view, *header_view;
3294 /* Check which widget has the focus */
3295 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3296 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3297 if (gtk_widget_is_focus (folder_view)) {
3298 TnyFolderStore *folder_store
3299 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3300 if (!folder_store) {
3301 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3304 /* Show only when it's a folder */
3305 /* This function should not be called for account items,
3306 * because we dim the menu item for them. */
3307 if (TNY_IS_FOLDER (folder_store)) {
3308 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3311 g_object_unref (folder_store);
3314 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3315 MODEST_WIDGET_TYPE_HEADER_VIEW);
3316 /* Show details of each header */
3317 do_headers_action (win, headers_action_show_details, header_view);
3323 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3324 ModestMsgEditWindow *window)
3326 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3328 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3332 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3333 ModestMsgEditWindow *window)
3335 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3337 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3341 modest_ui_actions_toggle_folders_view (GtkAction *action,
3342 ModestMainWindow *main_window)
3344 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3346 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3347 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3349 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3353 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3354 ModestWindow *window)
3356 gboolean active, fullscreen = FALSE;
3357 ModestWindowMgr *mgr;
3359 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3361 /* Check if we want to toggle the toolbar vuew in fullscreen
3363 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3364 "ViewShowToolbarFullScreen")) {
3368 /* Toggle toolbar */
3369 mgr = modest_runtime_get_window_mgr ();
3370 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3374 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3375 ModestMsgEditWindow *window)
3377 modest_msg_edit_window_select_font (window);
3381 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3382 const gchar *display_name,
3385 /* Do not change the application name if the widget has not
3386 the focus. This callback could be called even if the folder
3387 view has not the focus, because the handled signal could be
3388 emitted when the folder view is redrawn */
3389 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3391 gtk_window_set_title (window, display_name);
3393 gtk_window_set_title (window, " ");
3398 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3400 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3401 modest_msg_edit_window_select_contacts (window);
3405 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3408 modest_msg_edit_window_check_names (window, FALSE);
3412 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3414 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3415 GTK_WIDGET (user_data));
3419 create_move_to_dialog (GtkWindow *win,
3420 GtkWidget *folder_view,
3421 GtkWidget **tree_view)
3423 GtkWidget *dialog, *scroll;
3424 GtkWidget *new_button;
3426 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3428 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3431 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3432 /* We do this manually so GTK+ does not associate a response ID for
3434 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3435 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3436 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3438 /* Create scrolled window */
3439 scroll = gtk_scrolled_window_new (NULL, NULL);
3440 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3441 GTK_POLICY_AUTOMATIC,
3442 GTK_POLICY_AUTOMATIC);
3444 /* Create folder view */
3445 *tree_view = modest_platform_create_folder_view (NULL);
3447 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3449 /* It could happen that we're trying to move a message from a
3450 window (msg window for example) after the main window was
3451 closed, so we can not just get the model of the folder
3453 if (MODEST_IS_FOLDER_VIEW (folder_view))
3454 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3455 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3457 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3458 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3460 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3462 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3464 /* Add scroll to dialog */
3465 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3466 scroll, TRUE, TRUE, 0);
3468 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3469 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3475 * Returns TRUE if at least one of the headers of the list belongs to
3476 * a message that has been fully retrieved.
3479 has_retrieved_msgs (TnyList *list)
3482 gboolean found = FALSE;
3484 iter = tny_list_create_iterator (list);
3485 while (!tny_iterator_is_done (iter) && !found) {
3487 TnyHeaderFlags flags = 0;
3489 header = TNY_HEADER (tny_iterator_get_current (iter));
3491 flags = tny_header_get_flags (header);
3492 if (flags & TNY_HEADER_FLAG_CACHED)
3493 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3496 g_object_unref (header);
3500 tny_iterator_next (iter);
3502 g_object_unref (iter);
3508 * Shows a confirmation dialog to the user when we're moving messages
3509 * from a remote server to the local storage. Returns the dialog
3510 * response. If it's other kind of movement the it always returns
3514 msgs_move_to_confirmation (GtkWindow *win,
3515 TnyFolder *dest_folder,
3519 gint response = GTK_RESPONSE_OK;
3521 /* If the destination is a local folder (or MMC folder )*/
3522 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3523 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3524 TnyFolder *src_folder = NULL;
3525 TnyIterator *iter = NULL;
3526 TnyHeader *header = NULL;
3528 /* Get source folder */
3529 iter = tny_list_create_iterator (headers);
3530 header = TNY_HEADER (tny_iterator_get_current (iter));
3532 src_folder = tny_header_get_folder (header);
3533 g_object_unref (header);
3536 g_object_unref (iter);
3538 /* if no src_folder, message may be an attahcment */
3539 if (src_folder == NULL)
3540 return GTK_RESPONSE_CANCEL;
3542 /* If the source is a remote folder */
3543 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3544 if (modest_tny_folder_is_remote_folder (src_folder)) {
3545 const gchar *message = NULL;
3546 gboolean cached = has_retrieved_msgs (headers);
3548 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3549 tny_list_get_length (headers));
3551 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3552 tny_list_get_length (headers));
3554 if (cached && !delete)
3555 response = GTK_RESPONSE_OK;
3557 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3558 (const gchar *) message);
3561 g_object_unref (src_folder);
3570 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3572 ModestMsgViewWindow *self = NULL;
3574 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3575 self = MODEST_MSG_VIEW_WINDOW (object);
3577 if (!modest_msg_view_window_select_next_message (self))
3578 if (!modest_msg_view_window_select_previous_message (self))
3579 /* No more messages to view, so close this window */
3580 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3584 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3587 GObject *win = modest_mail_operation_get_source (mail_op);
3588 const GError *error = NULL;
3589 const gchar *message = NULL;
3591 /* Get error message */
3592 error = modest_mail_operation_get_error (mail_op);
3593 if (error != NULL && error->message != NULL) {
3594 message = error->message;
3596 message = _("mail_in_ui_folder_move_target_error");
3599 /* Show notification dialog */
3600 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3601 g_object_unref (win);
3605 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3608 GObject *win = modest_mail_operation_get_source (mail_op);
3609 const GError *error = modest_mail_operation_get_error (mail_op);
3611 g_return_if_fail (error != NULL);
3612 if (error->message != NULL)
3613 g_printerr ("modest: %s\n", error->message);
3615 g_printerr ("modest: unkonw error on send&receive operation");
3617 /* Show error message */
3618 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3619 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3620 /* _CS("sfil_ib_unable_to_receive")); */
3622 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3623 /* _CS("sfil_ib_unable_to_send")); */
3624 g_object_unref (win);
3628 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3635 gint pending_purges = 0;
3636 gboolean some_purged = FALSE;
3637 ModestWindow *win = MODEST_WINDOW (user_data);
3638 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3640 /* If there was any error */
3641 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3642 modest_window_mgr_unregister_header (mgr, header);
3646 /* Once the message has been retrieved for purging, we check if
3647 * it's all ok for purging */
3649 parts = tny_simple_list_new ();
3650 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3651 iter = tny_list_create_iterator (parts);
3653 while (!tny_iterator_is_done (iter)) {
3655 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3656 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3657 if (tny_mime_part_is_purged (part))
3664 g_object_unref (part);
3666 tny_iterator_next (iter);
3669 if (pending_purges>0) {
3671 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3673 if (response == GTK_RESPONSE_OK) {
3674 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3675 tny_iterator_first (iter);
3676 while (!tny_iterator_is_done (iter)) {
3679 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3680 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3681 tny_mime_part_set_purged (part);
3684 g_object_unref (part);
3686 tny_iterator_next (iter);
3689 tny_msg_rewrite_cache (msg);
3692 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3695 /* remove attachments */
3696 tny_iterator_first (iter);
3697 while (!tny_iterator_is_done (iter)) {
3700 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3702 /* One for the reference given by tny_iterator_get_current(): */
3703 g_object_unref (part);
3705 /* TODO: Is this meant to remove the attachment by doing another unref()?
3706 * Otherwise, this seems useless. */
3709 tny_iterator_next (iter);
3711 modest_window_mgr_unregister_header (mgr, header);
3713 g_object_unref (iter);
3714 g_object_unref (parts);
3718 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3719 ModestMainWindow *win)
3721 GtkWidget *header_view;
3722 TnyList *header_list;
3725 TnyHeaderFlags flags;
3726 ModestWindow *msg_view_window = NULL;
3729 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3731 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3732 MODEST_WIDGET_TYPE_HEADER_VIEW);
3734 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3736 if (tny_list_get_length (header_list) == 1) {
3737 iter = tny_list_create_iterator (header_list);
3738 header = TNY_HEADER (tny_iterator_get_current (iter));
3739 g_object_unref (iter);
3744 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3745 header, &msg_view_window);
3746 flags = tny_header_get_flags (header);
3747 if (!(flags & TNY_HEADER_FLAG_CACHED))
3750 if (msg_view_window != NULL)
3751 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3753 /* do nothing; uid was registered before, so window is probably on it's way */
3754 g_warning ("debug: header %p has already been registered", header);
3757 ModestMailOperation *mail_op = NULL;
3758 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3759 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3761 modest_ui_actions_get_msgs_full_error_handler,
3763 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3764 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3766 g_object_unref (mail_op);
3769 g_object_unref (header);
3771 g_object_unref (header_list);
3775 * Utility function that transfer messages from both the main window
3776 * and the msg view window when using the "Move to" dialog
3779 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3782 TnyList *headers = NULL;
3784 TnyAccount *dst_account = NULL;
3785 const gchar *proto_str = NULL;
3786 gboolean dst_is_pop = FALSE;
3788 if (!TNY_IS_FOLDER (dst_folder)) {
3789 modest_platform_information_banner (GTK_WIDGET (win),
3791 _CS("ckdg_ib_unable_to_move_to_current_location"));
3795 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3796 proto_str = tny_account_get_proto (dst_account);
3797 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3798 MODEST_PROTOCOL_STORE_POP);
3799 g_object_unref (dst_account);
3801 /* Get selected headers */
3802 headers = get_selected_headers (MODEST_WINDOW (win));
3805 modest_platform_information_banner (GTK_WIDGET (win),
3807 ngettext("mail_in_ui_folder_move_target_error",
3808 "mail_in_ui_folder_move_targets_error",
3809 tny_list_get_length (headers)));
3810 g_object_unref (headers);
3814 /* Ask for user confirmation */
3815 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3816 TNY_FOLDER (dst_folder),
3820 /* Transfer messages */
3821 if (response == GTK_RESPONSE_OK) {
3822 ModestMailOperation *mail_op =
3823 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3825 modest_ui_actions_move_folder_error_handler,
3827 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3830 modest_mail_operation_xfer_msgs (mail_op,
3832 TNY_FOLDER (dst_folder),
3834 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3837 g_object_unref (G_OBJECT (mail_op));
3839 g_object_unref (headers);
3844 * UI handler for the "Move to" action when invoked from the
3848 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3849 GtkWidget *folder_view,
3850 TnyFolderStore *dst_folder,
3851 ModestMainWindow *win)
3853 GtkWidget *header_view = NULL;
3854 ModestMailOperation *mail_op = NULL;
3855 TnyFolderStore *src_folder;
3857 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3859 /* Get the source folder */
3860 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3862 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3863 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3867 /* Get header view */
3869 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3871 /* Get folder or messages to transfer */
3872 if (gtk_widget_is_focus (folder_view)) {
3874 /* Allow only to transfer folders to the local root folder */
3875 if (TNY_IS_ACCOUNT (dst_folder) &&
3876 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3879 /* Clean folder on header view before moving it */
3880 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3882 if (TNY_IS_FOLDER (src_folder)) {
3884 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3886 modest_ui_actions_move_folder_error_handler,
3888 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3891 modest_mail_operation_xfer_folder (mail_op,
3892 TNY_FOLDER (src_folder),
3895 /* Unref mail operation */
3896 g_object_unref (G_OBJECT (mail_op));
3898 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3900 } else if (gtk_widget_is_focus (header_view)) {
3901 /* Transfer messages */
3902 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3907 g_object_unref (src_folder);
3912 * UI handler for the "Move to" action when invoked from the
3913 * ModestMsgViewWindow
3916 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3917 TnyFolderStore *dst_folder,
3918 ModestMsgViewWindow *win)
3920 TnyHeader *header = NULL;
3921 TnyFolder *src_folder;
3923 /* Create header list */
3924 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3925 src_folder = tny_header_get_folder(header);
3926 g_object_unref (header);
3928 /* Transfer the message */
3929 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3930 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3932 g_object_unref (src_folder);
3936 modest_ui_actions_on_move_to (GtkAction *action,
3939 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3941 TnyFolderStore *dst_folder = NULL;
3942 ModestMainWindow *main_window;
3944 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3945 MODEST_IS_MSG_VIEW_WINDOW (win));
3947 /* Get the main window if exists */
3948 if (MODEST_IS_MAIN_WINDOW (win))
3949 main_window = MODEST_MAIN_WINDOW (win);
3952 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3954 /* Get the folder view widget if exists */
3956 folder_view = modest_main_window_get_child_widget (main_window,
3957 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3961 /* Create and run the dialog */
3962 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3963 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3964 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3965 result = gtk_dialog_run (GTK_DIALOG(dialog));
3966 g_object_ref (tree_view);
3967 gtk_widget_destroy (dialog);
3969 if (result != GTK_RESPONSE_ACCEPT)
3972 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3973 /* Offer the connection dialog if necessary: */
3974 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3977 /* Do window specific stuff */
3978 if (MODEST_IS_MAIN_WINDOW (win))
3979 modest_ui_actions_on_main_window_move_to (action,
3982 MODEST_MAIN_WINDOW (win));
3984 modest_ui_actions_on_msg_view_window_move_to (action,
3986 MODEST_MSG_VIEW_WINDOW (win));
3989 g_object_unref (dst_folder);
3993 * Calls #HeadersFunc for each header already selected in the main
3994 * window or the message currently being shown in the msg view window
3997 do_headers_action (ModestWindow *win,
4001 TnyList *headers_list = NULL;
4002 TnyIterator *iter = NULL;
4003 TnyHeader *header = NULL;
4004 TnyFolder *folder = NULL;
4007 headers_list = get_selected_headers (win);
4011 /* Get the folder */
4012 iter = tny_list_create_iterator (headers_list);
4013 header = TNY_HEADER (tny_iterator_get_current (iter));
4015 folder = tny_header_get_folder (header);
4016 g_object_unref (header);
4019 /* Call the function for each header */
4020 while (!tny_iterator_is_done (iter)) {
4021 header = TNY_HEADER (tny_iterator_get_current (iter));
4022 func (header, win, user_data);
4023 g_object_unref (header);
4024 tny_iterator_next (iter);
4027 /* Trick: do a poke status in order to speed up the signaling
4029 tny_folder_poke_status (folder);
4032 g_object_unref (folder);
4033 g_object_unref (iter);
4034 g_object_unref (headers_list);
4038 modest_ui_actions_view_attachment (GtkAction *action,
4039 ModestWindow *window)
4041 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4042 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4044 /* not supported window for this action */
4045 g_return_if_reached ();
4050 modest_ui_actions_save_attachments (GtkAction *action,
4051 ModestWindow *window)
4053 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4054 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4056 /* not supported window for this action */
4057 g_return_if_reached ();
4062 modest_ui_actions_remove_attachments (GtkAction *action,
4063 ModestWindow *window)
4065 if (MODEST_IS_MAIN_WINDOW (window)) {
4066 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4067 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4068 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4070 /* not supported window for this action */
4071 g_return_if_reached ();
4076 modest_ui_actions_on_settings (GtkAction *action,
4081 dialog = modest_platform_get_global_settings_dialog ();
4082 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4083 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4084 gtk_widget_show_all (dialog);
4086 gtk_dialog_run (GTK_DIALOG (dialog));
4088 gtk_widget_destroy (dialog);
4092 modest_ui_actions_on_help (GtkAction *action,
4095 const gchar *help_id = NULL;
4097 if (MODEST_IS_MAIN_WINDOW (win)) {
4098 const gchar *action_name;
4099 action_name = gtk_action_get_name (action);
4101 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4102 !strcmp (action_name, "HeaderViewCSMHelp")) {
4103 GtkWidget *folder_view;
4104 TnyFolderStore *folder_store;
4105 /* Get selected folder */
4106 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4107 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4108 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4110 /* Switch help_id */
4111 if (TNY_IS_FOLDER (folder_store)) {
4112 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4113 case TNY_FOLDER_TYPE_NORMAL:
4114 help_id = "applications_email_managefolders";
4116 case TNY_FOLDER_TYPE_INBOX:
4117 help_id = "applications_email_inbox";
4119 case TNY_FOLDER_TYPE_OUTBOX:
4120 help_id = "applications_email_outbox";
4122 case TNY_FOLDER_TYPE_SENT:
4123 help_id = "applications_email_sent";
4125 case TNY_FOLDER_TYPE_DRAFTS:
4126 help_id = "applications_email_drafts";
4128 case TNY_FOLDER_TYPE_ARCHIVE:
4129 help_id = "applications_email_managefolders";
4132 help_id = "applications_email_managefolders";
4135 help_id = "applications_email_mainview";
4137 g_object_unref (folder_store);
4139 help_id = "applications_email_mainview";
4141 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4142 help_id = "applications_email_viewer";
4143 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4144 help_id = "applications_email_editor";
4146 modest_platform_show_help (GTK_WINDOW (win), help_id);
4150 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4151 ModestWindow *window)
4153 ModestMailOperation *mail_op;
4157 headers = get_selected_headers (window);
4161 /* Create mail operation */
4162 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4164 modest_ui_actions_get_msgs_full_error_handler,
4166 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4167 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4170 g_object_unref (headers);
4171 g_object_unref (mail_op);
4175 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4176 ModestWindow *window)
4178 g_return_if_fail (MODEST_IS_WINDOW (window));
4181 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4185 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4186 ModestWindow *window)
4188 g_return_if_fail (MODEST_IS_WINDOW (window));
4191 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4195 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4196 ModestWindow *window)
4198 g_return_if_fail (MODEST_IS_WINDOW (window));
4201 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4205 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4206 ModestWindow *window)
4208 g_return_if_fail (MODEST_IS_WINDOW (window));
4211 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4215 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4216 ModestWindow *window)
4218 g_return_if_fail (MODEST_IS_WINDOW (window));
4221 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4225 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4226 ModestWindow *window)
4228 g_return_if_fail (MODEST_IS_WINDOW (window));
4231 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4235 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4236 ModestWindow *window)
4238 g_return_if_fail (MODEST_IS_WINDOW (window));
4241 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4245 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4246 ModestWindow *window)
4248 g_return_if_fail (MODEST_IS_WINDOW (window));
4251 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4255 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4257 g_return_if_fail (MODEST_IS_WINDOW (window));
4260 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4264 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4266 g_return_if_fail (MODEST_IS_WINDOW (window));
4268 modest_platform_show_search_messages (GTK_WINDOW (window));
4272 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4274 g_return_if_fail (MODEST_IS_WINDOW (win));
4275 modest_platform_show_addressbook (GTK_WINDOW (win));
4280 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4281 ModestWindow *window)
4283 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4285 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4289 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4290 ModestMailOperationState *state,
4293 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4295 /* Set send/receive operation finished */
4296 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4297 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));