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 toolbar dimming state */
1725 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1729 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1731 ModestMainWindow *main_window)
1735 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1740 headers = tny_simple_list_new ();
1741 tny_list_prepend (headers, G_OBJECT (header));
1743 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1745 g_object_unref (headers);
1749 set_active_account_from_tny_account (TnyAccount *account,
1750 ModestWindow *window)
1752 const gchar *server_acc_name = tny_account_get_id (account);
1754 /* We need the TnyAccount provided by the
1755 account store because that is the one that
1756 knows the name of the Modest account */
1757 TnyAccount *modest_server_account = modest_server_account =
1758 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1759 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1762 const gchar *modest_acc_name =
1763 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1764 modest_window_set_active_account (window, modest_acc_name);
1765 g_object_unref (modest_server_account);
1770 folder_refreshed_cb (ModestMailOperation *mail_op,
1774 ModestMainWindow *win = NULL;
1775 GtkWidget *header_view;
1776 TnyFolder *current_folder;
1777 gboolean folder_empty = TRUE;
1778 gboolean all_marked_as_deleted = TRUE;
1780 g_return_if_fail (TNY_IS_FOLDER (folder));
1782 win = MODEST_MAIN_WINDOW (user_data);
1784 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1787 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1788 if (current_folder != NULL && folder != current_folder) {
1793 /* Check if folder is empty and set headers view contents style */
1794 folder_empty = (tny_folder_get_all_count (folder) == 0);
1795 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1796 folder_empty = folder_empty || all_marked_as_deleted ;
1799 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1800 modest_main_window_set_contents_style (win,
1801 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1803 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1808 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1809 TnyFolderStore *folder_store,
1811 ModestMainWindow *main_window)
1814 GtkWidget *header_view;
1816 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1818 header_view = modest_main_window_get_child_widget(main_window,
1819 MODEST_WIDGET_TYPE_HEADER_VIEW);
1823 conf = modest_runtime_get_conf ();
1825 if (TNY_IS_ACCOUNT (folder_store)) {
1827 /* Update active account */
1828 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1829 /* Show account details */
1830 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1833 if (TNY_IS_FOLDER (folder_store) && selected) {
1835 /* Update the active account */
1836 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1838 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1839 g_object_unref (account);
1843 /* Set the header style by default, it could
1844 be changed later by the refresh callback to
1846 modest_main_window_set_contents_style (main_window,
1847 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1849 /* Set folder on header view. This function
1850 will call tny_folder_refresh_async so we
1851 pass a callback that will be called when
1852 finished. We use that callback to set the
1853 empty view if there are no messages */
1854 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1855 TNY_FOLDER (folder_store),
1856 folder_refreshed_cb,
1859 /* Restore configuration. We need to do this
1860 *after* the set_folder because the widget
1861 memory asks the header view about its
1863 modest_widget_memory_restore (modest_runtime_get_conf (),
1864 G_OBJECT(header_view),
1865 MODEST_CONF_HEADER_VIEW_KEY);
1867 /* Update the active account */
1868 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1869 /* Save only if we're seeing headers */
1870 if (modest_main_window_get_contents_style (main_window) ==
1871 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1872 modest_widget_memory_save (conf, G_OBJECT (header_view),
1873 MODEST_CONF_HEADER_VIEW_KEY);
1874 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1878 /* Update toolbar dimming state */
1879 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1883 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1890 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1892 online = tny_device_is_online (modest_runtime_get_device());
1895 /* already online -- the item is simply not there... */
1896 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1898 GTK_MESSAGE_WARNING,
1900 _("The %s you selected cannot be found"),
1902 gtk_dialog_run (GTK_DIALOG(dialog));
1904 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1908 GTK_RESPONSE_REJECT,
1910 GTK_RESPONSE_ACCEPT,
1912 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1913 "Do you want to get online?"), item);
1914 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1915 gtk_label_new (txt), FALSE, FALSE, 0);
1916 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1919 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1920 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1921 /* TODO: Comment about why is this commented out: */
1922 /* modest_platform_connect_and_wait (); */
1925 gtk_widget_destroy (dialog);
1929 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1932 /* g_message ("%s %s", __FUNCTION__, link); */
1937 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1940 modest_platform_activate_uri (link);
1944 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1947 modest_platform_show_uri_popup (link);
1951 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1954 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1958 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1959 const gchar *address,
1962 /* g_message ("%s %s", __FUNCTION__, address); */
1966 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1968 TnyTransportAccount *transport_account;
1969 ModestMailOperation *mail_operation;
1971 gchar *account_name, *from;
1972 ModestAccountMgr *account_mgr;
1973 gchar *info_text = NULL;
1975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1977 data = modest_msg_edit_window_get_msg_data (edit_window);
1979 account_mgr = modest_runtime_get_account_mgr();
1980 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1982 account_name = modest_account_mgr_get_default_account (account_mgr);
1983 if (!account_name) {
1984 g_printerr ("modest: no account found\n");
1985 modest_msg_edit_window_free_msg_data (edit_window, data);
1989 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1990 account_name = g_strdup (data->account_name);
1994 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1995 (modest_runtime_get_account_store(),
1997 TNY_ACCOUNT_TYPE_TRANSPORT));
1998 if (!transport_account) {
1999 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2000 g_free (account_name);
2001 modest_msg_edit_window_free_msg_data (edit_window, data);
2004 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2006 /* Create the mail operation */
2007 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2008 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2010 modest_mail_operation_save_to_drafts (mail_operation,
2022 data->priority_flags);
2025 g_free (account_name);
2026 g_object_unref (G_OBJECT (transport_account));
2027 g_object_unref (G_OBJECT (mail_operation));
2029 modest_msg_edit_window_free_msg_data (edit_window, data);
2031 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2032 modest_platform_information_banner (NULL, NULL, info_text);
2036 /* For instance, when clicking the Send toolbar button when editing a message: */
2038 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2040 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2042 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2045 /* Offer the connection dialog, if necessary: */
2046 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2049 /* FIXME: Code added just for testing. The final version will
2050 use the send queue provided by tinymail and some
2052 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2053 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2055 account_name = modest_account_mgr_get_default_account (account_mgr);
2057 if (!account_name) {
2058 /* Run account setup wizard */
2059 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2064 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2066 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2067 account_name = g_strdup (data->account_name);
2070 /* Get the currently-active transport account for this modest account: */
2071 TnyTransportAccount *transport_account =
2072 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2073 (modest_runtime_get_account_store(),
2075 if (!transport_account) {
2076 /* Run account setup wizard */
2077 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2082 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2084 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2086 /* Create the mail operation */
2087 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2088 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2090 modest_mail_operation_send_new_mail (mail_operation,
2101 data->priority_flags);
2105 g_free (account_name);
2106 g_object_unref (G_OBJECT (transport_account));
2107 g_object_unref (G_OBJECT (mail_operation));
2109 modest_msg_edit_window_free_msg_data (edit_window, data);
2110 modest_msg_edit_window_set_sent (edit_window, TRUE);
2112 /* Save settings and close the window: */
2113 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2117 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2118 ModestMsgEditWindow *window)
2120 ModestMsgEditFormatState *format_state = NULL;
2122 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2123 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2125 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2128 format_state = modest_msg_edit_window_get_format_state (window);
2129 g_return_if_fail (format_state != NULL);
2131 format_state->bold = gtk_toggle_action_get_active (action);
2132 modest_msg_edit_window_set_format_state (window, format_state);
2133 g_free (format_state);
2138 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2139 ModestMsgEditWindow *window)
2141 ModestMsgEditFormatState *format_state = NULL;
2143 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2144 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2146 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2149 format_state = modest_msg_edit_window_get_format_state (window);
2150 g_return_if_fail (format_state != NULL);
2152 format_state->italics = gtk_toggle_action_get_active (action);
2153 modest_msg_edit_window_set_format_state (window, format_state);
2154 g_free (format_state);
2159 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2160 ModestMsgEditWindow *window)
2162 ModestMsgEditFormatState *format_state = NULL;
2164 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2165 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2167 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2170 format_state = modest_msg_edit_window_get_format_state (window);
2171 g_return_if_fail (format_state != NULL);
2173 format_state->bullet = gtk_toggle_action_get_active (action);
2174 modest_msg_edit_window_set_format_state (window, format_state);
2175 g_free (format_state);
2180 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2181 GtkRadioAction *selected,
2182 ModestMsgEditWindow *window)
2184 ModestMsgEditFormatState *format_state = NULL;
2185 GtkJustification value;
2187 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2189 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2192 value = gtk_radio_action_get_current_value (selected);
2194 format_state = modest_msg_edit_window_get_format_state (window);
2195 g_return_if_fail (format_state != NULL);
2197 format_state->justification = value;
2198 modest_msg_edit_window_set_format_state (window, format_state);
2199 g_free (format_state);
2203 modest_ui_actions_on_select_editor_color (GtkAction *action,
2204 ModestMsgEditWindow *window)
2206 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2207 g_return_if_fail (GTK_IS_ACTION (action));
2209 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2212 modest_msg_edit_window_select_color (window);
2216 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2217 ModestMsgEditWindow *window)
2219 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2220 g_return_if_fail (GTK_IS_ACTION (action));
2222 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2225 modest_msg_edit_window_select_background_color (window);
2229 modest_ui_actions_on_insert_image (GtkAction *action,
2230 ModestMsgEditWindow *window)
2232 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2233 g_return_if_fail (GTK_IS_ACTION (action));
2235 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2238 modest_msg_edit_window_insert_image (window);
2242 modest_ui_actions_on_attach_file (GtkAction *action,
2243 ModestMsgEditWindow *window)
2245 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2246 g_return_if_fail (GTK_IS_ACTION (action));
2248 modest_msg_edit_window_offer_attach_file (window);
2252 modest_ui_actions_on_remove_attachments (GtkAction *action,
2253 ModestMsgEditWindow *window)
2255 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2256 g_return_if_fail (GTK_IS_ACTION (action));
2258 modest_msg_edit_window_remove_attachments (window, NULL);
2262 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2265 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2266 const GError *error = modest_mail_operation_get_error (mail_op);
2270 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2271 modest_mail_operation_get_error (mail_op)->message);
2276 modest_ui_actions_create_folder(GtkWidget *parent_window,
2277 GtkWidget *folder_view)
2279 TnyFolderStore *parent_folder;
2281 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2283 if (parent_folder) {
2284 gboolean finished = FALSE;
2286 gchar *folder_name = NULL, *suggested_name = NULL;
2287 const gchar *proto_str = NULL;
2288 TnyAccount *account;
2290 if (TNY_IS_ACCOUNT (parent_folder))
2291 account = g_object_ref (parent_folder);
2293 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2294 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2296 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2297 MODEST_PROTOCOL_STORE_POP) {
2299 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2301 g_object_unref (account);
2303 /* Run the new folder dialog */
2305 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2310 g_free (suggested_name);
2311 suggested_name = NULL;
2313 if (result == GTK_RESPONSE_REJECT) {
2316 ModestMailOperation *mail_op;
2317 TnyFolder *new_folder = NULL;
2319 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2320 G_OBJECT(parent_window),
2321 modest_ui_actions_new_folder_error_handler,
2324 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2326 new_folder = modest_mail_operation_create_folder (mail_op,
2328 (const gchar *) folder_name);
2330 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2333 g_object_unref (new_folder);
2336 g_object_unref (mail_op);
2339 suggested_name = folder_name;
2343 g_object_unref (parent_folder);
2348 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2350 GtkWidget *folder_view;
2352 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2354 folder_view = modest_main_window_get_child_widget (main_window,
2355 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2359 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2363 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2366 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2367 const GError *error = NULL;
2368 const gchar *message = NULL;
2370 /* Get error message */
2371 error = modest_mail_operation_get_error (mail_op);
2372 if (error != NULL && error->message != NULL) {
2373 message = error->message;
2375 message = _("!!! FIXME: Unable to rename");
2378 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2383 modest_ui_actions_on_rename_folder (GtkAction *action,
2384 ModestMainWindow *main_window)
2386 TnyFolderStore *folder;
2387 GtkWidget *folder_view;
2388 GtkWidget *header_view;
2390 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2392 folder_view = modest_main_window_get_child_widget (main_window,
2393 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2397 header_view = modest_main_window_get_child_widget (main_window,
2398 MODEST_WIDGET_TYPE_HEADER_VIEW);
2403 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2407 /* Offer the connection dialog if necessary: */
2408 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2409 g_object_unref (G_OBJECT (folder));
2414 if (TNY_IS_FOLDER (folder)) {
2417 const gchar *current_name;
2419 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2420 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2421 current_name, &folder_name);
2423 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2424 ModestMailOperation *mail_op;
2427 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2428 G_OBJECT(main_window),
2429 modest_ui_actions_rename_folder_error_handler,
2432 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2435 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2437 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2438 TNY_FOLDER(folder), TRUE);
2440 modest_header_view_clear ((ModestHeaderView *) header_view);
2442 modest_mail_operation_rename_folder (mail_op,
2443 TNY_FOLDER (folder),
2444 (const gchar *) folder_name);
2446 g_object_unref (mail_op);
2447 g_free (folder_name);
2450 g_object_unref (folder);
2454 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2457 GObject *win = modest_mail_operation_get_source (mail_op);
2459 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2460 _("mail_in_ui_folder_delete_error"));
2461 g_object_unref (win);
2465 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2467 TnyFolderStore *folder;
2468 GtkWidget *folder_view;
2472 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2474 folder_view = modest_main_window_get_child_widget (main_window,
2475 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2479 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2481 /* Show an error if it's an account */
2482 if (!TNY_IS_FOLDER (folder)) {
2483 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2484 _("mail_in_ui_folder_delete_error"));
2485 g_object_unref (G_OBJECT (folder));
2489 /* Offer the connection dialog if necessary: */
2490 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2491 g_object_unref (G_OBJECT (folder));
2496 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2497 tny_folder_get_name (TNY_FOLDER (folder)));
2498 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2499 (const gchar *) message);
2502 if (response == GTK_RESPONSE_OK) {
2503 ModestMailOperation *mail_op =
2504 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2505 G_OBJECT(main_window),
2506 modest_ui_actions_delete_folder_error_handler,
2509 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2511 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2512 g_object_unref (G_OBJECT (mail_op));
2515 g_object_unref (G_OBJECT (folder));
2519 modest_ui_actions_on_delete_folder (GtkAction *action,
2520 ModestMainWindow *main_window)
2522 GtkWidget *folder_view;
2523 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2525 delete_folder (main_window, FALSE);
2526 folder_view = modest_main_window_get_child_widget (main_window,
2527 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2530 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2534 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2536 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2538 delete_folder (main_window, TRUE);
2543 show_error (GtkWidget *parent_widget, const gchar* text)
2545 hildon_banner_show_information(parent_widget, NULL, text);
2548 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2550 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2557 gtk_dialog_run (dialog);
2558 gtk_widget_destroy (GTK_WIDGET (dialog));
2563 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2564 const gchar* server_account_name,
2569 ModestMainWindow *main_window)
2571 g_return_if_fail(server_account_name);
2572 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2574 /* Initalize output parameters: */
2581 #ifdef MODEST_PLATFORM_MAEMO
2582 /* Maemo uses a different (awkward) button order,
2583 * It should probably just use gtk_alternative_dialog_button_order ().
2585 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2589 GTK_RESPONSE_ACCEPT,
2591 GTK_RESPONSE_REJECT,
2594 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2598 GTK_RESPONSE_REJECT,
2600 GTK_RESPONSE_ACCEPT,
2602 #endif /* MODEST_PLATFORM_MAEMO */
2604 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2606 gchar *server_name = modest_server_account_get_hostname (
2607 modest_runtime_get_account_mgr(), server_account_name);
2608 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2609 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2614 /* This causes a warning because the logical ID has no %s in it,
2615 * though the translation does, but there is not much we can do about that: */
2616 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2617 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2620 g_free (server_name);
2624 gchar *initial_username = modest_server_account_get_username (
2625 modest_runtime_get_account_mgr(), server_account_name);
2627 GtkWidget *entry_username = gtk_entry_new ();
2628 if (initial_username)
2629 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2630 /* Dim this if a connection has ever succeeded with this username,
2631 * as per the UI spec: */
2632 const gboolean username_known =
2633 modest_server_account_get_username_has_succeeded(
2634 modest_runtime_get_account_mgr(), server_account_name);
2635 gtk_widget_set_sensitive (entry_username, !username_known);
2637 #ifdef MODEST_PLATFORM_MAEMO
2638 /* Auto-capitalization is the default, so let's turn it off: */
2639 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2641 /* Create a size group to be used by all captions.
2642 * Note that HildonCaption does not create a default size group if we do not specify one.
2643 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2644 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2646 GtkWidget *caption = hildon_caption_new (sizegroup,
2647 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2648 gtk_widget_show (entry_username);
2649 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2650 FALSE, FALSE, MODEST_MARGIN_HALF);
2651 gtk_widget_show (caption);
2653 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2655 #endif /* MODEST_PLATFORM_MAEMO */
2658 GtkWidget *entry_password = gtk_entry_new ();
2659 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2660 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2662 #ifdef MODEST_PLATFORM_MAEMO
2663 /* Auto-capitalization is the default, so let's turn it off: */
2664 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2665 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2667 caption = hildon_caption_new (sizegroup,
2668 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2669 gtk_widget_show (entry_password);
2670 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2671 FALSE, FALSE, MODEST_MARGIN_HALF);
2672 gtk_widget_show (caption);
2673 g_object_unref (sizegroup);
2675 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2677 #endif /* MODEST_PLATFORM_MAEMO */
2679 /* This is not in the Maemo UI spec:
2680 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2681 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2685 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2687 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2689 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2691 modest_server_account_set_username (
2692 modest_runtime_get_account_mgr(), server_account_name,
2695 const gboolean username_was_changed =
2696 (strcmp (*username, initial_username) != 0);
2697 if (username_was_changed) {
2698 g_warning ("%s: tinymail does not yet support changing the "
2699 "username in the get_password() callback.\n", __FUNCTION__);
2704 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2706 /* We do not save the password in the configuration,
2707 * because this function is only called for passwords that should
2708 * not be remembered:
2709 modest_server_account_set_password (
2710 modest_runtime_get_account_mgr(), server_account_name,
2719 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2731 /* This is not in the Maemo UI spec:
2732 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2738 gtk_widget_destroy (dialog);
2740 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2744 modest_ui_actions_on_cut (GtkAction *action,
2745 ModestWindow *window)
2747 GtkWidget *focused_widget;
2748 GtkClipboard *clipboard;
2750 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2751 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2752 if (GTK_IS_EDITABLE (focused_widget)) {
2753 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2754 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2755 gtk_clipboard_store (clipboard);
2756 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2757 GtkTextBuffer *buffer;
2759 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2760 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2761 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2762 gtk_clipboard_store (clipboard);
2763 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2764 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2765 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2766 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2771 modest_ui_actions_on_copy (GtkAction *action,
2772 ModestWindow *window)
2774 GtkClipboard *clipboard;
2775 GtkWidget *focused_widget;
2777 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2778 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2780 if (GTK_IS_LABEL (focused_widget)) {
2781 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2782 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2783 gtk_clipboard_store (clipboard);
2784 } else if (GTK_IS_EDITABLE (focused_widget)) {
2785 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2786 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2787 gtk_clipboard_store (clipboard);
2788 } else if (GTK_IS_HTML (focused_widget)) {
2789 gtk_html_copy (GTK_HTML (focused_widget));
2790 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2791 gtk_clipboard_store (clipboard);
2792 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2793 GtkTextBuffer *buffer;
2794 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2795 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2796 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2797 gtk_clipboard_store (clipboard);
2798 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2799 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2800 TnyIterator *iter = tny_list_create_iterator (header_list);
2801 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2803 gboolean ask = FALSE;
2805 TnyFolder *folder = tny_header_get_folder (header);
2806 TnyAccount *account = tny_folder_get_account (folder);
2807 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2808 /* If it's POP then ask */
2809 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2810 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2811 g_object_unref (account);
2812 g_object_unref (folder);
2813 g_object_unref (header);
2816 g_object_unref (iter);
2818 /* Check that the messages have been previously downloaded */
2819 gboolean continue_download = TRUE;
2821 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2822 if (continue_download)
2823 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2824 g_object_unref (header_list);
2825 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2826 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2829 /* Show information banner */
2830 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2835 modest_ui_actions_on_undo (GtkAction *action,
2836 ModestWindow *window)
2838 ModestEmailClipboard *clipboard = NULL;
2840 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2841 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2842 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2843 /* Clear clipboard source */
2844 clipboard = modest_runtime_get_email_clipboard ();
2845 modest_email_clipboard_clear (clipboard);
2848 g_return_if_reached ();
2853 modest_ui_actions_on_redo (GtkAction *action,
2854 ModestWindow *window)
2856 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2857 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2860 g_return_if_reached ();
2866 paste_msgs_cb (const GObject *object, gpointer user_data)
2868 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2869 g_return_if_fail (GTK_IS_WIDGET (user_data));
2871 /* destroy information note */
2872 gtk_widget_destroy (GTK_WIDGET(user_data));
2876 paste_as_attachment_free (gpointer data)
2878 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2880 gtk_widget_destroy (helper->banner);
2881 g_object_unref (helper->banner);
2886 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2891 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2892 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2897 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2902 modest_ui_actions_on_paste (GtkAction *action,
2903 ModestWindow *window)
2905 GtkWidget *focused_widget = NULL;
2906 GtkWidget *inf_note = NULL;
2907 ModestMailOperation *mail_op = NULL;
2909 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2910 if (GTK_IS_EDITABLE (focused_widget)) {
2911 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2912 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2913 ModestEmailClipboard *e_clipboard = NULL;
2914 e_clipboard = modest_runtime_get_email_clipboard ();
2915 if (modest_email_clipboard_cleared (e_clipboard)) {
2916 GtkTextBuffer *buffer;
2917 GtkClipboard *clipboard;
2919 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2920 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2921 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2922 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2923 ModestMailOperation *mail_op;
2924 TnyFolder *src_folder;
2927 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2928 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2929 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2930 _CS("ckct_nw_pasting"));
2931 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2932 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2934 if (helper->banner != NULL) {
2935 g_object_ref (G_OBJECT (helper->banner));
2936 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2937 gtk_widget_show (GTK_WIDGET (helper->banner));
2941 modest_mail_operation_get_msgs_full (mail_op,
2943 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2945 paste_as_attachment_free);
2948 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2949 ModestEmailClipboard *clipboard = NULL;
2950 TnyFolder *src_folder = NULL;
2951 TnyFolderStore *folder_store = NULL;
2952 TnyList *data = NULL;
2953 gboolean delete = FALSE;
2955 /* Check clipboard source */
2956 clipboard = modest_runtime_get_email_clipboard ();
2957 if (modest_email_clipboard_cleared (clipboard))
2960 /* Get elements to paste */
2961 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2963 /* Create a new mail operation */
2964 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2966 /* Get destination folder */
2967 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2969 /* transfer messages */
2973 /* Ask for user confirmation */
2974 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2975 TNY_FOLDER (folder_store),
2979 if (response == GTK_RESPONSE_OK) {
2980 /* Launch notification */
2981 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2982 _CS("ckct_nw_pasting"));
2983 if (inf_note != NULL) {
2984 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2985 gtk_widget_show (GTK_WIDGET(inf_note));
2988 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2989 modest_mail_operation_xfer_msgs (mail_op,
2991 TNY_FOLDER (folder_store),
2996 g_object_unref (mail_op);
2999 } else if (src_folder != NULL) {
3000 /* Launch notification */
3001 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3002 _CS("ckct_nw_pasting"));
3003 if (inf_note != NULL) {
3004 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3005 gtk_widget_show (GTK_WIDGET(inf_note));
3008 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3009 modest_mail_operation_xfer_folder (mail_op,
3019 g_object_unref (data);
3020 if (src_folder != NULL)
3021 g_object_unref (src_folder);
3022 if (folder_store != NULL)
3023 g_object_unref (folder_store);
3029 modest_ui_actions_on_select_all (GtkAction *action,
3030 ModestWindow *window)
3032 GtkWidget *focused_widget;
3034 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3035 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3036 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3037 } else if (GTK_IS_LABEL (focused_widget)) {
3038 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3039 } else if (GTK_IS_EDITABLE (focused_widget)) {
3040 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3041 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3042 GtkTextBuffer *buffer;
3043 GtkTextIter start, end;
3045 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3046 gtk_text_buffer_get_start_iter (buffer, &start);
3047 gtk_text_buffer_get_end_iter (buffer, &end);
3048 gtk_text_buffer_select_range (buffer, &start, &end);
3049 } else if (GTK_IS_HTML (focused_widget)) {
3050 gtk_html_select_all (GTK_HTML (focused_widget));
3051 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3052 GtkWidget *header_view = focused_widget;
3053 GtkTreeSelection *selection = NULL;
3055 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3056 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3057 MODEST_WIDGET_TYPE_HEADER_VIEW);
3059 /* Select all messages */
3060 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3061 gtk_tree_selection_select_all (selection);
3063 /* Set focuse on header view */
3064 gtk_widget_grab_focus (header_view);
3070 modest_ui_actions_on_mark_as_read (GtkAction *action,
3071 ModestWindow *window)
3073 g_return_if_fail (MODEST_IS_WINDOW(window));
3075 /* Mark each header as read */
3076 do_headers_action (window, headers_action_mark_as_read, NULL);
3080 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3081 ModestWindow *window)
3083 g_return_if_fail (MODEST_IS_WINDOW(window));
3085 /* Mark each header as read */
3086 do_headers_action (window, headers_action_mark_as_unread, NULL);
3090 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3091 GtkRadioAction *selected,
3092 ModestWindow *window)
3096 value = gtk_radio_action_get_current_value (selected);
3097 if (MODEST_IS_WINDOW (window)) {
3098 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3102 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3103 GtkRadioAction *selected,
3104 ModestWindow *window)
3106 TnyHeaderFlags flags;
3107 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3109 flags = gtk_radio_action_get_current_value (selected);
3110 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3113 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3114 GtkRadioAction *selected,
3115 ModestWindow *window)
3119 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3121 file_format = gtk_radio_action_get_current_value (selected);
3122 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3127 modest_ui_actions_on_zoom_plus (GtkAction *action,
3128 ModestWindow *window)
3130 g_return_if_fail (MODEST_IS_WINDOW (window));
3132 modest_window_zoom_plus (MODEST_WINDOW (window));
3136 modest_ui_actions_on_zoom_minus (GtkAction *action,
3137 ModestWindow *window)
3139 g_return_if_fail (MODEST_IS_WINDOW (window));
3141 modest_window_zoom_minus (MODEST_WINDOW (window));
3145 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3146 ModestWindow *window)
3148 ModestWindowMgr *mgr;
3149 gboolean fullscreen, active;
3150 g_return_if_fail (MODEST_IS_WINDOW (window));
3152 mgr = modest_runtime_get_window_mgr ();
3154 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3155 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3157 if (active != fullscreen) {
3158 modest_window_mgr_set_fullscreen_mode (mgr, active);
3159 gtk_window_present (GTK_WINDOW (window));
3164 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3165 ModestWindow *window)
3167 ModestWindowMgr *mgr;
3168 gboolean fullscreen;
3170 g_return_if_fail (MODEST_IS_WINDOW (window));
3172 mgr = modest_runtime_get_window_mgr ();
3173 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3174 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3176 gtk_window_present (GTK_WINDOW (window));
3180 * Used by modest_ui_actions_on_details to call do_headers_action
3183 headers_action_show_details (TnyHeader *header,
3184 ModestWindow *window,
3191 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3194 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3195 gtk_widget_show_all (dialog);
3196 gtk_dialog_run (GTK_DIALOG (dialog));
3198 gtk_widget_destroy (dialog);
3202 * Show the folder details in a ModestDetailsDialog widget
3205 show_folder_details (TnyFolder *folder,
3211 dialog = modest_details_dialog_new_with_folder (window, folder);
3214 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3215 gtk_widget_show_all (dialog);
3216 gtk_dialog_run (GTK_DIALOG (dialog));
3218 gtk_widget_destroy (dialog);
3222 * Show the header details in a ModestDetailsDialog widget
3225 modest_ui_actions_on_details (GtkAction *action,
3228 TnyList * headers_list;
3232 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3235 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3238 g_object_unref (msg);
3240 headers_list = get_selected_headers (win);
3244 iter = tny_list_create_iterator (headers_list);
3246 header = TNY_HEADER (tny_iterator_get_current (iter));
3248 headers_action_show_details (header, win, NULL);
3249 g_object_unref (header);
3252 g_object_unref (iter);
3253 g_object_unref (headers_list);
3255 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3256 GtkWidget *folder_view, *header_view;
3258 /* Check which widget has the focus */
3259 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3260 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3261 if (gtk_widget_is_focus (folder_view)) {
3262 TnyFolderStore *folder_store
3263 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3264 if (!folder_store) {
3265 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3268 /* Show only when it's a folder */
3269 /* This function should not be called for account items,
3270 * because we dim the menu item for them. */
3271 if (TNY_IS_FOLDER (folder_store)) {
3272 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3275 g_object_unref (folder_store);
3278 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3279 MODEST_WIDGET_TYPE_HEADER_VIEW);
3280 /* Show details of each header */
3281 do_headers_action (win, headers_action_show_details, header_view);
3287 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3288 ModestMsgEditWindow *window)
3290 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3292 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3296 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3297 ModestMsgEditWindow *window)
3299 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3301 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3305 modest_ui_actions_toggle_folders_view (GtkAction *action,
3306 ModestMainWindow *main_window)
3308 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3310 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3311 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3313 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3317 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3318 ModestWindow *window)
3320 gboolean active, fullscreen = FALSE;
3321 ModestWindowMgr *mgr;
3323 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3325 /* Check if we want to toggle the toolbar vuew in fullscreen
3327 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3328 "ViewShowToolbarFullScreen")) {
3332 /* Toggle toolbar */
3333 mgr = modest_runtime_get_window_mgr ();
3334 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3338 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3339 ModestMsgEditWindow *window)
3341 modest_msg_edit_window_select_font (window);
3345 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3346 const gchar *display_name,
3349 /* Do not change the application name if the widget has not
3350 the focus. This callback could be called even if the folder
3351 view has not the focus, because the handled signal could be
3352 emitted when the folder view is redrawn */
3353 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3355 gtk_window_set_title (window, display_name);
3357 gtk_window_set_title (window, " ");
3362 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3365 modest_msg_edit_window_select_contacts (window);
3369 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3371 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3372 modest_msg_edit_window_check_names (window, FALSE);
3376 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3378 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3379 GTK_WIDGET (user_data));
3383 create_move_to_dialog (GtkWindow *win,
3384 GtkWidget *folder_view,
3385 GtkWidget **tree_view)
3387 GtkWidget *dialog, *scroll;
3388 GtkWidget *new_button;
3390 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3392 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3395 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3396 /* We do this manually so GTK+ does not associate a response ID for
3398 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3399 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3400 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3402 /* Create scrolled window */
3403 scroll = gtk_scrolled_window_new (NULL, NULL);
3404 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3405 GTK_POLICY_AUTOMATIC,
3406 GTK_POLICY_AUTOMATIC);
3408 /* Create folder view */
3409 *tree_view = modest_platform_create_folder_view (NULL);
3411 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3413 /* It could happen that we're trying to move a message from a
3414 window (msg window for example) after the main window was
3415 closed, so we can not just get the model of the folder
3417 if (MODEST_IS_FOLDER_VIEW (folder_view))
3418 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3419 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3421 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3422 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3424 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3426 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3428 /* Add scroll to dialog */
3429 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3430 scroll, TRUE, TRUE, 0);
3432 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3433 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3439 * Returns TRUE if at least one of the headers of the list belongs to
3440 * a message that has been fully retrieved.
3443 has_retrieved_msgs (TnyList *list)
3446 gboolean found = FALSE;
3448 iter = tny_list_create_iterator (list);
3449 while (!tny_iterator_is_done (iter) && !found) {
3451 TnyHeaderFlags flags = 0;
3453 header = TNY_HEADER (tny_iterator_get_current (iter));
3455 flags = tny_header_get_flags (header);
3456 if (flags & TNY_HEADER_FLAG_CACHED)
3457 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3460 g_object_unref (header);
3464 tny_iterator_next (iter);
3466 g_object_unref (iter);
3472 * Shows a confirmation dialog to the user when we're moving messages
3473 * from a remote server to the local storage. Returns the dialog
3474 * response. If it's other kind of movement the it always returns
3478 msgs_move_to_confirmation (GtkWindow *win,
3479 TnyFolder *dest_folder,
3483 gint response = GTK_RESPONSE_OK;
3485 /* If the destination is a local folder (or MMC folder )*/
3486 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3487 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3488 TnyFolder *src_folder = NULL;
3489 TnyIterator *iter = NULL;
3490 TnyHeader *header = NULL;
3492 /* Get source folder */
3493 iter = tny_list_create_iterator (headers);
3494 header = TNY_HEADER (tny_iterator_get_current (iter));
3496 src_folder = tny_header_get_folder (header);
3497 g_object_unref (header);
3500 g_object_unref (iter);
3502 /* if no src_folder, message may be an attahcment */
3503 if (src_folder == NULL)
3504 return GTK_RESPONSE_CANCEL;
3506 /* If the source is a remote folder */
3507 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3508 if (modest_tny_folder_is_remote_folder (src_folder)) {
3509 const gchar *message = NULL;
3510 gboolean cached = has_retrieved_msgs (headers);
3512 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3513 tny_list_get_length (headers));
3515 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3516 tny_list_get_length (headers));
3518 if (cached && !delete)
3519 response = GTK_RESPONSE_OK;
3521 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3522 (const gchar *) message);
3525 g_object_unref (src_folder);
3534 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3536 ModestMsgViewWindow *self = NULL;
3538 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3539 self = MODEST_MSG_VIEW_WINDOW (object);
3541 if (!modest_msg_view_window_select_next_message (self))
3542 if (!modest_msg_view_window_select_previous_message (self))
3543 /* No more messages to view, so close this window */
3544 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3548 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3551 GObject *win = modest_mail_operation_get_source (mail_op);
3552 const GError *error = NULL;
3553 const gchar *message = NULL;
3555 /* Get error message */
3556 error = modest_mail_operation_get_error (mail_op);
3557 if (error != NULL && error->message != NULL) {
3558 message = error->message;
3560 message = _("mail_in_ui_folder_move_target_error");
3563 /* Show notification dialog */
3564 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3565 g_object_unref (win);
3569 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3572 GObject *win = modest_mail_operation_get_source (mail_op);
3573 const GError *error = modest_mail_operation_get_error (mail_op);
3575 g_return_if_fail (error != NULL);
3576 if (error->message != NULL)
3577 g_printerr ("modest: %s\n", error->message);
3579 g_printerr ("modest: unkonw error on send&receive operation");
3581 /* Show error message */
3582 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3583 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3584 /* _CS("sfil_ib_unable_to_receive")); */
3586 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3587 /* _CS("sfil_ib_unable_to_send")); */
3588 g_object_unref (win);
3592 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3599 gint pending_purges = 0;
3600 gboolean some_purged = FALSE;
3601 ModestWindow *win = MODEST_WINDOW (user_data);
3602 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3604 /* If there was any error */
3605 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3606 modest_window_mgr_unregister_header (mgr, header);
3610 /* Once the message has been retrieved for purging, we check if
3611 * it's all ok for purging */
3613 parts = tny_simple_list_new ();
3614 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3615 iter = tny_list_create_iterator (parts);
3617 while (!tny_iterator_is_done (iter)) {
3619 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3620 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3621 if (tny_mime_part_is_purged (part))
3628 g_object_unref (part);
3630 tny_iterator_next (iter);
3633 if (pending_purges>0) {
3635 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3637 if (response == GTK_RESPONSE_OK) {
3638 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3639 tny_iterator_first (iter);
3640 while (!tny_iterator_is_done (iter)) {
3643 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3644 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3645 tny_mime_part_set_purged (part);
3648 g_object_unref (part);
3650 tny_iterator_next (iter);
3653 tny_msg_rewrite_cache (msg);
3656 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3659 /* remove attachments */
3660 tny_iterator_first (iter);
3661 while (!tny_iterator_is_done (iter)) {
3664 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3666 /* One for the reference given by tny_iterator_get_current(): */
3667 g_object_unref (part);
3669 /* TODO: Is this meant to remove the attachment by doing another unref()?
3670 * Otherwise, this seems useless. */
3673 tny_iterator_next (iter);
3675 modest_window_mgr_unregister_header (mgr, header);
3677 g_object_unref (iter);
3678 g_object_unref (parts);
3682 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3683 ModestMainWindow *win)
3685 GtkWidget *header_view;
3686 TnyList *header_list;
3689 TnyHeaderFlags flags;
3690 ModestWindow *msg_view_window = NULL;
3693 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3695 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3696 MODEST_WIDGET_TYPE_HEADER_VIEW);
3698 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3700 if (tny_list_get_length (header_list) == 1) {
3701 iter = tny_list_create_iterator (header_list);
3702 header = TNY_HEADER (tny_iterator_get_current (iter));
3703 g_object_unref (iter);
3708 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3709 header, &msg_view_window);
3710 flags = tny_header_get_flags (header);
3711 if (!(flags & TNY_HEADER_FLAG_CACHED))
3714 if (msg_view_window != NULL)
3715 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3717 /* do nothing; uid was registered before, so window is probably on it's way */
3718 g_warning ("debug: header %p has already been registered", header);
3721 ModestMailOperation *mail_op = NULL;
3722 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3723 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3725 modest_ui_actions_get_msgs_full_error_handler,
3727 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3728 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3730 g_object_unref (mail_op);
3733 g_object_unref (header);
3735 g_object_unref (header_list);
3739 * Utility function that transfer messages from both the main window
3740 * and the msg view window when using the "Move to" dialog
3743 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3746 TnyList *headers = NULL;
3748 TnyAccount *dst_account = NULL;
3749 const gchar *proto_str = NULL;
3750 gboolean dst_is_pop = FALSE;
3752 if (!TNY_IS_FOLDER (dst_folder)) {
3753 modest_platform_information_banner (GTK_WIDGET (win),
3755 _CS("ckdg_ib_unable_to_move_to_current_location"));
3759 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3760 proto_str = tny_account_get_proto (dst_account);
3761 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3762 MODEST_PROTOCOL_STORE_POP);
3763 g_object_unref (dst_account);
3765 /* Get selected headers */
3766 headers = get_selected_headers (MODEST_WINDOW (win));
3769 modest_platform_information_banner (GTK_WIDGET (win),
3771 ngettext("mail_in_ui_folder_move_target_error",
3772 "mail_in_ui_folder_move_targets_error",
3773 tny_list_get_length (headers)));
3774 g_object_unref (headers);
3778 /* Ask for user confirmation */
3779 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3780 TNY_FOLDER (dst_folder),
3784 /* Transfer messages */
3785 if (response == GTK_RESPONSE_OK) {
3786 ModestMailOperation *mail_op =
3787 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3789 modest_ui_actions_move_folder_error_handler,
3791 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3794 modest_mail_operation_xfer_msgs (mail_op,
3796 TNY_FOLDER (dst_folder),
3798 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3801 g_object_unref (G_OBJECT (mail_op));
3803 g_object_unref (headers);
3808 * UI handler for the "Move to" action when invoked from the
3812 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3813 GtkWidget *folder_view,
3814 TnyFolderStore *dst_folder,
3815 ModestMainWindow *win)
3817 GtkWidget *header_view = NULL;
3818 ModestMailOperation *mail_op = NULL;
3819 TnyFolderStore *src_folder;
3821 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3823 /* Get the source folder */
3824 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3826 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3827 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3831 /* Get header view */
3833 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3835 /* Get folder or messages to transfer */
3836 if (gtk_widget_is_focus (folder_view)) {
3838 /* Allow only to transfer folders to the local root folder */
3839 if (TNY_IS_ACCOUNT (dst_folder) &&
3840 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3843 /* Clean folder on header view before moving it */
3844 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3846 if (TNY_IS_FOLDER (src_folder)) {
3848 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3850 modest_ui_actions_move_folder_error_handler,
3852 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3855 modest_mail_operation_xfer_folder (mail_op,
3856 TNY_FOLDER (src_folder),
3859 /* Unref mail operation */
3860 g_object_unref (G_OBJECT (mail_op));
3862 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3864 } else if (gtk_widget_is_focus (header_view)) {
3865 /* Transfer messages */
3866 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3871 g_object_unref (src_folder);
3876 * UI handler for the "Move to" action when invoked from the
3877 * ModestMsgViewWindow
3880 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3881 TnyFolderStore *dst_folder,
3882 ModestMsgViewWindow *win)
3884 TnyHeader *header = NULL;
3885 TnyFolder *src_folder;
3887 /* Create header list */
3888 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3889 src_folder = tny_header_get_folder(header);
3890 g_object_unref (header);
3892 /* Transfer the message */
3893 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3894 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3896 g_object_unref (src_folder);
3900 modest_ui_actions_on_move_to (GtkAction *action,
3903 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3905 TnyFolderStore *dst_folder = NULL;
3906 ModestMainWindow *main_window;
3908 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3909 MODEST_IS_MSG_VIEW_WINDOW (win));
3911 /* Get the main window if exists */
3912 if (MODEST_IS_MAIN_WINDOW (win))
3913 main_window = MODEST_MAIN_WINDOW (win);
3916 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3918 /* Get the folder view widget if exists */
3920 folder_view = modest_main_window_get_child_widget (main_window,
3921 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3925 /* Create and run the dialog */
3926 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3927 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3928 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3929 result = gtk_dialog_run (GTK_DIALOG(dialog));
3930 g_object_ref (tree_view);
3931 gtk_widget_destroy (dialog);
3933 if (result != GTK_RESPONSE_ACCEPT)
3936 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3937 /* Offer the connection dialog if necessary: */
3938 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3941 /* Do window specific stuff */
3942 if (MODEST_IS_MAIN_WINDOW (win))
3943 modest_ui_actions_on_main_window_move_to (action,
3946 MODEST_MAIN_WINDOW (win));
3948 modest_ui_actions_on_msg_view_window_move_to (action,
3950 MODEST_MSG_VIEW_WINDOW (win));
3953 g_object_unref (dst_folder);
3957 * Calls #HeadersFunc for each header already selected in the main
3958 * window or the message currently being shown in the msg view window
3961 do_headers_action (ModestWindow *win,
3965 TnyList *headers_list = NULL;
3966 TnyIterator *iter = NULL;
3967 TnyHeader *header = NULL;
3968 TnyFolder *folder = NULL;
3971 headers_list = get_selected_headers (win);
3975 /* Get the folder */
3976 iter = tny_list_create_iterator (headers_list);
3977 header = TNY_HEADER (tny_iterator_get_current (iter));
3979 folder = tny_header_get_folder (header);
3980 g_object_unref (header);
3983 /* Call the function for each header */
3984 while (!tny_iterator_is_done (iter)) {
3985 header = TNY_HEADER (tny_iterator_get_current (iter));
3986 func (header, win, user_data);
3987 g_object_unref (header);
3988 tny_iterator_next (iter);
3991 /* Trick: do a poke status in order to speed up the signaling
3993 tny_folder_poke_status (folder);
3996 g_object_unref (folder);
3997 g_object_unref (iter);
3998 g_object_unref (headers_list);
4002 modest_ui_actions_view_attachment (GtkAction *action,
4003 ModestWindow *window)
4005 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4006 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4008 /* not supported window for this action */
4009 g_return_if_reached ();
4014 modest_ui_actions_save_attachments (GtkAction *action,
4015 ModestWindow *window)
4017 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4018 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4020 /* not supported window for this action */
4021 g_return_if_reached ();
4026 modest_ui_actions_remove_attachments (GtkAction *action,
4027 ModestWindow *window)
4029 if (MODEST_IS_MAIN_WINDOW (window)) {
4030 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4031 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4032 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4034 /* not supported window for this action */
4035 g_return_if_reached ();
4040 modest_ui_actions_on_settings (GtkAction *action,
4045 dialog = modest_platform_get_global_settings_dialog ();
4046 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4047 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4048 gtk_widget_show_all (dialog);
4050 gtk_dialog_run (GTK_DIALOG (dialog));
4052 gtk_widget_destroy (dialog);
4056 modest_ui_actions_on_help (GtkAction *action,
4059 const gchar *help_id = NULL;
4061 if (MODEST_IS_MAIN_WINDOW (win)) {
4062 const gchar *action_name;
4063 action_name = gtk_action_get_name (action);
4065 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4066 !strcmp (action_name, "HeaderViewCSMHelp")) {
4067 GtkWidget *folder_view;
4068 TnyFolderStore *folder_store;
4069 /* Get selected folder */
4070 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4071 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4072 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4074 /* Switch help_id */
4075 if (TNY_IS_FOLDER (folder_store)) {
4076 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4077 case TNY_FOLDER_TYPE_NORMAL:
4078 help_id = "applications_email_managefolders";
4080 case TNY_FOLDER_TYPE_INBOX:
4081 help_id = "applications_email_inbox";
4083 case TNY_FOLDER_TYPE_OUTBOX:
4084 help_id = "applications_email_outbox";
4086 case TNY_FOLDER_TYPE_SENT:
4087 help_id = "applications_email_sent";
4089 case TNY_FOLDER_TYPE_DRAFTS:
4090 help_id = "applications_email_drafts";
4092 case TNY_FOLDER_TYPE_ARCHIVE:
4093 help_id = "applications_email_managefolders";
4096 help_id = "applications_email_managefolders";
4099 help_id = "applications_email_mainview";
4101 g_object_unref (folder_store);
4103 help_id = "applications_email_mainview";
4105 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4106 help_id = "applications_email_viewer";
4107 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4108 help_id = "applications_email_editor";
4110 modest_platform_show_help (GTK_WINDOW (win), help_id);
4114 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4115 ModestWindow *window)
4117 ModestMailOperation *mail_op;
4121 headers = get_selected_headers (window);
4125 /* Create mail operation */
4126 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4128 modest_ui_actions_get_msgs_full_error_handler,
4130 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4131 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4134 g_object_unref (headers);
4135 g_object_unref (mail_op);
4139 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4140 ModestWindow *window)
4142 g_return_if_fail (MODEST_IS_WINDOW (window));
4145 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4149 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4150 ModestWindow *window)
4152 g_return_if_fail (MODEST_IS_WINDOW (window));
4155 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4159 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4160 ModestWindow *window)
4162 g_return_if_fail (MODEST_IS_WINDOW (window));
4165 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4169 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4170 ModestWindow *window)
4172 g_return_if_fail (MODEST_IS_WINDOW (window));
4175 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4179 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4180 ModestWindow *window)
4182 g_return_if_fail (MODEST_IS_WINDOW (window));
4185 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4189 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4190 ModestWindow *window)
4192 g_return_if_fail (MODEST_IS_WINDOW (window));
4195 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4199 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4200 ModestWindow *window)
4202 g_return_if_fail (MODEST_IS_WINDOW (window));
4205 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4209 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4210 ModestWindow *window)
4212 g_return_if_fail (MODEST_IS_WINDOW (window));
4215 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4219 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4221 g_return_if_fail (MODEST_IS_WINDOW (window));
4224 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4228 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4230 g_return_if_fail (MODEST_IS_WINDOW (window));
4232 modest_platform_show_search_messages (GTK_WINDOW (window));
4236 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4238 g_return_if_fail (MODEST_IS_WINDOW (win));
4239 modest_platform_show_addressbook (GTK_WINDOW (win));
4244 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4245 ModestWindow *window)
4247 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4249 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4253 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4254 ModestMailOperationState *state,
4257 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4259 /* Set send/receive operation finished */
4260 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4261 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));