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 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2095 /* Create the mail operation */
2096 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2097 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2099 modest_mail_operation_send_new_mail (mail_operation,
2110 data->priority_flags);
2114 g_free (account_name);
2115 g_object_unref (G_OBJECT (transport_account));
2116 g_object_unref (G_OBJECT (mail_operation));
2118 modest_msg_edit_window_free_msg_data (edit_window, data);
2119 modest_msg_edit_window_set_sent (edit_window, TRUE);
2121 /* Save settings and close the window: */
2122 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2126 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2127 ModestMsgEditWindow *window)
2129 ModestMsgEditFormatState *format_state = NULL;
2131 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2132 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2134 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2137 format_state = modest_msg_edit_window_get_format_state (window);
2138 g_return_if_fail (format_state != NULL);
2140 format_state->bold = gtk_toggle_action_get_active (action);
2141 modest_msg_edit_window_set_format_state (window, format_state);
2142 g_free (format_state);
2147 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2148 ModestMsgEditWindow *window)
2150 ModestMsgEditFormatState *format_state = NULL;
2152 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2153 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2155 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2158 format_state = modest_msg_edit_window_get_format_state (window);
2159 g_return_if_fail (format_state != NULL);
2161 format_state->italics = gtk_toggle_action_get_active (action);
2162 modest_msg_edit_window_set_format_state (window, format_state);
2163 g_free (format_state);
2168 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2169 ModestMsgEditWindow *window)
2171 ModestMsgEditFormatState *format_state = NULL;
2173 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2174 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2176 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2179 format_state = modest_msg_edit_window_get_format_state (window);
2180 g_return_if_fail (format_state != NULL);
2182 format_state->bullet = gtk_toggle_action_get_active (action);
2183 modest_msg_edit_window_set_format_state (window, format_state);
2184 g_free (format_state);
2189 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2190 GtkRadioAction *selected,
2191 ModestMsgEditWindow *window)
2193 ModestMsgEditFormatState *format_state = NULL;
2194 GtkJustification value;
2196 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2198 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2201 value = gtk_radio_action_get_current_value (selected);
2203 format_state = modest_msg_edit_window_get_format_state (window);
2204 g_return_if_fail (format_state != NULL);
2206 format_state->justification = value;
2207 modest_msg_edit_window_set_format_state (window, format_state);
2208 g_free (format_state);
2212 modest_ui_actions_on_select_editor_color (GtkAction *action,
2213 ModestMsgEditWindow *window)
2215 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2216 g_return_if_fail (GTK_IS_ACTION (action));
2218 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2221 modest_msg_edit_window_select_color (window);
2225 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2226 ModestMsgEditWindow *window)
2228 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2229 g_return_if_fail (GTK_IS_ACTION (action));
2231 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2234 modest_msg_edit_window_select_background_color (window);
2238 modest_ui_actions_on_insert_image (GtkAction *action,
2239 ModestMsgEditWindow *window)
2241 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2242 g_return_if_fail (GTK_IS_ACTION (action));
2244 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2247 modest_msg_edit_window_insert_image (window);
2251 modest_ui_actions_on_attach_file (GtkAction *action,
2252 ModestMsgEditWindow *window)
2254 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2255 g_return_if_fail (GTK_IS_ACTION (action));
2257 modest_msg_edit_window_offer_attach_file (window);
2261 modest_ui_actions_on_remove_attachments (GtkAction *action,
2262 ModestMsgEditWindow *window)
2264 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2265 g_return_if_fail (GTK_IS_ACTION (action));
2267 modest_msg_edit_window_remove_attachments (window, NULL);
2271 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2274 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2275 const GError *error = modest_mail_operation_get_error (mail_op);
2279 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2280 modest_mail_operation_get_error (mail_op)->message);
2285 modest_ui_actions_create_folder(GtkWidget *parent_window,
2286 GtkWidget *folder_view)
2288 TnyFolderStore *parent_folder;
2290 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2292 if (parent_folder) {
2293 gboolean finished = FALSE;
2295 gchar *folder_name = NULL, *suggested_name = NULL;
2296 const gchar *proto_str = NULL;
2297 TnyAccount *account;
2299 if (TNY_IS_ACCOUNT (parent_folder))
2300 account = g_object_ref (parent_folder);
2302 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2303 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2305 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2306 MODEST_PROTOCOL_STORE_POP) {
2308 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2310 g_object_unref (account);
2312 /* Run the new folder dialog */
2314 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2319 g_free (suggested_name);
2320 suggested_name = NULL;
2322 if (result == GTK_RESPONSE_REJECT) {
2325 ModestMailOperation *mail_op;
2326 TnyFolder *new_folder = NULL;
2328 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2329 G_OBJECT(parent_window),
2330 modest_ui_actions_new_folder_error_handler,
2333 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2335 new_folder = modest_mail_operation_create_folder (mail_op,
2337 (const gchar *) folder_name);
2339 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2342 g_object_unref (new_folder);
2345 g_object_unref (mail_op);
2348 suggested_name = folder_name;
2352 g_object_unref (parent_folder);
2357 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2359 GtkWidget *folder_view;
2361 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2363 folder_view = modest_main_window_get_child_widget (main_window,
2364 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2368 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2372 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2375 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2376 const GError *error = NULL;
2377 const gchar *message = NULL;
2379 /* Get error message */
2380 error = modest_mail_operation_get_error (mail_op);
2381 if (error != NULL && error->message != NULL) {
2382 message = error->message;
2384 message = _("!!! FIXME: Unable to rename");
2387 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2392 modest_ui_actions_on_rename_folder (GtkAction *action,
2393 ModestMainWindow *main_window)
2395 TnyFolderStore *folder;
2396 GtkWidget *folder_view;
2397 GtkWidget *header_view;
2399 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2401 folder_view = modest_main_window_get_child_widget (main_window,
2402 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2406 header_view = modest_main_window_get_child_widget (main_window,
2407 MODEST_WIDGET_TYPE_HEADER_VIEW);
2412 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2416 /* Offer the connection dialog if necessary: */
2417 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2418 g_object_unref (G_OBJECT (folder));
2423 if (TNY_IS_FOLDER (folder)) {
2426 const gchar *current_name;
2428 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2429 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2430 current_name, &folder_name);
2432 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2433 ModestMailOperation *mail_op;
2436 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2437 G_OBJECT(main_window),
2438 modest_ui_actions_rename_folder_error_handler,
2441 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2444 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2446 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2447 TNY_FOLDER(folder), TRUE);
2449 modest_header_view_clear ((ModestHeaderView *) header_view);
2451 modest_mail_operation_rename_folder (mail_op,
2452 TNY_FOLDER (folder),
2453 (const gchar *) folder_name);
2455 g_object_unref (mail_op);
2456 g_free (folder_name);
2459 g_object_unref (folder);
2463 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2466 GObject *win = modest_mail_operation_get_source (mail_op);
2468 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2469 _("mail_in_ui_folder_delete_error"));
2470 g_object_unref (win);
2474 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2476 TnyFolderStore *folder;
2477 GtkWidget *folder_view;
2481 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2483 folder_view = modest_main_window_get_child_widget (main_window,
2484 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2488 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2490 /* Show an error if it's an account */
2491 if (!TNY_IS_FOLDER (folder)) {
2492 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2493 _("mail_in_ui_folder_delete_error"));
2494 g_object_unref (G_OBJECT (folder));
2498 /* Offer the connection dialog if necessary: */
2499 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2500 g_object_unref (G_OBJECT (folder));
2505 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2506 tny_folder_get_name (TNY_FOLDER (folder)));
2507 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2508 (const gchar *) message);
2511 if (response == GTK_RESPONSE_OK) {
2512 ModestMailOperation *mail_op =
2513 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2514 G_OBJECT(main_window),
2515 modest_ui_actions_delete_folder_error_handler,
2518 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2520 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2521 g_object_unref (G_OBJECT (mail_op));
2524 g_object_unref (G_OBJECT (folder));
2528 modest_ui_actions_on_delete_folder (GtkAction *action,
2529 ModestMainWindow *main_window)
2531 GtkWidget *folder_view;
2532 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2534 delete_folder (main_window, FALSE);
2535 folder_view = modest_main_window_get_child_widget (main_window,
2536 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2539 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2543 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2545 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2547 delete_folder (main_window, TRUE);
2552 show_error (GtkWidget *parent_widget, const gchar* text)
2554 hildon_banner_show_information(parent_widget, NULL, text);
2557 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2559 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2566 gtk_dialog_run (dialog);
2567 gtk_widget_destroy (GTK_WIDGET (dialog));
2572 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2573 const gchar* server_account_name,
2578 ModestMainWindow *main_window)
2580 g_return_if_fail(server_account_name);
2581 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2583 /* Initalize output parameters: */
2590 #ifdef MODEST_PLATFORM_MAEMO
2591 /* Maemo uses a different (awkward) button order,
2592 * It should probably just use gtk_alternative_dialog_button_order ().
2594 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2598 GTK_RESPONSE_ACCEPT,
2600 GTK_RESPONSE_REJECT,
2603 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2607 GTK_RESPONSE_REJECT,
2609 GTK_RESPONSE_ACCEPT,
2611 #endif /* MODEST_PLATFORM_MAEMO */
2613 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2615 gchar *server_name = modest_server_account_get_hostname (
2616 modest_runtime_get_account_mgr(), server_account_name);
2617 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2618 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2623 /* This causes a warning because the logical ID has no %s in it,
2624 * though the translation does, but there is not much we can do about that: */
2625 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2626 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2629 g_free (server_name);
2633 gchar *initial_username = modest_server_account_get_username (
2634 modest_runtime_get_account_mgr(), server_account_name);
2636 GtkWidget *entry_username = gtk_entry_new ();
2637 if (initial_username)
2638 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2639 /* Dim this if a connection has ever succeeded with this username,
2640 * as per the UI spec: */
2641 const gboolean username_known =
2642 modest_server_account_get_username_has_succeeded(
2643 modest_runtime_get_account_mgr(), server_account_name);
2644 gtk_widget_set_sensitive (entry_username, !username_known);
2646 #ifdef MODEST_PLATFORM_MAEMO
2647 /* Auto-capitalization is the default, so let's turn it off: */
2648 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2650 /* Create a size group to be used by all captions.
2651 * Note that HildonCaption does not create a default size group if we do not specify one.
2652 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2653 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2655 GtkWidget *caption = hildon_caption_new (sizegroup,
2656 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2657 gtk_widget_show (entry_username);
2658 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2659 FALSE, FALSE, MODEST_MARGIN_HALF);
2660 gtk_widget_show (caption);
2662 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2664 #endif /* MODEST_PLATFORM_MAEMO */
2667 GtkWidget *entry_password = gtk_entry_new ();
2668 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2669 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2671 #ifdef MODEST_PLATFORM_MAEMO
2672 /* Auto-capitalization is the default, so let's turn it off: */
2673 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2674 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2676 caption = hildon_caption_new (sizegroup,
2677 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2678 gtk_widget_show (entry_password);
2679 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2680 FALSE, FALSE, MODEST_MARGIN_HALF);
2681 gtk_widget_show (caption);
2682 g_object_unref (sizegroup);
2684 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2686 #endif /* MODEST_PLATFORM_MAEMO */
2688 /* This is not in the Maemo UI spec:
2689 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2690 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2694 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2696 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2698 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2700 modest_server_account_set_username (
2701 modest_runtime_get_account_mgr(), server_account_name,
2704 const gboolean username_was_changed =
2705 (strcmp (*username, initial_username) != 0);
2706 if (username_was_changed) {
2707 g_warning ("%s: tinymail does not yet support changing the "
2708 "username in the get_password() callback.\n", __FUNCTION__);
2713 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2715 /* We do not save the password in the configuration,
2716 * because this function is only called for passwords that should
2717 * not be remembered:
2718 modest_server_account_set_password (
2719 modest_runtime_get_account_mgr(), server_account_name,
2728 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2740 /* This is not in the Maemo UI spec:
2741 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2747 gtk_widget_destroy (dialog);
2749 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2753 modest_ui_actions_on_cut (GtkAction *action,
2754 ModestWindow *window)
2756 GtkWidget *focused_widget;
2757 GtkClipboard *clipboard;
2759 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2760 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2761 if (GTK_IS_EDITABLE (focused_widget)) {
2762 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2763 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2764 gtk_clipboard_store (clipboard);
2765 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2766 GtkTextBuffer *buffer;
2768 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2769 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2770 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2771 gtk_clipboard_store (clipboard);
2772 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2773 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2774 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2775 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2780 modest_ui_actions_on_copy (GtkAction *action,
2781 ModestWindow *window)
2783 GtkClipboard *clipboard;
2784 GtkWidget *focused_widget;
2786 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2787 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2789 if (GTK_IS_LABEL (focused_widget)) {
2790 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2791 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2792 gtk_clipboard_store (clipboard);
2793 } else if (GTK_IS_EDITABLE (focused_widget)) {
2794 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2795 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2796 gtk_clipboard_store (clipboard);
2797 } else if (GTK_IS_HTML (focused_widget)) {
2798 gtk_html_copy (GTK_HTML (focused_widget));
2799 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2800 gtk_clipboard_store (clipboard);
2801 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2802 GtkTextBuffer *buffer;
2803 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2804 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2805 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2806 gtk_clipboard_store (clipboard);
2807 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2808 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2809 TnyIterator *iter = tny_list_create_iterator (header_list);
2810 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2812 gboolean ask = FALSE;
2814 TnyFolder *folder = tny_header_get_folder (header);
2815 TnyAccount *account = tny_folder_get_account (folder);
2816 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2817 /* If it's POP then ask */
2818 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2819 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2820 g_object_unref (account);
2821 g_object_unref (folder);
2822 g_object_unref (header);
2825 g_object_unref (iter);
2827 /* Check that the messages have been previously downloaded */
2828 gboolean continue_download = TRUE;
2830 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2831 if (continue_download)
2832 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2833 g_object_unref (header_list);
2834 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2835 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2838 /* Show information banner */
2839 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2844 modest_ui_actions_on_undo (GtkAction *action,
2845 ModestWindow *window)
2847 ModestEmailClipboard *clipboard = NULL;
2849 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2850 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2851 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2852 /* Clear clipboard source */
2853 clipboard = modest_runtime_get_email_clipboard ();
2854 modest_email_clipboard_clear (clipboard);
2857 g_return_if_reached ();
2862 modest_ui_actions_on_redo (GtkAction *action,
2863 ModestWindow *window)
2865 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2866 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2869 g_return_if_reached ();
2875 paste_msgs_cb (const GObject *object, gpointer user_data)
2877 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2878 g_return_if_fail (GTK_IS_WIDGET (user_data));
2880 /* destroy information note */
2881 gtk_widget_destroy (GTK_WIDGET(user_data));
2885 paste_as_attachment_free (gpointer data)
2887 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2889 gtk_widget_destroy (helper->banner);
2890 g_object_unref (helper->banner);
2895 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2900 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2901 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2906 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2911 modest_ui_actions_on_paste (GtkAction *action,
2912 ModestWindow *window)
2914 GtkWidget *focused_widget = NULL;
2915 GtkWidget *inf_note = NULL;
2916 ModestMailOperation *mail_op = NULL;
2918 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2919 if (GTK_IS_EDITABLE (focused_widget)) {
2920 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2921 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2922 ModestEmailClipboard *e_clipboard = NULL;
2923 e_clipboard = modest_runtime_get_email_clipboard ();
2924 if (modest_email_clipboard_cleared (e_clipboard)) {
2925 GtkTextBuffer *buffer;
2926 GtkClipboard *clipboard;
2928 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2929 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2930 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2931 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2932 ModestMailOperation *mail_op;
2933 TnyFolder *src_folder;
2936 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2937 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2938 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2939 _CS("ckct_nw_pasting"));
2940 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2941 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2943 if (helper->banner != NULL) {
2944 g_object_ref (G_OBJECT (helper->banner));
2945 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2946 gtk_widget_show (GTK_WIDGET (helper->banner));
2950 modest_mail_operation_get_msgs_full (mail_op,
2952 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2954 paste_as_attachment_free);
2957 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2958 ModestEmailClipboard *clipboard = NULL;
2959 TnyFolder *src_folder = NULL;
2960 TnyFolderStore *folder_store = NULL;
2961 TnyList *data = NULL;
2962 gboolean delete = FALSE;
2964 /* Check clipboard source */
2965 clipboard = modest_runtime_get_email_clipboard ();
2966 if (modest_email_clipboard_cleared (clipboard))
2969 /* Get elements to paste */
2970 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2972 /* Create a new mail operation */
2973 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2975 /* Get destination folder */
2976 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2978 /* transfer messages */
2982 /* Ask for user confirmation */
2983 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2984 TNY_FOLDER (folder_store),
2988 if (response == GTK_RESPONSE_OK) {
2989 /* Launch notification */
2990 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2991 _CS("ckct_nw_pasting"));
2992 if (inf_note != NULL) {
2993 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2994 gtk_widget_show (GTK_WIDGET(inf_note));
2997 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2998 modest_mail_operation_xfer_msgs (mail_op,
3000 TNY_FOLDER (folder_store),
3005 g_object_unref (mail_op);
3008 } else if (src_folder != NULL) {
3009 /* Launch notification */
3010 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3011 _CS("ckct_nw_pasting"));
3012 if (inf_note != NULL) {
3013 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3014 gtk_widget_show (GTK_WIDGET(inf_note));
3017 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3018 modest_mail_operation_xfer_folder (mail_op,
3028 g_object_unref (data);
3029 if (src_folder != NULL)
3030 g_object_unref (src_folder);
3031 if (folder_store != NULL)
3032 g_object_unref (folder_store);
3038 modest_ui_actions_on_select_all (GtkAction *action,
3039 ModestWindow *window)
3041 GtkWidget *focused_widget;
3043 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3044 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3045 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3046 } else if (GTK_IS_LABEL (focused_widget)) {
3047 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3048 } else if (GTK_IS_EDITABLE (focused_widget)) {
3049 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3050 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3051 GtkTextBuffer *buffer;
3052 GtkTextIter start, end;
3054 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3055 gtk_text_buffer_get_start_iter (buffer, &start);
3056 gtk_text_buffer_get_end_iter (buffer, &end);
3057 gtk_text_buffer_select_range (buffer, &start, &end);
3058 } else if (GTK_IS_HTML (focused_widget)) {
3059 gtk_html_select_all (GTK_HTML (focused_widget));
3060 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3061 GtkWidget *header_view = focused_widget;
3062 GtkTreeSelection *selection = NULL;
3064 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3065 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3066 MODEST_WIDGET_TYPE_HEADER_VIEW);
3068 /* Select all messages */
3069 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3070 gtk_tree_selection_select_all (selection);
3072 /* Set focuse on header view */
3073 gtk_widget_grab_focus (header_view);
3079 modest_ui_actions_on_mark_as_read (GtkAction *action,
3080 ModestWindow *window)
3082 g_return_if_fail (MODEST_IS_WINDOW(window));
3084 /* Mark each header as read */
3085 do_headers_action (window, headers_action_mark_as_read, NULL);
3089 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3090 ModestWindow *window)
3092 g_return_if_fail (MODEST_IS_WINDOW(window));
3094 /* Mark each header as read */
3095 do_headers_action (window, headers_action_mark_as_unread, NULL);
3099 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3100 GtkRadioAction *selected,
3101 ModestWindow *window)
3105 value = gtk_radio_action_get_current_value (selected);
3106 if (MODEST_IS_WINDOW (window)) {
3107 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3111 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3112 GtkRadioAction *selected,
3113 ModestWindow *window)
3115 TnyHeaderFlags flags;
3116 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3118 flags = gtk_radio_action_get_current_value (selected);
3119 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3122 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3123 GtkRadioAction *selected,
3124 ModestWindow *window)
3128 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3130 file_format = gtk_radio_action_get_current_value (selected);
3131 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3136 modest_ui_actions_on_zoom_plus (GtkAction *action,
3137 ModestWindow *window)
3139 g_return_if_fail (MODEST_IS_WINDOW (window));
3141 modest_window_zoom_plus (MODEST_WINDOW (window));
3145 modest_ui_actions_on_zoom_minus (GtkAction *action,
3146 ModestWindow *window)
3148 g_return_if_fail (MODEST_IS_WINDOW (window));
3150 modest_window_zoom_minus (MODEST_WINDOW (window));
3154 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3155 ModestWindow *window)
3157 ModestWindowMgr *mgr;
3158 gboolean fullscreen, active;
3159 g_return_if_fail (MODEST_IS_WINDOW (window));
3161 mgr = modest_runtime_get_window_mgr ();
3163 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3164 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3166 if (active != fullscreen) {
3167 modest_window_mgr_set_fullscreen_mode (mgr, active);
3168 gtk_window_present (GTK_WINDOW (window));
3173 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3174 ModestWindow *window)
3176 ModestWindowMgr *mgr;
3177 gboolean fullscreen;
3179 g_return_if_fail (MODEST_IS_WINDOW (window));
3181 mgr = modest_runtime_get_window_mgr ();
3182 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3183 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3185 gtk_window_present (GTK_WINDOW (window));
3189 * Used by modest_ui_actions_on_details to call do_headers_action
3192 headers_action_show_details (TnyHeader *header,
3193 ModestWindow *window,
3200 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3203 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3204 gtk_widget_show_all (dialog);
3205 gtk_dialog_run (GTK_DIALOG (dialog));
3207 gtk_widget_destroy (dialog);
3211 * Show the folder details in a ModestDetailsDialog widget
3214 show_folder_details (TnyFolder *folder,
3220 dialog = modest_details_dialog_new_with_folder (window, folder);
3223 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3224 gtk_widget_show_all (dialog);
3225 gtk_dialog_run (GTK_DIALOG (dialog));
3227 gtk_widget_destroy (dialog);
3231 * Show the header details in a ModestDetailsDialog widget
3234 modest_ui_actions_on_details (GtkAction *action,
3237 TnyList * headers_list;
3241 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3244 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3247 g_object_unref (msg);
3249 headers_list = get_selected_headers (win);
3253 iter = tny_list_create_iterator (headers_list);
3255 header = TNY_HEADER (tny_iterator_get_current (iter));
3257 headers_action_show_details (header, win, NULL);
3258 g_object_unref (header);
3261 g_object_unref (iter);
3262 g_object_unref (headers_list);
3264 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3265 GtkWidget *folder_view, *header_view;
3267 /* Check which widget has the focus */
3268 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3269 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3270 if (gtk_widget_is_focus (folder_view)) {
3271 TnyFolderStore *folder_store
3272 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3273 if (!folder_store) {
3274 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3277 /* Show only when it's a folder */
3278 /* This function should not be called for account items,
3279 * because we dim the menu item for them. */
3280 if (TNY_IS_FOLDER (folder_store)) {
3281 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3284 g_object_unref (folder_store);
3287 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3288 MODEST_WIDGET_TYPE_HEADER_VIEW);
3289 /* Show details of each header */
3290 do_headers_action (win, headers_action_show_details, header_view);
3296 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3297 ModestMsgEditWindow *window)
3299 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3301 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3305 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3306 ModestMsgEditWindow *window)
3308 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3310 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3314 modest_ui_actions_toggle_folders_view (GtkAction *action,
3315 ModestMainWindow *main_window)
3317 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3319 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3320 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3322 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3326 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3327 ModestWindow *window)
3329 gboolean active, fullscreen = FALSE;
3330 ModestWindowMgr *mgr;
3332 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3334 /* Check if we want to toggle the toolbar vuew in fullscreen
3336 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3337 "ViewShowToolbarFullScreen")) {
3341 /* Toggle toolbar */
3342 mgr = modest_runtime_get_window_mgr ();
3343 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3347 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3348 ModestMsgEditWindow *window)
3350 modest_msg_edit_window_select_font (window);
3354 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3355 const gchar *display_name,
3358 /* Do not change the application name if the widget has not
3359 the focus. This callback could be called even if the folder
3360 view has not the focus, because the handled signal could be
3361 emitted when the folder view is redrawn */
3362 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3364 gtk_window_set_title (window, display_name);
3366 gtk_window_set_title (window, " ");
3371 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3373 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3374 modest_msg_edit_window_select_contacts (window);
3378 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3380 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3381 modest_msg_edit_window_check_names (window, FALSE);
3385 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3387 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3388 GTK_WIDGET (user_data));
3392 create_move_to_dialog (GtkWindow *win,
3393 GtkWidget *folder_view,
3394 GtkWidget **tree_view)
3396 GtkWidget *dialog, *scroll;
3397 GtkWidget *new_button;
3399 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3401 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3404 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3405 /* We do this manually so GTK+ does not associate a response ID for
3407 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3408 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3409 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3411 /* Create scrolled window */
3412 scroll = gtk_scrolled_window_new (NULL, NULL);
3413 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3414 GTK_POLICY_AUTOMATIC,
3415 GTK_POLICY_AUTOMATIC);
3417 /* Create folder view */
3418 *tree_view = modest_platform_create_folder_view (NULL);
3420 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3422 /* It could happen that we're trying to move a message from a
3423 window (msg window for example) after the main window was
3424 closed, so we can not just get the model of the folder
3426 if (MODEST_IS_FOLDER_VIEW (folder_view))
3427 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3428 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3430 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3431 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3433 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3435 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3437 /* Add scroll to dialog */
3438 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3439 scroll, TRUE, TRUE, 0);
3441 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3442 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3448 * Returns TRUE if at least one of the headers of the list belongs to
3449 * a message that has been fully retrieved.
3452 has_retrieved_msgs (TnyList *list)
3455 gboolean found = FALSE;
3457 iter = tny_list_create_iterator (list);
3458 while (!tny_iterator_is_done (iter) && !found) {
3460 TnyHeaderFlags flags = 0;
3462 header = TNY_HEADER (tny_iterator_get_current (iter));
3464 flags = tny_header_get_flags (header);
3465 if (flags & TNY_HEADER_FLAG_CACHED)
3466 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3469 g_object_unref (header);
3473 tny_iterator_next (iter);
3475 g_object_unref (iter);
3481 * Shows a confirmation dialog to the user when we're moving messages
3482 * from a remote server to the local storage. Returns the dialog
3483 * response. If it's other kind of movement the it always returns
3487 msgs_move_to_confirmation (GtkWindow *win,
3488 TnyFolder *dest_folder,
3492 gint response = GTK_RESPONSE_OK;
3494 /* If the destination is a local folder (or MMC folder )*/
3495 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3496 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3497 TnyFolder *src_folder = NULL;
3498 TnyIterator *iter = NULL;
3499 TnyHeader *header = NULL;
3501 /* Get source folder */
3502 iter = tny_list_create_iterator (headers);
3503 header = TNY_HEADER (tny_iterator_get_current (iter));
3505 src_folder = tny_header_get_folder (header);
3506 g_object_unref (header);
3509 g_object_unref (iter);
3511 /* if no src_folder, message may be an attahcment */
3512 if (src_folder == NULL)
3513 return GTK_RESPONSE_CANCEL;
3515 /* If the source is a remote folder */
3516 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3517 if (modest_tny_folder_is_remote_folder (src_folder)) {
3518 const gchar *message = NULL;
3519 gboolean cached = has_retrieved_msgs (headers);
3521 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3522 tny_list_get_length (headers));
3524 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3525 tny_list_get_length (headers));
3527 if (cached && !delete)
3528 response = GTK_RESPONSE_OK;
3530 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3531 (const gchar *) message);
3534 g_object_unref (src_folder);
3543 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3545 ModestMsgViewWindow *self = NULL;
3547 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3548 self = MODEST_MSG_VIEW_WINDOW (object);
3550 if (!modest_msg_view_window_select_next_message (self))
3551 if (!modest_msg_view_window_select_previous_message (self))
3552 /* No more messages to view, so close this window */
3553 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3557 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3560 GObject *win = modest_mail_operation_get_source (mail_op);
3561 const GError *error = NULL;
3562 const gchar *message = NULL;
3564 /* Get error message */
3565 error = modest_mail_operation_get_error (mail_op);
3566 if (error != NULL && error->message != NULL) {
3567 message = error->message;
3569 message = _("mail_in_ui_folder_move_target_error");
3572 /* Show notification dialog */
3573 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3574 g_object_unref (win);
3578 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3581 GObject *win = modest_mail_operation_get_source (mail_op);
3582 const GError *error = modest_mail_operation_get_error (mail_op);
3584 g_return_if_fail (error != NULL);
3585 if (error->message != NULL)
3586 g_printerr ("modest: %s\n", error->message);
3588 g_printerr ("modest: unkonw error on send&receive operation");
3590 /* Show error message */
3591 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3592 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3593 /* _CS("sfil_ib_unable_to_receive")); */
3595 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3596 /* _CS("sfil_ib_unable_to_send")); */
3597 g_object_unref (win);
3601 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3608 gint pending_purges = 0;
3609 gboolean some_purged = FALSE;
3610 ModestWindow *win = MODEST_WINDOW (user_data);
3611 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3613 /* If there was any error */
3614 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3615 modest_window_mgr_unregister_header (mgr, header);
3619 /* Once the message has been retrieved for purging, we check if
3620 * it's all ok for purging */
3622 parts = tny_simple_list_new ();
3623 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3624 iter = tny_list_create_iterator (parts);
3626 while (!tny_iterator_is_done (iter)) {
3628 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3629 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3630 if (tny_mime_part_is_purged (part))
3637 g_object_unref (part);
3639 tny_iterator_next (iter);
3642 if (pending_purges>0) {
3644 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3646 if (response == GTK_RESPONSE_OK) {
3647 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3648 tny_iterator_first (iter);
3649 while (!tny_iterator_is_done (iter)) {
3652 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3653 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3654 tny_mime_part_set_purged (part);
3657 g_object_unref (part);
3659 tny_iterator_next (iter);
3662 tny_msg_rewrite_cache (msg);
3665 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3668 /* remove attachments */
3669 tny_iterator_first (iter);
3670 while (!tny_iterator_is_done (iter)) {
3673 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3675 /* One for the reference given by tny_iterator_get_current(): */
3676 g_object_unref (part);
3678 /* TODO: Is this meant to remove the attachment by doing another unref()?
3679 * Otherwise, this seems useless. */
3682 tny_iterator_next (iter);
3684 modest_window_mgr_unregister_header (mgr, header);
3686 g_object_unref (iter);
3687 g_object_unref (parts);
3691 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3692 ModestMainWindow *win)
3694 GtkWidget *header_view;
3695 TnyList *header_list;
3698 TnyHeaderFlags flags;
3699 ModestWindow *msg_view_window = NULL;
3702 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3704 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3705 MODEST_WIDGET_TYPE_HEADER_VIEW);
3707 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3709 if (tny_list_get_length (header_list) == 1) {
3710 iter = tny_list_create_iterator (header_list);
3711 header = TNY_HEADER (tny_iterator_get_current (iter));
3712 g_object_unref (iter);
3717 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3718 header, &msg_view_window);
3719 flags = tny_header_get_flags (header);
3720 if (!(flags & TNY_HEADER_FLAG_CACHED))
3723 if (msg_view_window != NULL)
3724 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3726 /* do nothing; uid was registered before, so window is probably on it's way */
3727 g_warning ("debug: header %p has already been registered", header);
3730 ModestMailOperation *mail_op = NULL;
3731 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3732 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3734 modest_ui_actions_get_msgs_full_error_handler,
3736 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3737 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3739 g_object_unref (mail_op);
3742 g_object_unref (header);
3744 g_object_unref (header_list);
3748 * Utility function that transfer messages from both the main window
3749 * and the msg view window when using the "Move to" dialog
3752 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3755 TnyList *headers = NULL;
3757 TnyAccount *dst_account = NULL;
3758 const gchar *proto_str = NULL;
3759 gboolean dst_is_pop = FALSE;
3761 if (!TNY_IS_FOLDER (dst_folder)) {
3762 modest_platform_information_banner (GTK_WIDGET (win),
3764 _CS("ckdg_ib_unable_to_move_to_current_location"));
3768 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3769 proto_str = tny_account_get_proto (dst_account);
3770 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3771 MODEST_PROTOCOL_STORE_POP);
3772 g_object_unref (dst_account);
3774 /* Get selected headers */
3775 headers = get_selected_headers (MODEST_WINDOW (win));
3778 modest_platform_information_banner (GTK_WIDGET (win),
3780 ngettext("mail_in_ui_folder_move_target_error",
3781 "mail_in_ui_folder_move_targets_error",
3782 tny_list_get_length (headers)));
3783 g_object_unref (headers);
3787 /* Ask for user confirmation */
3788 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3789 TNY_FOLDER (dst_folder),
3793 /* Transfer messages */
3794 if (response == GTK_RESPONSE_OK) {
3795 ModestMailOperation *mail_op =
3796 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3798 modest_ui_actions_move_folder_error_handler,
3800 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3803 modest_mail_operation_xfer_msgs (mail_op,
3805 TNY_FOLDER (dst_folder),
3807 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3810 g_object_unref (G_OBJECT (mail_op));
3812 g_object_unref (headers);
3817 * UI handler for the "Move to" action when invoked from the
3821 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3822 GtkWidget *folder_view,
3823 TnyFolderStore *dst_folder,
3824 ModestMainWindow *win)
3826 GtkWidget *header_view = NULL;
3827 ModestMailOperation *mail_op = NULL;
3828 TnyFolderStore *src_folder;
3830 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3832 /* Get the source folder */
3833 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3835 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3836 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3840 /* Get header view */
3842 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3844 /* Get folder or messages to transfer */
3845 if (gtk_widget_is_focus (folder_view)) {
3847 /* Allow only to transfer folders to the local root folder */
3848 if (TNY_IS_ACCOUNT (dst_folder) &&
3849 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3852 /* Clean folder on header view before moving it */
3853 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3855 if (TNY_IS_FOLDER (src_folder)) {
3857 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3859 modest_ui_actions_move_folder_error_handler,
3861 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3864 modest_mail_operation_xfer_folder (mail_op,
3865 TNY_FOLDER (src_folder),
3868 /* Unref mail operation */
3869 g_object_unref (G_OBJECT (mail_op));
3871 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3873 } else if (gtk_widget_is_focus (header_view)) {
3874 /* Transfer messages */
3875 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3880 g_object_unref (src_folder);
3885 * UI handler for the "Move to" action when invoked from the
3886 * ModestMsgViewWindow
3889 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3890 TnyFolderStore *dst_folder,
3891 ModestMsgViewWindow *win)
3893 TnyHeader *header = NULL;
3894 TnyFolder *src_folder;
3896 /* Create header list */
3897 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3898 src_folder = tny_header_get_folder(header);
3899 g_object_unref (header);
3901 /* Transfer the message */
3902 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3903 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3905 g_object_unref (src_folder);
3909 modest_ui_actions_on_move_to (GtkAction *action,
3912 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3914 TnyFolderStore *dst_folder = NULL;
3915 ModestMainWindow *main_window;
3917 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3918 MODEST_IS_MSG_VIEW_WINDOW (win));
3920 /* Get the main window if exists */
3921 if (MODEST_IS_MAIN_WINDOW (win))
3922 main_window = MODEST_MAIN_WINDOW (win);
3925 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3927 /* Get the folder view widget if exists */
3929 folder_view = modest_main_window_get_child_widget (main_window,
3930 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3934 /* Create and run the dialog */
3935 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3936 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3937 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3938 result = gtk_dialog_run (GTK_DIALOG(dialog));
3939 g_object_ref (tree_view);
3940 gtk_widget_destroy (dialog);
3942 if (result != GTK_RESPONSE_ACCEPT)
3945 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3946 /* Offer the connection dialog if necessary: */
3947 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3950 /* Do window specific stuff */
3951 if (MODEST_IS_MAIN_WINDOW (win))
3952 modest_ui_actions_on_main_window_move_to (action,
3955 MODEST_MAIN_WINDOW (win));
3957 modest_ui_actions_on_msg_view_window_move_to (action,
3959 MODEST_MSG_VIEW_WINDOW (win));
3962 g_object_unref (dst_folder);
3966 * Calls #HeadersFunc for each header already selected in the main
3967 * window or the message currently being shown in the msg view window
3970 do_headers_action (ModestWindow *win,
3974 TnyList *headers_list = NULL;
3975 TnyIterator *iter = NULL;
3976 TnyHeader *header = NULL;
3977 TnyFolder *folder = NULL;
3980 headers_list = get_selected_headers (win);
3984 /* Get the folder */
3985 iter = tny_list_create_iterator (headers_list);
3986 header = TNY_HEADER (tny_iterator_get_current (iter));
3988 folder = tny_header_get_folder (header);
3989 g_object_unref (header);
3992 /* Call the function for each header */
3993 while (!tny_iterator_is_done (iter)) {
3994 header = TNY_HEADER (tny_iterator_get_current (iter));
3995 func (header, win, user_data);
3996 g_object_unref (header);
3997 tny_iterator_next (iter);
4000 /* Trick: do a poke status in order to speed up the signaling
4002 tny_folder_poke_status (folder);
4005 g_object_unref (folder);
4006 g_object_unref (iter);
4007 g_object_unref (headers_list);
4011 modest_ui_actions_view_attachment (GtkAction *action,
4012 ModestWindow *window)
4014 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4015 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4017 /* not supported window for this action */
4018 g_return_if_reached ();
4023 modest_ui_actions_save_attachments (GtkAction *action,
4024 ModestWindow *window)
4026 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4027 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4029 /* not supported window for this action */
4030 g_return_if_reached ();
4035 modest_ui_actions_remove_attachments (GtkAction *action,
4036 ModestWindow *window)
4038 if (MODEST_IS_MAIN_WINDOW (window)) {
4039 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4040 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4041 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4043 /* not supported window for this action */
4044 g_return_if_reached ();
4049 modest_ui_actions_on_settings (GtkAction *action,
4054 dialog = modest_platform_get_global_settings_dialog ();
4055 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4056 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4057 gtk_widget_show_all (dialog);
4059 gtk_dialog_run (GTK_DIALOG (dialog));
4061 gtk_widget_destroy (dialog);
4065 modest_ui_actions_on_help (GtkAction *action,
4068 const gchar *help_id = NULL;
4070 if (MODEST_IS_MAIN_WINDOW (win)) {
4071 const gchar *action_name;
4072 action_name = gtk_action_get_name (action);
4074 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4075 !strcmp (action_name, "HeaderViewCSMHelp")) {
4076 GtkWidget *folder_view;
4077 TnyFolderStore *folder_store;
4078 /* Get selected folder */
4079 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4080 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4081 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4083 /* Switch help_id */
4084 if (TNY_IS_FOLDER (folder_store)) {
4085 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4086 case TNY_FOLDER_TYPE_NORMAL:
4087 help_id = "applications_email_managefolders";
4089 case TNY_FOLDER_TYPE_INBOX:
4090 help_id = "applications_email_inbox";
4092 case TNY_FOLDER_TYPE_OUTBOX:
4093 help_id = "applications_email_outbox";
4095 case TNY_FOLDER_TYPE_SENT:
4096 help_id = "applications_email_sent";
4098 case TNY_FOLDER_TYPE_DRAFTS:
4099 help_id = "applications_email_drafts";
4101 case TNY_FOLDER_TYPE_ARCHIVE:
4102 help_id = "applications_email_managefolders";
4105 help_id = "applications_email_managefolders";
4108 help_id = "applications_email_mainview";
4110 g_object_unref (folder_store);
4112 help_id = "applications_email_mainview";
4114 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4115 help_id = "applications_email_viewer";
4116 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4117 help_id = "applications_email_editor";
4119 modest_platform_show_help (GTK_WINDOW (win), help_id);
4123 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4124 ModestWindow *window)
4126 ModestMailOperation *mail_op;
4130 headers = get_selected_headers (window);
4134 /* Create mail operation */
4135 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4137 modest_ui_actions_get_msgs_full_error_handler,
4139 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4140 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4143 g_object_unref (headers);
4144 g_object_unref (mail_op);
4148 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4149 ModestWindow *window)
4151 g_return_if_fail (MODEST_IS_WINDOW (window));
4154 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4158 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4159 ModestWindow *window)
4161 g_return_if_fail (MODEST_IS_WINDOW (window));
4164 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4168 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4169 ModestWindow *window)
4171 g_return_if_fail (MODEST_IS_WINDOW (window));
4174 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4178 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4179 ModestWindow *window)
4181 g_return_if_fail (MODEST_IS_WINDOW (window));
4184 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4188 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4189 ModestWindow *window)
4191 g_return_if_fail (MODEST_IS_WINDOW (window));
4194 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4198 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4199 ModestWindow *window)
4201 g_return_if_fail (MODEST_IS_WINDOW (window));
4204 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4208 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4209 ModestWindow *window)
4211 g_return_if_fail (MODEST_IS_WINDOW (window));
4214 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4218 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4219 ModestWindow *window)
4221 g_return_if_fail (MODEST_IS_WINDOW (window));
4224 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4228 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4230 g_return_if_fail (MODEST_IS_WINDOW (window));
4233 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4237 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4239 g_return_if_fail (MODEST_IS_WINDOW (window));
4241 modest_platform_show_search_messages (GTK_WINDOW (window));
4245 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4247 g_return_if_fail (MODEST_IS_WINDOW (win));
4248 modest_platform_show_addressbook (GTK_WINDOW (win));
4253 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4254 ModestWindow *window)
4256 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4258 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4262 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4263 ModestMailOperationState *state,
4266 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4268 /* Set send/receive operation finished */
4269 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4270 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));