1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _PasteAsAttachmentHelper {
107 ModestMsgEditWindow *window;
109 } PasteAsAttachmentHelper;
113 * The do_headers_action uses this kind of functions to perform some
114 * action to each member of a list of headers
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
118 static void do_headers_action (ModestWindow *win,
122 static void open_msg_cb (ModestMailOperation *mail_op,
127 static void reply_forward_cb (ModestMailOperation *mail_op,
132 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
134 static void folder_refreshed_cb (ModestMailOperation *mail_op,
138 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
139 ModestMailOperationState *state,
143 download_uncached_messages (TnyList *header_list, GtkWindow *win);
147 msgs_move_to_confirmation (GtkWindow *win,
148 TnyFolder *dest_folder,
153 /* Show the account creation wizard dialog.
154 * returns: TRUE if an account was created. FALSE if the user cancelled.
157 modest_run_account_setup_wizard (ModestWindow *win)
159 gboolean result = FALSE;
160 ModestEasysetupWizardDialog *wizard;
163 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
165 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
167 wizard = modest_easysetup_wizard_dialog_new ();
168 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
170 /* Don't make this a modal window, because secondary windows will then
171 * be unusable, freezing the UI: */
172 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
174 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
175 if (dialog_response == GTK_RESPONSE_CANCEL)
178 /* Check whether an account was created: */
179 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
182 gtk_widget_destroy (GTK_WIDGET (wizard));
189 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
192 const gchar *authors[] = {
193 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
196 about = gtk_about_dialog_new ();
197 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
198 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
199 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
200 _("Copyright (c) 2006, Nokia Corporation\n"
201 "All rights reserved."));
202 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
203 _("a modest e-mail client\n\n"
204 "design and implementation: Dirk-Jan C. Binnema\n"
205 "contributions from the fine people at KC and Ig\n"
206 "uses the tinymail email framework written by Philip van Hoof"));
207 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
208 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
209 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
210 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
212 gtk_dialog_run (GTK_DIALOG (about));
213 gtk_widget_destroy(about);
217 * Gets the list of currently selected messages. If the win is the
218 * main window, then it returns a newly allocated list of the headers
219 * selected in the header view. If win is the msg view window, then
220 * the value returned is a list with just a single header.
222 * The caller of this funcion must free the list.
225 get_selected_headers (ModestWindow *win)
227 if (MODEST_IS_MAIN_WINDOW(win)) {
228 GtkWidget *header_view;
230 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
231 MODEST_WIDGET_TYPE_HEADER_VIEW);
232 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
234 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
235 /* for MsgViewWindows, we simply return a list with one element */
237 TnyList *list = NULL;
239 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
240 if (header != NULL) {
241 list = tny_simple_list_new ();
242 tny_list_prepend (list, G_OBJECT(header));
243 g_object_unref (G_OBJECT(header));
253 headers_action_mark_as_read (TnyHeader *header,
257 TnyHeaderFlags flags;
259 g_return_if_fail (TNY_IS_HEADER(header));
261 flags = tny_header_get_flags (header);
262 if (flags & TNY_HEADER_FLAG_SEEN) return;
263 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
267 headers_action_mark_as_unread (TnyHeader *header,
271 TnyHeaderFlags flags;
273 g_return_if_fail (TNY_IS_HEADER(header));
275 flags = tny_header_get_flags (header);
276 if (flags & TNY_HEADER_FLAG_SEEN) {
277 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
281 /** A convenience method, because deleting a message is
282 * otherwise complicated, and it's best to change it in one place
285 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
287 ModestMailOperation *mail_op = NULL;
288 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
289 win ? G_OBJECT(win) : NULL);
290 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
293 /* Always delete. TODO: Move to trash still not supported */
294 modest_mail_operation_remove_msg (mail_op, header, FALSE);
295 g_object_unref (G_OBJECT (mail_op));
299 headers_action_delete (TnyHeader *header,
303 modest_do_message_delete (header, win);
306 /** After deleing a message that is currently visible in a window,
307 * show the next message from the list, or close the window if there are no more messages.
309 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
311 /* Close msg view window or select next */
312 if (modest_msg_view_window_last_message_selected (win) &&
313 modest_msg_view_window_first_message_selected (win)) {
314 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
316 if (!modest_msg_view_window_select_next_message (win)) {
318 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
324 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
326 TnyList *header_list = NULL;
327 TnyIterator *iter = NULL;
328 TnyHeader *header = NULL;
329 gchar *message = NULL;
332 ModestWindowMgr *mgr;
333 GtkWidget *header_view = NULL;
335 g_return_if_fail (MODEST_IS_WINDOW(win));
337 /* Check first if the header view has the focus */
338 if (MODEST_IS_MAIN_WINDOW (win)) {
340 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
341 MODEST_WIDGET_TYPE_HEADER_VIEW);
342 if (!gtk_widget_is_focus (header_view))
346 /* Get the headers, either from the header view (if win is the main window),
347 * or from the message view window: */
348 header_list = get_selected_headers (win);
349 if (!header_list) return;
351 /* Check if any of the headers are already opened, or in the process of being opened */
352 if (MODEST_IS_MAIN_WINDOW (win)) {
354 iter = tny_list_create_iterator (header_list);
356 mgr = modest_runtime_get_window_mgr ();
357 while (!tny_iterator_is_done (iter) && !found) {
358 header = TNY_HEADER (tny_iterator_get_current (iter));
360 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
361 g_object_unref (header);
364 tny_iterator_next (iter);
366 g_object_unref (iter);
371 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
372 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
374 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
378 g_object_unref (header_list);
384 if (tny_list_get_length(header_list) == 1) {
385 iter = tny_list_create_iterator (header_list);
386 header = TNY_HEADER (tny_iterator_get_current (iter));
388 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
389 g_object_unref (header);
392 g_object_unref (iter);
394 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
395 tny_list_get_length(header_list)), desc);
397 /* Confirmation dialog */
398 printf("DEBUG: %s\n", __FUNCTION__);
399 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
403 if (response == GTK_RESPONSE_OK) {
404 ModestWindow *main_window = NULL;
405 ModestWindowMgr *mgr = NULL;
406 GtkTreeModel *model = NULL;
407 GtkTreeSelection *sel = NULL;
408 GList *sel_list = NULL, *tmp = NULL;
409 GtkTreeRowReference *row_reference = NULL;
410 GtkTreePath *next_path = NULL;
411 TnyFolder *folder = NULL;
414 /* Find last selected row */
415 if (MODEST_IS_MAIN_WINDOW (win)) {
416 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
417 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
418 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
419 for (tmp=sel_list; tmp; tmp=tmp->next) {
420 if (tmp->next == NULL) {
421 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
422 gtk_tree_path_next (next_path);
423 row_reference = gtk_tree_row_reference_new (model, next_path);
424 gtk_tree_path_free (next_path);
429 /* Remove each header. If it's a view window header_view == NULL */
430 do_headers_action (win, headers_action_delete, header_view);
432 /* refresh the header view (removing marked-as-deleted)*/
433 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
435 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
436 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
438 /* Get main window */
439 mgr = modest_runtime_get_window_mgr ();
440 main_window = modest_window_mgr_get_main_window (mgr);
443 /* Move cursor to next row */
446 /* Select next row */
447 if (gtk_tree_row_reference_valid (row_reference)) {
448 next_path = gtk_tree_row_reference_get_path (row_reference);
449 gtk_tree_selection_select_path (sel, next_path);
450 gtk_tree_path_free (next_path);
452 if (row_reference != NULL)
453 gtk_tree_row_reference_free (row_reference);
456 /* Get folder from first header and sync it */
457 iter = tny_list_create_iterator (header_list);
458 header = TNY_HEADER (tny_iterator_get_current (iter));
459 folder = tny_header_get_folder (header);
460 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
461 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
462 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
463 else if (TNY_IS_CAMEL_POP_FOLDER (folder))
464 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
465 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
468 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
469 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
472 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
476 g_object_unref (header);
477 g_object_unref (iter);
478 g_object_unref (folder);
480 /* Update toolbar dimming state */
481 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
484 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
485 g_list_free (sel_list);
491 g_object_unref (header_list);
497 /* delete either message or folder, based on where we are */
499 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
501 g_return_if_fail (MODEST_IS_WINDOW(win));
503 /* Check first if the header view has the focus */
504 if (MODEST_IS_MAIN_WINDOW (win)) {
506 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
507 MODEST_WIDGET_TYPE_FOLDER_VIEW);
508 if (gtk_widget_is_focus (w)) {
509 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
513 modest_ui_actions_on_delete_message (action, win);
519 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
521 #ifdef MODEST_PLATFORM_MAEMO
522 modest_osso_save_state();
523 #endif /* MODEST_PLATFORM_MAEMO */
525 g_debug ("closing down, clearing %d item(s) from operation queue",
526 modest_mail_operation_queue_num_elements
527 (modest_runtime_get_mail_operation_queue()));
529 /* cancel all outstanding operations */
530 modest_mail_operation_queue_cancel_all
531 (modest_runtime_get_mail_operation_queue());
533 g_debug ("queue has been cleared");
535 /* note: when modest-tny-account-store is finalized,
536 it will automatically set all network connections
543 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
547 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
549 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
550 /* gtk_widget_destroy (GTK_WIDGET (win)); */
551 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
552 /* gboolean ret_value; */
553 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
554 /* } else if (MODEST_IS_WINDOW (win)) { */
555 /* gtk_widget_destroy (GTK_WIDGET (win)); */
557 /* g_return_if_reached (); */
562 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
564 GtkClipboard *clipboard = NULL;
565 gchar *selection = NULL;
567 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
568 selection = gtk_clipboard_wait_for_text (clipboard);
570 /* Question: why is the clipboard being used here?
571 * It doesn't really make a lot of sense. */
575 modest_address_book_add_address (selection);
581 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
583 /* This is currently only implemented for Maemo */
584 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
585 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
586 modest_run_account_setup_wizard (win);
589 /* Show the list of accounts: */
590 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
591 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
593 /* Don't make this a modal window, because secondary windows will then
594 * be unusable, freezing the UI: */
595 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
596 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
599 GtkWidget *dialog, *label;
601 /* Create the widgets */
603 dialog = gtk_dialog_new_with_buttons ("Message",
605 GTK_DIALOG_DESTROY_WITH_PARENT,
609 label = gtk_label_new ("Hello World!");
611 /* Ensure that the dialog box is destroyed when the user responds. */
613 g_signal_connect_swapped (dialog, "response",
614 G_CALLBACK (gtk_widget_destroy),
617 /* Add the label, and show everything we've added to the dialog. */
619 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
621 gtk_widget_show_all (dialog);
622 #endif /* MODEST_PLATFORM_MAEMO */
626 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
628 ModestWindow *main_window = MODEST_WINDOW (user_data);
630 /* Save any changes. */
631 modest_connection_specific_smtp_window_save_server_accounts (
632 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
633 modest_window_get_active_account (main_window));
634 gtk_widget_destroy (GTK_WIDGET (window));
640 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
642 /* This is currently only implemented for Maemo,
643 * because it requires an API (libconic) to detect different connection
646 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
648 /* Create the window if necessary: */
649 const gchar *active_account_name = modest_window_get_active_account (win);
651 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
652 * or show the default account?
653 * If we show the default account then the account name should be shown in
654 * the window when we show it. */
655 if (!active_account_name) {
656 g_warning ("%s: No account is active.", __FUNCTION__);
660 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
661 modest_connection_specific_smtp_window_fill_with_connections (
662 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
663 modest_runtime_get_account_mgr(),
664 active_account_name);
666 /* Show the window: */
667 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
668 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
669 gtk_widget_show (specific_window);
671 /* Save changes when the window is hidden: */
672 g_signal_connect (specific_window, "hide",
673 G_CALLBACK (on_smtp_servers_window_hide), win);
674 #endif /* MODEST_PLATFORM_MAEMO */
678 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
680 ModestWindow *msg_win = NULL;
682 TnyFolder *folder = NULL;
683 gchar *account_name = NULL;
684 gchar *from_str = NULL;
685 /* GError *err = NULL; */
686 TnyAccount *account = NULL;
687 ModestWindowMgr *mgr;
688 gchar *signature = NULL, *blank_and_signature = NULL;
690 /* if there are no accounts yet, just show the wizard */
691 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
692 const gboolean created = modest_run_account_setup_wizard (win);
697 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
699 account_name = g_strdup (modest_window_get_active_account (win));
701 g_printerr ("modest: no account found\n");
705 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
707 TNY_ACCOUNT_TYPE_STORE);
709 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
713 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
715 g_printerr ("modest: failed get from string for '%s'\n", account_name);
719 gboolean use_signature = FALSE;
720 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
723 blank_and_signature = g_strconcat ("\n", signature, NULL);
725 blank_and_signature = g_strdup ("");
730 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
732 g_printerr ("modest: failed to create new msg\n");
736 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
738 g_printerr ("modest: failed to find Drafts folder\n");
743 /* Create and register edit window */
744 /* This is destroyed by TODO. */
745 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
746 mgr = modest_runtime_get_window_mgr ();
747 modest_window_mgr_register_window (mgr, msg_win);
750 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
752 gtk_widget_show_all (GTK_WIDGET (msg_win));
755 g_free (account_name);
757 g_free (blank_and_signature);
759 g_object_unref (msg_win);
761 g_object_unref (G_OBJECT(account));
763 g_object_unref (G_OBJECT(msg));
765 g_object_unref (G_OBJECT(folder));
769 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
773 ModestMailOperationStatus status;
775 /* If there is no message or the operation was not successful */
776 status = modest_mail_operation_get_status (mail_op);
777 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
779 /* Remove the header from the preregistered uids */
780 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
790 open_msg_cb (ModestMailOperation *mail_op,
795 ModestWindowMgr *mgr = NULL;
796 ModestWindow *parent_win = NULL;
797 ModestWindow *win = NULL;
798 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
799 gchar *account = NULL;
802 /* Do nothing if there was any problem with the mail
803 operation. The error will be shown by the error_handler of
804 the mail operation */
805 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
809 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
810 folder = tny_header_get_folder (header);
812 /* Mark header as read */
813 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
816 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
818 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
820 /* Gets folder type (OUTBOX headers will be opened in edit window */
821 if (modest_tny_folder_is_local_folder (folder))
822 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
824 /* If the header is in the drafts folder then open the editor,
825 else the message view window */
826 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
827 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
828 /* we cannot edit without a valid account... */
829 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
830 const gboolean created = modest_run_account_setup_wizard(parent_win);
834 win = modest_msg_edit_window_new (msg, account, TRUE);
837 gchar *uid = modest_tny_folder_get_header_unique_id (header);
839 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
840 GtkWidget *header_view;
841 GtkTreeSelection *sel;
842 GList *sel_list = NULL;
845 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
846 MODEST_WIDGET_TYPE_HEADER_VIEW);
848 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
849 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
851 if (sel_list != NULL) {
852 GtkTreeRowReference *row_reference;
854 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
855 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
856 g_list_free (sel_list);
858 win = modest_msg_view_window_new_with_header_model (
859 msg, account, (const gchar*) uid,
860 model, row_reference);
861 gtk_tree_row_reference_free (row_reference);
863 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
866 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
871 /* Register and show new window */
873 mgr = modest_runtime_get_window_mgr ();
874 modest_window_mgr_register_window (mgr, win);
875 g_object_unref (win);
876 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
877 gtk_widget_show_all (GTK_WIDGET(win));
880 /* Update toolbar dimming state */
881 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
882 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
888 g_object_unref (parent_win);
889 g_object_unref (folder);
893 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
897 GObject *win = modest_mail_operation_get_source (mail_op);
899 error = modest_mail_operation_get_error (mail_op);
900 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
902 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
904 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
907 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
908 _("mail_ni_ui_folder_get_msg_folder_error"));
912 g_object_unref (win);
916 * This function is used by both modest_ui_actions_on_open and
917 * modest_ui_actions_on_header_activated. This way we always do the
918 * same when trying to open messages.
921 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
923 ModestWindowMgr *mgr = NULL;
924 TnyIterator *iter = NULL;
925 ModestMailOperation *mail_op = NULL;
926 TnyList *not_opened_headers = NULL;
927 TnyHeaderFlags flags = 0;
929 /* Look if we already have a message view for each header. If
930 true, then remove the header from the list of headers to
932 mgr = modest_runtime_get_window_mgr ();
933 iter = tny_list_create_iterator (headers);
934 not_opened_headers = tny_simple_list_new ();
936 while (!tny_iterator_is_done (iter)) {
938 ModestWindow *window = NULL;
939 TnyHeader *header = NULL;
940 gboolean found = FALSE;
942 header = TNY_HEADER (tny_iterator_get_current (iter));
944 flags = tny_header_get_flags (header);
947 found = modest_window_mgr_find_registered_header (mgr, header, &window);
949 /* Do not open again the message and present the
950 window to the user */
953 gtk_window_present (GTK_WINDOW (window));
955 /* the header has been registered already, we don't do
956 * anything but wait for the window to come up*/
957 g_debug ("header %p already registered, waiting for window", header);
959 tny_list_append (not_opened_headers, G_OBJECT (header));
963 g_object_unref (header);
965 tny_iterator_next (iter);
967 g_object_unref (iter);
970 /* If some messages would have to be downloaded, ask the user to
971 * make a connection. It's generally easier to do this here (in the mainloop)
972 * than later in a thread:
974 if (tny_list_get_length (not_opened_headers) > 0) {
976 gboolean found = FALSE;
978 iter = tny_list_create_iterator (not_opened_headers);
979 while (!tny_iterator_is_done (iter) && !found) {
980 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
981 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
984 tny_iterator_next (iter);
986 g_object_unref (header);
988 g_object_unref (iter);
990 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
991 g_object_unref (not_opened_headers);
996 /* Register the headers before actually creating the windows: */
997 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
998 while (!tny_iterator_is_done (iter_not_opened)) {
999 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1001 modest_window_mgr_register_header (mgr, header);
1002 g_object_unref (header);
1005 tny_iterator_next (iter_not_opened);
1007 g_object_unref (iter_not_opened);
1008 iter_not_opened = NULL;
1010 /* Open each message */
1011 if (tny_list_get_length (not_opened_headers) > 0) {
1012 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1014 modest_ui_actions_get_msgs_full_error_handler,
1016 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1017 if (tny_list_get_length (not_opened_headers) > 1) {
1018 modest_mail_operation_get_msgs_full (mail_op,
1024 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1025 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1026 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1027 g_object_unref (header);
1028 g_object_unref (iter);
1030 g_object_unref (mail_op);
1034 if (not_opened_headers != NULL)
1035 g_object_unref (not_opened_headers);
1039 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1044 headers = get_selected_headers (win);
1049 _modest_ui_actions_open (headers, win);
1051 g_object_unref(headers);
1056 free_reply_forward_helper (gpointer data)
1058 ReplyForwardHelper *helper;
1060 helper = (ReplyForwardHelper *) data;
1061 g_free (helper->account_name);
1062 g_slice_free (ReplyForwardHelper, helper);
1066 reply_forward_cb (ModestMailOperation *mail_op,
1072 ReplyForwardHelper *rf_helper;
1073 ModestWindow *msg_win = NULL;
1074 ModestEditType edit_type;
1076 TnyAccount *account = NULL;
1077 ModestWindowMgr *mgr = NULL;
1078 gchar *signature = NULL;
1080 /* If there was any error. The mail operation could be NULL,
1081 this means that we already have the message downloaded and
1082 that we didn't do a mail operation to retrieve it */
1083 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1086 g_return_if_fail (user_data != NULL);
1087 rf_helper = (ReplyForwardHelper *) user_data;
1089 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1090 rf_helper->account_name);
1091 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1092 rf_helper->account_name,
1093 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1094 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1095 rf_helper->account_name,
1096 MODEST_ACCOUNT_SIGNATURE, FALSE);
1099 /* Create reply mail */
1100 switch (rf_helper->action) {
1103 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1104 rf_helper->reply_forward_type,
1105 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1107 case ACTION_REPLY_TO_ALL:
1109 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1110 MODEST_TNY_MSG_REPLY_MODE_ALL);
1111 edit_type = MODEST_EDIT_TYPE_REPLY;
1113 case ACTION_FORWARD:
1115 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1116 edit_type = MODEST_EDIT_TYPE_FORWARD;
1119 g_return_if_reached ();
1126 g_printerr ("modest: failed to create message\n");
1130 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1131 rf_helper->account_name,
1132 TNY_ACCOUNT_TYPE_STORE);
1134 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1138 /* Create and register the windows */
1139 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1140 mgr = modest_runtime_get_window_mgr ();
1141 modest_window_mgr_register_window (mgr, msg_win);
1143 if (rf_helper->parent_window != NULL) {
1144 gdouble parent_zoom;
1146 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1147 modest_window_set_zoom (msg_win, parent_zoom);
1150 /* Show edit window */
1151 gtk_widget_show_all (GTK_WIDGET (msg_win));
1155 g_object_unref (msg_win);
1157 g_object_unref (G_OBJECT (new_msg));
1159 g_object_unref (G_OBJECT (account));
1160 /* g_object_unref (msg); */
1161 free_reply_forward_helper (rf_helper);
1165 * Checks a list of headers. If any of them are not currently
1166 * downloaded (CACHED) then it asks the user for permission to
1169 * Returns FALSE if the user does not want to download the
1170 * messages. Returns TRUE if the user allowed the download or if all
1171 * of them are currently downloaded
1174 download_uncached_messages (TnyList *header_list,
1179 gint uncached_messages = 0;
1181 iter = tny_list_create_iterator (header_list);
1182 while (!tny_iterator_is_done (iter)) {
1185 header = TNY_HEADER (tny_iterator_get_current (iter));
1187 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1188 uncached_messages ++;
1189 g_object_unref (header);
1192 tny_iterator_next (iter);
1194 g_object_unref (iter);
1196 /* Ask for user permission to download the messages */
1198 if (uncached_messages > 0) {
1199 gboolean download = TRUE;
1200 if (!tny_device_is_online (modest_runtime_get_device())) {
1201 GtkResponseType response =
1202 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1203 ngettext("mcen_nc_get_msg",
1205 uncached_messages));
1206 if (response == GTK_RESPONSE_CANCEL) download = FALSE;
1209 /* If a download will be necessary, make sure that we have a connection: */
1210 retval = modest_platform_connect_and_wait(win, NULL);
1220 * Common code for the reply and forward actions
1223 reply_forward (ReplyForwardAction action, ModestWindow *win)
1225 ModestMailOperation *mail_op = NULL;
1226 TnyList *header_list = NULL;
1227 ReplyForwardHelper *rf_helper = NULL;
1228 guint reply_forward_type;
1229 gboolean continue_download = TRUE;
1230 gboolean do_retrieve = TRUE;
1232 g_return_if_fail (MODEST_IS_WINDOW(win));
1234 /* we need an account when editing */
1235 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1236 const gboolean created = modest_run_account_setup_wizard (win);
1241 header_list = get_selected_headers (win);
1245 reply_forward_type =
1246 modest_conf_get_int (modest_runtime_get_conf (),
1247 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1250 /* Check that the messages have been previously downloaded */
1251 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1253 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1254 if (!continue_download) {
1255 g_object_unref (header_list);
1259 /* We assume that we can only select messages of the
1260 same folder and that we reply all of them from the
1261 same account. In fact the interface currently only
1262 allows single selection */
1265 rf_helper = g_slice_new0 (ReplyForwardHelper);
1266 rf_helper->reply_forward_type = reply_forward_type;
1267 rf_helper->action = action;
1268 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1270 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1271 rf_helper->parent_window = GTK_WIDGET (win);
1272 if (!rf_helper->account_name)
1273 rf_helper->account_name =
1274 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1276 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1279 /* Get header and message. Do not free them here, the
1280 reply_forward_cb must do it */
1281 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1282 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1283 if (!msg || !header) {
1285 g_object_unref (msg);
1286 g_printerr ("modest: no message found\n");
1289 reply_forward_cb (NULL, header, msg, rf_helper);
1292 g_object_unref (header);
1297 /* Only reply/forward to one message */
1298 iter = tny_list_create_iterator (header_list);
1299 header = TNY_HEADER (tny_iterator_get_current (iter));
1300 g_object_unref (iter);
1303 /* Retrieve messages */
1305 mail_op = modest_mail_operation_new_with_error_handling (
1306 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1308 modest_ui_actions_get_msgs_full_error_handler,
1310 modest_mail_operation_queue_add (
1311 modest_runtime_get_mail_operation_queue (), mail_op);
1313 modest_mail_operation_get_msg (mail_op,
1318 g_object_unref(mail_op);
1320 /* we put a ref here to prevent double unref as the reply
1321 * forward callback unrefs the header at its end */
1322 reply_forward_cb (NULL, header, NULL, rf_helper);
1326 g_object_unref (header);
1332 g_object_unref (header_list);
1336 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1338 g_return_if_fail (MODEST_IS_WINDOW(win));
1340 reply_forward (ACTION_REPLY, win);
1344 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1346 g_return_if_fail (MODEST_IS_WINDOW(win));
1348 reply_forward (ACTION_FORWARD, win);
1352 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1354 g_return_if_fail (MODEST_IS_WINDOW(win));
1356 reply_forward (ACTION_REPLY_TO_ALL, win);
1360 modest_ui_actions_on_next (GtkAction *action,
1361 ModestWindow *window)
1363 if (MODEST_IS_MAIN_WINDOW (window)) {
1364 GtkWidget *header_view;
1366 header_view = modest_main_window_get_child_widget (
1367 MODEST_MAIN_WINDOW(window),
1368 MODEST_WIDGET_TYPE_HEADER_VIEW);
1372 modest_header_view_select_next (
1373 MODEST_HEADER_VIEW(header_view));
1374 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1375 modest_msg_view_window_select_next_message (
1376 MODEST_MSG_VIEW_WINDOW (window));
1378 g_return_if_reached ();
1383 modest_ui_actions_on_prev (GtkAction *action,
1384 ModestWindow *window)
1386 g_return_if_fail (MODEST_IS_WINDOW(window));
1388 if (MODEST_IS_MAIN_WINDOW (window)) {
1389 GtkWidget *header_view;
1390 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1391 MODEST_WIDGET_TYPE_HEADER_VIEW);
1395 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1396 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1397 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1399 g_return_if_reached ();
1404 modest_ui_actions_on_sort (GtkAction *action,
1405 ModestWindow *window)
1407 g_return_if_fail (MODEST_IS_WINDOW(window));
1409 if (MODEST_IS_MAIN_WINDOW (window)) {
1410 GtkWidget *header_view;
1411 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1412 MODEST_WIDGET_TYPE_HEADER_VIEW);
1414 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1419 /* Show sorting dialog */
1420 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1425 new_messages_arrived (ModestMailOperation *self,
1429 ModestMainWindow *win = NULL;
1430 GtkWidget *folder_view = NULL;
1431 TnyFolderStore *folder = NULL;
1432 gboolean folder_empty = FALSE;
1434 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1435 win = MODEST_MAIN_WINDOW (user_data);
1437 /* Set contents style of headers view */
1438 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1439 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1440 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1441 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1444 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1447 modest_main_window_set_contents_style (win,
1448 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1451 /* Notify new messages have been downloaded */
1452 if (new_messages > 0)
1453 modest_platform_on_new_msg ();
1457 * This function performs the send & receive required actions. The
1458 * window is used to create the mail operation. Typically it should
1459 * always be the main window, but we pass it as argument in order to
1463 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1465 gchar *acc_name = NULL;
1466 ModestMailOperation *mail_op;
1468 /* If no account name was provided then get the current account, and if
1469 there is no current account then pick the default one: */
1470 if (!account_name) {
1471 acc_name = g_strdup (modest_window_get_active_account(win));
1473 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1475 g_printerr ("modest: cannot get default account\n");
1479 acc_name = g_strdup (account_name);
1482 /* Set send/receive operation in progress */
1483 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1485 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1487 modest_ui_actions_send_receive_error_handler,
1490 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1491 G_CALLBACK (_on_send_receive_progress_changed),
1494 /* Send & receive. */
1495 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1496 /* Receive and then send. The operation is tagged initially as
1497 a receive operation because the account update performs a
1498 receive and then a send. The operation changes its type
1499 internally, so the progress objects will receive the proper
1500 progress information */
1501 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1502 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1503 g_object_unref (G_OBJECT (mail_op));
1511 modest_ui_actions_do_cancel_send (const gchar *account_name,
1514 TnyTransportAccount *transport_account;
1515 TnySendQueue *send_queue = NULL;
1516 GError *error = NULL;
1518 /* Get transport account */
1520 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1521 (modest_runtime_get_account_store(),
1523 TNY_ACCOUNT_TYPE_TRANSPORT));
1524 if (!transport_account) {
1525 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1530 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1531 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1532 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1533 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1534 "modest: could not find send queue for account\n");
1536 /* Keeep messages in outbox folder */
1537 tny_send_queue_cancel (send_queue, FALSE, &error);
1541 if (transport_account != NULL)
1542 g_object_unref (G_OBJECT (transport_account));
1546 modest_ui_actions_cancel_send_all (ModestWindow *win)
1548 GSList *account_names, *iter;
1550 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1553 iter = account_names;
1555 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1556 iter = g_slist_next (iter);
1559 modest_account_mgr_free_account_names (account_names);
1560 account_names = NULL;
1564 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1567 /* Check if accounts exist */
1568 gboolean accounts_exist =
1569 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1571 /* If not, allow the user to create an account before trying to send/receive. */
1572 if (!accounts_exist)
1573 modest_ui_actions_on_accounts (NULL, win);
1575 /* Cancel all sending operaitons */
1576 modest_ui_actions_cancel_send_all (win);
1580 * Refreshes all accounts. This function will be used by automatic
1584 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1586 GSList *account_names, *iter;
1588 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1591 iter = account_names;
1593 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1594 iter = g_slist_next (iter);
1597 modest_account_mgr_free_account_names (account_names);
1598 account_names = NULL;
1602 modest_do_refresh_current_folder(ModestWindow *win)
1604 /* Refresh currently selected folder. Note that if we only
1605 want to retreive the headers, then the refresh only will
1606 invoke a poke_status over all folders, i.e., only the
1607 total/unread count will be updated */
1608 if (MODEST_IS_MAIN_WINDOW (win)) {
1609 GtkWidget *header_view, *folder_view;
1610 TnyFolderStore *folder_store;
1612 /* Get folder and header view */
1614 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1615 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1617 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1619 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1621 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1622 MODEST_WIDGET_TYPE_HEADER_VIEW);
1624 /* We do not need to set the contents style
1625 because it hasn't changed. We also do not
1626 need to save the widget status. Just force
1628 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1629 TNY_FOLDER (folder_store),
1630 folder_refreshed_cb,
1631 MODEST_MAIN_WINDOW (win));
1635 g_object_unref (folder_store);
1641 * Handler of the click on Send&Receive button in the main toolbar
1644 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1646 /* Check if accounts exist */
1647 gboolean accounts_exist =
1648 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1650 /* If not, allow the user to create an account before trying to send/receive. */
1651 if (!accounts_exist)
1652 modest_ui_actions_on_accounts (NULL, win);
1654 modest_do_refresh_current_folder (win);
1656 /* Refresh the active account */
1657 modest_ui_actions_do_send_receive (NULL, win);
1662 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1665 GtkWidget *header_view;
1667 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1669 header_view = modest_main_window_get_child_widget (main_window,
1670 MODEST_WIDGET_TYPE_HEADER_VIEW);
1674 conf = modest_runtime_get_conf ();
1676 /* what is saved/restored is depending on the style; thus; we save with
1677 * old style, then update the style, and restore for this new style
1679 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1681 if (modest_header_view_get_style
1682 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1683 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1684 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1686 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1687 MODEST_HEADER_VIEW_STYLE_DETAILS);
1689 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1690 MODEST_CONF_HEADER_VIEW_KEY);
1695 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1697 ModestMainWindow *main_window)
1699 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1700 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1702 /* in the case the folder is empty, show the empty folder message and focus
1704 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1705 if (modest_header_view_is_empty (header_view)) {
1706 TnyFolder *folder = modest_header_view_get_folder (header_view);
1707 GtkWidget *folder_view =
1708 modest_main_window_get_child_widget (main_window,
1709 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1711 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1712 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1716 /* If no header has been selected then exit */
1721 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1722 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1724 /* Update toolbar dimming state */
1725 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1729 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1731 ModestMainWindow *main_window)
1735 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1740 headers = tny_simple_list_new ();
1741 tny_list_prepend (headers, G_OBJECT (header));
1743 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1745 g_object_unref (headers);
1749 set_active_account_from_tny_account (TnyAccount *account,
1750 ModestWindow *window)
1752 const gchar *server_acc_name = tny_account_get_id (account);
1754 /* We need the TnyAccount provided by the
1755 account store because that is the one that
1756 knows the name of the Modest account */
1757 TnyAccount *modest_server_account = modest_server_account =
1758 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1759 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1762 const gchar *modest_acc_name =
1763 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1764 modest_window_set_active_account (window, modest_acc_name);
1765 g_object_unref (modest_server_account);
1770 folder_refreshed_cb (ModestMailOperation *mail_op,
1774 ModestMainWindow *win = NULL;
1775 GtkWidget *header_view;
1776 TnyFolder *current_folder;
1777 gboolean folder_empty = TRUE;
1778 gboolean all_marked_as_deleted = TRUE;
1780 g_return_if_fail (TNY_IS_FOLDER (folder));
1782 win = MODEST_MAIN_WINDOW (user_data);
1784 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1787 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1788 if (current_folder != NULL && folder != current_folder) {
1793 /* Check if folder is empty and set headers view contents style */
1794 folder_empty = (tny_folder_get_all_count (folder) == 0);
1795 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1796 folder_empty = folder_empty || all_marked_as_deleted ;
1799 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1800 modest_main_window_set_contents_style (win,
1801 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1803 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1808 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1809 TnyFolderStore *folder_store,
1811 ModestMainWindow *main_window)
1814 GtkWidget *header_view;
1816 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1818 header_view = modest_main_window_get_child_widget(main_window,
1819 MODEST_WIDGET_TYPE_HEADER_VIEW);
1823 conf = modest_runtime_get_conf ();
1825 if (TNY_IS_ACCOUNT (folder_store)) {
1827 /* Update active account */
1828 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1829 /* Show account details */
1830 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1833 if (TNY_IS_FOLDER (folder_store) && selected) {
1835 /* Update the active account */
1836 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1838 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1839 g_object_unref (account);
1843 /* Set the header style by default, it could
1844 be changed later by the refresh callback to
1846 modest_main_window_set_contents_style (main_window,
1847 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1849 /* Set folder on header view. This function
1850 will call tny_folder_refresh_async so we
1851 pass a callback that will be called when
1852 finished. We use that callback to set the
1853 empty view if there are no messages */
1854 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1855 TNY_FOLDER (folder_store),
1856 folder_refreshed_cb,
1859 /* Restore configuration. We need to do this
1860 *after* the set_folder because the widget
1861 memory asks the header view about its
1863 modest_widget_memory_restore (modest_runtime_get_conf (),
1864 G_OBJECT(header_view),
1865 MODEST_CONF_HEADER_VIEW_KEY);
1867 /* Update the active account */
1868 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1869 /* Save only if we're seeing headers */
1870 if (modest_main_window_get_contents_style (main_window) ==
1871 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1872 modest_widget_memory_save (conf, G_OBJECT (header_view),
1873 MODEST_CONF_HEADER_VIEW_KEY);
1874 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1878 /* Update toolbar dimming state */
1879 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1883 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1890 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1892 online = tny_device_is_online (modest_runtime_get_device());
1895 /* already online -- the item is simply not there... */
1896 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1898 GTK_MESSAGE_WARNING,
1900 _("The %s you selected cannot be found"),
1902 gtk_dialog_run (GTK_DIALOG(dialog));
1904 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1908 GTK_RESPONSE_REJECT,
1910 GTK_RESPONSE_ACCEPT,
1912 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1913 "Do you want to get online?"), item);
1914 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1915 gtk_label_new (txt), FALSE, FALSE, 0);
1916 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1919 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1920 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1921 /* TODO: Comment about why is this commented out: */
1922 /* modest_platform_connect_and_wait (); */
1925 gtk_widget_destroy (dialog);
1929 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1932 /* g_message ("%s %s", __FUNCTION__, link); */
1937 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1940 modest_platform_activate_uri (link);
1944 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1947 modest_platform_show_uri_popup (link);
1951 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1954 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1958 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1959 const gchar *address,
1962 /* g_message ("%s %s", __FUNCTION__, address); */
1966 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1968 TnyTransportAccount *transport_account;
1969 ModestMailOperation *mail_operation;
1971 gchar *account_name, *from;
1972 ModestAccountMgr *account_mgr;
1973 gchar *info_text = NULL;
1975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1977 data = modest_msg_edit_window_get_msg_data (edit_window);
1979 account_mgr = modest_runtime_get_account_mgr();
1980 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1982 account_name = modest_account_mgr_get_default_account (account_mgr);
1983 if (!account_name) {
1984 g_printerr ("modest: no account found\n");
1985 modest_msg_edit_window_free_msg_data (edit_window, data);
1989 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1990 account_name = g_strdup (data->account_name);
1994 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1995 (modest_runtime_get_account_store(),
1997 TNY_ACCOUNT_TYPE_TRANSPORT));
1998 if (!transport_account) {
1999 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2000 g_free (account_name);
2001 modest_msg_edit_window_free_msg_data (edit_window, data);
2004 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2006 /* Create the mail operation */
2007 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2008 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2010 modest_mail_operation_save_to_drafts (mail_operation,
2022 data->priority_flags);
2025 g_free (account_name);
2026 g_object_unref (G_OBJECT (transport_account));
2027 g_object_unref (G_OBJECT (mail_operation));
2029 modest_msg_edit_window_free_msg_data (edit_window, data);
2031 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2032 modest_platform_information_banner (NULL, NULL, info_text);
2036 /* For instance, when clicking the Send toolbar button when editing a message: */
2038 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2040 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2042 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2045 /* Offer the connection dialog, if necessary: */
2046 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2049 /* FIXME: Code added just for testing. The final version will
2050 use the send queue provided by tinymail and some
2052 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2053 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2055 account_name = modest_account_mgr_get_default_account (account_mgr);
2057 if (!account_name) {
2058 /* Run account setup wizard */
2059 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2064 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2066 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2067 account_name = g_strdup (data->account_name);
2070 /* Get the currently-active transport account for this modest account: */
2071 TnyTransportAccount *transport_account =
2072 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2073 (modest_runtime_get_account_store(),
2075 if (!transport_account) {
2076 /* Run account setup wizard */
2077 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2082 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2084 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2086 /* Create the mail operation */
2087 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2088 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2090 modest_mail_operation_send_new_mail (mail_operation,
2101 data->priority_flags);
2105 g_free (account_name);
2106 g_object_unref (G_OBJECT (transport_account));
2107 g_object_unref (G_OBJECT (mail_operation));
2109 modest_msg_edit_window_free_msg_data (edit_window, data);
2110 modest_msg_edit_window_set_sent (edit_window, TRUE);
2112 /* Save settings and close the window: */
2113 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2117 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2118 ModestMsgEditWindow *window)
2120 ModestMsgEditFormatState *format_state = NULL;
2122 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2123 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2125 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2128 format_state = modest_msg_edit_window_get_format_state (window);
2129 g_return_if_fail (format_state != NULL);
2131 format_state->bold = gtk_toggle_action_get_active (action);
2132 modest_msg_edit_window_set_format_state (window, format_state);
2133 g_free (format_state);
2138 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2139 ModestMsgEditWindow *window)
2141 ModestMsgEditFormatState *format_state = NULL;
2143 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2144 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2146 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2149 format_state = modest_msg_edit_window_get_format_state (window);
2150 g_return_if_fail (format_state != NULL);
2152 format_state->italics = gtk_toggle_action_get_active (action);
2153 modest_msg_edit_window_set_format_state (window, format_state);
2154 g_free (format_state);
2159 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2160 ModestMsgEditWindow *window)
2162 ModestMsgEditFormatState *format_state = NULL;
2164 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2165 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2167 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2170 format_state = modest_msg_edit_window_get_format_state (window);
2171 g_return_if_fail (format_state != NULL);
2173 format_state->bullet = gtk_toggle_action_get_active (action);
2174 modest_msg_edit_window_set_format_state (window, format_state);
2175 g_free (format_state);
2180 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2181 GtkRadioAction *selected,
2182 ModestMsgEditWindow *window)
2184 ModestMsgEditFormatState *format_state = NULL;
2185 GtkJustification value;
2187 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2189 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2192 value = gtk_radio_action_get_current_value (selected);
2194 format_state = modest_msg_edit_window_get_format_state (window);
2195 g_return_if_fail (format_state != NULL);
2197 format_state->justification = value;
2198 modest_msg_edit_window_set_format_state (window, format_state);
2199 g_free (format_state);
2203 modest_ui_actions_on_select_editor_color (GtkAction *action,
2204 ModestMsgEditWindow *window)
2206 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2207 g_return_if_fail (GTK_IS_ACTION (action));
2209 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2212 modest_msg_edit_window_select_color (window);
2216 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2217 ModestMsgEditWindow *window)
2219 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2220 g_return_if_fail (GTK_IS_ACTION (action));
2222 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2225 modest_msg_edit_window_select_background_color (window);
2229 modest_ui_actions_on_insert_image (GtkAction *action,
2230 ModestMsgEditWindow *window)
2232 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2233 g_return_if_fail (GTK_IS_ACTION (action));
2235 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2238 modest_msg_edit_window_insert_image (window);
2242 modest_ui_actions_on_attach_file (GtkAction *action,
2243 ModestMsgEditWindow *window)
2245 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2246 g_return_if_fail (GTK_IS_ACTION (action));
2248 modest_msg_edit_window_offer_attach_file (window);
2252 modest_ui_actions_on_remove_attachments (GtkAction *action,
2253 ModestMsgEditWindow *window)
2255 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2256 g_return_if_fail (GTK_IS_ACTION (action));
2258 modest_msg_edit_window_remove_attachments (window, NULL);
2262 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2265 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2266 const GError *error = modest_mail_operation_get_error (mail_op);
2270 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2271 modest_mail_operation_get_error (mail_op)->message);
2276 modest_ui_actions_create_folder(GtkWidget *parent_window,
2277 GtkWidget *folder_view)
2279 TnyFolderStore *parent_folder;
2281 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2283 if (parent_folder) {
2284 gboolean finished = FALSE;
2286 gchar *folder_name = NULL, *suggested_name = NULL;
2287 const gchar *proto_str = NULL;
2288 TnyAccount *account;
2290 if (TNY_IS_ACCOUNT (parent_folder))
2291 account = g_object_ref (parent_folder);
2293 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2294 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2296 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2297 MODEST_PROTOCOL_STORE_POP) {
2299 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2301 g_object_unref (account);
2303 /* Run the new folder dialog */
2305 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2310 g_free (suggested_name);
2311 suggested_name = NULL;
2313 if (result == GTK_RESPONSE_REJECT) {
2316 ModestMailOperation *mail_op;
2317 TnyFolder *new_folder = NULL;
2319 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2320 G_OBJECT(parent_window),
2321 modest_ui_actions_new_folder_error_handler,
2324 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2326 new_folder = modest_mail_operation_create_folder (mail_op,
2328 (const gchar *) folder_name);
2330 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2333 g_object_unref (new_folder);
2336 g_object_unref (mail_op);
2339 suggested_name = folder_name;
2343 g_object_unref (parent_folder);
2348 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2350 GtkWidget *folder_view;
2352 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2354 folder_view = modest_main_window_get_child_widget (main_window,
2355 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2359 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2363 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2366 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2367 const GError *error = NULL;
2368 const gchar *message = NULL;
2370 /* Get error message */
2371 error = modest_mail_operation_get_error (mail_op);
2372 if (error != NULL && error->message != NULL) {
2373 message = error->message;
2375 message = _("!!! FIXME: Unable to rename");
2378 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2383 modest_ui_actions_on_rename_folder (GtkAction *action,
2384 ModestMainWindow *main_window)
2386 TnyFolderStore *folder;
2387 GtkWidget *folder_view;
2388 GtkWidget *header_view;
2390 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2392 folder_view = modest_main_window_get_child_widget (main_window,
2393 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2397 header_view = modest_main_window_get_child_widget (main_window,
2398 MODEST_WIDGET_TYPE_HEADER_VIEW);
2403 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2407 /* Offer the connection dialog if necessary: */
2408 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2409 g_object_unref (G_OBJECT (folder));
2414 if (TNY_IS_FOLDER (folder)) {
2417 const gchar *current_name;
2419 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2420 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2421 current_name, &folder_name);
2423 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2424 ModestMailOperation *mail_op;
2427 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2428 G_OBJECT(main_window),
2429 modest_ui_actions_rename_folder_error_handler,
2433 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2436 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2438 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2439 TNY_FOLDER(folder), TRUE);
2441 modest_header_view_clear ((ModestHeaderView *) header_view);
2443 modest_mail_operation_rename_folder (mail_op,
2444 TNY_FOLDER (folder),
2445 (const gchar *) folder_name);
2447 g_object_unref (mail_op);
2448 g_free (folder_name);
2451 g_object_unref (folder);
2455 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2458 GObject *win = modest_mail_operation_get_source (mail_op);
2460 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2461 _("mail_in_ui_folder_delete_error"));
2462 g_object_unref (win);
2466 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2468 TnyFolderStore *folder;
2469 GtkWidget *folder_view;
2473 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2475 folder_view = modest_main_window_get_child_widget (main_window,
2476 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2480 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2482 /* Show an error if it's an account */
2483 if (!TNY_IS_FOLDER (folder)) {
2484 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2485 _("mail_in_ui_folder_delete_error"));
2486 g_object_unref (G_OBJECT (folder));
2490 /* Offer the connection dialog if necessary: */
2491 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2492 g_object_unref (G_OBJECT (folder));
2497 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2498 tny_folder_get_name (TNY_FOLDER (folder)));
2499 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2500 (const gchar *) message);
2503 if (response == GTK_RESPONSE_OK) {
2504 ModestMailOperation *mail_op =
2505 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2506 G_OBJECT(main_window),
2507 modest_ui_actions_delete_folder_error_handler,
2510 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2512 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2513 g_object_unref (G_OBJECT (mail_op));
2516 g_object_unref (G_OBJECT (folder));
2520 modest_ui_actions_on_delete_folder (GtkAction *action,
2521 ModestMainWindow *main_window)
2523 GtkWidget *folder_view;
2524 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2526 delete_folder (main_window, FALSE);
2527 folder_view = modest_main_window_get_child_widget (main_window,
2528 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2531 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2535 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2537 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2539 delete_folder (main_window, TRUE);
2544 show_error (GtkWidget *parent_widget, const gchar* text)
2546 hildon_banner_show_information(parent_widget, NULL, text);
2549 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2551 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2558 gtk_dialog_run (dialog);
2559 gtk_widget_destroy (GTK_WIDGET (dialog));
2564 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2565 const gchar* server_account_name,
2570 ModestMainWindow *main_window)
2572 g_return_if_fail(server_account_name);
2573 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2575 /* Initalize output parameters: */
2582 #ifdef MODEST_PLATFORM_MAEMO
2583 /* Maemo uses a different (awkward) button order,
2584 * It should probably just use gtk_alternative_dialog_button_order ().
2586 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2590 GTK_RESPONSE_ACCEPT,
2592 GTK_RESPONSE_REJECT,
2595 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2599 GTK_RESPONSE_REJECT,
2601 GTK_RESPONSE_ACCEPT,
2603 #endif /* MODEST_PLATFORM_MAEMO */
2605 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2607 gchar *server_name = modest_server_account_get_hostname (
2608 modest_runtime_get_account_mgr(), server_account_name);
2609 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2610 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2615 /* This causes a warning because the logical ID has no %s in it,
2616 * though the translation does, but there is not much we can do about that: */
2617 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2618 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2621 g_free (server_name);
2625 gchar *initial_username = modest_server_account_get_username (
2626 modest_runtime_get_account_mgr(), server_account_name);
2628 GtkWidget *entry_username = gtk_entry_new ();
2629 if (initial_username)
2630 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2631 /* Dim this if a connection has ever succeeded with this username,
2632 * as per the UI spec: */
2633 const gboolean username_known =
2634 modest_server_account_get_username_has_succeeded(
2635 modest_runtime_get_account_mgr(), server_account_name);
2636 gtk_widget_set_sensitive (entry_username, !username_known);
2638 #ifdef MODEST_PLATFORM_MAEMO
2639 /* Auto-capitalization is the default, so let's turn it off: */
2640 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2642 /* Create a size group to be used by all captions.
2643 * Note that HildonCaption does not create a default size group if we do not specify one.
2644 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2645 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2647 GtkWidget *caption = hildon_caption_new (sizegroup,
2648 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2649 gtk_widget_show (entry_username);
2650 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2651 FALSE, FALSE, MODEST_MARGIN_HALF);
2652 gtk_widget_show (caption);
2654 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2656 #endif /* MODEST_PLATFORM_MAEMO */
2659 GtkWidget *entry_password = gtk_entry_new ();
2660 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2661 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2663 #ifdef MODEST_PLATFORM_MAEMO
2664 /* Auto-capitalization is the default, so let's turn it off: */
2665 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2666 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2668 caption = hildon_caption_new (sizegroup,
2669 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2670 gtk_widget_show (entry_password);
2671 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2672 FALSE, FALSE, MODEST_MARGIN_HALF);
2673 gtk_widget_show (caption);
2674 g_object_unref (sizegroup);
2676 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2678 #endif /* MODEST_PLATFORM_MAEMO */
2680 /* This is not in the Maemo UI spec:
2681 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2682 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2686 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2688 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2690 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2692 modest_server_account_set_username (
2693 modest_runtime_get_account_mgr(), server_account_name,
2696 const gboolean username_was_changed =
2697 (strcmp (*username, initial_username) != 0);
2698 if (username_was_changed) {
2699 g_warning ("%s: tinymail does not yet support changing the "
2700 "username in the get_password() callback.\n", __FUNCTION__);
2705 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2707 /* We do not save the password in the configuration,
2708 * because this function is only called for passwords that should
2709 * not be remembered:
2710 modest_server_account_set_password (
2711 modest_runtime_get_account_mgr(), server_account_name,
2720 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2732 /* This is not in the Maemo UI spec:
2733 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2739 gtk_widget_destroy (dialog);
2741 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2745 modest_ui_actions_on_cut (GtkAction *action,
2746 ModestWindow *window)
2748 GtkWidget *focused_widget;
2749 GtkClipboard *clipboard;
2751 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2752 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2753 if (GTK_IS_EDITABLE (focused_widget)) {
2754 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2755 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2756 gtk_clipboard_store (clipboard);
2757 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2758 GtkTextBuffer *buffer;
2760 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2761 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2762 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2763 gtk_clipboard_store (clipboard);
2764 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2765 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2766 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2767 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2772 modest_ui_actions_on_copy (GtkAction *action,
2773 ModestWindow *window)
2775 GtkClipboard *clipboard;
2776 GtkWidget *focused_widget;
2778 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2779 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2781 if (GTK_IS_LABEL (focused_widget)) {
2782 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2783 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2784 gtk_clipboard_store (clipboard);
2785 } else if (GTK_IS_EDITABLE (focused_widget)) {
2786 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2787 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2788 gtk_clipboard_store (clipboard);
2789 } else if (GTK_IS_HTML (focused_widget)) {
2790 gtk_html_copy (GTK_HTML (focused_widget));
2791 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2792 gtk_clipboard_store (clipboard);
2793 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2794 GtkTextBuffer *buffer;
2795 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2796 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2797 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2798 gtk_clipboard_store (clipboard);
2799 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2800 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2801 TnyIterator *iter = tny_list_create_iterator (header_list);
2802 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2804 gboolean ask = FALSE;
2806 TnyFolder *folder = tny_header_get_folder (header);
2807 TnyAccount *account = tny_folder_get_account (folder);
2808 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2809 /* If it's POP then ask */
2810 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2811 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2812 g_object_unref (account);
2813 g_object_unref (folder);
2814 g_object_unref (header);
2817 g_object_unref (iter);
2819 /* Check that the messages have been previously downloaded */
2820 gboolean continue_download = TRUE;
2822 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2823 if (continue_download)
2824 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2825 g_object_unref (header_list);
2826 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2827 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2830 /* Show information banner */
2831 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2836 modest_ui_actions_on_undo (GtkAction *action,
2837 ModestWindow *window)
2839 ModestEmailClipboard *clipboard = NULL;
2841 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2842 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2843 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2844 /* Clear clipboard source */
2845 clipboard = modest_runtime_get_email_clipboard ();
2846 modest_email_clipboard_clear (clipboard);
2849 g_return_if_reached ();
2854 modest_ui_actions_on_redo (GtkAction *action,
2855 ModestWindow *window)
2857 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2858 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2861 g_return_if_reached ();
2867 paste_msgs_cb (const GObject *object, gpointer user_data)
2869 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2870 g_return_if_fail (GTK_IS_WIDGET (user_data));
2872 /* destroy information note */
2873 gtk_widget_destroy (GTK_WIDGET(user_data));
2877 paste_as_attachment_free (gpointer data)
2879 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2881 gtk_widget_destroy (helper->banner);
2882 g_object_unref (helper->banner);
2887 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2892 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2898 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2903 modest_ui_actions_on_paste (GtkAction *action,
2904 ModestWindow *window)
2906 GtkWidget *focused_widget = NULL;
2907 GtkWidget *inf_note = NULL;
2908 ModestMailOperation *mail_op = NULL;
2910 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2911 if (GTK_IS_EDITABLE (focused_widget)) {
2912 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2913 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2914 ModestEmailClipboard *e_clipboard = NULL;
2915 e_clipboard = modest_runtime_get_email_clipboard ();
2916 if (modest_email_clipboard_cleared (e_clipboard)) {
2917 GtkTextBuffer *buffer;
2918 GtkClipboard *clipboard;
2920 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2921 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2922 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2923 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2924 ModestMailOperation *mail_op;
2925 TnyFolder *src_folder;
2928 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2929 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2930 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2931 _CS("ckct_nw_pasting"));
2932 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2933 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2935 if (helper->banner != NULL) {
2936 g_object_ref (G_OBJECT (helper->banner));
2937 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2938 gtk_widget_show (GTK_WIDGET (helper->banner));
2942 modest_mail_operation_get_msgs_full (mail_op,
2944 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2946 paste_as_attachment_free);
2949 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2950 ModestEmailClipboard *clipboard = NULL;
2951 TnyFolder *src_folder = NULL;
2952 TnyFolderStore *folder_store = NULL;
2953 TnyList *data = NULL;
2954 gboolean delete = FALSE;
2956 /* Check clipboard source */
2957 clipboard = modest_runtime_get_email_clipboard ();
2958 if (modest_email_clipboard_cleared (clipboard))
2961 /* Get elements to paste */
2962 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2964 /* Create a new mail operation */
2965 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2967 /* Get destination folder */
2968 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2970 /* transfer messages */
2974 /* Ask for user confirmation */
2975 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2976 TNY_FOLDER (folder_store),
2980 if (response == GTK_RESPONSE_OK) {
2981 /* Launch notification */
2982 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2983 _CS("ckct_nw_pasting"));
2984 if (inf_note != NULL) {
2985 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2986 gtk_widget_show (GTK_WIDGET(inf_note));
2989 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2990 modest_mail_operation_xfer_msgs (mail_op,
2992 TNY_FOLDER (folder_store),
2997 g_object_unref (mail_op);
3000 } else if (src_folder != NULL) {
3001 /* Launch notification */
3002 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3003 _CS("ckct_nw_pasting"));
3004 if (inf_note != NULL) {
3005 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3006 gtk_widget_show (GTK_WIDGET(inf_note));
3009 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3010 modest_mail_operation_xfer_folder (mail_op,
3020 g_object_unref (data);
3021 if (src_folder != NULL)
3022 g_object_unref (src_folder);
3023 if (folder_store != NULL)
3024 g_object_unref (folder_store);
3030 modest_ui_actions_on_select_all (GtkAction *action,
3031 ModestWindow *window)
3033 GtkWidget *focused_widget;
3035 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3036 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3037 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3038 } else if (GTK_IS_LABEL (focused_widget)) {
3039 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3040 } else if (GTK_IS_EDITABLE (focused_widget)) {
3041 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3042 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3043 GtkTextBuffer *buffer;
3044 GtkTextIter start, end;
3046 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3047 gtk_text_buffer_get_start_iter (buffer, &start);
3048 gtk_text_buffer_get_end_iter (buffer, &end);
3049 gtk_text_buffer_select_range (buffer, &start, &end);
3050 } else if (GTK_IS_HTML (focused_widget)) {
3051 gtk_html_select_all (GTK_HTML (focused_widget));
3052 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3053 GtkWidget *header_view = focused_widget;
3054 GtkTreeSelection *selection = NULL;
3056 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3057 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3058 MODEST_WIDGET_TYPE_HEADER_VIEW);
3060 /* Select all messages */
3061 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3062 gtk_tree_selection_select_all (selection);
3064 /* Set focuse on header view */
3065 gtk_widget_grab_focus (header_view);
3071 modest_ui_actions_on_mark_as_read (GtkAction *action,
3072 ModestWindow *window)
3074 g_return_if_fail (MODEST_IS_WINDOW(window));
3076 /* Mark each header as read */
3077 do_headers_action (window, headers_action_mark_as_read, NULL);
3081 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3082 ModestWindow *window)
3084 g_return_if_fail (MODEST_IS_WINDOW(window));
3086 /* Mark each header as read */
3087 do_headers_action (window, headers_action_mark_as_unread, NULL);
3091 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3092 GtkRadioAction *selected,
3093 ModestWindow *window)
3097 value = gtk_radio_action_get_current_value (selected);
3098 if (MODEST_IS_WINDOW (window)) {
3099 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3103 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3104 GtkRadioAction *selected,
3105 ModestWindow *window)
3107 TnyHeaderFlags flags;
3108 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3110 flags = gtk_radio_action_get_current_value (selected);
3111 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3114 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3115 GtkRadioAction *selected,
3116 ModestWindow *window)
3120 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3122 file_format = gtk_radio_action_get_current_value (selected);
3123 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3128 modest_ui_actions_on_zoom_plus (GtkAction *action,
3129 ModestWindow *window)
3131 g_return_if_fail (MODEST_IS_WINDOW (window));
3133 modest_window_zoom_plus (MODEST_WINDOW (window));
3137 modest_ui_actions_on_zoom_minus (GtkAction *action,
3138 ModestWindow *window)
3140 g_return_if_fail (MODEST_IS_WINDOW (window));
3142 modest_window_zoom_minus (MODEST_WINDOW (window));
3146 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3147 ModestWindow *window)
3149 ModestWindowMgr *mgr;
3150 gboolean fullscreen, active;
3151 g_return_if_fail (MODEST_IS_WINDOW (window));
3153 mgr = modest_runtime_get_window_mgr ();
3155 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3156 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3158 if (active != fullscreen) {
3159 modest_window_mgr_set_fullscreen_mode (mgr, active);
3160 gtk_window_present (GTK_WINDOW (window));
3165 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3166 ModestWindow *window)
3168 ModestWindowMgr *mgr;
3169 gboolean fullscreen;
3171 g_return_if_fail (MODEST_IS_WINDOW (window));
3173 mgr = modest_runtime_get_window_mgr ();
3174 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3175 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3177 gtk_window_present (GTK_WINDOW (window));
3181 * Used by modest_ui_actions_on_details to call do_headers_action
3184 headers_action_show_details (TnyHeader *header,
3185 ModestWindow *window,
3192 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3195 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3196 gtk_widget_show_all (dialog);
3197 gtk_dialog_run (GTK_DIALOG (dialog));
3199 gtk_widget_destroy (dialog);
3203 * Show the folder details in a ModestDetailsDialog widget
3206 show_folder_details (TnyFolder *folder,
3212 dialog = modest_details_dialog_new_with_folder (window, folder);
3215 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3216 gtk_widget_show_all (dialog);
3217 gtk_dialog_run (GTK_DIALOG (dialog));
3219 gtk_widget_destroy (dialog);
3223 * Show the header details in a ModestDetailsDialog widget
3226 modest_ui_actions_on_details (GtkAction *action,
3229 TnyList * headers_list;
3233 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3236 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3239 g_object_unref (msg);
3241 headers_list = get_selected_headers (win);
3245 iter = tny_list_create_iterator (headers_list);
3247 header = TNY_HEADER (tny_iterator_get_current (iter));
3249 headers_action_show_details (header, win, NULL);
3250 g_object_unref (header);
3253 g_object_unref (iter);
3254 g_object_unref (headers_list);
3256 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3257 GtkWidget *folder_view, *header_view;
3259 /* Check which widget has the focus */
3260 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3261 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3262 if (gtk_widget_is_focus (folder_view)) {
3263 TnyFolderStore *folder_store
3264 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3265 if (!folder_store) {
3266 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3269 /* Show only when it's a folder */
3270 /* This function should not be called for account items,
3271 * because we dim the menu item for them. */
3272 if (TNY_IS_FOLDER (folder_store)) {
3273 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3276 g_object_unref (folder_store);
3279 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3280 MODEST_WIDGET_TYPE_HEADER_VIEW);
3281 /* Show details of each header */
3282 do_headers_action (win, headers_action_show_details, header_view);
3288 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3289 ModestMsgEditWindow *window)
3291 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3293 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3297 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3298 ModestMsgEditWindow *window)
3300 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3302 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3306 modest_ui_actions_toggle_folders_view (GtkAction *action,
3307 ModestMainWindow *main_window)
3309 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3311 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3312 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3314 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3318 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3319 ModestWindow *window)
3321 gboolean active, fullscreen = FALSE;
3322 ModestWindowMgr *mgr;
3324 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3326 /* Check if we want to toggle the toolbar vuew in fullscreen
3328 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3329 "ViewShowToolbarFullScreen")) {
3333 /* Toggle toolbar */
3334 mgr = modest_runtime_get_window_mgr ();
3335 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3339 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3340 ModestMsgEditWindow *window)
3342 modest_msg_edit_window_select_font (window);
3346 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3347 const gchar *display_name,
3350 /* Do not change the application name if the widget has not
3351 the focus. This callback could be called even if the folder
3352 view has not the focus, because the handled signal could be
3353 emitted when the folder view is redrawn */
3354 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3356 gtk_window_set_title (window, display_name);
3358 gtk_window_set_title (window, " ");
3363 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3365 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3366 modest_msg_edit_window_select_contacts (window);
3370 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3372 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3373 modest_msg_edit_window_check_names (window, FALSE);
3377 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3379 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3380 GTK_WIDGET (user_data));
3384 create_move_to_dialog (GtkWindow *win,
3385 GtkWidget *folder_view,
3386 GtkWidget **tree_view)
3388 GtkWidget *dialog, *scroll;
3389 GtkWidget *new_button;
3391 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3393 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3396 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3397 /* We do this manually so GTK+ does not associate a response ID for
3399 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3400 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3401 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3403 /* Create scrolled window */
3404 scroll = gtk_scrolled_window_new (NULL, NULL);
3405 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3406 GTK_POLICY_AUTOMATIC,
3407 GTK_POLICY_AUTOMATIC);
3409 /* Create folder view */
3410 *tree_view = modest_platform_create_folder_view (NULL);
3412 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3414 /* It could happen that we're trying to move a message from a
3415 window (msg window for example) after the main window was
3416 closed, so we can not just get the model of the folder
3418 if (MODEST_IS_FOLDER_VIEW (folder_view))
3419 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3420 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3422 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3423 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3425 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3427 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3429 /* Add scroll to dialog */
3430 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3431 scroll, TRUE, TRUE, 0);
3433 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3434 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3440 * Returns TRUE if at least one of the headers of the list belongs to
3441 * a message that has been fully retrieved.
3444 has_retrieved_msgs (TnyList *list)
3447 gboolean found = FALSE;
3449 iter = tny_list_create_iterator (list);
3450 while (!tny_iterator_is_done (iter) && !found) {
3452 TnyHeaderFlags flags = 0;
3454 header = TNY_HEADER (tny_iterator_get_current (iter));
3456 flags = tny_header_get_flags (header);
3457 if (flags & TNY_HEADER_FLAG_CACHED)
3458 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3461 g_object_unref (header);
3465 tny_iterator_next (iter);
3467 g_object_unref (iter);
3473 * Shows a confirmation dialog to the user when we're moving messages
3474 * from a remote server to the local storage. Returns the dialog
3475 * response. If it's other kind of movement the it always returns
3479 msgs_move_to_confirmation (GtkWindow *win,
3480 TnyFolder *dest_folder,
3484 gint response = GTK_RESPONSE_OK;
3486 /* If the destination is a local folder (or MMC folder )*/
3487 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3488 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3489 TnyFolder *src_folder = NULL;
3490 TnyIterator *iter = NULL;
3491 TnyHeader *header = NULL;
3493 /* Get source folder */
3494 iter = tny_list_create_iterator (headers);
3495 header = TNY_HEADER (tny_iterator_get_current (iter));
3497 src_folder = tny_header_get_folder (header);
3498 g_object_unref (header);
3501 g_object_unref (iter);
3503 /* if no src_folder, message may be an attahcment */
3504 if (src_folder == NULL)
3505 return GTK_RESPONSE_CANCEL;
3507 /* If the source is a remote folder */
3508 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3509 if (modest_tny_folder_is_remote_folder (src_folder)) {
3510 const gchar *message = NULL;
3511 gboolean cached = has_retrieved_msgs (headers);
3513 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3514 tny_list_get_length (headers));
3516 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3517 tny_list_get_length (headers));
3519 if (cached && !delete)
3520 response = GTK_RESPONSE_OK;
3522 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3523 (const gchar *) message);
3526 g_object_unref (src_folder);
3535 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3537 ModestMsgViewWindow *self = NULL;
3539 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3540 self = MODEST_MSG_VIEW_WINDOW (object);
3542 if (!modest_msg_view_window_select_next_message (self))
3543 if (!modest_msg_view_window_select_previous_message (self))
3544 /* No more messages to view, so close this window */
3545 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3549 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3552 GObject *win = modest_mail_operation_get_source (mail_op);
3553 const GError *error = NULL;
3554 const gchar *message = NULL;
3556 /* Get error message */
3557 error = modest_mail_operation_get_error (mail_op);
3558 if (error != NULL && error->message != NULL) {
3559 message = error->message;
3561 message = _("mail_in_ui_folder_move_target_error");
3564 /* Show notification dialog */
3565 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3566 g_object_unref (win);
3570 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3573 GObject *win = modest_mail_operation_get_source (mail_op);
3574 const GError *error = modest_mail_operation_get_error (mail_op);
3576 g_return_if_fail (error != NULL);
3577 if (error->message != NULL)
3578 g_printerr ("modest: %s\n", error->message);
3580 g_printerr ("modest: unkonw error on send&receive operation");
3582 /* Show error message */
3583 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3584 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3585 /* _CS("sfil_ib_unable_to_receive")); */
3587 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3588 /* _CS("sfil_ib_unable_to_send")); */
3589 g_object_unref (win);
3593 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3600 gint pending_purges = 0;
3601 gboolean some_purged = FALSE;
3602 ModestWindow *win = MODEST_WINDOW (user_data);
3603 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3605 /* If there was any error */
3606 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3607 modest_window_mgr_unregister_header (mgr, header);
3611 /* Once the message has been retrieved for purging, we check if
3612 * it's all ok for purging */
3614 parts = tny_simple_list_new ();
3615 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3616 iter = tny_list_create_iterator (parts);
3618 while (!tny_iterator_is_done (iter)) {
3620 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3621 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3622 if (tny_mime_part_is_purged (part))
3629 g_object_unref (part);
3631 tny_iterator_next (iter);
3634 if (pending_purges>0) {
3636 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3638 if (response == GTK_RESPONSE_OK) {
3639 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3640 tny_iterator_first (iter);
3641 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 tny_mime_part_set_purged (part);
3649 g_object_unref (part);
3651 tny_iterator_next (iter);
3654 tny_msg_rewrite_cache (msg);
3657 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3660 /* remove attachments */
3661 tny_iterator_first (iter);
3662 while (!tny_iterator_is_done (iter)) {
3665 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3667 /* One for the reference given by tny_iterator_get_current(): */
3668 g_object_unref (part);
3670 /* TODO: Is this meant to remove the attachment by doing another unref()?
3671 * Otherwise, this seems useless. */
3674 tny_iterator_next (iter);
3676 modest_window_mgr_unregister_header (mgr, header);
3678 g_object_unref (iter);
3679 g_object_unref (parts);
3683 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3684 ModestMainWindow *win)
3686 GtkWidget *header_view;
3687 TnyList *header_list;
3690 TnyHeaderFlags flags;
3691 ModestWindow *msg_view_window = NULL;
3694 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3696 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3697 MODEST_WIDGET_TYPE_HEADER_VIEW);
3699 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3701 if (tny_list_get_length (header_list) == 1) {
3702 iter = tny_list_create_iterator (header_list);
3703 header = TNY_HEADER (tny_iterator_get_current (iter));
3704 g_object_unref (iter);
3709 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3710 header, &msg_view_window);
3711 flags = tny_header_get_flags (header);
3712 if (!(flags & TNY_HEADER_FLAG_CACHED))
3715 if (msg_view_window != NULL)
3716 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3718 /* do nothing; uid was registered before, so window is probably on it's way */
3719 g_warning ("debug: header %p has already been registered", header);
3722 ModestMailOperation *mail_op = NULL;
3723 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3724 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3726 modest_ui_actions_get_msgs_full_error_handler,
3728 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3729 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3731 g_object_unref (mail_op);
3734 g_object_unref (header);
3736 g_object_unref (header_list);
3740 * Utility function that transfer messages from both the main window
3741 * and the msg view window when using the "Move to" dialog
3744 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3747 TnyList *headers = NULL;
3749 TnyAccount *dst_account = NULL;
3750 const gchar *proto_str = NULL;
3751 gboolean dst_is_pop = FALSE;
3753 if (!TNY_IS_FOLDER (dst_folder)) {
3754 modest_platform_information_banner (GTK_WIDGET (win),
3756 _CS("ckdg_ib_unable_to_move_to_current_location"));
3760 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3761 proto_str = tny_account_get_proto (dst_account);
3763 /* tinymail will return NULL for local folders it seems */
3764 dst_is_pop = proto_str &&
3765 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3766 MODEST_PROTOCOL_STORE_POP);
3768 g_object_unref (dst_account);
3770 /* Get selected headers */
3771 headers = get_selected_headers (MODEST_WINDOW (win));
3774 modest_platform_information_banner (GTK_WIDGET (win),
3776 ngettext("mail_in_ui_folder_move_target_error",
3777 "mail_in_ui_folder_move_targets_error",
3778 tny_list_get_length (headers)));
3779 g_object_unref (headers);
3783 /* Ask for user confirmation */
3784 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3785 TNY_FOLDER (dst_folder),
3789 /* Transfer messages */
3790 if (response == GTK_RESPONSE_OK) {
3791 ModestMailOperation *mail_op =
3792 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3794 modest_ui_actions_move_folder_error_handler,
3796 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3799 modest_mail_operation_xfer_msgs (mail_op,
3801 TNY_FOLDER (dst_folder),
3803 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3806 g_object_unref (G_OBJECT (mail_op));
3808 g_object_unref (headers);
3813 * UI handler for the "Move to" action when invoked from the
3817 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3818 GtkWidget *folder_view,
3819 TnyFolderStore *dst_folder,
3820 ModestMainWindow *win)
3822 GtkWidget *header_view = NULL;
3823 ModestMailOperation *mail_op = NULL;
3824 TnyFolderStore *src_folder;
3826 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3828 /* Get the source folder */
3829 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3831 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3832 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3836 /* Get header view */
3838 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3840 /* Get folder or messages to transfer */
3841 if (gtk_widget_is_focus (folder_view)) {
3843 /* Allow only to transfer folders to the local root folder */
3844 if (TNY_IS_ACCOUNT (dst_folder) &&
3845 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3848 /* Clean folder on header view before moving it */
3849 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3851 if (TNY_IS_FOLDER (src_folder)) {
3853 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3855 modest_ui_actions_move_folder_error_handler,
3857 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3860 modest_mail_operation_xfer_folder (mail_op,
3861 TNY_FOLDER (src_folder),
3864 /* Unref mail operation */
3865 g_object_unref (G_OBJECT (mail_op));
3867 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3869 } else if (gtk_widget_is_focus (header_view)) {
3870 /* Transfer messages */
3871 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3876 g_object_unref (src_folder);
3881 * UI handler for the "Move to" action when invoked from the
3882 * ModestMsgViewWindow
3885 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3886 TnyFolderStore *dst_folder,
3887 ModestMsgViewWindow *win)
3889 TnyHeader *header = NULL;
3890 TnyFolder *src_folder;
3892 /* Create header list */
3893 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3894 src_folder = tny_header_get_folder(header);
3895 g_object_unref (header);
3897 /* Transfer the message */
3898 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3899 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3901 g_object_unref (src_folder);
3905 modest_ui_actions_on_move_to (GtkAction *action,
3908 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3910 TnyFolderStore *dst_folder = NULL;
3911 ModestMainWindow *main_window;
3913 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3914 MODEST_IS_MSG_VIEW_WINDOW (win));
3916 /* Get the main window if exists */
3917 if (MODEST_IS_MAIN_WINDOW (win))
3918 main_window = MODEST_MAIN_WINDOW (win);
3921 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3923 /* Get the folder view widget if exists */
3925 folder_view = modest_main_window_get_child_widget (main_window,
3926 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3930 /* Create and run the dialog */
3931 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3932 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3933 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3934 result = gtk_dialog_run (GTK_DIALOG(dialog));
3935 g_object_ref (tree_view);
3936 gtk_widget_destroy (dialog);
3938 if (result != GTK_RESPONSE_ACCEPT)
3941 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3942 /* Offer the connection dialog if necessary: */
3943 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3946 /* Do window specific stuff */
3947 if (MODEST_IS_MAIN_WINDOW (win))
3948 modest_ui_actions_on_main_window_move_to (action,
3951 MODEST_MAIN_WINDOW (win));
3953 modest_ui_actions_on_msg_view_window_move_to (action,
3955 MODEST_MSG_VIEW_WINDOW (win));
3958 g_object_unref (dst_folder);
3962 * Calls #HeadersFunc for each header already selected in the main
3963 * window or the message currently being shown in the msg view window
3966 do_headers_action (ModestWindow *win,
3970 TnyList *headers_list = NULL;
3971 TnyIterator *iter = NULL;
3972 TnyHeader *header = NULL;
3973 TnyFolder *folder = NULL;
3976 headers_list = get_selected_headers (win);
3980 /* Get the folder */
3981 iter = tny_list_create_iterator (headers_list);
3982 header = TNY_HEADER (tny_iterator_get_current (iter));
3984 folder = tny_header_get_folder (header);
3985 g_object_unref (header);
3988 /* Call the function for each header */
3989 while (!tny_iterator_is_done (iter)) {
3990 header = TNY_HEADER (tny_iterator_get_current (iter));
3991 func (header, win, user_data);
3992 g_object_unref (header);
3993 tny_iterator_next (iter);
3996 /* Trick: do a poke status in order to speed up the signaling
3998 tny_folder_poke_status (folder);
4001 g_object_unref (folder);
4002 g_object_unref (iter);
4003 g_object_unref (headers_list);
4007 modest_ui_actions_view_attachment (GtkAction *action,
4008 ModestWindow *window)
4010 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4011 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4013 /* not supported window for this action */
4014 g_return_if_reached ();
4019 modest_ui_actions_save_attachments (GtkAction *action,
4020 ModestWindow *window)
4022 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4023 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4025 /* not supported window for this action */
4026 g_return_if_reached ();
4031 modest_ui_actions_remove_attachments (GtkAction *action,
4032 ModestWindow *window)
4034 if (MODEST_IS_MAIN_WINDOW (window)) {
4035 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4036 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4037 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4039 /* not supported window for this action */
4040 g_return_if_reached ();
4045 modest_ui_actions_on_settings (GtkAction *action,
4050 dialog = modest_platform_get_global_settings_dialog ();
4051 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4052 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4053 gtk_widget_show_all (dialog);
4055 gtk_dialog_run (GTK_DIALOG (dialog));
4057 gtk_widget_destroy (dialog);
4061 modest_ui_actions_on_help (GtkAction *action,
4064 const gchar *help_id = NULL;
4066 if (MODEST_IS_MAIN_WINDOW (win)) {
4067 const gchar *action_name;
4068 action_name = gtk_action_get_name (action);
4070 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4071 !strcmp (action_name, "HeaderViewCSMHelp")) {
4072 GtkWidget *folder_view;
4073 TnyFolderStore *folder_store;
4074 /* Get selected folder */
4075 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4076 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4077 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4079 /* Switch help_id */
4080 if (TNY_IS_FOLDER (folder_store)) {
4081 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4082 case TNY_FOLDER_TYPE_NORMAL:
4083 help_id = "applications_email_managefolders";
4085 case TNY_FOLDER_TYPE_INBOX:
4086 help_id = "applications_email_inbox";
4088 case TNY_FOLDER_TYPE_OUTBOX:
4089 help_id = "applications_email_outbox";
4091 case TNY_FOLDER_TYPE_SENT:
4092 help_id = "applications_email_sent";
4094 case TNY_FOLDER_TYPE_DRAFTS:
4095 help_id = "applications_email_drafts";
4097 case TNY_FOLDER_TYPE_ARCHIVE:
4098 help_id = "applications_email_managefolders";
4101 help_id = "applications_email_managefolders";
4104 help_id = "applications_email_mainview";
4106 g_object_unref (folder_store);
4108 help_id = "applications_email_mainview";
4110 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4111 help_id = "applications_email_viewer";
4112 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4113 help_id = "applications_email_editor";
4115 modest_platform_show_help (GTK_WINDOW (win), help_id);
4119 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4120 ModestWindow *window)
4122 ModestMailOperation *mail_op;
4126 headers = get_selected_headers (window);
4130 /* Create mail operation */
4131 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4133 modest_ui_actions_get_msgs_full_error_handler,
4135 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4136 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4139 g_object_unref (headers);
4140 g_object_unref (mail_op);
4144 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4145 ModestWindow *window)
4147 g_return_if_fail (MODEST_IS_WINDOW (window));
4150 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4154 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4155 ModestWindow *window)
4157 g_return_if_fail (MODEST_IS_WINDOW (window));
4160 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4164 modest_ui_actions_on_view_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_tools_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_attachment_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_toolbar_csm_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_folder_view_csm_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_header_view_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_check_toolbar_dimming_rules (ModestWindow *window)
4226 g_return_if_fail (MODEST_IS_WINDOW (window));
4229 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4233 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4235 g_return_if_fail (MODEST_IS_WINDOW (window));
4237 modest_platform_show_search_messages (GTK_WINDOW (window));
4241 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4243 g_return_if_fail (MODEST_IS_WINDOW (win));
4244 modest_platform_show_addressbook (GTK_WINDOW (win));
4249 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4250 ModestWindow *window)
4252 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4254 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4258 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4259 ModestMailOperationState *state,
4262 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4264 /* Set send/receive operation finished */
4265 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4266 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));