1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _PasteAsAttachmentHelper {
107 ModestMsgEditWindow *window;
109 } PasteAsAttachmentHelper;
113 * The do_headers_action uses this kind of functions to perform some
114 * action to each member of a list of headers
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
118 static void do_headers_action (ModestWindow *win,
122 static void open_msg_cb (ModestMailOperation *mail_op,
127 static void reply_forward_cb (ModestMailOperation *mail_op,
132 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
134 static void folder_refreshed_cb (ModestMailOperation *mail_op,
138 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
139 ModestMailOperationState *state,
143 download_uncached_messages (TnyList *header_list, GtkWindow *win);
147 msgs_move_to_confirmation (GtkWindow *win,
148 TnyFolder *dest_folder,
153 /* Show the account creation wizard dialog.
154 * returns: TRUE if an account was created. FALSE if the user cancelled.
157 modest_run_account_setup_wizard (ModestWindow *win)
159 gboolean result = FALSE;
160 ModestEasysetupWizardDialog *wizard;
163 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
165 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
167 wizard = modest_easysetup_wizard_dialog_new ();
168 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
170 /* Don't make this a modal window, because secondary windows will then
171 * be unusable, freezing the UI: */
172 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
174 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
175 if (dialog_response == GTK_RESPONSE_CANCEL)
178 /* Check whether an account was created: */
179 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
182 gtk_widget_destroy (GTK_WIDGET (wizard));
189 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
192 const gchar *authors[] = {
193 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
196 about = gtk_about_dialog_new ();
197 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
198 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
199 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
200 _("Copyright (c) 2006, Nokia Corporation\n"
201 "All rights reserved."));
202 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
203 _("a modest e-mail client\n\n"
204 "design and implementation: Dirk-Jan C. Binnema\n"
205 "contributions from the fine people at KC and Ig\n"
206 "uses the tinymail email framework written by Philip van Hoof"));
207 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
208 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
209 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
210 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
212 gtk_dialog_run (GTK_DIALOG (about));
213 gtk_widget_destroy(about);
217 * Gets the list of currently selected messages. If the win is the
218 * main window, then it returns a newly allocated list of the headers
219 * selected in the header view. If win is the msg view window, then
220 * the value returned is a list with just a single header.
222 * The caller of this funcion must free the list.
225 get_selected_headers (ModestWindow *win)
227 if (MODEST_IS_MAIN_WINDOW(win)) {
228 GtkWidget *header_view;
230 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
231 MODEST_WIDGET_TYPE_HEADER_VIEW);
232 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
234 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
235 /* for MsgViewWindows, we simply return a list with one element */
237 TnyList *list = NULL;
239 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
240 if (header != NULL) {
241 list = tny_simple_list_new ();
242 tny_list_prepend (list, G_OBJECT(header));
243 g_object_unref (G_OBJECT(header));
253 headers_action_mark_as_read (TnyHeader *header,
257 TnyHeaderFlags flags;
259 g_return_if_fail (TNY_IS_HEADER(header));
261 flags = tny_header_get_flags (header);
262 if (flags & TNY_HEADER_FLAG_SEEN) return;
263 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
267 headers_action_mark_as_unread (TnyHeader *header,
271 TnyHeaderFlags flags;
273 g_return_if_fail (TNY_IS_HEADER(header));
275 flags = tny_header_get_flags (header);
276 if (flags & TNY_HEADER_FLAG_SEEN) {
277 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
281 /** A convenience method, because deleting a message is
282 * otherwise complicated, and it's best to change it in one place
285 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
287 ModestMailOperation *mail_op = NULL;
288 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
289 win ? G_OBJECT(win) : NULL);
290 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
293 /* Always delete. TODO: Move to trash still not supported */
294 modest_mail_operation_remove_msg (mail_op, header, FALSE);
295 g_object_unref (G_OBJECT (mail_op));
299 headers_action_delete (TnyHeader *header,
303 modest_do_message_delete (header, win);
306 /** After deleing a message that is currently visible in a window,
307 * show the next message from the list, or close the window if there are no more messages.
309 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
311 /* Close msg view window or select next */
312 if (modest_msg_view_window_last_message_selected (win) &&
313 modest_msg_view_window_first_message_selected (win)) {
314 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
316 if (!modest_msg_view_window_select_next_message (win)) {
318 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
324 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
326 TnyList *header_list = NULL;
327 TnyIterator *iter = NULL;
328 TnyHeader *header = NULL;
329 gchar *message = NULL;
332 ModestWindowMgr *mgr;
333 GtkWidget *header_view = NULL;
335 g_return_if_fail (MODEST_IS_WINDOW(win));
337 /* Check first if the header view has the focus */
338 if (MODEST_IS_MAIN_WINDOW (win)) {
340 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
341 MODEST_WIDGET_TYPE_HEADER_VIEW);
342 if (!gtk_widget_is_focus (header_view))
346 /* Get the headers, either from the header view (if win is the main window),
347 * or from the message view window: */
348 header_list = get_selected_headers (win);
349 if (!header_list) return;
351 /* Check if any of the headers are already opened, or in the process of being opened */
352 if (MODEST_IS_MAIN_WINDOW (win)) {
354 iter = tny_list_create_iterator (header_list);
356 mgr = modest_runtime_get_window_mgr ();
357 while (!tny_iterator_is_done (iter) && !found) {
358 header = TNY_HEADER (tny_iterator_get_current (iter));
360 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
361 g_object_unref (header);
364 tny_iterator_next (iter);
366 g_object_unref (iter);
371 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
372 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
374 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
378 g_object_unref (header_list);
384 if (tny_list_get_length(header_list) == 1) {
385 iter = tny_list_create_iterator (header_list);
386 header = TNY_HEADER (tny_iterator_get_current (iter));
388 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
389 g_object_unref (header);
392 g_object_unref (iter);
394 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
395 tny_list_get_length(header_list)), desc);
397 /* Confirmation dialog */
398 printf("DEBUG: %s\n", __FUNCTION__);
399 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
403 if (response == GTK_RESPONSE_OK) {
404 ModestWindow *main_window = NULL;
405 ModestWindowMgr *mgr = NULL;
406 GtkTreeModel *model = NULL;
407 GtkTreeSelection *sel = NULL;
408 GList *sel_list = NULL, *tmp = NULL;
409 GtkTreeRowReference *row_reference = NULL;
410 GtkTreePath *next_path = NULL;
411 TnyFolder *folder = NULL;
414 /* Find last selected row */
415 if (MODEST_IS_MAIN_WINDOW (win)) {
416 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
417 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
418 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
419 for (tmp=sel_list; tmp; tmp=tmp->next) {
420 if (tmp->next == NULL) {
421 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
422 gtk_tree_path_next (next_path);
423 row_reference = gtk_tree_row_reference_new (model, next_path);
424 gtk_tree_path_free (next_path);
429 /* Remove each header. If it's a view window header_view == NULL */
430 do_headers_action (win, headers_action_delete, header_view);
432 /* refresh the header view (removing marked-as-deleted)*/
433 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
435 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
436 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
438 /* Get main window */
439 mgr = modest_runtime_get_window_mgr ();
440 main_window = modest_window_mgr_get_main_window (mgr);
443 /* Move cursor to next row */
446 /* Select next row */
447 if (gtk_tree_row_reference_valid (row_reference)) {
448 next_path = gtk_tree_row_reference_get_path (row_reference);
449 gtk_tree_selection_select_path (sel, next_path);
450 gtk_tree_path_free (next_path);
452 if (row_reference != NULL)
453 gtk_tree_row_reference_free (row_reference);
456 /* Get folder from first header and sync it */
457 iter = tny_list_create_iterator (header_list);
458 header = TNY_HEADER (tny_iterator_get_current (iter));
459 folder = tny_header_get_folder (header);
460 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
461 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
462 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
463 else if (TNY_IS_CAMEL_POP_FOLDER (folder))
464 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
465 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
468 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
469 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
472 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
476 g_object_unref (header);
477 g_object_unref (iter);
478 g_object_unref (folder);
480 /* Update toolbar dimming state */
481 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
484 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
485 g_list_free (sel_list);
491 g_object_unref (header_list);
497 /* delete either message or folder, based on where we are */
499 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
501 g_return_if_fail (MODEST_IS_WINDOW(win));
503 /* Check first if the header view has the focus */
504 if (MODEST_IS_MAIN_WINDOW (win)) {
506 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
507 MODEST_WIDGET_TYPE_FOLDER_VIEW);
508 if (gtk_widget_is_focus (w)) {
509 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
513 modest_ui_actions_on_delete_message (action, win);
519 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
521 #ifdef MODEST_PLATFORM_MAEMO
522 modest_osso_save_state();
523 #endif /* MODEST_PLATFORM_MAEMO */
525 g_debug ("closing down, clearing %d item(s) from operation queue",
526 modest_mail_operation_queue_num_elements
527 (modest_runtime_get_mail_operation_queue()));
529 /* cancel all outstanding operations */
530 modest_mail_operation_queue_cancel_all
531 (modest_runtime_get_mail_operation_queue());
533 g_debug ("queue has been cleared");
535 /* note: when modest-tny-account-store is finalized,
536 it will automatically set all network connections
543 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
547 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
549 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
550 /* gtk_widget_destroy (GTK_WIDGET (win)); */
551 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
552 /* gboolean ret_value; */
553 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
554 /* } else if (MODEST_IS_WINDOW (win)) { */
555 /* gtk_widget_destroy (GTK_WIDGET (win)); */
557 /* g_return_if_reached (); */
562 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
564 GtkClipboard *clipboard = NULL;
565 gchar *selection = NULL;
567 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
568 selection = gtk_clipboard_wait_for_text (clipboard);
570 /* Question: why is the clipboard being used here?
571 * It doesn't really make a lot of sense. */
575 modest_address_book_add_address (selection);
581 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
583 /* This is currently only implemented for Maemo */
584 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
585 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
586 modest_run_account_setup_wizard (win);
589 /* Show the list of accounts: */
590 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
591 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
593 /* Don't make this a modal window, because secondary windows will then
594 * be unusable, freezing the UI: */
595 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
596 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
599 GtkWidget *dialog, *label;
601 /* Create the widgets */
603 dialog = gtk_dialog_new_with_buttons ("Message",
605 GTK_DIALOG_DESTROY_WITH_PARENT,
609 label = gtk_label_new ("Hello World!");
611 /* Ensure that the dialog box is destroyed when the user responds. */
613 g_signal_connect_swapped (dialog, "response",
614 G_CALLBACK (gtk_widget_destroy),
617 /* Add the label, and show everything we've added to the dialog. */
619 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
621 gtk_widget_show_all (dialog);
622 #endif /* MODEST_PLATFORM_MAEMO */
626 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
628 ModestWindow *main_window = MODEST_WINDOW (user_data);
630 /* Save any changes. */
631 modest_connection_specific_smtp_window_save_server_accounts (
632 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
633 modest_window_get_active_account (main_window));
634 gtk_widget_destroy (GTK_WIDGET (window));
640 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
642 /* This is currently only implemented for Maemo,
643 * because it requires an API (libconic) to detect different connection
646 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
648 /* Create the window if necessary: */
649 const gchar *active_account_name = modest_window_get_active_account (win);
651 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
652 * or show the default account?
653 * If we show the default account then the account name should be shown in
654 * the window when we show it. */
655 if (!active_account_name) {
656 g_warning ("%s: No account is active.", __FUNCTION__);
660 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
661 modest_connection_specific_smtp_window_fill_with_connections (
662 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
663 modest_runtime_get_account_mgr(),
664 active_account_name);
666 /* Show the window: */
667 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
668 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
669 gtk_widget_show (specific_window);
671 /* Save changes when the window is hidden: */
672 g_signal_connect (specific_window, "hide",
673 G_CALLBACK (on_smtp_servers_window_hide), win);
674 #endif /* MODEST_PLATFORM_MAEMO */
678 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
680 ModestWindow *msg_win = NULL;
682 TnyFolder *folder = NULL;
683 gchar *account_name = NULL;
684 gchar *from_str = NULL;
685 /* GError *err = NULL; */
686 TnyAccount *account = NULL;
687 ModestWindowMgr *mgr;
688 gchar *signature = NULL, *blank_and_signature = NULL;
690 /* if there are no accounts yet, just show the wizard */
691 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
692 const gboolean created = modest_run_account_setup_wizard (win);
697 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
699 account_name = g_strdup (modest_window_get_active_account (win));
701 g_printerr ("modest: no account found\n");
705 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
707 TNY_ACCOUNT_TYPE_STORE);
709 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
713 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
715 g_printerr ("modest: failed get from string for '%s'\n", account_name);
719 gboolean use_signature = FALSE;
720 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
723 blank_and_signature = g_strconcat ("\n", signature, NULL);
725 blank_and_signature = g_strdup ("");
730 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
732 g_printerr ("modest: failed to create new msg\n");
736 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
738 g_printerr ("modest: failed to find Drafts folder\n");
743 /* Create and register edit window */
744 /* This is destroyed by TODO. */
745 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
746 mgr = modest_runtime_get_window_mgr ();
747 modest_window_mgr_register_window (mgr, msg_win);
750 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
752 gtk_widget_show_all (GTK_WIDGET (msg_win));
755 g_free (account_name);
757 g_free (blank_and_signature);
759 g_object_unref (msg_win);
761 g_object_unref (G_OBJECT(account));
763 g_object_unref (G_OBJECT(msg));
765 g_object_unref (G_OBJECT(folder));
769 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
773 ModestMailOperationStatus status;
775 /* If there is no message or the operation was not successful */
776 status = modest_mail_operation_get_status (mail_op);
777 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
779 /* Remove the header from the preregistered uids */
780 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
790 open_msg_cb (ModestMailOperation *mail_op,
795 ModestWindowMgr *mgr = NULL;
796 ModestWindow *parent_win = NULL;
797 ModestWindow *win = NULL;
798 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
799 gchar *account = NULL;
802 /* Do nothing if there was any problem with the mail
803 operation. The error will be shown by the error_handler of
804 the mail operation */
805 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
809 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
810 folder = tny_header_get_folder (header);
812 /* Mark header as read */
813 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
816 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
818 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
820 /* Gets folder type (OUTBOX headers will be opened in edit window */
821 if (modest_tny_folder_is_local_folder (folder))
822 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
824 /* If the header is in the drafts folder then open the editor,
825 else the message view window */
826 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
827 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
828 /* we cannot edit without a valid account... */
829 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
830 const gboolean created = modest_run_account_setup_wizard(parent_win);
834 win = modest_msg_edit_window_new (msg, account, TRUE);
837 gchar *uid = modest_tny_folder_get_header_unique_id (header);
839 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
840 GtkWidget *header_view;
841 GtkTreeSelection *sel;
842 GList *sel_list = NULL;
845 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
846 MODEST_WIDGET_TYPE_HEADER_VIEW);
848 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
849 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
851 if (sel_list != NULL) {
852 GtkTreeRowReference *row_reference;
854 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
855 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
856 g_list_free (sel_list);
858 win = modest_msg_view_window_new_with_header_model (
859 msg, account, (const gchar*) uid,
860 model, row_reference);
861 gtk_tree_row_reference_free (row_reference);
863 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
866 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
871 /* Register and show new window */
873 mgr = modest_runtime_get_window_mgr ();
874 modest_window_mgr_register_window (mgr, win);
875 g_object_unref (win);
876 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
877 gtk_widget_show_all (GTK_WIDGET(win));
880 /* Update toolbar dimming state */
881 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
882 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
888 g_object_unref (parent_win);
889 g_object_unref (folder);
893 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
897 GObject *win = modest_mail_operation_get_source (mail_op);
899 error = modest_mail_operation_get_error (mail_op);
900 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
902 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
904 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
907 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
908 _("mail_ni_ui_folder_get_msg_folder_error"));
912 g_object_unref (win);
916 * This function is used by both modest_ui_actions_on_open and
917 * modest_ui_actions_on_header_activated. This way we always do the
918 * same when trying to open messages.
921 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
923 ModestWindowMgr *mgr = NULL;
924 TnyIterator *iter = NULL;
925 ModestMailOperation *mail_op = NULL;
926 TnyList *not_opened_headers = NULL;
927 TnyHeaderFlags flags = 0;
929 /* Look if we already have a message view for each header. If
930 true, then remove the header from the list of headers to
932 mgr = modest_runtime_get_window_mgr ();
933 iter = tny_list_create_iterator (headers);
934 not_opened_headers = tny_simple_list_new ();
936 while (!tny_iterator_is_done (iter)) {
938 ModestWindow *window = NULL;
939 TnyHeader *header = NULL;
940 gboolean found = FALSE;
942 header = TNY_HEADER (tny_iterator_get_current (iter));
944 flags = tny_header_get_flags (header);
947 found = modest_window_mgr_find_registered_header (mgr, header, &window);
949 /* Do not open again the message and present the
950 window to the user */
953 gtk_window_present (GTK_WINDOW (window));
955 /* the header has been registered already, we don't do
956 * anything but wait for the window to come up*/
957 g_debug ("header %p already registered, waiting for window", header);
959 tny_list_append (not_opened_headers, G_OBJECT (header));
963 g_object_unref (header);
965 tny_iterator_next (iter);
967 g_object_unref (iter);
970 /* If some messages would have to be downloaded, ask the user to
971 * make a connection. It's generally easier to do this here (in the mainloop)
972 * than later in a thread:
974 if (tny_list_get_length (not_opened_headers) > 0) {
976 gboolean found = FALSE;
978 iter = tny_list_create_iterator (not_opened_headers);
979 while (!tny_iterator_is_done (iter) && !found) {
980 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
981 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
984 tny_iterator_next (iter);
986 g_object_unref (header);
988 g_object_unref (iter);
990 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
991 g_object_unref (not_opened_headers);
996 /* Register the headers before actually creating the windows: */
997 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
998 while (!tny_iterator_is_done (iter_not_opened)) {
999 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1001 modest_window_mgr_register_header (mgr, header);
1002 g_object_unref (header);
1005 tny_iterator_next (iter_not_opened);
1007 g_object_unref (iter_not_opened);
1008 iter_not_opened = NULL;
1010 /* Open each message */
1011 if (tny_list_get_length (not_opened_headers) > 0) {
1012 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1014 modest_ui_actions_get_msgs_full_error_handler,
1016 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1017 if (tny_list_get_length (not_opened_headers) > 1) {
1018 modest_mail_operation_get_msgs_full (mail_op,
1024 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1025 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1026 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1027 g_object_unref (header);
1028 g_object_unref (iter);
1030 g_object_unref (mail_op);
1034 if (not_opened_headers != NULL)
1035 g_object_unref (not_opened_headers);
1039 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1044 headers = get_selected_headers (win);
1049 _modest_ui_actions_open (headers, win);
1051 g_object_unref(headers);
1056 free_reply_forward_helper (gpointer data)
1058 ReplyForwardHelper *helper;
1060 helper = (ReplyForwardHelper *) data;
1061 g_free (helper->account_name);
1062 g_slice_free (ReplyForwardHelper, helper);
1066 reply_forward_cb (ModestMailOperation *mail_op,
1072 ReplyForwardHelper *rf_helper;
1073 ModestWindow *msg_win = NULL;
1074 ModestEditType edit_type;
1076 TnyAccount *account = NULL;
1077 ModestWindowMgr *mgr = NULL;
1078 gchar *signature = NULL;
1080 /* If there was any error. The mail operation could be NULL,
1081 this means that we already have the message downloaded and
1082 that we didn't do a mail operation to retrieve it */
1083 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1086 g_return_if_fail (user_data != NULL);
1087 rf_helper = (ReplyForwardHelper *) user_data;
1089 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1090 rf_helper->account_name);
1091 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1092 rf_helper->account_name,
1093 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1094 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1095 rf_helper->account_name,
1096 MODEST_ACCOUNT_SIGNATURE, FALSE);
1099 /* Create reply mail */
1100 switch (rf_helper->action) {
1103 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1104 rf_helper->reply_forward_type,
1105 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1107 case ACTION_REPLY_TO_ALL:
1109 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1110 MODEST_TNY_MSG_REPLY_MODE_ALL);
1111 edit_type = MODEST_EDIT_TYPE_REPLY;
1113 case ACTION_FORWARD:
1115 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1116 edit_type = MODEST_EDIT_TYPE_FORWARD;
1119 g_return_if_reached ();
1126 g_printerr ("modest: failed to create message\n");
1130 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1131 rf_helper->account_name,
1132 TNY_ACCOUNT_TYPE_STORE);
1134 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1138 /* Create and register the windows */
1139 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1140 mgr = modest_runtime_get_window_mgr ();
1141 modest_window_mgr_register_window (mgr, msg_win);
1143 if (rf_helper->parent_window != NULL) {
1144 gdouble parent_zoom;
1146 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1147 modest_window_set_zoom (msg_win, parent_zoom);
1150 /* Show edit window */
1151 gtk_widget_show_all (GTK_WIDGET (msg_win));
1155 g_object_unref (msg_win);
1157 g_object_unref (G_OBJECT (new_msg));
1159 g_object_unref (G_OBJECT (account));
1160 /* g_object_unref (msg); */
1161 free_reply_forward_helper (rf_helper);
1165 * Checks a list of headers. If any of them are not currently
1166 * downloaded (CACHED) then it asks the user for permission to
1169 * Returns FALSE if the user does not want to download the
1170 * messages. Returns TRUE if the user allowed the download or if all
1171 * of them are currently downloaded
1174 download_uncached_messages (TnyList *header_list,
1179 gint uncached_messages = 0;
1181 iter = tny_list_create_iterator (header_list);
1182 while (!tny_iterator_is_done (iter)) {
1185 header = TNY_HEADER (tny_iterator_get_current (iter));
1187 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1188 uncached_messages ++;
1189 g_object_unref (header);
1192 tny_iterator_next (iter);
1194 g_object_unref (iter);
1196 /* Ask for user permission to download the messages */
1198 if (uncached_messages > 0) {
1199 gboolean download = TRUE;
1200 if (!tny_device_is_online (modest_runtime_get_device())) {
1201 GtkResponseType response =
1202 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1203 ngettext("mcen_nc_get_msg",
1205 uncached_messages));
1206 if (response == GTK_RESPONSE_CANCEL) download = FALSE;
1209 /* If a download will be necessary, make sure that we have a connection: */
1210 retval = modest_platform_connect_and_wait(win, NULL);
1220 * Common code for the reply and forward actions
1223 reply_forward (ReplyForwardAction action, ModestWindow *win)
1225 ModestMailOperation *mail_op = NULL;
1226 TnyList *header_list = NULL;
1227 ReplyForwardHelper *rf_helper = NULL;
1228 guint reply_forward_type;
1229 gboolean continue_download = TRUE;
1230 gboolean do_retrieve = TRUE;
1232 g_return_if_fail (MODEST_IS_WINDOW(win));
1234 /* we need an account when editing */
1235 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1236 const gboolean created = modest_run_account_setup_wizard (win);
1241 header_list = get_selected_headers (win);
1245 reply_forward_type =
1246 modest_conf_get_int (modest_runtime_get_conf (),
1247 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1250 /* Check that the messages have been previously downloaded */
1251 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1253 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1254 if (!continue_download) {
1255 g_object_unref (header_list);
1259 /* We assume that we can only select messages of the
1260 same folder and that we reply all of them from the
1261 same account. In fact the interface currently only
1262 allows single selection */
1265 rf_helper = g_slice_new0 (ReplyForwardHelper);
1266 rf_helper->reply_forward_type = reply_forward_type;
1267 rf_helper->action = action;
1268 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1270 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1271 rf_helper->parent_window = GTK_WIDGET (win);
1272 if (!rf_helper->account_name)
1273 rf_helper->account_name =
1274 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1276 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1279 /* Get header and message. Do not free them here, the
1280 reply_forward_cb must do it */
1281 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1282 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1283 if (!msg || !header) {
1285 g_object_unref (msg);
1286 g_printerr ("modest: no message found\n");
1289 reply_forward_cb (NULL, header, msg, rf_helper);
1292 g_object_unref (header);
1297 /* Only reply/forward to one message */
1298 iter = tny_list_create_iterator (header_list);
1299 header = TNY_HEADER (tny_iterator_get_current (iter));
1300 g_object_unref (iter);
1303 /* Retrieve messages */
1305 mail_op = modest_mail_operation_new_with_error_handling (
1306 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1308 modest_ui_actions_get_msgs_full_error_handler,
1310 modest_mail_operation_queue_add (
1311 modest_runtime_get_mail_operation_queue (), mail_op);
1313 modest_mail_operation_get_msg (mail_op,
1318 g_object_unref(mail_op);
1320 /* we put a ref here to prevent double unref as the reply
1321 * forward callback unrefs the header at its end */
1322 reply_forward_cb (NULL, header, NULL, rf_helper);
1326 g_object_unref (header);
1332 g_object_unref (header_list);
1336 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1338 g_return_if_fail (MODEST_IS_WINDOW(win));
1340 reply_forward (ACTION_REPLY, win);
1344 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1346 g_return_if_fail (MODEST_IS_WINDOW(win));
1348 reply_forward (ACTION_FORWARD, win);
1352 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1354 g_return_if_fail (MODEST_IS_WINDOW(win));
1356 reply_forward (ACTION_REPLY_TO_ALL, win);
1360 modest_ui_actions_on_next (GtkAction *action,
1361 ModestWindow *window)
1363 if (MODEST_IS_MAIN_WINDOW (window)) {
1364 GtkWidget *header_view;
1366 header_view = modest_main_window_get_child_widget (
1367 MODEST_MAIN_WINDOW(window),
1368 MODEST_WIDGET_TYPE_HEADER_VIEW);
1372 modest_header_view_select_next (
1373 MODEST_HEADER_VIEW(header_view));
1374 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1375 modest_msg_view_window_select_next_message (
1376 MODEST_MSG_VIEW_WINDOW (window));
1378 g_return_if_reached ();
1383 modest_ui_actions_on_prev (GtkAction *action,
1384 ModestWindow *window)
1386 g_return_if_fail (MODEST_IS_WINDOW(window));
1388 if (MODEST_IS_MAIN_WINDOW (window)) {
1389 GtkWidget *header_view;
1390 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1391 MODEST_WIDGET_TYPE_HEADER_VIEW);
1395 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1396 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1397 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1399 g_return_if_reached ();
1404 modest_ui_actions_on_sort (GtkAction *action,
1405 ModestWindow *window)
1407 g_return_if_fail (MODEST_IS_WINDOW(window));
1409 if (MODEST_IS_MAIN_WINDOW (window)) {
1410 GtkWidget *header_view;
1411 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1412 MODEST_WIDGET_TYPE_HEADER_VIEW);
1414 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1419 /* Show sorting dialog */
1420 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1425 new_messages_arrived (ModestMailOperation *self,
1429 ModestMainWindow *win = NULL;
1430 GtkWidget *folder_view = NULL;
1431 TnyFolderStore *folder = NULL;
1432 gboolean folder_empty = FALSE;
1434 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1435 win = MODEST_MAIN_WINDOW (user_data);
1437 /* Set contents style of headers view */
1438 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1439 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1440 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1441 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1444 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1447 modest_main_window_set_contents_style (win,
1448 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1451 /* Notify new messages have been downloaded */
1452 if (new_messages > 0)
1453 modest_platform_on_new_msg ();
1457 * This function performs the send & receive required actions. The
1458 * window is used to create the mail operation. Typically it should
1459 * always be the main window, but we pass it as argument in order to
1463 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1465 gchar *acc_name = NULL;
1466 ModestMailOperation *mail_op;
1468 /* If no account name was provided then get the current account, and if
1469 there is no current account then pick the default one: */
1470 if (!account_name) {
1471 acc_name = g_strdup (modest_window_get_active_account(win));
1473 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1475 g_printerr ("modest: cannot get default account\n");
1479 acc_name = g_strdup (account_name);
1482 /* Set send/receive operation in progress */
1483 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1485 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1487 modest_ui_actions_send_receive_error_handler,
1490 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1491 G_CALLBACK (_on_send_receive_progress_changed),
1494 /* Send & receive. */
1495 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1496 /* Receive and then send. The operation is tagged initially as
1497 a receive operation because the account update performs a
1498 receive and then a send. The operation changes its type
1499 internally, so the progress objects will receive the proper
1500 progress information */
1501 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1502 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1503 g_object_unref (G_OBJECT (mail_op));
1511 modest_ui_actions_do_cancel_send (const gchar *account_name,
1514 TnyTransportAccount *transport_account;
1515 TnySendQueue *send_queue = NULL;
1516 GError *error = NULL;
1518 /* Get transport account */
1520 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1521 (modest_runtime_get_account_store(),
1523 TNY_ACCOUNT_TYPE_TRANSPORT));
1524 if (!transport_account) {
1525 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1530 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1531 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1532 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1533 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1534 "modest: could not find send queue for account\n");
1536 /* Keeep messages in outbox folder */
1537 tny_send_queue_cancel (send_queue, FALSE, &error);
1541 if (transport_account != NULL)
1542 g_object_unref (G_OBJECT (transport_account));
1546 modest_ui_actions_cancel_send_all (ModestWindow *win)
1548 GSList *account_names, *iter;
1550 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1553 iter = account_names;
1555 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1556 iter = g_slist_next (iter);
1559 modest_account_mgr_free_account_names (account_names);
1560 account_names = NULL;
1564 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1567 /* Check if accounts exist */
1568 gboolean accounts_exist =
1569 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1571 /* If not, allow the user to create an account before trying to send/receive. */
1572 if (!accounts_exist)
1573 modest_ui_actions_on_accounts (NULL, win);
1575 /* Cancel all sending operaitons */
1576 modest_ui_actions_cancel_send_all (win);
1580 * Refreshes all accounts. This function will be used by automatic
1584 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1586 GSList *account_names, *iter;
1588 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1591 iter = account_names;
1593 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1594 iter = g_slist_next (iter);
1597 modest_account_mgr_free_account_names (account_names);
1598 account_names = NULL;
1602 modest_do_refresh_current_folder(ModestWindow *win)
1604 /* Refresh currently selected folder. Note that if we only
1605 want to retreive the headers, then the refresh only will
1606 invoke a poke_status over all folders, i.e., only the
1607 total/unread count will be updated */
1608 if (MODEST_IS_MAIN_WINDOW (win)) {
1609 GtkWidget *header_view, *folder_view;
1610 TnyFolderStore *folder_store;
1612 /* Get folder and header view */
1614 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1615 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1617 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1619 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1621 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1622 MODEST_WIDGET_TYPE_HEADER_VIEW);
1624 /* We do not need to set the contents style
1625 because it hasn't changed. We also do not
1626 need to save the widget status. Just force
1628 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1629 TNY_FOLDER (folder_store),
1630 folder_refreshed_cb,
1631 MODEST_MAIN_WINDOW (win));
1635 g_object_unref (folder_store);
1641 * Handler of the click on Send&Receive button in the main toolbar
1644 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1646 /* Check if accounts exist */
1647 gboolean accounts_exist =
1648 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1650 /* If not, allow the user to create an account before trying to send/receive. */
1651 if (!accounts_exist)
1652 modest_ui_actions_on_accounts (NULL, win);
1654 modest_do_refresh_current_folder (win);
1656 /* Refresh the active account */
1657 modest_ui_actions_do_send_receive (NULL, win);
1662 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1665 GtkWidget *header_view;
1667 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1669 header_view = modest_main_window_get_child_widget (main_window,
1670 MODEST_WIDGET_TYPE_HEADER_VIEW);
1674 conf = modest_runtime_get_conf ();
1676 /* what is saved/restored is depending on the style; thus; we save with
1677 * old style, then update the style, and restore for this new style
1679 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1681 if (modest_header_view_get_style
1682 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1683 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1684 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1686 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1687 MODEST_HEADER_VIEW_STYLE_DETAILS);
1689 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1690 MODEST_CONF_HEADER_VIEW_KEY);
1695 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1697 ModestMainWindow *main_window)
1699 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1700 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1702 /* in the case the folder is empty, show the empty folder message and focus
1704 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1705 if (modest_header_view_is_empty (header_view)) {
1706 TnyFolder *folder = modest_header_view_get_folder (header_view);
1707 GtkWidget *folder_view =
1708 modest_main_window_get_child_widget (main_window,
1709 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1711 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1712 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1716 /* If no header has been selected then exit */
1721 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1722 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1724 /* Update Main window title */
1725 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1726 const gchar *subject = tny_header_get_subject (header);
1727 if (subject && strlen(subject) > 0)
1728 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1730 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1733 /* Update toolbar dimming state */
1734 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1738 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1740 ModestMainWindow *main_window)
1744 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1749 headers = tny_simple_list_new ();
1750 tny_list_prepend (headers, G_OBJECT (header));
1752 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1754 g_object_unref (headers);
1758 set_active_account_from_tny_account (TnyAccount *account,
1759 ModestWindow *window)
1761 const gchar *server_acc_name = tny_account_get_id (account);
1763 /* We need the TnyAccount provided by the
1764 account store because that is the one that
1765 knows the name of the Modest account */
1766 TnyAccount *modest_server_account = modest_server_account =
1767 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1768 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1771 const gchar *modest_acc_name =
1772 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1773 modest_window_set_active_account (window, modest_acc_name);
1774 g_object_unref (modest_server_account);
1779 folder_refreshed_cb (ModestMailOperation *mail_op,
1783 ModestMainWindow *win = NULL;
1784 GtkWidget *header_view;
1785 TnyFolder *current_folder;
1786 gboolean folder_empty = TRUE;
1787 gboolean all_marked_as_deleted = TRUE;
1789 g_return_if_fail (TNY_IS_FOLDER (folder));
1791 win = MODEST_MAIN_WINDOW (user_data);
1793 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1796 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1797 if (current_folder != NULL && folder != current_folder) {
1802 /* Check if folder is empty and set headers view contents style */
1803 folder_empty = (tny_folder_get_all_count (folder) == 0);
1804 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1805 folder_empty = folder_empty || all_marked_as_deleted ;
1808 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1809 modest_main_window_set_contents_style (win,
1810 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1812 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1817 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1818 TnyFolderStore *folder_store,
1820 ModestMainWindow *main_window)
1823 GtkWidget *header_view;
1825 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1827 header_view = modest_main_window_get_child_widget(main_window,
1828 MODEST_WIDGET_TYPE_HEADER_VIEW);
1832 conf = modest_runtime_get_conf ();
1834 if (TNY_IS_ACCOUNT (folder_store)) {
1836 /* Update active account */
1837 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1838 /* Show account details */
1839 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1842 if (TNY_IS_FOLDER (folder_store) && selected) {
1844 /* Update the active account */
1845 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1847 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1848 g_object_unref (account);
1852 /* Set the header style by default, it could
1853 be changed later by the refresh callback to
1855 modest_main_window_set_contents_style (main_window,
1856 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1858 /* Set folder on header view. This function
1859 will call tny_folder_refresh_async so we
1860 pass a callback that will be called when
1861 finished. We use that callback to set the
1862 empty view if there are no messages */
1863 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1864 TNY_FOLDER (folder_store),
1865 folder_refreshed_cb,
1868 /* Restore configuration. We need to do this
1869 *after* the set_folder because the widget
1870 memory asks the header view about its
1872 modest_widget_memory_restore (modest_runtime_get_conf (),
1873 G_OBJECT(header_view),
1874 MODEST_CONF_HEADER_VIEW_KEY);
1876 /* Update the active account */
1877 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1878 /* Save only if we're seeing headers */
1879 if (modest_main_window_get_contents_style (main_window) ==
1880 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1881 modest_widget_memory_save (conf, G_OBJECT (header_view),
1882 MODEST_CONF_HEADER_VIEW_KEY);
1883 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1887 /* Update toolbar dimming state */
1888 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1892 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1899 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1901 online = tny_device_is_online (modest_runtime_get_device());
1904 /* already online -- the item is simply not there... */
1905 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1907 GTK_MESSAGE_WARNING,
1909 _("The %s you selected cannot be found"),
1911 gtk_dialog_run (GTK_DIALOG(dialog));
1913 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1917 GTK_RESPONSE_REJECT,
1919 GTK_RESPONSE_ACCEPT,
1921 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1922 "Do you want to get online?"), item);
1923 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1924 gtk_label_new (txt), FALSE, FALSE, 0);
1925 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1928 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1929 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1930 /* TODO: Comment about why is this commented out: */
1931 /* modest_platform_connect_and_wait (); */
1934 gtk_widget_destroy (dialog);
1938 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1941 /* g_message ("%s %s", __FUNCTION__, link); */
1946 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1949 modest_platform_activate_uri (link);
1953 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1956 modest_platform_show_uri_popup (link);
1960 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1963 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1967 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1968 const gchar *address,
1971 /* g_message ("%s %s", __FUNCTION__, address); */
1975 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1977 TnyTransportAccount *transport_account;
1978 ModestMailOperation *mail_operation;
1980 gchar *account_name, *from;
1981 ModestAccountMgr *account_mgr;
1982 gchar *info_text = NULL;
1984 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1986 data = modest_msg_edit_window_get_msg_data (edit_window);
1988 account_mgr = modest_runtime_get_account_mgr();
1989 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1991 account_name = modest_account_mgr_get_default_account (account_mgr);
1992 if (!account_name) {
1993 g_printerr ("modest: no account found\n");
1994 modest_msg_edit_window_free_msg_data (edit_window, data);
1998 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1999 account_name = g_strdup (data->account_name);
2003 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2004 (modest_runtime_get_account_store(),
2006 TNY_ACCOUNT_TYPE_TRANSPORT));
2007 if (!transport_account) {
2008 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2009 g_free (account_name);
2010 modest_msg_edit_window_free_msg_data (edit_window, data);
2013 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2015 /* Create the mail operation */
2016 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2017 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2019 modest_mail_operation_save_to_drafts (mail_operation,
2031 data->priority_flags);
2034 g_free (account_name);
2035 g_object_unref (G_OBJECT (transport_account));
2036 g_object_unref (G_OBJECT (mail_operation));
2038 modest_msg_edit_window_free_msg_data (edit_window, data);
2040 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2041 modest_platform_information_banner (NULL, NULL, info_text);
2045 /* For instance, when clicking the Send toolbar button when editing a message: */
2047 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2049 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2051 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2054 /* Offer the connection dialog, if necessary: */
2055 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2058 /* FIXME: Code added just for testing. The final version will
2059 use the send queue provided by tinymail and some
2061 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2062 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2064 account_name = modest_account_mgr_get_default_account (account_mgr);
2066 if (!account_name) {
2067 /* Run account setup wizard */
2068 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2073 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2075 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2076 account_name = g_strdup (data->account_name);
2079 /* Get the currently-active transport account for this modest account: */
2080 TnyTransportAccount *transport_account =
2081 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2082 (modest_runtime_get_account_store(),
2084 if (!transport_account) {
2085 /* Run account setup wizard */
2086 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2091 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2093 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2094 GtkResponseType response;
2095 gchar *note_message;
2096 gchar *note_subject = data->subject;
2097 if (note_subject == NULL || note_subject[0] == '\0')
2098 note_subject = _("mail_va_no_subject");
2099 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2100 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2102 g_free (note_message);
2103 if (response == GTK_RESPONSE_CANCEL) {
2104 g_free (account_name);
2109 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2111 /* Create the mail operation */
2112 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2113 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2115 modest_mail_operation_send_new_mail (mail_operation,
2126 data->priority_flags);
2130 g_free (account_name);
2131 g_object_unref (G_OBJECT (transport_account));
2132 g_object_unref (G_OBJECT (mail_operation));
2134 modest_msg_edit_window_free_msg_data (edit_window, data);
2135 modest_msg_edit_window_set_sent (edit_window, TRUE);
2137 /* Save settings and close the window: */
2138 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2142 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2143 ModestMsgEditWindow *window)
2145 ModestMsgEditFormatState *format_state = NULL;
2147 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2148 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2150 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2153 format_state = modest_msg_edit_window_get_format_state (window);
2154 g_return_if_fail (format_state != NULL);
2156 format_state->bold = gtk_toggle_action_get_active (action);
2157 modest_msg_edit_window_set_format_state (window, format_state);
2158 g_free (format_state);
2163 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2164 ModestMsgEditWindow *window)
2166 ModestMsgEditFormatState *format_state = NULL;
2168 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2169 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2171 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2174 format_state = modest_msg_edit_window_get_format_state (window);
2175 g_return_if_fail (format_state != NULL);
2177 format_state->italics = gtk_toggle_action_get_active (action);
2178 modest_msg_edit_window_set_format_state (window, format_state);
2179 g_free (format_state);
2184 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2185 ModestMsgEditWindow *window)
2187 ModestMsgEditFormatState *format_state = NULL;
2189 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2190 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2192 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2195 format_state = modest_msg_edit_window_get_format_state (window);
2196 g_return_if_fail (format_state != NULL);
2198 format_state->bullet = gtk_toggle_action_get_active (action);
2199 modest_msg_edit_window_set_format_state (window, format_state);
2200 g_free (format_state);
2205 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2206 GtkRadioAction *selected,
2207 ModestMsgEditWindow *window)
2209 ModestMsgEditFormatState *format_state = NULL;
2210 GtkJustification value;
2212 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2214 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2217 value = gtk_radio_action_get_current_value (selected);
2219 format_state = modest_msg_edit_window_get_format_state (window);
2220 g_return_if_fail (format_state != NULL);
2222 format_state->justification = value;
2223 modest_msg_edit_window_set_format_state (window, format_state);
2224 g_free (format_state);
2228 modest_ui_actions_on_select_editor_color (GtkAction *action,
2229 ModestMsgEditWindow *window)
2231 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2232 g_return_if_fail (GTK_IS_ACTION (action));
2234 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2237 modest_msg_edit_window_select_color (window);
2241 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2242 ModestMsgEditWindow *window)
2244 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2245 g_return_if_fail (GTK_IS_ACTION (action));
2247 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2250 modest_msg_edit_window_select_background_color (window);
2254 modest_ui_actions_on_insert_image (GtkAction *action,
2255 ModestMsgEditWindow *window)
2257 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2258 g_return_if_fail (GTK_IS_ACTION (action));
2260 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2263 modest_msg_edit_window_insert_image (window);
2267 modest_ui_actions_on_attach_file (GtkAction *action,
2268 ModestMsgEditWindow *window)
2270 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2271 g_return_if_fail (GTK_IS_ACTION (action));
2273 modest_msg_edit_window_offer_attach_file (window);
2277 modest_ui_actions_on_remove_attachments (GtkAction *action,
2278 ModestMsgEditWindow *window)
2280 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2281 g_return_if_fail (GTK_IS_ACTION (action));
2283 modest_msg_edit_window_remove_attachments (window, NULL);
2287 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2290 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2291 const GError *error = modest_mail_operation_get_error (mail_op);
2295 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2296 modest_mail_operation_get_error (mail_op)->message);
2301 modest_ui_actions_create_folder(GtkWidget *parent_window,
2302 GtkWidget *folder_view)
2304 TnyFolderStore *parent_folder;
2306 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2308 if (parent_folder) {
2309 gboolean finished = FALSE;
2311 gchar *folder_name = NULL, *suggested_name = NULL;
2312 const gchar *proto_str = NULL;
2313 TnyAccount *account;
2315 if (TNY_IS_ACCOUNT (parent_folder))
2316 account = g_object_ref (parent_folder);
2318 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2319 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2321 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2322 MODEST_PROTOCOL_STORE_POP) {
2324 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2326 g_object_unref (account);
2328 /* Run the new folder dialog */
2330 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2335 g_free (suggested_name);
2336 suggested_name = NULL;
2338 if (result == GTK_RESPONSE_REJECT) {
2341 ModestMailOperation *mail_op;
2342 TnyFolder *new_folder = NULL;
2344 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2345 G_OBJECT(parent_window),
2346 modest_ui_actions_new_folder_error_handler,
2349 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2351 new_folder = modest_mail_operation_create_folder (mail_op,
2353 (const gchar *) folder_name);
2355 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2358 g_object_unref (new_folder);
2361 g_object_unref (mail_op);
2364 suggested_name = folder_name;
2368 g_object_unref (parent_folder);
2373 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2375 GtkWidget *folder_view;
2377 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2379 folder_view = modest_main_window_get_child_widget (main_window,
2380 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2384 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2388 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2391 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2392 const GError *error = NULL;
2393 const gchar *message = NULL;
2395 /* Get error message */
2396 error = modest_mail_operation_get_error (mail_op);
2397 if (error != NULL && error->message != NULL) {
2398 message = error->message;
2400 message = _("!!! FIXME: Unable to rename");
2403 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2408 modest_ui_actions_on_rename_folder (GtkAction *action,
2409 ModestMainWindow *main_window)
2411 TnyFolderStore *folder;
2412 GtkWidget *folder_view;
2413 GtkWidget *header_view;
2415 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2417 folder_view = modest_main_window_get_child_widget (main_window,
2418 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2422 header_view = modest_main_window_get_child_widget (main_window,
2423 MODEST_WIDGET_TYPE_HEADER_VIEW);
2428 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2432 /* Offer the connection dialog if necessary: */
2433 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2434 g_object_unref (G_OBJECT (folder));
2439 if (TNY_IS_FOLDER (folder)) {
2442 const gchar *current_name;
2444 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2445 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2446 current_name, &folder_name);
2448 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2449 ModestMailOperation *mail_op;
2452 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2453 G_OBJECT(main_window),
2454 modest_ui_actions_rename_folder_error_handler,
2457 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2460 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2462 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2463 TNY_FOLDER(folder), TRUE);
2465 modest_header_view_clear ((ModestHeaderView *) header_view);
2467 modest_mail_operation_rename_folder (mail_op,
2468 TNY_FOLDER (folder),
2469 (const gchar *) folder_name);
2471 g_object_unref (mail_op);
2472 g_free (folder_name);
2475 g_object_unref (folder);
2479 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2482 GObject *win = modest_mail_operation_get_source (mail_op);
2484 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2485 _("mail_in_ui_folder_delete_error"));
2486 g_object_unref (win);
2490 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2492 TnyFolderStore *folder;
2493 GtkWidget *folder_view;
2497 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2499 folder_view = modest_main_window_get_child_widget (main_window,
2500 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2504 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2506 /* Show an error if it's an account */
2507 if (!TNY_IS_FOLDER (folder)) {
2508 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2509 _("mail_in_ui_folder_delete_error"));
2510 g_object_unref (G_OBJECT (folder));
2514 /* Offer the connection dialog if necessary: */
2515 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2516 g_object_unref (G_OBJECT (folder));
2521 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2522 tny_folder_get_name (TNY_FOLDER (folder)));
2523 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2524 (const gchar *) message);
2527 if (response == GTK_RESPONSE_OK) {
2528 ModestMailOperation *mail_op =
2529 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2530 G_OBJECT(main_window),
2531 modest_ui_actions_delete_folder_error_handler,
2534 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2536 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2537 g_object_unref (G_OBJECT (mail_op));
2540 g_object_unref (G_OBJECT (folder));
2544 modest_ui_actions_on_delete_folder (GtkAction *action,
2545 ModestMainWindow *main_window)
2547 GtkWidget *folder_view;
2548 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2550 delete_folder (main_window, FALSE);
2551 folder_view = modest_main_window_get_child_widget (main_window,
2552 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2555 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2559 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2561 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2563 delete_folder (main_window, TRUE);
2568 show_error (GtkWidget *parent_widget, const gchar* text)
2570 hildon_banner_show_information(parent_widget, NULL, text);
2573 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2575 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2582 gtk_dialog_run (dialog);
2583 gtk_widget_destroy (GTK_WIDGET (dialog));
2588 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2589 const gchar* server_account_name,
2594 ModestMainWindow *main_window)
2596 g_return_if_fail(server_account_name);
2597 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2599 /* Initalize output parameters: */
2606 #ifdef MODEST_PLATFORM_MAEMO
2607 /* Maemo uses a different (awkward) button order,
2608 * It should probably just use gtk_alternative_dialog_button_order ().
2610 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2614 GTK_RESPONSE_ACCEPT,
2616 GTK_RESPONSE_REJECT,
2619 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2623 GTK_RESPONSE_REJECT,
2625 GTK_RESPONSE_ACCEPT,
2627 #endif /* MODEST_PLATFORM_MAEMO */
2629 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2631 gchar *server_name = modest_server_account_get_hostname (
2632 modest_runtime_get_account_mgr(), server_account_name);
2633 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2634 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2639 /* This causes a warning because the logical ID has no %s in it,
2640 * though the translation does, but there is not much we can do about that: */
2641 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2642 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2645 g_free (server_name);
2649 gchar *initial_username = modest_server_account_get_username (
2650 modest_runtime_get_account_mgr(), server_account_name);
2652 GtkWidget *entry_username = gtk_entry_new ();
2653 if (initial_username)
2654 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2655 /* Dim this if a connection has ever succeeded with this username,
2656 * as per the UI spec: */
2657 const gboolean username_known =
2658 modest_server_account_get_username_has_succeeded(
2659 modest_runtime_get_account_mgr(), server_account_name);
2660 gtk_widget_set_sensitive (entry_username, !username_known);
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_username), HILDON_GTK_INPUT_MODE_FULL);
2666 /* Create a size group to be used by all captions.
2667 * Note that HildonCaption does not create a default size group if we do not specify one.
2668 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2669 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2671 GtkWidget *caption = hildon_caption_new (sizegroup,
2672 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2673 gtk_widget_show (entry_username);
2674 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2675 FALSE, FALSE, MODEST_MARGIN_HALF);
2676 gtk_widget_show (caption);
2678 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2680 #endif /* MODEST_PLATFORM_MAEMO */
2683 GtkWidget *entry_password = gtk_entry_new ();
2684 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2685 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2687 #ifdef MODEST_PLATFORM_MAEMO
2688 /* Auto-capitalization is the default, so let's turn it off: */
2689 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2690 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2692 caption = hildon_caption_new (sizegroup,
2693 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2694 gtk_widget_show (entry_password);
2695 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2696 FALSE, FALSE, MODEST_MARGIN_HALF);
2697 gtk_widget_show (caption);
2698 g_object_unref (sizegroup);
2700 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2702 #endif /* MODEST_PLATFORM_MAEMO */
2704 /* This is not in the Maemo UI spec:
2705 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2706 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2710 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2712 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2714 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2716 modest_server_account_set_username (
2717 modest_runtime_get_account_mgr(), server_account_name,
2720 const gboolean username_was_changed =
2721 (strcmp (*username, initial_username) != 0);
2722 if (username_was_changed) {
2723 g_warning ("%s: tinymail does not yet support changing the "
2724 "username in the get_password() callback.\n", __FUNCTION__);
2729 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2731 /* We do not save the password in the configuration,
2732 * because this function is only called for passwords that should
2733 * not be remembered:
2734 modest_server_account_set_password (
2735 modest_runtime_get_account_mgr(), server_account_name,
2744 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2756 /* This is not in the Maemo UI spec:
2757 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2763 gtk_widget_destroy (dialog);
2765 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2769 modest_ui_actions_on_cut (GtkAction *action,
2770 ModestWindow *window)
2772 GtkWidget *focused_widget;
2773 GtkClipboard *clipboard;
2775 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2776 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2777 if (GTK_IS_EDITABLE (focused_widget)) {
2778 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2779 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2780 gtk_clipboard_store (clipboard);
2781 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2782 GtkTextBuffer *buffer;
2784 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2785 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2786 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2787 gtk_clipboard_store (clipboard);
2788 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2789 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2790 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2791 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2796 modest_ui_actions_on_copy (GtkAction *action,
2797 ModestWindow *window)
2799 GtkClipboard *clipboard;
2800 GtkWidget *focused_widget;
2802 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2803 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2805 if (GTK_IS_LABEL (focused_widget)) {
2806 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2807 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2808 gtk_clipboard_store (clipboard);
2809 } else if (GTK_IS_EDITABLE (focused_widget)) {
2810 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2811 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2812 gtk_clipboard_store (clipboard);
2813 } else if (GTK_IS_HTML (focused_widget)) {
2814 gtk_html_copy (GTK_HTML (focused_widget));
2815 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2816 gtk_clipboard_store (clipboard);
2817 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2818 GtkTextBuffer *buffer;
2819 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2820 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2821 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2822 gtk_clipboard_store (clipboard);
2823 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2824 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2825 TnyIterator *iter = tny_list_create_iterator (header_list);
2826 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2828 gboolean ask = FALSE;
2830 TnyFolder *folder = tny_header_get_folder (header);
2831 TnyAccount *account = tny_folder_get_account (folder);
2832 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2833 /* If it's POP then ask */
2834 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2835 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2836 g_object_unref (account);
2837 g_object_unref (folder);
2838 g_object_unref (header);
2841 g_object_unref (iter);
2843 /* Check that the messages have been previously downloaded */
2844 gboolean continue_download = TRUE;
2846 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2847 if (continue_download)
2848 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2849 g_object_unref (header_list);
2850 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2851 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2854 /* Show information banner */
2855 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2860 modest_ui_actions_on_undo (GtkAction *action,
2861 ModestWindow *window)
2863 ModestEmailClipboard *clipboard = NULL;
2865 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2866 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2867 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2868 /* Clear clipboard source */
2869 clipboard = modest_runtime_get_email_clipboard ();
2870 modest_email_clipboard_clear (clipboard);
2873 g_return_if_reached ();
2878 modest_ui_actions_on_redo (GtkAction *action,
2879 ModestWindow *window)
2881 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2882 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2885 g_return_if_reached ();
2891 paste_msgs_cb (const GObject *object, gpointer user_data)
2893 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2894 g_return_if_fail (GTK_IS_WIDGET (user_data));
2896 /* destroy information note */
2897 gtk_widget_destroy (GTK_WIDGET(user_data));
2901 paste_as_attachment_free (gpointer data)
2903 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2905 gtk_widget_destroy (helper->banner);
2906 g_object_unref (helper->banner);
2911 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2916 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2917 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2922 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2927 modest_ui_actions_on_paste (GtkAction *action,
2928 ModestWindow *window)
2930 GtkWidget *focused_widget = NULL;
2931 GtkWidget *inf_note = NULL;
2932 ModestMailOperation *mail_op = NULL;
2934 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2935 if (GTK_IS_EDITABLE (focused_widget)) {
2936 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2937 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2938 ModestEmailClipboard *e_clipboard = NULL;
2939 e_clipboard = modest_runtime_get_email_clipboard ();
2940 if (modest_email_clipboard_cleared (e_clipboard)) {
2941 GtkTextBuffer *buffer;
2942 GtkClipboard *clipboard;
2944 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2945 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2946 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2947 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2948 ModestMailOperation *mail_op;
2949 TnyFolder *src_folder;
2952 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2953 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2954 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2955 _CS("ckct_nw_pasting"));
2956 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2957 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2959 if (helper->banner != NULL) {
2960 g_object_ref (G_OBJECT (helper->banner));
2961 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2962 gtk_widget_show (GTK_WIDGET (helper->banner));
2966 modest_mail_operation_get_msgs_full (mail_op,
2968 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2970 paste_as_attachment_free);
2973 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2974 ModestEmailClipboard *clipboard = NULL;
2975 TnyFolder *src_folder = NULL;
2976 TnyFolderStore *folder_store = NULL;
2977 TnyList *data = NULL;
2978 gboolean delete = FALSE;
2980 /* Check clipboard source */
2981 clipboard = modest_runtime_get_email_clipboard ();
2982 if (modest_email_clipboard_cleared (clipboard))
2985 /* Get elements to paste */
2986 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2988 /* Create a new mail operation */
2989 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2991 /* Get destination folder */
2992 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2994 /* transfer messages */
2998 /* Ask for user confirmation */
2999 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3000 TNY_FOLDER (folder_store),
3004 if (response == GTK_RESPONSE_OK) {
3005 /* Launch notification */
3006 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3007 _CS("ckct_nw_pasting"));
3008 if (inf_note != NULL) {
3009 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3010 gtk_widget_show (GTK_WIDGET(inf_note));
3013 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3014 modest_mail_operation_xfer_msgs (mail_op,
3016 TNY_FOLDER (folder_store),
3021 g_object_unref (mail_op);
3024 } else if (src_folder != NULL) {
3025 /* Launch notification */
3026 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3027 _CS("ckct_nw_pasting"));
3028 if (inf_note != NULL) {
3029 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3030 gtk_widget_show (GTK_WIDGET(inf_note));
3033 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3034 modest_mail_operation_xfer_folder (mail_op,
3044 g_object_unref (data);
3045 if (src_folder != NULL)
3046 g_object_unref (src_folder);
3047 if (folder_store != NULL)
3048 g_object_unref (folder_store);
3054 modest_ui_actions_on_select_all (GtkAction *action,
3055 ModestWindow *window)
3057 GtkWidget *focused_widget;
3059 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3060 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3061 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3062 } else if (GTK_IS_LABEL (focused_widget)) {
3063 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3064 } else if (GTK_IS_EDITABLE (focused_widget)) {
3065 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3066 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3067 GtkTextBuffer *buffer;
3068 GtkTextIter start, end;
3070 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3071 gtk_text_buffer_get_start_iter (buffer, &start);
3072 gtk_text_buffer_get_end_iter (buffer, &end);
3073 gtk_text_buffer_select_range (buffer, &start, &end);
3074 } else if (GTK_IS_HTML (focused_widget)) {
3075 gtk_html_select_all (GTK_HTML (focused_widget));
3076 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3077 GtkWidget *header_view = focused_widget;
3078 GtkTreeSelection *selection = NULL;
3080 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3081 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3082 MODEST_WIDGET_TYPE_HEADER_VIEW);
3084 /* Select all messages */
3085 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3086 gtk_tree_selection_select_all (selection);
3088 /* Set focuse on header view */
3089 gtk_widget_grab_focus (header_view);
3095 modest_ui_actions_on_mark_as_read (GtkAction *action,
3096 ModestWindow *window)
3098 g_return_if_fail (MODEST_IS_WINDOW(window));
3100 /* Mark each header as read */
3101 do_headers_action (window, headers_action_mark_as_read, NULL);
3105 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3106 ModestWindow *window)
3108 g_return_if_fail (MODEST_IS_WINDOW(window));
3110 /* Mark each header as read */
3111 do_headers_action (window, headers_action_mark_as_unread, NULL);
3115 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3116 GtkRadioAction *selected,
3117 ModestWindow *window)
3121 value = gtk_radio_action_get_current_value (selected);
3122 if (MODEST_IS_WINDOW (window)) {
3123 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3127 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3128 GtkRadioAction *selected,
3129 ModestWindow *window)
3131 TnyHeaderFlags flags;
3132 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3134 flags = gtk_radio_action_get_current_value (selected);
3135 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3138 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3139 GtkRadioAction *selected,
3140 ModestWindow *window)
3144 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3146 file_format = gtk_radio_action_get_current_value (selected);
3147 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3152 modest_ui_actions_on_zoom_plus (GtkAction *action,
3153 ModestWindow *window)
3155 g_return_if_fail (MODEST_IS_WINDOW (window));
3157 modest_window_zoom_plus (MODEST_WINDOW (window));
3161 modest_ui_actions_on_zoom_minus (GtkAction *action,
3162 ModestWindow *window)
3164 g_return_if_fail (MODEST_IS_WINDOW (window));
3166 modest_window_zoom_minus (MODEST_WINDOW (window));
3170 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3171 ModestWindow *window)
3173 ModestWindowMgr *mgr;
3174 gboolean fullscreen, active;
3175 g_return_if_fail (MODEST_IS_WINDOW (window));
3177 mgr = modest_runtime_get_window_mgr ();
3179 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3180 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3182 if (active != fullscreen) {
3183 modest_window_mgr_set_fullscreen_mode (mgr, active);
3184 gtk_window_present (GTK_WINDOW (window));
3189 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3190 ModestWindow *window)
3192 ModestWindowMgr *mgr;
3193 gboolean fullscreen;
3195 g_return_if_fail (MODEST_IS_WINDOW (window));
3197 mgr = modest_runtime_get_window_mgr ();
3198 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3199 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3201 gtk_window_present (GTK_WINDOW (window));
3205 * Used by modest_ui_actions_on_details to call do_headers_action
3208 headers_action_show_details (TnyHeader *header,
3209 ModestWindow *window,
3216 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3219 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3220 gtk_widget_show_all (dialog);
3221 gtk_dialog_run (GTK_DIALOG (dialog));
3223 gtk_widget_destroy (dialog);
3227 * Show the folder details in a ModestDetailsDialog widget
3230 show_folder_details (TnyFolder *folder,
3236 dialog = modest_details_dialog_new_with_folder (window, folder);
3239 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3240 gtk_widget_show_all (dialog);
3241 gtk_dialog_run (GTK_DIALOG (dialog));
3243 gtk_widget_destroy (dialog);
3247 * Show the header details in a ModestDetailsDialog widget
3250 modest_ui_actions_on_details (GtkAction *action,
3253 TnyList * headers_list;
3257 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3260 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3263 g_object_unref (msg);
3265 headers_list = get_selected_headers (win);
3269 iter = tny_list_create_iterator (headers_list);
3271 header = TNY_HEADER (tny_iterator_get_current (iter));
3273 headers_action_show_details (header, win, NULL);
3274 g_object_unref (header);
3277 g_object_unref (iter);
3278 g_object_unref (headers_list);
3280 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3281 GtkWidget *folder_view, *header_view;
3283 /* Check which widget has the focus */
3284 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3285 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3286 if (gtk_widget_is_focus (folder_view)) {
3287 TnyFolderStore *folder_store
3288 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3289 if (!folder_store) {
3290 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3293 /* Show only when it's a folder */
3294 /* This function should not be called for account items,
3295 * because we dim the menu item for them. */
3296 if (TNY_IS_FOLDER (folder_store)) {
3297 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3300 g_object_unref (folder_store);
3303 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3304 MODEST_WIDGET_TYPE_HEADER_VIEW);
3305 /* Show details of each header */
3306 do_headers_action (win, headers_action_show_details, header_view);
3312 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3313 ModestMsgEditWindow *window)
3315 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3317 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3321 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3322 ModestMsgEditWindow *window)
3324 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3326 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3330 modest_ui_actions_toggle_folders_view (GtkAction *action,
3331 ModestMainWindow *main_window)
3333 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3335 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3336 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3338 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3342 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3343 ModestWindow *window)
3345 gboolean active, fullscreen = FALSE;
3346 ModestWindowMgr *mgr;
3348 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3350 /* Check if we want to toggle the toolbar vuew in fullscreen
3352 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3353 "ViewShowToolbarFullScreen")) {
3357 /* Toggle toolbar */
3358 mgr = modest_runtime_get_window_mgr ();
3359 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3363 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3364 ModestMsgEditWindow *window)
3366 modest_msg_edit_window_select_font (window);
3370 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3371 const gchar *display_name,
3374 /* Do not change the application name if the widget has not
3375 the focus. This callback could be called even if the folder
3376 view has not the focus, because the handled signal could be
3377 emitted when the folder view is redrawn */
3378 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3380 gtk_window_set_title (window, display_name);
3382 gtk_window_set_title (window, " ");
3387 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3389 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3390 modest_msg_edit_window_select_contacts (window);
3394 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3397 modest_msg_edit_window_check_names (window, FALSE);
3401 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3403 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3404 GTK_WIDGET (user_data));
3408 create_move_to_dialog (GtkWindow *win,
3409 GtkWidget *folder_view,
3410 GtkWidget **tree_view)
3412 GtkWidget *dialog, *scroll;
3413 GtkWidget *new_button;
3415 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3417 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3420 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3421 /* We do this manually so GTK+ does not associate a response ID for
3423 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3424 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3425 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3427 /* Create scrolled window */
3428 scroll = gtk_scrolled_window_new (NULL, NULL);
3429 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3430 GTK_POLICY_AUTOMATIC,
3431 GTK_POLICY_AUTOMATIC);
3433 /* Create folder view */
3434 *tree_view = modest_platform_create_folder_view (NULL);
3436 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3438 /* It could happen that we're trying to move a message from a
3439 window (msg window for example) after the main window was
3440 closed, so we can not just get the model of the folder
3442 if (MODEST_IS_FOLDER_VIEW (folder_view))
3443 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3444 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3446 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3447 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3449 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3451 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3453 /* Add scroll to dialog */
3454 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3455 scroll, TRUE, TRUE, 0);
3457 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3458 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3464 * Returns TRUE if at least one of the headers of the list belongs to
3465 * a message that has been fully retrieved.
3468 has_retrieved_msgs (TnyList *list)
3471 gboolean found = FALSE;
3473 iter = tny_list_create_iterator (list);
3474 while (!tny_iterator_is_done (iter) && !found) {
3476 TnyHeaderFlags flags = 0;
3478 header = TNY_HEADER (tny_iterator_get_current (iter));
3480 flags = tny_header_get_flags (header);
3481 if (flags & TNY_HEADER_FLAG_CACHED)
3482 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3485 g_object_unref (header);
3489 tny_iterator_next (iter);
3491 g_object_unref (iter);
3497 * Shows a confirmation dialog to the user when we're moving messages
3498 * from a remote server to the local storage. Returns the dialog
3499 * response. If it's other kind of movement the it always returns
3503 msgs_move_to_confirmation (GtkWindow *win,
3504 TnyFolder *dest_folder,
3508 gint response = GTK_RESPONSE_OK;
3510 /* If the destination is a local folder (or MMC folder )*/
3511 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3512 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3513 TnyFolder *src_folder = NULL;
3514 TnyIterator *iter = NULL;
3515 TnyHeader *header = NULL;
3517 /* Get source folder */
3518 iter = tny_list_create_iterator (headers);
3519 header = TNY_HEADER (tny_iterator_get_current (iter));
3521 src_folder = tny_header_get_folder (header);
3522 g_object_unref (header);
3525 g_object_unref (iter);
3527 /* if no src_folder, message may be an attahcment */
3528 if (src_folder == NULL)
3529 return GTK_RESPONSE_CANCEL;
3531 /* If the source is a remote folder */
3532 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3533 if (modest_tny_folder_is_remote_folder (src_folder)) {
3534 const gchar *message = NULL;
3535 gboolean cached = has_retrieved_msgs (headers);
3537 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3538 tny_list_get_length (headers));
3540 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3541 tny_list_get_length (headers));
3543 if (cached && !delete)
3544 response = GTK_RESPONSE_OK;
3546 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3547 (const gchar *) message);
3550 g_object_unref (src_folder);
3559 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3561 ModestMsgViewWindow *self = NULL;
3563 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3564 self = MODEST_MSG_VIEW_WINDOW (object);
3566 if (!modest_msg_view_window_select_next_message (self))
3567 if (!modest_msg_view_window_select_previous_message (self))
3568 /* No more messages to view, so close this window */
3569 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3573 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3576 GObject *win = modest_mail_operation_get_source (mail_op);
3577 const GError *error = NULL;
3578 const gchar *message = NULL;
3580 /* Get error message */
3581 error = modest_mail_operation_get_error (mail_op);
3582 if (error != NULL && error->message != NULL) {
3583 message = error->message;
3585 message = _("mail_in_ui_folder_move_target_error");
3588 /* Show notification dialog */
3589 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3590 g_object_unref (win);
3594 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3597 GObject *win = modest_mail_operation_get_source (mail_op);
3598 const GError *error = modest_mail_operation_get_error (mail_op);
3600 g_return_if_fail (error != NULL);
3601 if (error->message != NULL)
3602 g_printerr ("modest: %s\n", error->message);
3604 g_printerr ("modest: unkonw error on send&receive operation");
3606 /* Show error message */
3607 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3608 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3609 /* _CS("sfil_ib_unable_to_receive")); */
3611 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3612 /* _CS("sfil_ib_unable_to_send")); */
3613 g_object_unref (win);
3617 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3624 gint pending_purges = 0;
3625 gboolean some_purged = FALSE;
3626 ModestWindow *win = MODEST_WINDOW (user_data);
3627 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3629 /* If there was any error */
3630 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3631 modest_window_mgr_unregister_header (mgr, header);
3635 /* Once the message has been retrieved for purging, we check if
3636 * it's all ok for purging */
3638 parts = tny_simple_list_new ();
3639 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3640 iter = tny_list_create_iterator (parts);
3642 while (!tny_iterator_is_done (iter)) {
3644 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3645 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3646 if (tny_mime_part_is_purged (part))
3653 g_object_unref (part);
3655 tny_iterator_next (iter);
3658 if (pending_purges>0) {
3660 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3662 if (response == GTK_RESPONSE_OK) {
3663 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3664 tny_iterator_first (iter);
3665 while (!tny_iterator_is_done (iter)) {
3668 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3669 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3670 tny_mime_part_set_purged (part);
3673 g_object_unref (part);
3675 tny_iterator_next (iter);
3678 tny_msg_rewrite_cache (msg);
3681 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3684 /* remove attachments */
3685 tny_iterator_first (iter);
3686 while (!tny_iterator_is_done (iter)) {
3689 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3691 /* One for the reference given by tny_iterator_get_current(): */
3692 g_object_unref (part);
3694 /* TODO: Is this meant to remove the attachment by doing another unref()?
3695 * Otherwise, this seems useless. */
3698 tny_iterator_next (iter);
3700 modest_window_mgr_unregister_header (mgr, header);
3702 g_object_unref (iter);
3703 g_object_unref (parts);
3707 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3708 ModestMainWindow *win)
3710 GtkWidget *header_view;
3711 TnyList *header_list;
3714 TnyHeaderFlags flags;
3715 ModestWindow *msg_view_window = NULL;
3718 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3720 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3721 MODEST_WIDGET_TYPE_HEADER_VIEW);
3723 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3725 if (tny_list_get_length (header_list) == 1) {
3726 iter = tny_list_create_iterator (header_list);
3727 header = TNY_HEADER (tny_iterator_get_current (iter));
3728 g_object_unref (iter);
3733 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3734 header, &msg_view_window);
3735 flags = tny_header_get_flags (header);
3736 if (!(flags & TNY_HEADER_FLAG_CACHED))
3739 if (msg_view_window != NULL)
3740 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3742 /* do nothing; uid was registered before, so window is probably on it's way */
3743 g_warning ("debug: header %p has already been registered", header);
3746 ModestMailOperation *mail_op = NULL;
3747 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3748 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3750 modest_ui_actions_get_msgs_full_error_handler,
3752 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3753 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3755 g_object_unref (mail_op);
3758 g_object_unref (header);
3760 g_object_unref (header_list);
3764 * Utility function that transfer messages from both the main window
3765 * and the msg view window when using the "Move to" dialog
3768 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3771 TnyList *headers = NULL;
3773 TnyAccount *dst_account = NULL;
3774 const gchar *proto_str = NULL;
3775 gboolean dst_is_pop = FALSE;
3777 if (!TNY_IS_FOLDER (dst_folder)) {
3778 modest_platform_information_banner (GTK_WIDGET (win),
3780 _CS("ckdg_ib_unable_to_move_to_current_location"));
3784 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3785 proto_str = tny_account_get_proto (dst_account);
3786 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3787 MODEST_PROTOCOL_STORE_POP);
3788 g_object_unref (dst_account);
3790 /* Get selected headers */
3791 headers = get_selected_headers (MODEST_WINDOW (win));
3794 modest_platform_information_banner (GTK_WIDGET (win),
3796 ngettext("mail_in_ui_folder_move_target_error",
3797 "mail_in_ui_folder_move_targets_error",
3798 tny_list_get_length (headers)));
3799 g_object_unref (headers);
3803 /* Ask for user confirmation */
3804 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3805 TNY_FOLDER (dst_folder),
3809 /* Transfer messages */
3810 if (response == GTK_RESPONSE_OK) {
3811 ModestMailOperation *mail_op =
3812 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3814 modest_ui_actions_move_folder_error_handler,
3816 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3819 modest_mail_operation_xfer_msgs (mail_op,
3821 TNY_FOLDER (dst_folder),
3823 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3826 g_object_unref (G_OBJECT (mail_op));
3828 g_object_unref (headers);
3833 * UI handler for the "Move to" action when invoked from the
3837 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3838 GtkWidget *folder_view,
3839 TnyFolderStore *dst_folder,
3840 ModestMainWindow *win)
3842 GtkWidget *header_view = NULL;
3843 ModestMailOperation *mail_op = NULL;
3844 TnyFolderStore *src_folder;
3846 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3848 /* Get the source folder */
3849 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3851 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3852 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3856 /* Get header view */
3858 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3860 /* Get folder or messages to transfer */
3861 if (gtk_widget_is_focus (folder_view)) {
3863 /* Allow only to transfer folders to the local root folder */
3864 if (TNY_IS_ACCOUNT (dst_folder) &&
3865 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3868 /* Clean folder on header view before moving it */
3869 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3871 if (TNY_IS_FOLDER (src_folder)) {
3873 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3875 modest_ui_actions_move_folder_error_handler,
3877 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3880 modest_mail_operation_xfer_folder (mail_op,
3881 TNY_FOLDER (src_folder),
3884 /* Unref mail operation */
3885 g_object_unref (G_OBJECT (mail_op));
3887 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3889 } else if (gtk_widget_is_focus (header_view)) {
3890 /* Transfer messages */
3891 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3896 g_object_unref (src_folder);
3901 * UI handler for the "Move to" action when invoked from the
3902 * ModestMsgViewWindow
3905 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3906 TnyFolderStore *dst_folder,
3907 ModestMsgViewWindow *win)
3909 TnyHeader *header = NULL;
3910 TnyFolder *src_folder;
3912 /* Create header list */
3913 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3914 src_folder = tny_header_get_folder(header);
3915 g_object_unref (header);
3917 /* Transfer the message */
3918 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3919 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3921 g_object_unref (src_folder);
3925 modest_ui_actions_on_move_to (GtkAction *action,
3928 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3930 TnyFolderStore *dst_folder = NULL;
3931 ModestMainWindow *main_window;
3933 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3934 MODEST_IS_MSG_VIEW_WINDOW (win));
3936 /* Get the main window if exists */
3937 if (MODEST_IS_MAIN_WINDOW (win))
3938 main_window = MODEST_MAIN_WINDOW (win);
3941 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3943 /* Get the folder view widget if exists */
3945 folder_view = modest_main_window_get_child_widget (main_window,
3946 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3950 /* Create and run the dialog */
3951 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3952 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3953 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3954 result = gtk_dialog_run (GTK_DIALOG(dialog));
3955 g_object_ref (tree_view);
3956 gtk_widget_destroy (dialog);
3958 if (result != GTK_RESPONSE_ACCEPT)
3961 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3962 /* Offer the connection dialog if necessary: */
3963 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3966 /* Do window specific stuff */
3967 if (MODEST_IS_MAIN_WINDOW (win))
3968 modest_ui_actions_on_main_window_move_to (action,
3971 MODEST_MAIN_WINDOW (win));
3973 modest_ui_actions_on_msg_view_window_move_to (action,
3975 MODEST_MSG_VIEW_WINDOW (win));
3978 g_object_unref (dst_folder);
3982 * Calls #HeadersFunc for each header already selected in the main
3983 * window or the message currently being shown in the msg view window
3986 do_headers_action (ModestWindow *win,
3990 TnyList *headers_list = NULL;
3991 TnyIterator *iter = NULL;
3992 TnyHeader *header = NULL;
3993 TnyFolder *folder = NULL;
3996 headers_list = get_selected_headers (win);
4000 /* Get the folder */
4001 iter = tny_list_create_iterator (headers_list);
4002 header = TNY_HEADER (tny_iterator_get_current (iter));
4004 folder = tny_header_get_folder (header);
4005 g_object_unref (header);
4008 /* Call the function for each header */
4009 while (!tny_iterator_is_done (iter)) {
4010 header = TNY_HEADER (tny_iterator_get_current (iter));
4011 func (header, win, user_data);
4012 g_object_unref (header);
4013 tny_iterator_next (iter);
4016 /* Trick: do a poke status in order to speed up the signaling
4018 tny_folder_poke_status (folder);
4021 g_object_unref (folder);
4022 g_object_unref (iter);
4023 g_object_unref (headers_list);
4027 modest_ui_actions_view_attachment (GtkAction *action,
4028 ModestWindow *window)
4030 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4031 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4033 /* not supported window for this action */
4034 g_return_if_reached ();
4039 modest_ui_actions_save_attachments (GtkAction *action,
4040 ModestWindow *window)
4042 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4043 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4045 /* not supported window for this action */
4046 g_return_if_reached ();
4051 modest_ui_actions_remove_attachments (GtkAction *action,
4052 ModestWindow *window)
4054 if (MODEST_IS_MAIN_WINDOW (window)) {
4055 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4056 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4057 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4059 /* not supported window for this action */
4060 g_return_if_reached ();
4065 modest_ui_actions_on_settings (GtkAction *action,
4070 dialog = modest_platform_get_global_settings_dialog ();
4071 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4072 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4073 gtk_widget_show_all (dialog);
4075 gtk_dialog_run (GTK_DIALOG (dialog));
4077 gtk_widget_destroy (dialog);
4081 modest_ui_actions_on_help (GtkAction *action,
4084 const gchar *help_id = NULL;
4086 if (MODEST_IS_MAIN_WINDOW (win)) {
4087 const gchar *action_name;
4088 action_name = gtk_action_get_name (action);
4090 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4091 !strcmp (action_name, "HeaderViewCSMHelp")) {
4092 GtkWidget *folder_view;
4093 TnyFolderStore *folder_store;
4094 /* Get selected folder */
4095 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4096 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4097 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4099 /* Switch help_id */
4100 if (TNY_IS_FOLDER (folder_store)) {
4101 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4102 case TNY_FOLDER_TYPE_NORMAL:
4103 help_id = "applications_email_managefolders";
4105 case TNY_FOLDER_TYPE_INBOX:
4106 help_id = "applications_email_inbox";
4108 case TNY_FOLDER_TYPE_OUTBOX:
4109 help_id = "applications_email_outbox";
4111 case TNY_FOLDER_TYPE_SENT:
4112 help_id = "applications_email_sent";
4114 case TNY_FOLDER_TYPE_DRAFTS:
4115 help_id = "applications_email_drafts";
4117 case TNY_FOLDER_TYPE_ARCHIVE:
4118 help_id = "applications_email_managefolders";
4121 help_id = "applications_email_managefolders";
4124 help_id = "applications_email_mainview";
4126 g_object_unref (folder_store);
4128 help_id = "applications_email_mainview";
4130 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4131 help_id = "applications_email_viewer";
4132 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4133 help_id = "applications_email_editor";
4135 modest_platform_show_help (GTK_WINDOW (win), help_id);
4139 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4140 ModestWindow *window)
4142 ModestMailOperation *mail_op;
4146 headers = get_selected_headers (window);
4150 /* Create mail operation */
4151 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4153 modest_ui_actions_get_msgs_full_error_handler,
4155 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4156 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4159 g_object_unref (headers);
4160 g_object_unref (mail_op);
4164 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4165 ModestWindow *window)
4167 g_return_if_fail (MODEST_IS_WINDOW (window));
4170 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4174 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4175 ModestWindow *window)
4177 g_return_if_fail (MODEST_IS_WINDOW (window));
4180 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4184 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4185 ModestWindow *window)
4187 g_return_if_fail (MODEST_IS_WINDOW (window));
4190 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4194 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4195 ModestWindow *window)
4197 g_return_if_fail (MODEST_IS_WINDOW (window));
4200 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4204 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4205 ModestWindow *window)
4207 g_return_if_fail (MODEST_IS_WINDOW (window));
4210 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4214 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4215 ModestWindow *window)
4217 g_return_if_fail (MODEST_IS_WINDOW (window));
4220 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4224 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4225 ModestWindow *window)
4227 g_return_if_fail (MODEST_IS_WINDOW (window));
4230 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4234 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4235 ModestWindow *window)
4237 g_return_if_fail (MODEST_IS_WINDOW (window));
4240 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4244 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4246 g_return_if_fail (MODEST_IS_WINDOW (window));
4249 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4253 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4255 g_return_if_fail (MODEST_IS_WINDOW (window));
4257 modest_platform_show_search_messages (GTK_WINDOW (window));
4261 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4263 g_return_if_fail (MODEST_IS_WINDOW (win));
4264 modest_platform_show_addressbook (GTK_WINDOW (win));
4269 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4270 ModestWindow *window)
4272 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4274 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4278 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4279 ModestMailOperationState *state,
4282 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4284 /* Set send/receive operation finished */
4285 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4286 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));