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-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #ifdef MODEST_PLATFORM_MAEMO
63 #include "maemo/modest-osso-state-saving.h"
64 #endif /* MODEST_PLATFORM_MAEMO */
65 #ifndef MODEST_TOOLKIT_GTK
66 #include "maemo/modest-hildon-includes.h"
67 #include "maemo/modest-connection-specific-smtp-window.h"
68 #endif /* !MODEST_TOOLKIT_GTK */
69 #include <modest-utils.h>
71 #include "widgets/modest-ui-constants.h"
72 #include <widgets/modest-main-window.h>
73 #include <widgets/modest-msg-view-window.h>
74 #include <widgets/modest-account-view-window.h>
75 #include <widgets/modest-details-dialog.h>
76 #include <widgets/modest-attachments-view.h>
77 #include "widgets/modest-folder-view.h"
78 #include "widgets/modest-global-settings-dialog.h"
79 #include "modest-account-mgr-helpers.h"
80 #include "modest-mail-operation.h"
81 #include "modest-text-utils.h"
82 #include <modest-widget-memory.h>
83 #include <tny-error.h>
84 #include <tny-simple-list.h>
85 #include <tny-msg-view.h>
86 #include <tny-device.h>
87 #include <tny-merge-folder.h>
89 #include <gtkhtml/gtkhtml.h>
91 #define MIN_FREE_SPACE 5 * 1024 * 1024
92 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
94 typedef struct _GetMsgAsyncHelper {
96 ModestMailOperation *mail_op;
103 typedef enum _ReplyForwardAction {
107 } ReplyForwardAction;
109 typedef struct _ReplyForwardHelper {
110 guint reply_forward_type;
111 ReplyForwardAction action;
114 GtkWidget *parent_window;
116 } ReplyForwardHelper;
118 typedef struct _MoveToHelper {
119 GtkTreeRowReference *reference;
123 typedef struct _PasteAsAttachmentHelper {
124 ModestMsgEditWindow *window;
126 } PasteAsAttachmentHelper;
134 * The do_headers_action uses this kind of functions to perform some
135 * action to each member of a list of headers
137 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
139 static void do_headers_action (ModestWindow *win,
143 static void open_msg_cb (ModestMailOperation *mail_op,
150 static void reply_forward_cb (ModestMailOperation *mail_op,
157 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
159 static void folder_refreshed_cb (ModestMailOperation *mail_op,
163 static void on_send_receive_finished (ModestMailOperation *mail_op,
166 static gint header_list_count_uncached_msgs (TnyList *header_list);
168 static gboolean connect_to_get_msg (ModestWindow *win,
169 gint num_of_uncached_msgs,
170 TnyAccount *account);
172 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
174 static void do_create_folder (GtkWindow *window,
175 TnyFolderStore *parent_folder,
176 const gchar *suggested_name);
178 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
180 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
181 GtkWidget *folder_view,
182 TnyFolderStore *dst_folder,
183 ModestMainWindow *win);
184 #ifdef MODEST_TOOLKIT_HILDON2
185 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
186 TnyFolderStore *dst_folder,
191 static void modest_ui_actions_on_window_move_to (GtkAction *action,
192 TnyList *list_to_move,
193 TnyFolderStore *dst_folder,
197 * This function checks whether a TnyFolderStore is a pop account
200 remote_folder_has_leave_on_server (TnyFolderStore *folder)
205 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
207 account = get_account_from_folder_store (folder);
208 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
209 modest_tny_account_get_protocol_type (account)));
210 g_object_unref (account);
215 /* FIXME: this should be merged with the similar code in modest-account-view-window */
216 /* Show the account creation wizard dialog.
217 * returns: TRUE if an account was created. FALSE if the user cancelled.
220 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
222 gboolean result = FALSE;
224 gint dialog_response;
226 /* there is no such wizard yet */
227 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
228 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
230 #ifndef MODEST_TOOLKIT_HILDON2
231 /* always present a main window in the background
232 * we do it here, so we cannot end up with two wizards (as this
233 * function might be called in modest_window_mgr_get_main_window as well */
235 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
236 TRUE); /* create if not existent */
240 ModestWindowMgr *mgr;
242 mgr = modest_runtime_get_window_mgr ();
244 window_list = modest_window_mgr_get_window_list (mgr);
245 if (window_list == NULL) {
246 win = MODEST_WINDOW (modest_accounts_window_new ());
247 if (modest_window_mgr_register_window (mgr, win, NULL)) {
248 gtk_widget_show_all (GTK_WIDGET (win));
250 gtk_widget_destroy (GTK_WIDGET (win));
255 g_list_free (window_list);
261 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
263 /* make sure the mainwindow is visible. We need to present the
264 wizard again to give it the focus back. show_all are needed
265 in order to get the widgets properly drawn (MainWindow main
266 paned won't be in its right position and the dialog will be
268 #ifndef MODEST_TOOLKIT_HILDON2
269 gtk_widget_show_all (GTK_WIDGET (win));
270 gtk_widget_show_all (GTK_WIDGET (wizard));
271 gtk_window_present (GTK_WINDOW (win));
272 gtk_window_present (GTK_WINDOW (wizard));
275 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
276 gtk_widget_destroy (GTK_WIDGET (wizard));
277 if (gtk_events_pending ())
278 gtk_main_iteration ();
280 if (dialog_response == GTK_RESPONSE_CANCEL) {
283 /* Check whether an account was created: */
284 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
291 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
294 const gchar *authors[] = {
295 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
298 about = gtk_about_dialog_new ();
299 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
300 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
301 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
302 _("Copyright (c) 2006, Nokia Corporation\n"
303 "All rights reserved."));
304 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
305 _("a modest e-mail client\n\n"
306 "design and implementation: Dirk-Jan C. Binnema\n"
307 "contributions from the fine people at KC and Ig\n"
308 "uses the tinymail email framework written by Philip van Hoof"));
309 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
310 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
311 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
312 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
314 gtk_dialog_run (GTK_DIALOG (about));
315 gtk_widget_destroy(about);
319 * Gets the list of currently selected messages. If the win is the
320 * main window, then it returns a newly allocated list of the headers
321 * selected in the header view. If win is the msg view window, then
322 * the value returned is a list with just a single header.
324 * The caller of this funcion must free the list.
327 get_selected_headers (ModestWindow *win)
329 if (MODEST_IS_MAIN_WINDOW(win)) {
330 GtkWidget *header_view;
332 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
333 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
334 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
336 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
337 /* for MsgViewWindows, we simply return a list with one element */
339 TnyList *list = NULL;
341 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
342 if (header != NULL) {
343 list = tny_simple_list_new ();
344 tny_list_prepend (list, G_OBJECT(header));
345 g_object_unref (G_OBJECT(header));
350 #ifdef MODEST_TOOLKIT_HILDON2
351 } else if (MODEST_IS_HEADER_WINDOW (win)) {
352 GtkWidget *header_view;
354 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
355 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
361 static GtkTreeRowReference *
362 get_next_after_selected_headers (ModestHeaderView *header_view)
364 GtkTreeSelection *sel;
365 GList *selected_rows, *node;
367 GtkTreeRowReference *result;
370 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
371 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
372 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
374 if (selected_rows == NULL)
377 node = g_list_last (selected_rows);
378 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
379 gtk_tree_path_next (path);
381 result = gtk_tree_row_reference_new (model, path);
383 gtk_tree_path_free (path);
384 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
385 g_list_free (selected_rows);
391 headers_action_mark_as_read (TnyHeader *header,
395 TnyHeaderFlags flags;
397 g_return_if_fail (TNY_IS_HEADER(header));
399 flags = tny_header_get_flags (header);
400 if (flags & TNY_HEADER_FLAG_SEEN) return;
401 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
405 headers_action_mark_as_unread (TnyHeader *header,
409 TnyHeaderFlags flags;
411 g_return_if_fail (TNY_IS_HEADER(header));
413 flags = tny_header_get_flags (header);
414 if (flags & TNY_HEADER_FLAG_SEEN) {
415 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
419 /** After deleing a message that is currently visible in a window,
420 * show the next message from the list, or close the window if there are no more messages.
423 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
425 /* Close msg view window or select next */
426 if (!modest_msg_view_window_select_next_message (win) &&
427 !modest_msg_view_window_select_previous_message (win)) {
429 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
435 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
437 modest_ui_actions_on_edit_mode_delete_message (win);
441 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
443 TnyList *header_list = NULL;
444 TnyIterator *iter = NULL;
445 TnyHeader *header = NULL;
446 gchar *message = NULL;
449 ModestWindowMgr *mgr;
450 GtkWidget *header_view = NULL;
451 gboolean retval = TRUE;
453 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
455 /* Check first if the header view has the focus */
456 if (MODEST_IS_MAIN_WINDOW (win)) {
458 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
459 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
460 if (!gtk_widget_is_focus (header_view))
464 /* Get the headers, either from the header view (if win is the main window),
465 * or from the message view window: */
466 header_list = get_selected_headers (win);
467 if (!header_list) return FALSE;
469 /* Check if any of the headers are already opened, or in the process of being opened */
470 if (MODEST_IS_MAIN_WINDOW (win)) {
471 gint opened_headers = 0;
473 iter = tny_list_create_iterator (header_list);
474 mgr = modest_runtime_get_window_mgr ();
475 while (!tny_iterator_is_done (iter)) {
476 header = TNY_HEADER (tny_iterator_get_current (iter));
478 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
480 g_object_unref (header);
482 tny_iterator_next (iter);
484 g_object_unref (iter);
486 if (opened_headers > 0) {
489 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
492 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
495 g_object_unref (header_list);
501 if (tny_list_get_length(header_list) == 1) {
502 iter = tny_list_create_iterator (header_list);
503 header = TNY_HEADER (tny_iterator_get_current (iter));
506 subject = tny_header_dup_subject (header);
508 subject = g_strdup (_("mail_va_no_subject"));
509 desc = g_strdup_printf ("%s", subject);
511 g_object_unref (header);
514 g_object_unref (iter);
516 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
517 tny_list_get_length(header_list)), desc);
519 /* Confirmation dialog */
520 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
524 if (response == GTK_RESPONSE_OK) {
525 ModestWindow *main_window = NULL;
526 ModestWindowMgr *mgr = NULL;
527 GtkTreeModel *model = NULL;
528 GtkTreeSelection *sel = NULL;
529 GList *sel_list = NULL, *tmp = NULL;
530 GtkTreeRowReference *next_row_reference = NULL;
531 GtkTreeRowReference *prev_row_reference = NULL;
532 GtkTreePath *next_path = NULL;
533 GtkTreePath *prev_path = NULL;
534 ModestMailOperation *mail_op = NULL;
536 /* Find last selected row */
537 if (MODEST_IS_MAIN_WINDOW (win)) {
538 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
539 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
540 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
541 for (tmp=sel_list; tmp; tmp=tmp->next) {
542 if (tmp->next == NULL) {
543 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
544 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
546 gtk_tree_path_prev (prev_path);
547 gtk_tree_path_next (next_path);
549 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
550 next_row_reference = gtk_tree_row_reference_new (model, next_path);
555 /* Disable window dimming management */
556 modest_window_disable_dimming (MODEST_WINDOW(win));
558 /* Remove each header. If it's a view window header_view == NULL */
559 mail_op = modest_mail_operation_new ((GObject *) win);
560 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
562 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
563 g_object_unref (mail_op);
565 /* Enable window dimming management */
567 gtk_tree_selection_unselect_all (sel);
569 modest_window_enable_dimming (MODEST_WINDOW(win));
571 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
572 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
574 /* Get main window */
575 mgr = modest_runtime_get_window_mgr ();
576 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
577 } else if (MODEST_IS_MAIN_WINDOW (win)) {
578 /* Move cursor to next row */
581 /* Select next or previous row */
582 if (gtk_tree_row_reference_valid (next_row_reference)) {
583 gtk_tree_selection_select_path (sel, next_path);
585 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
586 gtk_tree_selection_select_path (sel, prev_path);
590 if (gtk_tree_row_reference_valid (next_row_reference))
591 gtk_tree_row_reference_free (next_row_reference);
592 if (next_path != NULL)
593 gtk_tree_path_free (next_path);
594 if (gtk_tree_row_reference_valid (prev_row_reference))
595 gtk_tree_row_reference_free (prev_row_reference);
596 if (prev_path != NULL)
597 gtk_tree_path_free (prev_path);
600 /* Update toolbar dimming state */
602 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
603 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
607 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
608 g_list_free (sel_list);
617 g_object_unref (header_list);
625 /* delete either message or folder, based on where we are */
627 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
629 g_return_if_fail (MODEST_IS_WINDOW(win));
631 /* Check first if the header view has the focus */
632 if (MODEST_IS_MAIN_WINDOW (win)) {
634 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
635 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
636 if (gtk_widget_is_focus (w)) {
637 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
641 modest_ui_actions_on_delete_message (action, win);
645 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
647 ModestWindowMgr *mgr = NULL;
649 #ifdef MODEST_PLATFORM_MAEMO
650 modest_osso_save_state();
651 #endif /* MODEST_PLATFORM_MAEMO */
653 g_debug ("closing down, clearing %d item(s) from operation queue",
654 modest_mail_operation_queue_num_elements
655 (modest_runtime_get_mail_operation_queue()));
657 /* cancel all outstanding operations */
658 modest_mail_operation_queue_cancel_all
659 (modest_runtime_get_mail_operation_queue());
661 g_debug ("queue has been cleared");
664 /* Check if there are opened editing windows */
665 mgr = modest_runtime_get_window_mgr ();
666 modest_window_mgr_close_all_windows (mgr);
668 /* note: when modest-tny-account-store is finalized,
669 it will automatically set all network connections
672 /* gtk_main_quit (); */
676 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
680 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
682 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
683 /* gtk_widget_destroy (GTK_WIDGET (win)); */
684 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
685 /* gboolean ret_value; */
686 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
687 /* } else if (MODEST_IS_WINDOW (win)) { */
688 /* gtk_widget_destroy (GTK_WIDGET (win)); */
690 /* g_return_if_reached (); */
695 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
697 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
699 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
703 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
705 GtkClipboard *clipboard = NULL;
706 gchar *selection = NULL;
708 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
709 selection = gtk_clipboard_wait_for_text (clipboard);
711 /* Question: why is the clipboard being used here?
712 * It doesn't really make a lot of sense. */
716 modest_address_book_add_address (selection);
722 modest_ui_actions_on_new_account (GtkAction *action,
723 ModestWindow *window)
725 if (!modest_ui_actions_run_account_setup_wizard (window)) {
726 g_debug ("%s: wizard was already running", __FUNCTION__);
731 modest_ui_actions_on_accounts (GtkAction *action,
734 /* This is currently only implemented for Maemo */
735 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
736 if (!modest_ui_actions_run_account_setup_wizard (win))
737 g_debug ("%s: wizard was already running", __FUNCTION__);
741 /* Show the list of accounts */
742 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
744 /* The accounts dialog must be modal */
745 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
746 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
751 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
753 /* This is currently only implemented for Maemo,
754 * because it requires an API (libconic) to detect different connection
757 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
759 /* Create the window if necessary: */
760 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
761 modest_connection_specific_smtp_window_fill_with_connections (
762 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
763 modest_runtime_get_account_mgr());
765 /* Show the window: */
766 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
767 GTK_WINDOW (specific_window), (GtkWindow *) win);
768 gtk_widget_show (specific_window);
769 #endif /* !MODEST_TOOLKIT_GTK */
773 modest_ui_actions_compose_msg(ModestWindow *win,
776 const gchar *bcc_str,
777 const gchar *subject_str,
778 const gchar *body_str,
780 gboolean set_as_modified)
782 gchar *account_name = NULL;
783 const gchar *mailbox;
785 TnyAccount *account = NULL;
786 TnyFolder *folder = NULL;
787 gchar *from_str = NULL, *signature = NULL, *body = NULL;
788 gchar *recipient = NULL;
789 gboolean use_signature = FALSE;
790 ModestWindow *msg_win = NULL;
791 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
792 ModestTnyAccountStore *store = modest_runtime_get_account_store();
793 GnomeVFSFileSize total_size, allowed_size;
795 /* we check for low-mem */
796 if (modest_platform_check_memory_low (win, TRUE))
799 #ifdef MODEST_TOOLKIT_HILDON2
801 account_name = g_strdup (modest_window_get_active_account(win));
804 account_name = modest_account_mgr_get_default_account(mgr);
807 g_printerr ("modest: no account found\n");
812 mailbox = modest_window_get_active_mailbox (win);
815 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
817 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
820 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
822 g_printerr ("modest: failed to find Drafts folder\n");
825 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
827 g_printerr ("modest: failed get from string for '%s'\n", account_name);
831 recipient = modest_text_utils_get_email_address (from_str);
832 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
834 if (body_str != NULL) {
835 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
837 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
840 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
842 g_printerr ("modest: failed to create new msg\n");
846 /* Create and register edit window */
847 /* This is destroyed by TODO. */
849 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
850 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
852 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
853 gtk_widget_destroy (GTK_WIDGET (msg_win));
856 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
857 gtk_widget_show_all (GTK_WIDGET (msg_win));
859 while (attachments) {
861 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
862 attachments->data, allowed_size);
864 if (total_size > allowed_size) {
865 g_warning ("%s: total size: %u",
866 __FUNCTION__, (unsigned int)total_size);
869 allowed_size -= total_size;
871 attachments = g_slist_next(attachments);
878 g_free (account_name);
880 g_object_unref (G_OBJECT(account));
882 g_object_unref (G_OBJECT(folder));
884 g_object_unref (G_OBJECT(msg));
888 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
890 /* if there are no accounts yet, just show the wizard */
891 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
892 if (!modest_ui_actions_run_account_setup_wizard (win))
895 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
900 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
904 ModestMailOperationStatus status;
906 /* If there is no message or the operation was not successful */
907 status = modest_mail_operation_get_status (mail_op);
908 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
911 /* If it's a memory low issue, then show a banner */
912 error = modest_mail_operation_get_error (mail_op);
913 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
914 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
915 GObject *source = modest_mail_operation_get_source (mail_op);
916 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
917 _KR("memr_ib_operation_disabled"),
919 g_object_unref (source);
922 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
923 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
924 gchar *subject, *msg, *format = NULL;
926 subject = tny_header_dup_subject (header);
928 subject = g_strdup (_("mail_va_no_subject"));
930 account = modest_mail_operation_get_account (mail_op);
932 ModestProtocol *protocol;
933 ModestProtocolType proto;
934 proto = modest_tny_account_get_protocol_type (account);
935 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
937 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
938 g_object_unref (account);
942 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
944 msg = g_strdup_printf (format, subject);
945 modest_platform_run_information_dialog (NULL, msg, FALSE);
951 /* Remove the header from the preregistered uids */
952 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
970 OpenMsgBannerInfo *banner_info;
971 GtkTreeRowReference *rowref;
975 open_msg_banner_idle (gpointer userdata)
977 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
979 gdk_threads_enter ();
980 banner_info->idle_handler = 0;
981 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
982 if (banner_info->banner)
983 g_object_ref (banner_info->banner);
985 gdk_threads_leave ();
991 get_header_view_from_window (ModestWindow *window)
993 GtkWidget *header_view;
995 if (MODEST_IS_MAIN_WINDOW (window)) {
996 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
997 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
998 #ifdef MODEST_TOOLKIT_HILDON2
999 } else if (MODEST_IS_HEADER_WINDOW (window)){
1000 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1010 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1013 gchar *account = NULL;
1014 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1019 folder = tny_header_get_folder (header);
1020 /* Gets folder type (OUTBOX headers will be opened in edit window */
1021 if (modest_tny_folder_is_local_folder (folder)) {
1022 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1023 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1024 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1027 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1028 TnyTransportAccount *traccount = NULL;
1029 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1030 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1032 ModestTnySendQueue *send_queue = NULL;
1033 ModestTnySendQueueStatus status;
1035 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1036 TNY_ACCOUNT(traccount)));
1037 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1038 if (TNY_IS_SEND_QUEUE (send_queue)) {
1039 msg_id = modest_tny_send_queue_get_msg_id (header);
1040 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1042 /* Only open messages in outbox with the editor if they are in Failed state */
1043 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1046 #ifdef MODEST_TOOLKIT_HILDON2
1048 /* In Fremantle we can not
1049 open any message from
1050 outbox which is not in
1056 g_object_unref(traccount);
1058 g_warning("Cannot get transport account for message in outbox!!");
1060 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1061 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1065 TnyAccount *acc = tny_folder_get_account (folder);
1068 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1069 g_object_unref (acc);
1073 g_object_unref (folder);
1079 open_msg_cb (ModestMailOperation *mail_op,
1086 ModestWindowMgr *mgr = NULL;
1087 ModestWindow *parent_win = NULL;
1088 ModestWindow *win = NULL;
1089 gchar *account = NULL;
1090 gboolean open_in_editor = FALSE;
1092 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1094 /* Do nothing if there was any problem with the mail
1095 operation. The error will be shown by the error_handler of
1096 the mail operation */
1097 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1100 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1102 /* Mark header as read */
1103 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1105 account = get_info_from_header (header, &open_in_editor, &can_open);
1109 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1111 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1113 if (open_in_editor) {
1114 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1115 gchar *from_header = NULL, *acc_name;
1116 gchar *mailbox = NULL;
1118 from_header = tny_header_dup_from (header);
1120 /* we cannot edit without a valid account... */
1121 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1122 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1123 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1125 g_free (from_header);
1130 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1131 g_free (from_header);
1137 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1141 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1142 const gchar *mailbox = NULL;
1144 if (parent_win && MODEST_IS_WINDOW (parent_win))
1145 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1147 if (helper->rowref && helper->model) {
1148 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1149 helper->model, helper->rowref);
1151 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1156 /* Register and show new window */
1158 mgr = modest_runtime_get_window_mgr ();
1159 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1160 gtk_widget_destroy (GTK_WIDGET (win));
1163 gtk_widget_show_all (GTK_WIDGET(win));
1166 /* Update toolbar dimming state */
1167 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1168 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1174 g_object_unref (parent_win);
1178 is_memory_full_error (GError *error, ModestMailOperation *mail_op)
1180 gboolean enough_free_space = TRUE;
1181 GnomeVFSURI *cache_dir_uri;
1182 const gchar *cache_dir = NULL;
1183 GnomeVFSFileSize free_space;
1184 TnyAccountStore *acc_store;
1186 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store ());
1188 /* Cache dir is different in case we're using an external storage (like MMC account) */
1190 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1192 if (modest_tny_account_is_memory_card_account (account)) {
1193 cache_dir = g_getenv (MODEST_MMC1_VOLUMEPATH_ENV);
1195 g_object_unref (account);
1199 /* Get the default local cache dir */
1201 cache_dir = tny_account_store_get_cache_dir (acc_store);
1203 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1204 if (cache_dir_uri) {
1205 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1206 if (free_space < MIN_FREE_SPACE)
1207 enough_free_space = FALSE;
1209 gnome_vfs_uri_unref (cache_dir_uri);
1212 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1213 /* When asking for a mail and no space left on device
1214 tinymail returns this error */
1215 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1216 /* When the folder summary could not be read or
1218 error->code == TNY_IO_ERROR_WRITE ||
1219 error->code == TNY_IO_ERROR_READ) &&
1220 !enough_free_space) {
1228 check_memory_full_error (GtkWidget *parent_window, GError *err)
1233 if (is_memory_full_error (err, NULL)) {
1234 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1235 modest_platform_information_banner (parent_window, NULL, msg);
1237 } else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1238 /* If the account was created in memory full
1239 conditions then tinymail won't be able to
1240 connect so it'll return this error code */
1241 modest_platform_information_banner (parent_window,
1242 NULL, _("emev_ui_imap_inbox_select_error"));
1250 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1253 const GError *error;
1254 GObject *win = NULL;
1255 ModestMailOperationStatus status;
1257 win = modest_mail_operation_get_source (mail_op);
1258 error = modest_mail_operation_get_error (mail_op);
1259 status = modest_mail_operation_get_status (mail_op);
1261 /* If the mail op has been cancelled then it's not an error:
1262 don't show any message */
1263 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1264 if (is_memory_full_error ((GError *) error, mail_op)) {
1265 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1266 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1268 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1269 modest_platform_information_banner ((GtkWidget *) win,
1270 NULL, _("emev_ui_imap_inbox_select_error"));
1271 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1272 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1273 modest_platform_information_banner ((GtkWidget *) win,
1274 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1275 } else if (user_data) {
1276 modest_platform_information_banner ((GtkWidget *) win,
1282 g_object_unref (win);
1286 * Returns the account a list of headers belongs to. It returns a
1287 * *new* reference so don't forget to unref it
1290 get_account_from_header_list (TnyList *headers)
1292 TnyAccount *account = NULL;
1294 if (tny_list_get_length (headers) > 0) {
1295 TnyIterator *iter = tny_list_create_iterator (headers);
1296 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1297 TnyFolder *folder = tny_header_get_folder (header);
1300 g_object_unref (header);
1302 while (!tny_iterator_is_done (iter)) {
1303 header = TNY_HEADER (tny_iterator_get_current (iter));
1304 folder = tny_header_get_folder (header);
1307 g_object_unref (header);
1309 tny_iterator_next (iter);
1314 account = tny_folder_get_account (folder);
1315 g_object_unref (folder);
1319 g_object_unref (header);
1321 g_object_unref (iter);
1327 get_account_from_header (TnyHeader *header)
1329 TnyAccount *account = NULL;
1332 folder = tny_header_get_folder (header);
1335 account = tny_folder_get_account (folder);
1336 g_object_unref (folder);
1342 open_msg_helper_destroyer (gpointer user_data)
1344 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1346 if (helper->banner_info) {
1347 g_free (helper->banner_info->message);
1348 if (helper->banner_info->idle_handler > 0) {
1349 g_source_remove (helper->banner_info->idle_handler);
1350 helper->banner_info->idle_handler = 0;
1352 if (helper->banner_info->banner != NULL) {
1353 gtk_widget_destroy (helper->banner_info->banner);
1354 g_object_unref (helper->banner_info->banner);
1355 helper->banner_info->banner = NULL;
1357 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1358 helper->banner_info = NULL;
1360 g_object_unref (helper->model);
1361 g_object_unref (helper->header);
1362 gtk_tree_row_reference_free (helper->rowref);
1363 g_slice_free (OpenMsgHelper, helper);
1367 open_msg_performer(gboolean canceled,
1369 GtkWindow *parent_window,
1370 TnyAccount *account,
1373 ModestMailOperation *mail_op = NULL;
1374 gchar *error_msg = NULL;
1375 ModestProtocolType proto;
1376 TnyConnectionStatus status;
1377 OpenMsgHelper *helper = NULL;
1378 ModestProtocol *protocol;
1379 ModestProtocolRegistry *protocol_registry;
1382 helper = (OpenMsgHelper *) user_data;
1384 status = tny_account_get_connection_status (account);
1385 if (err || canceled) {
1386 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1387 /* Free the helper */
1388 open_msg_helper_destroyer (helper);
1390 /* In memory full conditions we could get this error here */
1391 check_memory_full_error ((GtkWidget *) parent_window, err);
1396 /* Get the error message depending on the protocol */
1397 proto = modest_tny_account_get_protocol_type (account);
1398 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1399 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1402 protocol_registry = modest_runtime_get_protocol_registry ();
1403 subject = tny_header_dup_subject (helper->header);
1405 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1406 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1410 if (error_msg == NULL) {
1411 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1414 #ifndef MODEST_TOOLKIT_HILDON2
1415 gboolean show_open_draft = FALSE;
1416 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1418 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1420 TnyFolderType folder_type;
1422 folder = tny_header_get_folder (helper->header);
1423 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1424 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1425 g_object_unref (folder);
1429 #ifdef MODEST_TOOLKIT_HILDON2
1432 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1435 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1436 g_free (account_name);
1437 open_msg_helper_destroyer (helper);
1442 ModestWindow *window;
1443 GtkWidget *header_view;
1446 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1447 uid = modest_tny_folder_get_header_unique_id (helper->header);
1449 const gchar *mailbox = NULL;
1450 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1451 window = modest_msg_view_window_new_from_header_view
1452 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1453 if (window != NULL) {
1454 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1456 gtk_widget_destroy (GTK_WIDGET (window));
1458 gtk_widget_show_all (GTK_WIDGET(window));
1462 g_free (account_name);
1464 open_msg_helper_destroyer (helper);
1467 g_free (account_name);
1469 /* Create the mail operation */
1471 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1472 modest_ui_actions_disk_operations_error_handler,
1473 g_strdup (error_msg), g_free);
1474 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1478 #ifndef MODEST_TOOLKIT_HILDON2
1479 if (show_open_draft) {
1480 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1481 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1482 helper->banner_info->banner = NULL;
1483 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1484 helper->banner_info);
1490 headers = TNY_LIST (tny_simple_list_new ());
1491 tny_list_prepend (headers, G_OBJECT (helper->header));
1492 modest_mail_operation_get_msgs_full (mail_op,
1496 open_msg_helper_destroyer);
1497 g_object_unref (headers);
1504 g_object_unref (mail_op);
1505 g_object_unref (account);
1509 * This function is used by both modest_ui_actions_on_open and
1510 * modest_ui_actions_on_header_activated. This way we always do the
1511 * same when trying to open messages.
1514 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1516 ModestWindowMgr *mgr = NULL;
1517 TnyAccount *account;
1518 gboolean cached = FALSE;
1520 GtkWidget *header_view = NULL;
1521 OpenMsgHelper *helper;
1522 ModestWindow *window;
1524 g_return_if_fail (header != NULL && rowref != NULL);
1526 mgr = modest_runtime_get_window_mgr ();
1529 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1530 if (header_view == NULL)
1533 /* Get the account */
1534 account = get_account_from_header (header);
1539 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1541 /* Do not open again the message and present the
1542 window to the user */
1545 #ifndef MODEST_TOOLKIT_HILDON2
1546 gtk_window_present (GTK_WINDOW (window));
1549 /* the header has been registered already, we don't do
1550 * anything but wait for the window to come up*/
1551 g_debug ("header %p already registered, waiting for window", header);
1556 /* Open each message */
1557 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1559 /* Allways download if we are online. */
1560 if (!tny_device_is_online (modest_runtime_get_device ())) {
1563 /* If ask for user permission to download the messages */
1564 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1565 _("mcen_nc_get_msg"));
1567 /* End if the user does not want to continue */
1568 if (response == GTK_RESPONSE_CANCEL) {
1574 /* We register the window for opening */
1575 modest_window_mgr_register_header (mgr, header, NULL);
1577 /* Create the helper. We need to get a reference to the model
1578 here because it could change while the message is readed
1579 (the user could switch between folders) */
1580 helper = g_slice_new (OpenMsgHelper);
1581 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1582 helper->header = g_object_ref (header);
1583 helper->rowref = gtk_tree_row_reference_copy (rowref);
1584 helper->banner_info = NULL;
1586 /* Connect to the account and perform */
1588 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1589 open_msg_performer, helper);
1591 /* Call directly the performer, do not need to connect */
1592 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1593 g_object_ref (account), helper);
1598 g_object_unref (account);
1602 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1609 /* we check for low-mem; in that case, show a warning, and don't allow
1612 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1616 headers = get_selected_headers (win);
1620 headers_count = tny_list_get_length (headers);
1621 if (headers_count != 1) {
1622 if (headers_count > 1) {
1623 /* Don't allow activation if there are more than one message selected */
1624 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1627 g_object_unref (headers);
1631 iter = tny_list_create_iterator (headers);
1632 header = TNY_HEADER (tny_iterator_get_current (iter));
1633 g_object_unref (iter);
1637 open_msg_from_header (header, NULL, win);
1638 g_object_unref (header);
1641 g_object_unref(headers);
1645 rf_helper_window_closed (gpointer data,
1648 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1650 helper->parent_window = NULL;
1653 static ReplyForwardHelper*
1654 create_reply_forward_helper (ReplyForwardAction action,
1656 guint reply_forward_type,
1659 ReplyForwardHelper *rf_helper = NULL;
1660 const gchar *active_acc = modest_window_get_active_account (win);
1661 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1663 rf_helper = g_slice_new0 (ReplyForwardHelper);
1664 rf_helper->reply_forward_type = reply_forward_type;
1665 rf_helper->action = action;
1666 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1667 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1668 rf_helper->account_name = (active_acc) ?
1669 g_strdup (active_acc) :
1670 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1671 rf_helper->mailbox = g_strdup (active_mailbox);
1673 /* Note that window could be destroyed just AFTER calling
1674 register_window so we must ensure that this pointer does
1675 not hold invalid references */
1676 if (rf_helper->parent_window)
1677 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1678 rf_helper_window_closed, rf_helper);
1684 free_reply_forward_helper (gpointer data)
1686 ReplyForwardHelper *helper;
1688 helper = (ReplyForwardHelper *) data;
1689 g_free (helper->account_name);
1690 g_free (helper->mailbox);
1692 g_object_unref (helper->header);
1693 if (helper->parent_window)
1694 g_object_weak_unref (G_OBJECT (helper->parent_window),
1695 rf_helper_window_closed, helper);
1696 g_slice_free (ReplyForwardHelper, helper);
1700 reply_forward_cb (ModestMailOperation *mail_op,
1707 TnyMsg *new_msg = NULL;
1708 ReplyForwardHelper *rf_helper;
1709 ModestWindow *msg_win = NULL;
1710 ModestEditType edit_type;
1712 TnyAccount *account = NULL;
1713 ModestWindowMgr *mgr = NULL;
1714 gchar *signature = NULL;
1715 gboolean use_signature;
1718 /* If there was any error. The mail operation could be NULL,
1719 this means that we already have the message downloaded and
1720 that we didn't do a mail operation to retrieve it */
1721 rf_helper = (ReplyForwardHelper *) user_data;
1722 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1725 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1726 rf_helper->account_name, rf_helper->mailbox);
1727 recipient = modest_text_utils_get_email_address (from);
1728 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1733 /* Create reply mail */
1734 switch (rf_helper->action) {
1737 modest_tny_msg_create_reply_msg (msg, header, from,
1738 (use_signature) ? signature : NULL,
1739 rf_helper->reply_forward_type,
1740 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1742 case ACTION_REPLY_TO_ALL:
1744 modest_tny_msg_create_reply_msg (msg, header, from,
1745 (use_signature) ? signature : NULL,
1746 rf_helper->reply_forward_type,
1747 MODEST_TNY_MSG_REPLY_MODE_ALL);
1748 edit_type = MODEST_EDIT_TYPE_REPLY;
1750 case ACTION_FORWARD:
1752 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1753 rf_helper->reply_forward_type);
1754 edit_type = MODEST_EDIT_TYPE_FORWARD;
1757 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1759 g_return_if_reached ();
1767 g_warning ("%s: failed to create message\n", __FUNCTION__);
1771 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1772 rf_helper->account_name,
1773 TNY_ACCOUNT_TYPE_STORE);
1775 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1779 /* Create and register the windows */
1780 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1781 mgr = modest_runtime_get_window_mgr ();
1782 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1784 /* Note that register_window could have deleted the account */
1785 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1786 gdouble parent_zoom;
1788 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1789 modest_window_set_zoom (msg_win, parent_zoom);
1792 /* Show edit window */
1793 gtk_widget_show_all (GTK_WIDGET (msg_win));
1796 /* We always unregister the header because the message is
1797 forwarded or replied so the original one is no longer
1799 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1802 g_object_unref (G_OBJECT (new_msg));
1804 g_object_unref (G_OBJECT (account));
1805 free_reply_forward_helper (rf_helper);
1808 /* Checks a list of headers. If any of them are not currently
1809 * downloaded (CACHED) then returns TRUE else returns FALSE.
1812 header_list_count_uncached_msgs (TnyList *header_list)
1815 gint uncached_messages = 0;
1817 iter = tny_list_create_iterator (header_list);
1818 while (!tny_iterator_is_done (iter)) {
1821 header = TNY_HEADER (tny_iterator_get_current (iter));
1823 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1824 uncached_messages ++;
1825 g_object_unref (header);
1828 tny_iterator_next (iter);
1830 g_object_unref (iter);
1832 return uncached_messages;
1835 /* Returns FALSE if the user does not want to download the
1836 * messages. Returns TRUE if the user allowed the download.
1839 connect_to_get_msg (ModestWindow *win,
1840 gint num_of_uncached_msgs,
1841 TnyAccount *account)
1843 GtkResponseType response;
1845 /* Allways download if we are online. */
1846 if (tny_device_is_online (modest_runtime_get_device ()))
1849 /* If offline, then ask for user permission to download the messages */
1850 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1851 ngettext("mcen_nc_get_msg",
1853 num_of_uncached_msgs));
1855 if (response == GTK_RESPONSE_CANCEL)
1858 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1862 reply_forward_performer (gboolean canceled,
1864 GtkWindow *parent_window,
1865 TnyAccount *account,
1868 ReplyForwardHelper *rf_helper = NULL;
1869 ModestMailOperation *mail_op;
1871 rf_helper = (ReplyForwardHelper *) user_data;
1873 if (canceled || err) {
1874 free_reply_forward_helper (rf_helper);
1878 /* Retrieve the message */
1879 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1880 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1881 modest_ui_actions_disk_operations_error_handler,
1883 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1884 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1887 g_object_unref(mail_op);
1891 * Common code for the reply and forward actions
1894 reply_forward (ReplyForwardAction action, ModestWindow *win)
1896 ReplyForwardHelper *rf_helper = NULL;
1897 guint reply_forward_type;
1899 g_return_if_fail (MODEST_IS_WINDOW(win));
1901 /* we check for low-mem; in that case, show a warning, and don't allow
1902 * reply/forward (because it could potentially require a lot of memory */
1903 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1907 /* we need an account when editing */
1908 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1909 if (!modest_ui_actions_run_account_setup_wizard (win))
1913 reply_forward_type =
1914 modest_conf_get_int (modest_runtime_get_conf (),
1915 (action == ACTION_FORWARD) ?
1916 MODEST_CONF_FORWARD_TYPE :
1917 MODEST_CONF_REPLY_TYPE,
1920 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1922 TnyHeader *header = NULL;
1923 /* Get header and message. Do not free them here, the
1924 reply_forward_cb must do it */
1925 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1926 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1928 if (msg && header) {
1930 rf_helper = create_reply_forward_helper (action, win,
1931 reply_forward_type, header);
1932 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1934 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1938 g_object_unref (msg);
1940 g_object_unref (header);
1942 TnyHeader *header = NULL;
1944 gboolean do_retrieve = TRUE;
1945 TnyList *header_list = NULL;
1947 header_list = get_selected_headers (win);
1950 /* Check that only one message is selected for replying */
1951 if (tny_list_get_length (header_list) != 1) {
1952 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1953 NULL, _("mcen_ib_select_one_message"));
1954 g_object_unref (header_list);
1958 /* Only reply/forward to one message */
1959 iter = tny_list_create_iterator (header_list);
1960 header = TNY_HEADER (tny_iterator_get_current (iter));
1961 g_object_unref (iter);
1963 /* Retrieve messages */
1964 do_retrieve = (action == ACTION_FORWARD) ||
1965 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1968 TnyAccount *account = NULL;
1969 TnyFolder *folder = NULL;
1970 gdouble download = TRUE;
1971 guint uncached_msgs = 0;
1973 folder = tny_header_get_folder (header);
1975 goto do_retrieve_frees;
1976 account = tny_folder_get_account (folder);
1978 goto do_retrieve_frees;
1980 uncached_msgs = header_list_count_uncached_msgs (header_list);
1982 if (uncached_msgs > 0) {
1983 /* Allways download if we are online. */
1984 if (!tny_device_is_online (modest_runtime_get_device ())) {
1987 /* If ask for user permission to download the messages */
1988 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1989 ngettext("mcen_nc_get_msg",
1993 /* End if the user does not want to continue */
1994 if (response == GTK_RESPONSE_CANCEL)
2001 rf_helper = create_reply_forward_helper (action, win,
2002 reply_forward_type, header);
2003 if (uncached_msgs > 0) {
2004 modest_platform_connect_and_perform (GTK_WINDOW (win),
2006 reply_forward_performer,
2009 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2010 account, rf_helper);
2015 g_object_unref (account);
2017 g_object_unref (folder);
2019 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
2022 g_object_unref (header_list);
2023 g_object_unref (header);
2028 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2030 g_return_if_fail (MODEST_IS_WINDOW(win));
2032 reply_forward (ACTION_REPLY, win);
2036 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2038 g_return_if_fail (MODEST_IS_WINDOW(win));
2040 reply_forward (ACTION_FORWARD, win);
2044 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2046 g_return_if_fail (MODEST_IS_WINDOW(win));
2048 reply_forward (ACTION_REPLY_TO_ALL, win);
2052 modest_ui_actions_on_next (GtkAction *action,
2053 ModestWindow *window)
2055 if (MODEST_IS_MAIN_WINDOW (window)) {
2056 GtkWidget *header_view;
2058 header_view = modest_main_window_get_child_widget (
2059 MODEST_MAIN_WINDOW(window),
2060 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2064 modest_header_view_select_next (
2065 MODEST_HEADER_VIEW(header_view));
2066 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2067 modest_msg_view_window_select_next_message (
2068 MODEST_MSG_VIEW_WINDOW (window));
2070 g_return_if_reached ();
2075 modest_ui_actions_on_prev (GtkAction *action,
2076 ModestWindow *window)
2078 g_return_if_fail (MODEST_IS_WINDOW(window));
2080 if (MODEST_IS_MAIN_WINDOW (window)) {
2081 GtkWidget *header_view;
2082 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2083 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2087 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2088 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2089 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2091 g_return_if_reached ();
2096 modest_ui_actions_on_sort (GtkAction *action,
2097 ModestWindow *window)
2099 GtkWidget *header_view = NULL;
2101 g_return_if_fail (MODEST_IS_WINDOW(window));
2103 if (MODEST_IS_MAIN_WINDOW (window)) {
2104 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2105 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2106 #ifdef MODEST_TOOLKIT_HILDON2
2107 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2108 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2113 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2118 /* Show sorting dialog */
2119 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2123 new_messages_arrived (ModestMailOperation *self,
2124 TnyList *new_headers,
2128 gboolean show_visual_notifications;
2130 source = modest_mail_operation_get_source (self);
2131 show_visual_notifications = (source) ? FALSE : TRUE;
2133 g_object_unref (source);
2135 /* Notify new messages have been downloaded. If the
2136 send&receive was invoked by the user then do not show any
2137 visual notification, only play a sound and activate the LED
2138 (for the Maemo version) */
2139 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2141 /* We only notify about really new messages (not seen) we get */
2142 TnyList *actually_new_list;
2143 TnyIterator *iterator;
2144 actually_new_list = TNY_LIST (tny_simple_list_new ());
2145 for (iterator = tny_list_create_iterator (new_headers);
2146 !tny_iterator_is_done (iterator);
2147 tny_iterator_next (iterator)) {
2149 TnyHeaderFlags flags;
2150 header = TNY_HEADER (tny_iterator_get_current (iterator));
2151 flags = tny_header_get_flags (header);
2153 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2154 tny_list_append (actually_new_list, G_OBJECT (header));
2156 g_object_unref (header);
2159 g_object_unref (iterator);
2161 if (tny_list_get_length (actually_new_list) > 0) {
2162 modest_platform_on_new_headers_received (actually_new_list,
2163 show_visual_notifications);
2165 g_object_unref (actually_new_list);
2171 retrieve_all_messages_cb (GObject *source,
2173 guint retrieve_limit)
2179 window = GTK_WINDOW (source);
2180 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2181 num_msgs, retrieve_limit);
2183 /* Ask the user if they want to retrieve all the messages */
2185 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2186 _("mcen_bd_get_all"),
2187 _("mcen_bd_newest_only"));
2188 /* Free and return */
2190 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2194 TnyAccount *account;
2196 gchar *account_name;
2197 gboolean poke_status;
2198 gboolean interactive;
2199 ModestMailOperation *mail_op;
2203 do_send_receive_performer (gboolean canceled,
2205 GtkWindow *parent_window,
2206 TnyAccount *account,
2209 SendReceiveInfo *info;
2211 info = (SendReceiveInfo *) user_data;
2213 if (err || canceled) {
2214 /* In memory full conditions we could get this error here */
2215 check_memory_full_error ((GtkWidget *) parent_window, err);
2217 if (info->mail_op) {
2218 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2224 /* Set send/receive operation in progress */
2225 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2226 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2229 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2230 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2231 G_CALLBACK (on_send_receive_finished),
2234 /* Send & receive. */
2235 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2236 (info->win) ? retrieve_all_messages_cb : NULL,
2237 new_messages_arrived, info->win);
2242 g_object_unref (G_OBJECT (info->mail_op));
2243 if (info->account_name)
2244 g_free (info->account_name);
2246 g_object_unref (info->win);
2248 g_object_unref (info->account);
2249 g_slice_free (SendReceiveInfo, info);
2253 * This function performs the send & receive required actions. The
2254 * window is used to create the mail operation. Typically it should
2255 * always be the main window, but we pass it as argument in order to
2259 modest_ui_actions_do_send_receive (const gchar *account_name,
2260 gboolean force_connection,
2261 gboolean poke_status,
2262 gboolean interactive,
2265 gchar *acc_name = NULL;
2266 SendReceiveInfo *info;
2267 ModestTnyAccountStore *acc_store;
2269 /* If no account name was provided then get the current account, and if
2270 there is no current account then pick the default one: */
2271 if (!account_name) {
2273 acc_name = g_strdup (modest_window_get_active_account (win));
2275 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2277 g_printerr ("modest: cannot get default account\n");
2281 acc_name = g_strdup (account_name);
2284 acc_store = modest_runtime_get_account_store ();
2286 /* Create the info for the connect and perform */
2287 info = g_slice_new (SendReceiveInfo);
2288 info->account_name = acc_name;
2289 info->win = (win) ? g_object_ref (win) : NULL;
2290 info->poke_status = poke_status;
2291 info->interactive = interactive;
2292 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2293 TNY_ACCOUNT_TYPE_STORE);
2294 /* We need to create the operation here, because otherwise it
2295 could happen that the queue emits the queue-empty signal
2296 while we're trying to connect the account */
2297 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2298 modest_ui_actions_disk_operations_error_handler,
2300 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2302 /* Invoke the connect and perform */
2303 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2304 force_connection, info->account,
2305 do_send_receive_performer, info);
2310 modest_ui_actions_do_cancel_send (const gchar *account_name,
2313 TnyTransportAccount *transport_account;
2314 TnySendQueue *send_queue = NULL;
2315 GError *error = NULL;
2317 /* Get transport account */
2319 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2320 (modest_runtime_get_account_store(),
2322 TNY_ACCOUNT_TYPE_TRANSPORT));
2323 if (!transport_account) {
2324 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2329 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2330 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2331 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2332 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2333 "modest: could not find send queue for account\n");
2335 /* Cancel the current send */
2336 tny_account_cancel (TNY_ACCOUNT (transport_account));
2338 /* Suspend all pending messages */
2339 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2343 if (transport_account != NULL)
2344 g_object_unref (G_OBJECT (transport_account));
2348 modest_ui_actions_cancel_send_all (ModestWindow *win)
2350 GSList *account_names, *iter;
2352 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2355 iter = account_names;
2357 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2358 iter = g_slist_next (iter);
2361 modest_account_mgr_free_account_names (account_names);
2362 account_names = NULL;
2366 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2369 /* Check if accounts exist */
2370 gboolean accounts_exist =
2371 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2373 /* If not, allow the user to create an account before trying to send/receive. */
2374 if (!accounts_exist)
2375 modest_ui_actions_on_accounts (NULL, win);
2377 /* Cancel all sending operaitons */
2378 modest_ui_actions_cancel_send_all (win);
2382 * Refreshes all accounts. This function will be used by automatic
2386 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2387 gboolean force_connection,
2388 gboolean poke_status,
2389 gboolean interactive)
2391 GSList *account_names, *iter;
2393 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2396 iter = account_names;
2398 modest_ui_actions_do_send_receive ((const char*) iter->data,
2400 poke_status, interactive, win);
2401 iter = g_slist_next (iter);
2404 modest_account_mgr_free_account_names (account_names);
2405 account_names = NULL;
2409 * Handler of the click on Send&Receive button in the main toolbar
2412 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2414 /* Check if accounts exist */
2415 gboolean accounts_exist;
2418 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2420 /* If not, allow the user to create an account before trying to send/receive. */
2421 if (!accounts_exist)
2422 modest_ui_actions_on_accounts (NULL, win);
2424 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2425 if (MODEST_IS_MAIN_WINDOW (win)) {
2426 GtkWidget *folder_view;
2427 TnyFolderStore *folder_store;
2430 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2431 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2435 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2438 g_object_unref (folder_store);
2439 /* Refresh the active account. Force the connection if needed
2440 and poke the status of all folders */
2441 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2442 #ifdef MODEST_TOOLKIT_HILDON2
2443 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2444 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2447 const gchar *active_account;
2448 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2450 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2457 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2460 GtkWidget *header_view;
2462 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2464 header_view = modest_main_window_get_child_widget (main_window,
2465 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2469 conf = modest_runtime_get_conf ();
2471 /* what is saved/restored is depending on the style; thus; we save with
2472 * old style, then update the style, and restore for this new style
2474 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2476 if (modest_header_view_get_style
2477 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2478 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2479 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2481 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2482 MODEST_HEADER_VIEW_STYLE_DETAILS);
2484 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2485 MODEST_CONF_HEADER_VIEW_KEY);
2490 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2492 ModestMainWindow *main_window)
2494 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2495 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2497 /* in the case the folder is empty, show the empty folder message and focus
2499 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2500 if (modest_header_view_is_empty (header_view)) {
2501 TnyFolder *folder = modest_header_view_get_folder (header_view);
2502 GtkWidget *folder_view =
2503 modest_main_window_get_child_widget (main_window,
2504 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2505 if (folder != NULL) {
2506 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2507 g_object_unref (folder);
2509 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2513 /* If no header has been selected then exit */
2518 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2519 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2521 /* Update toolbar dimming state */
2522 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2523 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2527 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2530 ModestWindow *window)
2532 GtkWidget *open_widget;
2533 GtkTreeRowReference *rowref;
2535 g_return_if_fail (MODEST_IS_WINDOW(window));
2536 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2537 g_return_if_fail (TNY_IS_HEADER (header));
2539 if (modest_header_view_count_selected_headers (header_view) > 1) {
2540 /* Don't allow activation if there are more than one message selected */
2541 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2545 /* we check for low-mem; in that case, show a warning, and don't allow
2546 * activating headers
2548 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2551 if (MODEST_IS_MAIN_WINDOW (window)) {
2552 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2553 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2554 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2558 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2559 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2560 gtk_tree_row_reference_free (rowref);
2564 set_active_account_from_tny_account (TnyAccount *account,
2565 ModestWindow *window)
2567 const gchar *server_acc_name = tny_account_get_id (account);
2569 /* We need the TnyAccount provided by the
2570 account store because that is the one that
2571 knows the name of the Modest account */
2572 TnyAccount *modest_server_account =
2573 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2574 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2576 if (!modest_server_account) {
2577 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2581 /* Update active account, but only if it's not a pseudo-account */
2582 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2583 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2584 const gchar *modest_acc_name =
2585 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2586 if (modest_acc_name)
2587 modest_window_set_active_account (window, modest_acc_name);
2590 g_object_unref (modest_server_account);
2595 folder_refreshed_cb (ModestMailOperation *mail_op,
2599 ModestMainWindow *win = NULL;
2600 GtkWidget *folder_view, *header_view;
2601 const GError *error;
2603 g_return_if_fail (TNY_IS_FOLDER (folder));
2605 win = MODEST_MAIN_WINDOW (user_data);
2607 /* Check if the operation failed due to memory low conditions */
2608 error = modest_mail_operation_get_error (mail_op);
2609 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2610 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2611 modest_platform_run_information_dialog (GTK_WINDOW (win),
2612 _KR("memr_ib_operation_disabled"),
2618 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2620 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2623 TnyFolderStore *current_folder;
2625 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2626 if (current_folder) {
2627 gboolean different = ((TnyFolderStore *) folder != current_folder);
2628 g_object_unref (current_folder);
2634 /* Check if folder is empty and set headers view contents style */
2635 if ((tny_folder_get_all_count (folder) == 0) ||
2636 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2637 modest_main_window_set_contents_style (win,
2638 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2642 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2643 TnyFolderStore *folder_store,
2645 ModestMainWindow *main_window)
2647 GtkWidget *header_view;
2649 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2651 header_view = modest_main_window_get_child_widget(main_window,
2652 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2657 if (TNY_IS_ACCOUNT (folder_store)) {
2659 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2661 /* Show account details */
2662 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2665 if (TNY_IS_FOLDER (folder_store) && selected) {
2666 TnyAccount *account;
2668 /* Update the active account */
2669 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2671 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2672 g_object_unref (account);
2676 /* Set the header style by default, it could
2677 be changed later by the refresh callback to
2679 modest_main_window_set_contents_style (main_window,
2680 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2682 /* Set folder on header view. This function
2683 will call tny_folder_refresh_async so we
2684 pass a callback that will be called when
2685 finished. We use that callback to set the
2686 empty view if there are no messages */
2687 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2688 TNY_FOLDER (folder_store),
2690 MODEST_WINDOW (main_window),
2691 folder_refreshed_cb,
2694 /* Restore configuration. We need to do this
2695 *after* the set_folder because the widget
2696 memory asks the header view about its
2698 modest_widget_memory_restore (modest_runtime_get_conf (),
2699 G_OBJECT(header_view),
2700 MODEST_CONF_HEADER_VIEW_KEY);
2702 /* No need to save the header view
2703 configuration for Maemo because it only
2704 saves the sorting stuff and that it's
2705 already being done by the sort
2706 dialog. Remove it when the GNOME version
2707 has the same behaviour */
2708 #ifdef MODEST_TOOLKIT_GTK
2709 if (modest_main_window_get_contents_style (main_window) ==
2710 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2711 modest_widget_memory_save (modest_runtime_get_conf (),
2712 G_OBJECT (header_view),
2713 MODEST_CONF_HEADER_VIEW_KEY);
2715 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2719 /* Update dimming state */
2720 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2721 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2725 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2732 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2734 online = tny_device_is_online (modest_runtime_get_device());
2737 /* already online -- the item is simply not there... */
2738 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2740 GTK_MESSAGE_WARNING,
2742 _("The %s you selected cannot be found"),
2744 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2745 gtk_dialog_run (GTK_DIALOG(dialog));
2747 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2750 _("mcen_bd_dialog_cancel"),
2751 GTK_RESPONSE_REJECT,
2752 _("mcen_bd_dialog_ok"),
2753 GTK_RESPONSE_ACCEPT,
2755 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2756 "Do you want to get online?"), item);
2757 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2758 gtk_label_new (txt), FALSE, FALSE, 0);
2759 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2762 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2763 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2764 /* TODO: Comment about why is this commented out: */
2765 /* modest_platform_connect_and_wait (); */
2768 gtk_widget_destroy (dialog);
2772 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2775 /* g_message ("%s %s", __FUNCTION__, link); */
2780 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2783 modest_platform_activate_uri (link);
2787 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2790 modest_platform_show_uri_popup (link);
2794 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2797 /* we check for low-mem; in that case, show a warning, and don't allow
2798 * viewing attachments
2800 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2803 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2807 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2808 const gchar *address,
2811 /* g_message ("%s %s", __FUNCTION__, address); */
2815 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2816 TnyMsg *saved_draft,
2819 ModestMsgEditWindow *edit_window;
2821 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2822 #ifndef MODEST_TOOLKIT_HILDON2
2823 ModestMainWindow *win;
2825 /* FIXME. Make the header view sensitive again. This is a
2826 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2828 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2829 modest_runtime_get_window_mgr(), FALSE));
2831 GtkWidget *hdrview = modest_main_window_get_child_widget(
2832 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2833 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2837 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2839 /* Set draft is there was no error */
2840 if (!modest_mail_operation_get_error (mail_op))
2841 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2843 g_object_unref(edit_window);
2847 enough_space_for_message (ModestMsgEditWindow *edit_window,
2850 guint64 available_disk, expected_size;
2855 available_disk = modest_utils_get_available_space (NULL);
2856 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2857 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2862 /* Double check: memory full condition or message too big */
2863 if (available_disk < MIN_FREE_SPACE ||
2864 expected_size > available_disk) {
2865 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2866 modest_platform_information_banner (NULL, NULL, msg);
2873 * djcb: if we're in low-memory state, we only allow for
2874 * saving messages smaller than
2875 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2876 * should still allow for sending anything critical...
2878 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2879 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2883 * djcb: we also make sure that the attachments are smaller than the max size
2884 * this is for the case where we'd try to forward a message with attachments
2885 * bigger than our max allowed size, or sending an message from drafts which
2886 * somehow got past our checks when attaching.
2888 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2889 modest_platform_run_information_dialog (
2890 GTK_WINDOW(edit_window),
2891 _KR("memr_ib_operation_disabled"),
2900 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2902 TnyTransportAccount *transport_account;
2903 ModestMailOperation *mail_operation;
2905 gchar *account_name;
2906 ModestAccountMgr *account_mgr;
2907 gboolean had_error = FALSE;
2908 ModestMainWindow *win = NULL;
2910 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2912 data = modest_msg_edit_window_get_msg_data (edit_window);
2915 if (!enough_space_for_message (edit_window, data)) {
2916 modest_msg_edit_window_free_msg_data (edit_window, data);
2920 account_name = g_strdup (data->account_name);
2921 account_mgr = modest_runtime_get_account_mgr();
2923 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2925 account_name = modest_account_mgr_get_default_account (account_mgr);
2926 if (!account_name) {
2927 g_printerr ("modest: no account found\n");
2928 modest_msg_edit_window_free_msg_data (edit_window, data);
2932 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2933 account_name = g_strdup (data->account_name);
2937 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2938 (modest_runtime_get_account_store (),
2940 TNY_ACCOUNT_TYPE_TRANSPORT));
2941 if (!transport_account) {
2942 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2943 g_free (account_name);
2944 modest_msg_edit_window_free_msg_data (edit_window, data);
2948 /* Create the mail operation */
2949 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2951 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2953 modest_mail_operation_save_to_drafts (mail_operation,
2965 data->priority_flags,
2968 on_save_to_drafts_cb,
2969 g_object_ref(edit_window));
2971 #ifdef MODEST_TOOLKIT_HILDON2
2972 /* In hildon2 we always show the information banner on saving to drafts.
2973 * It will be a system information banner in this case.
2975 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2976 modest_platform_information_banner (NULL, NULL, text);
2979 /* Use the main window as the parent of the banner, if the
2980 main window does not exist it won't be shown, if the parent
2981 window exists then it's properly shown. We don't use the
2982 editor window because it could be closed (save to drafts
2983 could happen after closing the window */
2984 win = (ModestMainWindow *)
2985 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2987 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2988 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2992 modest_msg_edit_window_set_modified (edit_window, FALSE);
2995 g_free (account_name);
2996 g_object_unref (G_OBJECT (transport_account));
2997 g_object_unref (G_OBJECT (mail_operation));
2999 modest_msg_edit_window_free_msg_data (edit_window, data);
3002 * If the drafts folder is selected then make the header view
3003 * insensitive while the message is being saved to drafts
3004 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3005 * is not very clean but it avoids letting the drafts folder
3006 * in an inconsistent state: the user could edit the message
3007 * being saved and undesirable things would happen.
3008 * In the average case the user won't notice anything at
3009 * all. In the worst case (the user is editing a really big
3010 * file from Drafts) the header view will be insensitive
3011 * during the saving process (10 or 20 seconds, depending on
3012 * the message). Anyway this is just a quick workaround: once
3013 * we find a better solution it should be removed
3014 * See NB#65125 (commend #18) for details.
3016 if (!had_error && win != NULL) {
3017 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3018 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3020 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3022 if (modest_tny_folder_is_local_folder(folder)) {
3023 TnyFolderType folder_type;
3024 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3025 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3026 GtkWidget *hdrview = modest_main_window_get_child_widget(
3027 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3028 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3032 if (folder != NULL) g_object_unref(folder);
3039 /* For instance, when clicking the Send toolbar button when editing a message: */
3041 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3043 TnyTransportAccount *transport_account = NULL;
3044 gboolean had_error = FALSE;
3046 ModestAccountMgr *account_mgr;
3047 gchar *account_name;
3048 ModestMailOperation *mail_operation;
3050 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3052 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3055 data = modest_msg_edit_window_get_msg_data (edit_window);
3058 if (!enough_space_for_message (edit_window, data)) {
3059 modest_msg_edit_window_free_msg_data (edit_window, data);
3063 account_mgr = modest_runtime_get_account_mgr();
3064 account_name = g_strdup (data->account_name);
3066 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3069 account_name = modest_account_mgr_get_default_account (account_mgr);
3071 if (!account_name) {
3072 modest_msg_edit_window_free_msg_data (edit_window, data);
3073 /* Run account setup wizard */
3074 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3079 /* Get the currently-active transport account for this modest account: */
3080 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3082 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3083 (modest_runtime_get_account_store (),
3084 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3087 if (!transport_account) {
3088 modest_msg_edit_window_free_msg_data (edit_window, data);
3089 /* Run account setup wizard */
3090 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3095 /* Create the mail operation */
3096 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3097 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3099 modest_mail_operation_send_new_mail (mail_operation,
3113 data->priority_flags);
3115 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3116 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3118 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3119 const GError *error = modest_mail_operation_get_error (mail_operation);
3120 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3121 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3122 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3123 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3129 g_free (account_name);
3130 g_object_unref (G_OBJECT (transport_account));
3131 g_object_unref (G_OBJECT (mail_operation));
3133 modest_msg_edit_window_free_msg_data (edit_window, data);
3136 modest_msg_edit_window_set_sent (edit_window, TRUE);
3138 /* Save settings and close the window: */
3139 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3146 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3147 ModestMsgEditWindow *window)
3149 ModestMsgEditFormatState *format_state = NULL;
3151 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3152 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3154 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3157 format_state = modest_msg_edit_window_get_format_state (window);
3158 g_return_if_fail (format_state != NULL);
3160 format_state->bold = gtk_toggle_action_get_active (action);
3161 modest_msg_edit_window_set_format_state (window, format_state);
3162 g_free (format_state);
3167 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3168 ModestMsgEditWindow *window)
3170 ModestMsgEditFormatState *format_state = NULL;
3172 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3173 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3175 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3178 format_state = modest_msg_edit_window_get_format_state (window);
3179 g_return_if_fail (format_state != NULL);
3181 format_state->italics = gtk_toggle_action_get_active (action);
3182 modest_msg_edit_window_set_format_state (window, format_state);
3183 g_free (format_state);
3188 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3189 ModestMsgEditWindow *window)
3191 ModestMsgEditFormatState *format_state = NULL;
3193 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3194 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3196 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3199 format_state = modest_msg_edit_window_get_format_state (window);
3200 g_return_if_fail (format_state != NULL);
3202 format_state->bullet = gtk_toggle_action_get_active (action);
3203 modest_msg_edit_window_set_format_state (window, format_state);
3204 g_free (format_state);
3209 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3210 GtkRadioAction *selected,
3211 ModestMsgEditWindow *window)
3213 ModestMsgEditFormatState *format_state = NULL;
3214 GtkJustification value;
3216 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3218 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3221 value = gtk_radio_action_get_current_value (selected);
3223 format_state = modest_msg_edit_window_get_format_state (window);
3224 g_return_if_fail (format_state != NULL);
3226 format_state->justification = value;
3227 modest_msg_edit_window_set_format_state (window, format_state);
3228 g_free (format_state);
3232 modest_ui_actions_on_select_editor_color (GtkAction *action,
3233 ModestMsgEditWindow *window)
3235 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3236 g_return_if_fail (GTK_IS_ACTION (action));
3238 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3241 modest_msg_edit_window_select_color (window);
3245 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3246 ModestMsgEditWindow *window)
3248 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3249 g_return_if_fail (GTK_IS_ACTION (action));
3251 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3254 modest_msg_edit_window_select_background_color (window);
3258 modest_ui_actions_on_insert_image (GObject *object,
3259 ModestMsgEditWindow *window)
3261 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3264 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3267 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3270 modest_msg_edit_window_insert_image (window);
3274 modest_ui_actions_on_attach_file (GtkAction *action,
3275 ModestMsgEditWindow *window)
3277 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3278 g_return_if_fail (GTK_IS_ACTION (action));
3280 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3283 modest_msg_edit_window_offer_attach_file (window);
3287 modest_ui_actions_on_remove_attachments (GtkAction *action,
3288 ModestMsgEditWindow *window)
3290 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3292 modest_msg_edit_window_remove_attachments (window, NULL);
3296 do_create_folder_cb (ModestMailOperation *mail_op,
3297 TnyFolderStore *parent_folder,
3298 TnyFolder *new_folder,
3301 gchar *suggested_name = (gchar *) user_data;
3302 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3303 const GError *error;
3305 error = modest_mail_operation_get_error (mail_op);
3308 /* Show an error. If there was some problem writing to
3309 disk, show it, otherwise show the generic folder
3310 create error. We do it here and not in an error
3311 handler because the call to do_create_folder will
3312 stop the main loop in a gtk_dialog_run and then,
3313 the message won't be shown until that dialog is
3315 modest_ui_actions_disk_operations_error_handler (mail_op,
3316 _("mail_in_ui_folder_create_error"));
3318 if (!is_memory_full_error ((GError *) error, mail_op)) {
3319 /* Try again if there is no full memory condition */
3320 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3323 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3324 * FIXME: any other? */
3325 GtkWidget *folder_view;
3327 if (MODEST_IS_MAIN_WINDOW(source_win))
3329 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3330 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3332 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3333 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3335 /* Select the newly created folder. It could happen
3336 that the widget is no longer there (i.e. the window
3337 has been destroyed, so we need to check this */
3339 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3341 g_object_unref (new_folder);
3343 /* Free. Note that the first time it'll be NULL so noop */
3344 g_free (suggested_name);
3345 g_object_unref (source_win);
3350 TnyFolderStore *parent;
3351 } CreateFolderConnect;
3354 do_create_folder_performer (gboolean canceled,
3356 GtkWindow *parent_window,
3357 TnyAccount *account,
3360 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3361 ModestMailOperation *mail_op;
3363 if (canceled || err) {
3364 /* In memory full conditions we could get this error here */
3365 check_memory_full_error ((GtkWidget *) parent_window, err);
3367 /* This happens if we have selected the outbox folder
3369 if (err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3370 TNY_IS_MERGE_FOLDER (helper->parent)) {
3371 /* Show an error and retry */
3372 modest_platform_information_banner ((GtkWidget *) parent_window,
3374 _("mail_in_ui_folder_create_error"));
3376 do_create_folder (parent_window, helper->parent, helper->folder_name);
3382 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3383 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3385 modest_mail_operation_create_folder (mail_op,
3387 (const gchar *) helper->folder_name,
3388 do_create_folder_cb,
3389 g_strdup (helper->folder_name));
3390 g_object_unref (mail_op);
3394 g_object_unref (helper->parent);
3395 if (helper->folder_name)
3396 g_free (helper->folder_name);
3397 g_slice_free (CreateFolderConnect, helper);
3402 do_create_folder (GtkWindow *parent_window,
3403 TnyFolderStore *suggested_parent,
3404 const gchar *suggested_name)
3407 gchar *folder_name = NULL;
3408 TnyFolderStore *parent_folder = NULL;
3410 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3412 (gchar *) suggested_name,
3416 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3417 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3418 helper->folder_name = g_strdup (folder_name);
3419 helper->parent = g_object_ref (parent_folder);
3421 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3424 do_create_folder_performer,
3429 g_free (folder_name);
3431 g_object_unref (parent_folder);
3435 modest_ui_actions_create_folder(GtkWidget *parent_window,
3436 GtkWidget *folder_view,
3437 TnyFolderStore *parent_folder)
3439 if (!parent_folder) {
3440 #ifdef MODEST_TOOLKIT_HILDON2
3441 ModestTnyAccountStore *acc_store;
3443 acc_store = modest_runtime_get_account_store ();
3445 parent_folder = (TnyFolderStore *)
3446 modest_tny_account_store_get_local_folders_account (acc_store);
3448 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3452 if (parent_folder) {
3453 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3454 g_object_unref (parent_folder);
3459 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3462 g_return_if_fail (MODEST_IS_WINDOW(window));
3464 if (MODEST_IS_MAIN_WINDOW (window)) {
3465 GtkWidget *folder_view;
3467 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3468 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3472 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3473 #ifdef MODEST_TOOLKIT_HILDON2
3474 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3475 GtkWidget *folder_view;
3477 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3478 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3481 g_assert_not_reached ();
3486 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3489 const GError *error = NULL;
3490 gchar *message = NULL;
3493 /* Get error message */
3494 error = modest_mail_operation_get_error (mail_op);
3496 g_return_if_reached ();
3498 mem_full = is_memory_full_error ((GError *) error, mail_op);
3500 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3501 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3502 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3503 message = _CS("ckdg_ib_folder_already_exists");
3504 } else if (error->domain == TNY_ERROR_DOMAIN &&
3505 error->code == TNY_SERVICE_ERROR_STATE) {
3506 /* This means that the folder is already in use (a
3507 message is opened for example */
3508 message = _("emev_ni_internal_error");
3510 message = _CS("ckdg_ib_unable_to_rename");
3513 /* We don't set a parent for the dialog because the dialog
3514 will be destroyed so the banner won't appear */
3515 modest_platform_information_banner (NULL, NULL, message);
3522 TnyFolderStore *folder;
3527 on_rename_folder_cb (ModestMailOperation *mail_op,
3528 TnyFolder *new_folder,
3531 ModestFolderView *folder_view;
3533 /* If the window was closed when renaming a folder, or if
3534 * it's not a main window this will happen */
3535 if (!MODEST_IS_FOLDER_VIEW (user_data))
3538 folder_view = MODEST_FOLDER_VIEW (user_data);
3539 /* Note that if the rename fails new_folder will be NULL */
3541 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3543 modest_folder_view_select_first_inbox_or_local (folder_view);
3545 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3549 on_rename_folder_performer (gboolean canceled,
3551 GtkWindow *parent_window,
3552 TnyAccount *account,
3555 ModestMailOperation *mail_op = NULL;
3556 GtkTreeSelection *sel = NULL;
3557 GtkWidget *folder_view = NULL;
3558 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3560 if (canceled || err) {
3561 /* In memory full conditions we could get this error here */
3562 check_memory_full_error ((GtkWidget *) parent_window, err);
3566 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3567 modest_ui_actions_rename_folder_error_handler,
3568 parent_window, NULL);
3570 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3573 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3575 folder_view = modest_main_window_get_child_widget (
3576 MODEST_MAIN_WINDOW (parent_window),
3577 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3579 #ifdef MODEST_TOOLKIT_HILDON2
3580 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3581 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3582 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3586 /* Clear the folders view */
3587 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3588 gtk_tree_selection_unselect_all (sel);
3590 /* Actually rename the folder */
3591 modest_mail_operation_rename_folder (mail_op,
3592 TNY_FOLDER (data->folder),
3593 (const gchar *) (data->new_name),
3594 on_rename_folder_cb,
3596 g_object_unref (mail_op);
3599 g_object_unref (data->folder);
3600 g_free (data->new_name);
3605 modest_ui_actions_on_rename_folder (GtkAction *action,
3606 ModestWindow *window)
3608 modest_ui_actions_on_edit_mode_rename_folder (window);
3612 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3614 TnyFolderStore *folder;
3615 GtkWidget *folder_view;
3616 gboolean do_rename = TRUE;
3618 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3620 if (MODEST_IS_MAIN_WINDOW (window)) {
3621 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3622 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3626 #ifdef MODEST_TOOLKIT_HILDON2
3627 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3628 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3634 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3639 if (TNY_IS_FOLDER (folder)) {
3640 gchar *folder_name = NULL;
3642 const gchar *current_name;
3643 TnyFolderStore *parent;
3645 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3646 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3647 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3648 parent, current_name,
3650 g_object_unref (parent);
3652 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3655 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3656 rename_folder_data->folder = g_object_ref (folder);
3657 rename_folder_data->new_name = folder_name;
3658 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3659 folder, on_rename_folder_performer, rename_folder_data);
3662 g_object_unref (folder);
3667 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3670 GObject *win = modest_mail_operation_get_source (mail_op);
3672 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3673 _("mail_in_ui_folder_delete_error"),
3675 g_object_unref (win);
3679 TnyFolderStore *folder;
3680 gboolean move_to_trash;
3684 on_delete_folder_cb (gboolean canceled,
3686 GtkWindow *parent_window,
3687 TnyAccount *account,
3690 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3691 GtkWidget *folder_view;
3692 ModestMailOperation *mail_op;
3693 GtkTreeSelection *sel;
3695 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3696 g_object_unref (G_OBJECT (info->folder));
3701 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3702 folder_view = modest_main_window_get_child_widget (
3703 MODEST_MAIN_WINDOW (parent_window),
3704 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3705 #ifdef MODEST_TOOLKIT_HILDON2
3706 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3707 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3710 g_object_unref (G_OBJECT (info->folder));
3715 /* Unselect the folder before deleting it to free the headers */
3716 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3717 gtk_tree_selection_unselect_all (sel);
3719 /* Create the mail operation */
3721 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3722 modest_ui_actions_delete_folder_error_handler,
3725 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3727 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3729 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3731 g_object_unref (G_OBJECT (mail_op));
3732 g_object_unref (G_OBJECT (info->folder));
3737 delete_folder (ModestWindow *window, gboolean move_to_trash)
3739 TnyFolderStore *folder;
3740 GtkWidget *folder_view;
3744 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3746 if (MODEST_IS_MAIN_WINDOW (window)) {
3748 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3749 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3750 #ifdef MODEST_TOOLKIT_HILDON2
3751 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3752 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3760 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3765 /* Show an error if it's an account */
3766 if (!TNY_IS_FOLDER (folder)) {
3767 modest_platform_run_information_dialog (GTK_WINDOW (window),
3768 _("mail_in_ui_folder_delete_error"),
3770 g_object_unref (G_OBJECT (folder));
3775 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3776 tny_folder_get_name (TNY_FOLDER (folder)));
3777 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3778 (const gchar *) message);
3781 if (response == GTK_RESPONSE_OK) {
3782 DeleteFolderInfo *info;
3783 info = g_new0(DeleteFolderInfo, 1);
3784 info->folder = folder;
3785 info->move_to_trash = move_to_trash;
3786 g_object_ref (G_OBJECT (info->folder));
3787 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3788 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3790 TNY_FOLDER_STORE (account),
3791 on_delete_folder_cb, info);
3792 g_object_unref (account);
3797 g_object_unref (G_OBJECT (folder));
3801 modest_ui_actions_on_delete_folder (GtkAction *action,
3802 ModestWindow *window)
3804 modest_ui_actions_on_edit_mode_delete_folder (window);
3808 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3810 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3812 return delete_folder (window, FALSE);
3816 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3818 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3820 delete_folder (MODEST_WINDOW (main_window), TRUE);
3824 typedef struct _PasswordDialogFields {
3825 GtkWidget *username;
3826 GtkWidget *password;
3828 } PasswordDialogFields;
3831 password_dialog_check_field (GtkEditable *editable,
3832 PasswordDialogFields *fields)
3835 gboolean any_value_empty = FALSE;
3837 #ifdef MODEST_TOOLKIT_HILDON2
3838 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3840 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3842 if ((value == NULL) || value[0] == '\0') {
3843 any_value_empty = TRUE;
3845 #ifdef MODEST_TOOLKIT_HILDON2
3846 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3848 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3850 if ((value == NULL) || value[0] == '\0') {
3851 any_value_empty = TRUE;
3853 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3857 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3858 const gchar* server_account_name,
3863 ModestMainWindow *main_window)
3865 g_return_if_fail(server_account_name);
3866 gboolean completed = FALSE;
3867 PasswordDialogFields *fields = NULL;
3869 /* Initalize output parameters: */
3876 #ifndef MODEST_TOOLKIT_GTK
3877 /* Maemo uses a different (awkward) button order,
3878 * It should probably just use gtk_alternative_dialog_button_order ().
3880 #ifdef MODEST_TOOLKIT_HILDON2
3882 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3885 _HL("wdgt_bd_done"),
3886 GTK_RESPONSE_ACCEPT,
3888 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3889 HILDON_MARGIN_DOUBLE);
3892 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3895 _("mcen_bd_dialog_ok"),
3896 GTK_RESPONSE_ACCEPT,
3897 _("mcen_bd_dialog_cancel"),
3898 GTK_RESPONSE_REJECT,
3900 #endif /* MODEST_TOOLKIT_HILDON2 */
3903 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3907 GTK_RESPONSE_REJECT,
3909 GTK_RESPONSE_ACCEPT,
3911 #endif /* MODEST_TOOLKIT_GTK */
3913 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3915 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3916 modest_runtime_get_account_mgr(), server_account_name);
3917 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3918 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3921 gtk_widget_destroy (dialog);
3925 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3926 GtkWidget *label = gtk_label_new (txt);
3927 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3929 g_free (server_name);
3930 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3935 gchar *initial_username = modest_account_mgr_get_server_account_username (
3936 modest_runtime_get_account_mgr(), server_account_name);
3938 #ifdef MODEST_TOOLKIT_HILDON2
3939 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3940 if (initial_username)
3941 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3943 GtkWidget *entry_username = gtk_entry_new ();
3944 if (initial_username)
3945 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3947 /* Dim this if a connection has ever succeeded with this username,
3948 * as per the UI spec: */
3949 /* const gboolean username_known = */
3950 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3951 /* modest_runtime_get_account_mgr(), server_account_name); */
3952 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3954 /* We drop the username sensitive code and disallow changing it here
3955 * as tinymail does not support really changing the username in the callback
3957 gtk_widget_set_sensitive (entry_username, FALSE);
3959 #ifndef MODEST_TOOLKIT_GTK
3960 /* Auto-capitalization is the default, so let's turn it off: */
3961 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3963 /* Create a size group to be used by all captions.
3964 * Note that HildonCaption does not create a default size group if we do not specify one.
3965 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3966 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3968 #ifdef MODEST_TOOLKIT_HILDON2
3969 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3970 _("mail_fi_username"), FALSE,
3973 GtkWidget *caption = hildon_caption_new (sizegroup,
3974 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3976 gtk_widget_show (entry_username);
3977 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3978 FALSE, FALSE, MODEST_MARGIN_HALF);
3979 gtk_widget_show (caption);
3981 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3983 #endif /* !MODEST_TOOLKIT_GTK */
3986 #ifdef MODEST_TOOLKIT_HILDON2
3987 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3989 GtkWidget *entry_password = gtk_entry_new ();
3991 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3992 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3994 #ifndef MODEST_TOOLKIT_GTK
3995 /* Auto-capitalization is the default, so let's turn it off: */
3996 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3997 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3999 #ifdef MODEST_TOOLKIT_HILDON2
4000 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4001 _("mail_fi_password"), FALSE,
4004 caption = hildon_caption_new (sizegroup,
4005 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4007 gtk_widget_show (entry_password);
4008 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4009 FALSE, FALSE, MODEST_MARGIN_HALF);
4010 gtk_widget_show (caption);
4011 g_object_unref (sizegroup);
4013 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4015 #endif /* !MODEST_TOOLKIT_GTK */
4017 if (initial_username != NULL)
4018 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4020 /* This is not in the Maemo UI spec:
4021 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4022 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4026 fields = g_slice_new0 (PasswordDialogFields);
4027 fields->username = entry_username;
4028 fields->password = entry_password;
4029 fields->dialog = dialog;
4031 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4032 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4033 password_dialog_check_field (NULL, fields);
4035 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4037 while (!completed) {
4039 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4041 #ifdef MODEST_TOOLKIT_HILDON2
4042 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4044 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4047 /* Note that an empty field becomes the "" string */
4048 if (*username && strlen (*username) > 0) {
4049 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4050 server_account_name,
4054 const gboolean username_was_changed =
4055 (strcmp (*username, initial_username) != 0);
4056 if (username_was_changed) {
4057 g_warning ("%s: tinymail does not yet support changing the "
4058 "username in the get_password() callback.\n", __FUNCTION__);
4064 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4065 _("mcen_ib_username_pw_incorrect"));
4071 #ifdef MODEST_TOOLKIT_HILDON2
4072 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4074 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4077 /* We do not save the password in the configuration,
4078 * because this function is only called for passwords that should
4079 * not be remembered:
4080 modest_server_account_set_password (
4081 modest_runtime_get_account_mgr(), server_account_name,
4088 #ifndef MODEST_TOOLKIT_HILDON2
4089 /* Set parent to NULL or the banner will disappear with its parent dialog */
4090 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4102 /* This is not in the Maemo UI spec:
4103 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4109 g_free (initial_username);
4110 gtk_widget_destroy (dialog);
4111 g_slice_free (PasswordDialogFields, fields);
4113 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4117 modest_ui_actions_on_cut (GtkAction *action,
4118 ModestWindow *window)
4120 GtkWidget *focused_widget;
4121 GtkClipboard *clipboard;
4123 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4124 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4125 if (GTK_IS_EDITABLE (focused_widget)) {
4126 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4127 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4128 gtk_clipboard_store (clipboard);
4129 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4130 GtkTextBuffer *buffer;
4132 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4133 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4134 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4135 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4136 gtk_clipboard_store (clipboard);
4138 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4139 TnyList *header_list = modest_header_view_get_selected_headers (
4140 MODEST_HEADER_VIEW (focused_widget));
4141 gboolean continue_download = FALSE;
4142 gint num_of_unc_msgs;
4144 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4146 if (num_of_unc_msgs) {
4147 TnyAccount *account = get_account_from_header_list (header_list);
4149 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4150 g_object_unref (account);
4154 if (num_of_unc_msgs == 0 || continue_download) {
4155 /* modest_platform_information_banner (
4156 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4157 modest_header_view_cut_selection (
4158 MODEST_HEADER_VIEW (focused_widget));
4161 g_object_unref (header_list);
4162 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4163 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4168 modest_ui_actions_on_copy (GtkAction *action,
4169 ModestWindow *window)
4171 GtkClipboard *clipboard;
4172 GtkWidget *focused_widget;
4173 gboolean copied = TRUE;
4175 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4176 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4178 if (GTK_IS_LABEL (focused_widget)) {
4180 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4181 gtk_clipboard_set_text (clipboard, selection, -1);
4183 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4184 gtk_clipboard_store (clipboard);
4185 } else if (GTK_IS_EDITABLE (focused_widget)) {
4186 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4187 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4188 gtk_clipboard_store (clipboard);
4189 } else if (GTK_IS_HTML (focused_widget)) {
4192 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4193 if ((sel == NULL) || (sel[0] == '\0')) {
4196 gtk_html_copy (GTK_HTML (focused_widget));
4197 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4198 gtk_clipboard_store (clipboard);
4200 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4201 GtkTextBuffer *buffer;
4202 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4203 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4204 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4205 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4206 gtk_clipboard_store (clipboard);
4208 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4209 TnyList *header_list = modest_header_view_get_selected_headers (
4210 MODEST_HEADER_VIEW (focused_widget));
4211 gboolean continue_download = FALSE;
4212 gint num_of_unc_msgs;
4214 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4216 if (num_of_unc_msgs) {
4217 TnyAccount *account = get_account_from_header_list (header_list);
4219 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4220 g_object_unref (account);
4224 if (num_of_unc_msgs == 0 || continue_download) {
4225 modest_platform_information_banner (
4226 NULL, NULL, _CS("mcen_ib_getting_items"));
4227 modest_header_view_copy_selection (
4228 MODEST_HEADER_VIEW (focused_widget));
4232 g_object_unref (header_list);
4234 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4235 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4238 /* Show information banner if there was a copy to clipboard */
4240 modest_platform_information_banner (
4241 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4245 modest_ui_actions_on_undo (GtkAction *action,
4246 ModestWindow *window)
4248 ModestEmailClipboard *clipboard = NULL;
4250 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4251 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4252 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4253 /* Clear clipboard source */
4254 clipboard = modest_runtime_get_email_clipboard ();
4255 modest_email_clipboard_clear (clipboard);
4258 g_return_if_reached ();
4263 modest_ui_actions_on_redo (GtkAction *action,
4264 ModestWindow *window)
4266 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4267 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4270 g_return_if_reached ();
4276 destroy_information_note (ModestMailOperation *mail_op,
4279 /* destroy information note */
4280 gtk_widget_destroy (GTK_WIDGET(user_data));
4284 destroy_folder_information_note (ModestMailOperation *mail_op,
4285 TnyFolder *new_folder,
4288 /* destroy information note */
4289 gtk_widget_destroy (GTK_WIDGET(user_data));
4294 paste_as_attachment_free (gpointer data)
4296 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4298 if (helper->banner) {
4299 gtk_widget_destroy (helper->banner);
4300 g_object_unref (helper->banner);
4306 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4311 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4312 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4317 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4322 modest_ui_actions_on_paste (GtkAction *action,
4323 ModestWindow *window)
4325 GtkWidget *focused_widget = NULL;
4326 GtkWidget *inf_note = NULL;
4327 ModestMailOperation *mail_op = NULL;
4329 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4330 if (GTK_IS_EDITABLE (focused_widget)) {
4331 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4332 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4333 ModestEmailClipboard *e_clipboard = NULL;
4334 e_clipboard = modest_runtime_get_email_clipboard ();
4335 if (modest_email_clipboard_cleared (e_clipboard)) {
4336 GtkTextBuffer *buffer;
4337 GtkClipboard *clipboard;
4339 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4340 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4341 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4342 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4343 ModestMailOperation *mail_op;
4344 TnyFolder *src_folder = NULL;
4345 TnyList *data = NULL;
4347 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4348 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4349 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4350 _CS("ckct_nw_pasting"));
4351 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4352 mail_op = modest_mail_operation_new (G_OBJECT (window));
4353 if (helper->banner != NULL) {
4354 g_object_ref (G_OBJECT (helper->banner));
4355 gtk_widget_show (GTK_WIDGET (helper->banner));
4359 modest_mail_operation_get_msgs_full (mail_op,
4361 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4363 paste_as_attachment_free);
4367 g_object_unref (data);
4369 g_object_unref (src_folder);
4372 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4373 ModestEmailClipboard *clipboard = NULL;
4374 TnyFolder *src_folder = NULL;
4375 TnyFolderStore *folder_store = NULL;
4376 TnyList *data = NULL;
4377 gboolean delete = FALSE;
4379 /* Check clipboard source */
4380 clipboard = modest_runtime_get_email_clipboard ();
4381 if (modest_email_clipboard_cleared (clipboard))
4384 /* Get elements to paste */
4385 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4387 /* Create a new mail operation */
4388 mail_op = modest_mail_operation_new (G_OBJECT(window));
4390 /* Get destination folder */
4391 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4393 /* transfer messages */
4397 /* Ask for user confirmation */
4399 modest_ui_actions_msgs_move_to_confirmation (window,
4400 TNY_FOLDER (folder_store),
4404 if (response == GTK_RESPONSE_OK) {
4405 /* Launch notification */
4406 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4407 _CS("ckct_nw_pasting"));
4408 if (inf_note != NULL) {
4409 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4410 gtk_widget_show (GTK_WIDGET(inf_note));
4413 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4414 modest_mail_operation_xfer_msgs (mail_op,
4416 TNY_FOLDER (folder_store),
4418 destroy_information_note,
4421 g_object_unref (mail_op);
4424 } else if (src_folder != NULL) {
4425 /* Launch notification */
4426 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4427 _CS("ckct_nw_pasting"));
4428 if (inf_note != NULL) {
4429 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4430 gtk_widget_show (GTK_WIDGET(inf_note));
4433 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4434 modest_mail_operation_xfer_folder (mail_op,
4438 destroy_folder_information_note,
4444 g_object_unref (data);
4445 if (src_folder != NULL)
4446 g_object_unref (src_folder);
4447 if (folder_store != NULL)
4448 g_object_unref (folder_store);
4454 modest_ui_actions_on_select_all (GtkAction *action,
4455 ModestWindow *window)
4457 GtkWidget *focused_widget;
4459 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4460 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4461 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4462 } else if (GTK_IS_LABEL (focused_widget)) {
4463 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4464 } else if (GTK_IS_EDITABLE (focused_widget)) {
4465 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4466 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4467 GtkTextBuffer *buffer;
4468 GtkTextIter start, end;
4470 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4471 gtk_text_buffer_get_start_iter (buffer, &start);
4472 gtk_text_buffer_get_end_iter (buffer, &end);
4473 gtk_text_buffer_select_range (buffer, &start, &end);
4474 } else if (GTK_IS_HTML (focused_widget)) {
4475 gtk_html_select_all (GTK_HTML (focused_widget));
4476 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4477 GtkWidget *header_view = focused_widget;
4478 GtkTreeSelection *selection = NULL;
4480 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4481 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4482 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4485 /* Disable window dimming management */
4486 modest_window_disable_dimming (MODEST_WINDOW(window));
4488 /* Select all messages */
4489 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4490 gtk_tree_selection_select_all (selection);
4492 /* Set focuse on header view */
4493 gtk_widget_grab_focus (header_view);
4495 /* Enable window dimming management */
4496 modest_window_enable_dimming (MODEST_WINDOW(window));
4497 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4498 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4504 modest_ui_actions_on_mark_as_read (GtkAction *action,
4505 ModestWindow *window)
4507 g_return_if_fail (MODEST_IS_WINDOW(window));
4509 /* Mark each header as read */
4510 do_headers_action (window, headers_action_mark_as_read, NULL);
4514 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4515 ModestWindow *window)
4517 g_return_if_fail (MODEST_IS_WINDOW(window));
4519 /* Mark each header as read */
4520 do_headers_action (window, headers_action_mark_as_unread, NULL);
4524 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4525 GtkRadioAction *selected,
4526 ModestWindow *window)
4530 value = gtk_radio_action_get_current_value (selected);
4531 if (MODEST_IS_WINDOW (window)) {
4532 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4537 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4538 GtkRadioAction *selected,
4539 ModestWindow *window)
4541 TnyHeaderFlags flags;
4542 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4544 flags = gtk_radio_action_get_current_value (selected);
4545 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4549 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4550 GtkRadioAction *selected,
4551 ModestWindow *window)
4555 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4557 file_format = gtk_radio_action_get_current_value (selected);
4558 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4563 modest_ui_actions_on_zoom_plus (GtkAction *action,
4564 ModestWindow *window)
4566 g_return_if_fail (MODEST_IS_WINDOW (window));
4568 modest_window_zoom_plus (MODEST_WINDOW (window));
4572 modest_ui_actions_on_zoom_minus (GtkAction *action,
4573 ModestWindow *window)
4575 g_return_if_fail (MODEST_IS_WINDOW (window));
4577 modest_window_zoom_minus (MODEST_WINDOW (window));
4581 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4582 ModestWindow *window)
4584 ModestWindowMgr *mgr;
4585 gboolean fullscreen, active;
4586 g_return_if_fail (MODEST_IS_WINDOW (window));
4588 mgr = modest_runtime_get_window_mgr ();
4590 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4591 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4593 if (active != fullscreen) {
4594 modest_window_mgr_set_fullscreen_mode (mgr, active);
4595 #ifndef MODEST_TOOLKIT_HILDON2
4596 gtk_window_present (GTK_WINDOW (window));
4602 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4603 ModestWindow *window)
4605 ModestWindowMgr *mgr;
4606 gboolean fullscreen;
4608 g_return_if_fail (MODEST_IS_WINDOW (window));
4610 mgr = modest_runtime_get_window_mgr ();
4611 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4612 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4614 #ifndef MODEST_TOOLKIT_HILDON2
4615 gtk_window_present (GTK_WINDOW (window));
4620 * Used by modest_ui_actions_on_details to call do_headers_action
4623 headers_action_show_details (TnyHeader *header,
4624 ModestWindow *window,
4628 gboolean async_retrieval;
4631 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4632 async_retrieval = TRUE;
4633 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4635 async_retrieval = FALSE;
4637 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4639 g_object_unref (msg);
4643 * Show the header details in a ModestDetailsDialog widget
4646 modest_ui_actions_on_details (GtkAction *action,
4649 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4653 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4657 header = tny_msg_get_header (msg);
4659 headers_action_show_details (header, win, NULL);
4660 g_object_unref (header);
4662 g_object_unref (msg);
4664 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4665 GtkWidget *folder_view, *header_view;
4667 /* Check which widget has the focus */
4668 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4669 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4670 if (gtk_widget_is_focus (folder_view)) {
4671 TnyFolderStore *folder_store
4672 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4673 if (!folder_store) {
4674 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4677 /* Show only when it's a folder */
4678 /* This function should not be called for account items,
4679 * because we dim the menu item for them. */
4680 if (TNY_IS_FOLDER (folder_store)) {
4681 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4682 TNY_FOLDER (folder_store));
4685 g_object_unref (folder_store);
4688 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4689 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4690 /* Show details of each header */
4691 do_headers_action (win, headers_action_show_details, header_view);
4693 #ifdef MODEST_TOOLKIT_HILDON2
4694 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4696 GtkWidget *header_view;
4698 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4699 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4701 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4703 g_object_unref (folder);
4710 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4711 ModestMsgEditWindow *window)
4713 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4715 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4719 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4720 ModestMsgEditWindow *window)
4722 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4724 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4728 modest_ui_actions_toggle_folders_view (GtkAction *action,
4729 ModestMainWindow *main_window)
4731 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4733 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4734 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4736 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4740 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4741 ModestWindow *window)
4743 gboolean active, fullscreen = FALSE;
4744 ModestWindowMgr *mgr;
4746 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4748 /* Check if we want to toggle the toolbar view in fullscreen
4750 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4751 "ViewShowToolbarFullScreen")) {
4755 /* Toggle toolbar */
4756 mgr = modest_runtime_get_window_mgr ();
4757 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4761 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4762 ModestMsgEditWindow *window)
4764 modest_msg_edit_window_select_font (window);
4769 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4770 const gchar *display_name,
4773 /* don't update the display name if it was already set;
4774 * updating the display name apparently is expensive */
4775 const gchar* old_name = gtk_window_get_title (window);
4777 if (display_name == NULL)
4780 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4781 return; /* don't do anything */
4783 /* This is usually used to change the title of the main window, which
4784 * is the one that holds the folder view. Note that this change can
4785 * happen even when the widget doesn't have the focus. */
4786 gtk_window_set_title (window, display_name);
4791 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4793 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4794 modest_msg_edit_window_select_contacts (window);
4798 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4800 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4801 modest_msg_edit_window_check_names (window, FALSE);
4804 #ifndef MODEST_TOOLKIT_HILDON2
4806 * This function is used to track changes in the selection of the
4807 * folder view that is inside the "move to" dialog to enable/disable
4808 * the OK button because we do not want the user to select a disallowed
4809 * destination for a folder.
4810 * The user also not desired to be able to use NEW button on items where
4811 * folder creation is not possibel.
4814 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4815 TnyFolderStore *folder_store,
4819 GtkWidget *dialog = NULL;
4820 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4821 gboolean moving_folder = FALSE;
4822 gboolean is_local_account = TRUE;
4823 GtkWidget *folder_view = NULL;
4824 ModestTnyFolderRules rules;
4826 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4831 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4835 /* check if folder_store is an remote account */
4836 if (TNY_IS_ACCOUNT (folder_store)) {
4837 TnyAccount *local_account = NULL;
4838 TnyAccount *mmc_account = NULL;
4839 ModestTnyAccountStore *account_store = NULL;
4841 account_store = modest_runtime_get_account_store ();
4842 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4843 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4845 if ((gpointer) local_account != (gpointer) folder_store &&
4846 (gpointer) mmc_account != (gpointer) folder_store) {
4847 ModestProtocolType proto;
4848 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4849 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4850 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4852 is_local_account = FALSE;
4853 /* New button should be dimmed on remote
4855 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4857 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4859 g_object_unref (local_account);
4861 /* It could not exist */
4863 g_object_unref (mmc_account);
4866 /* Check the target folder rules */
4867 if (TNY_IS_FOLDER (folder_store)) {
4868 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4869 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4870 ok_sensitive = FALSE;
4871 new_sensitive = FALSE;
4876 /* Check if we're moving a folder */
4877 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4878 /* Get the widgets */
4879 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4880 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4881 if (gtk_widget_is_focus (folder_view))
4882 moving_folder = TRUE;
4885 if (moving_folder) {
4886 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4888 /* Get the folder to move */
4889 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4891 /* Check that we're not moving to the same folder */
4892 if (TNY_IS_FOLDER (moved_folder)) {
4893 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4894 if (parent == folder_store)
4895 ok_sensitive = FALSE;
4896 g_object_unref (parent);
4899 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4900 /* Do not allow to move to an account unless it's the
4901 local folders account */
4902 if (!is_local_account)
4903 ok_sensitive = FALSE;
4906 if (ok_sensitive && (moved_folder == folder_store)) {
4907 /* Do not allow to move to itself */
4908 ok_sensitive = FALSE;
4910 g_object_unref (moved_folder);
4912 TnyFolder *src_folder = NULL;
4914 /* Moving a message */
4915 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4917 TnyHeader *header = NULL;
4918 header = modest_msg_view_window_get_header
4919 (MODEST_MSG_VIEW_WINDOW (user_data));
4920 if (!TNY_IS_HEADER(header))
4921 g_warning ("%s: could not get source header", __FUNCTION__);
4923 src_folder = tny_header_get_folder (header);
4926 g_object_unref (header);
4929 TNY_FOLDER (modest_folder_view_get_selected
4930 (MODEST_FOLDER_VIEW (folder_view)));
4933 if (TNY_IS_FOLDER(src_folder)) {
4934 /* Do not allow to move the msg to the same folder */
4935 /* Do not allow to move the msg to an account */
4936 if ((gpointer) src_folder == (gpointer) folder_store ||
4937 TNY_IS_ACCOUNT (folder_store))
4938 ok_sensitive = FALSE;
4939 g_object_unref (src_folder);
4941 g_warning ("%s: could not get source folder", __FUNCTION__);
4945 /* Set sensitivity of the OK and NEW button */
4946 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4947 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4952 on_move_to_dialog_response (GtkDialog *dialog,
4956 GtkWidget *parent_win;
4957 MoveToInfo *helper = NULL;
4958 ModestFolderView *folder_view;
4960 helper = (MoveToInfo *) user_data;
4962 parent_win = (GtkWidget *) helper->win;
4963 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4964 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4967 TnyFolderStore *dst_folder;
4968 TnyFolderStore *selected;
4970 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4971 selected = modest_folder_view_get_selected (folder_view);
4972 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
4973 g_object_unref (selected);
4975 case GTK_RESPONSE_NONE:
4976 case GTK_RESPONSE_CANCEL:
4977 case GTK_RESPONSE_DELETE_EVENT:
4979 case GTK_RESPONSE_OK:
4980 dst_folder = modest_folder_view_get_selected (folder_view);
4982 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4983 /* Clean list to move used for filtering */
4984 modest_folder_view_set_list_to_move (folder_view, NULL);
4986 modest_ui_actions_on_main_window_move_to (NULL,
4987 GTK_WIDGET (folder_view),
4989 MODEST_MAIN_WINDOW (parent_win));
4990 #ifdef MODEST_TOOLKIT_HILDON2
4991 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4992 /* Clean list to move used for filtering */
4993 modest_folder_view_set_list_to_move (folder_view, NULL);
4995 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4998 GTK_WINDOW (parent_win));
5001 /* if the user selected a root folder
5002 (account) then do not perform any action */
5003 if (TNY_IS_ACCOUNT (dst_folder)) {
5004 g_signal_stop_emission_by_name (dialog, "response");
5008 /* Clean list to move used for filtering */
5009 modest_folder_view_set_list_to_move (folder_view, NULL);
5011 /* Moving from headers window in edit mode */
5012 modest_ui_actions_on_window_move_to (NULL, helper->list,
5014 MODEST_WINDOW (parent_win));
5018 g_object_unref (dst_folder);
5022 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5025 /* Free the helper and exit */
5027 g_object_unref (helper->list);
5028 g_slice_free (MoveToInfo, helper);
5029 gtk_widget_destroy (GTK_WIDGET (dialog));
5033 create_move_to_dialog (GtkWindow *win,
5034 GtkWidget *folder_view,
5035 TnyList *list_to_move)
5037 GtkWidget *dialog, *tree_view = NULL;
5039 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5041 #ifndef MODEST_TOOLKIT_HILDON2
5042 /* Track changes in the selection to
5043 * disable the OK button whenever "Move to" is not possible
5044 * disbale NEW button whenever New is not possible */
5045 g_signal_connect (tree_view,
5046 "folder_selection_changed",
5047 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5051 /* It could happen that we're trying to move a message from a
5052 window (msg window for example) after the main window was
5053 closed, so we can not just get the model of the folder
5055 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5056 const gchar *visible_id = NULL;
5058 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5059 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5060 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5061 MODEST_FOLDER_VIEW(tree_view));
5064 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5066 /* Show the same account than the one that is shown in the main window */
5067 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5070 const gchar *active_account_name = NULL;
5071 ModestAccountMgr *mgr = NULL;
5072 ModestAccountSettings *settings = NULL;
5073 ModestServerAccountSettings *store_settings = NULL;
5075 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5076 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5077 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5078 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5080 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5081 mgr = modest_runtime_get_account_mgr ();
5082 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5085 const gchar *store_account_name;
5086 store_settings = modest_account_settings_get_store_settings (settings);
5087 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5089 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5090 store_account_name);
5091 g_object_unref (store_settings);
5092 g_object_unref (settings);
5096 /* we keep a pointer to the embedded folder view, so we can
5097 * retrieve it with get_folder_view_from_move_to_dialog (see
5098 * above) later (needed for focus handling)
5100 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5102 /* Hide special folders */
5103 #ifndef MODEST_TOOLKIT_HILDON2
5104 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5107 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5108 #ifndef MODEST_TOOLKIT_HILDON2
5109 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5112 gtk_widget_show (GTK_WIDGET (tree_view));
5118 * Shows a confirmation dialog to the user when we're moving messages
5119 * from a remote server to the local storage. Returns the dialog
5120 * response. If it's other kind of movement then it always returns
5123 * This one is used by the next functions:
5124 * modest_ui_actions_on_paste - commented out
5125 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5128 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5129 TnyFolder *dest_folder,
5133 gint response = GTK_RESPONSE_OK;
5134 TnyAccount *account = NULL;
5135 TnyFolder *src_folder = NULL;
5136 TnyIterator *iter = NULL;
5137 TnyHeader *header = NULL;
5139 /* return with OK if the destination is a remote folder */
5140 if (modest_tny_folder_is_remote_folder (dest_folder))
5141 return GTK_RESPONSE_OK;
5143 /* Get source folder */
5144 iter = tny_list_create_iterator (headers);
5145 header = TNY_HEADER (tny_iterator_get_current (iter));
5147 src_folder = tny_header_get_folder (header);
5148 g_object_unref (header);
5150 g_object_unref (iter);
5152 /* if no src_folder, message may be an attahcment */
5153 if (src_folder == NULL)
5154 return GTK_RESPONSE_CANCEL;
5156 /* If the source is a local or MMC folder */
5157 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5158 g_object_unref (src_folder);
5159 return GTK_RESPONSE_OK;
5162 /* Get the account */
5163 account = tny_folder_get_account (src_folder);
5165 /* now if offline we ask the user */
5166 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5167 response = GTK_RESPONSE_OK;
5169 response = GTK_RESPONSE_CANCEL;
5172 g_object_unref (src_folder);
5173 g_object_unref (account);
5179 move_to_helper_destroyer (gpointer user_data)
5181 MoveToHelper *helper = (MoveToHelper *) user_data;
5183 /* Close the "Pasting" information banner */
5184 if (helper->banner) {
5185 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5186 g_object_unref (helper->banner);
5188 if (gtk_tree_row_reference_valid (helper->reference)) {
5189 gtk_tree_row_reference_free (helper->reference);
5190 helper->reference = NULL;
5196 move_to_cb (ModestMailOperation *mail_op,
5199 MoveToHelper *helper = (MoveToHelper *) user_data;
5200 GObject *object = modest_mail_operation_get_source (mail_op);
5202 /* Note that the operation could have failed, in that case do
5204 if (modest_mail_operation_get_status (mail_op) !=
5205 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5208 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5209 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5211 if (!modest_msg_view_window_select_next_message (self) &&
5212 !modest_msg_view_window_select_previous_message (self)) {
5213 /* No more messages to view, so close this window */
5214 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5216 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5217 gtk_tree_row_reference_valid (helper->reference)) {
5218 GtkWidget *header_view;
5220 GtkTreeSelection *sel;
5222 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5223 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5224 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5225 path = gtk_tree_row_reference_get_path (helper->reference);
5226 /* We need to unselect the previous one
5227 because we could be copying instead of
5229 gtk_tree_selection_unselect_all (sel);
5230 gtk_tree_selection_select_path (sel, path);
5231 gtk_tree_path_free (path);
5233 g_object_unref (object);
5236 /* Destroy the helper */
5237 move_to_helper_destroyer (helper);
5241 folder_move_to_cb (ModestMailOperation *mail_op,
5242 TnyFolder *new_folder,
5245 GtkWidget *folder_view;
5248 object = modest_mail_operation_get_source (mail_op);
5249 if (MODEST_IS_MAIN_WINDOW (object)) {
5250 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5251 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5252 g_object_ref (folder_view);
5253 g_object_unref (object);
5254 move_to_cb (mail_op, user_data);
5255 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5256 g_object_unref (folder_view);
5258 move_to_cb (mail_op, user_data);
5263 msgs_move_to_cb (ModestMailOperation *mail_op,
5266 move_to_cb (mail_op, user_data);
5270 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5273 GObject *win = NULL;
5275 #ifndef MODEST_TOOLKIT_HILDON2
5276 ModestWindow *main_window = NULL;
5278 /* Disable next automatic folder selection */
5279 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5280 FALSE); /* don't create */
5282 GtkWidget *folder_view = NULL;
5284 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5285 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5286 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5288 if (user_data && TNY_IS_FOLDER (user_data)) {
5289 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5290 TNY_FOLDER (user_data), FALSE);
5294 /* Show notification dialog only if the main window exists */
5295 win = modest_mail_operation_get_source (mail_op);
5296 modest_platform_run_information_dialog ((GtkWindow *) win,
5297 _("mail_in_ui_folder_move_target_error"),
5300 g_object_unref (win);
5304 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5313 gint pending_purges = 0;
5314 gboolean some_purged = FALSE;
5315 ModestWindow *win = MODEST_WINDOW (user_data);
5316 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5318 /* If there was any error */
5319 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5320 modest_window_mgr_unregister_header (mgr, header);
5324 /* Once the message has been retrieved for purging, we check if
5325 * it's all ok for purging */
5327 parts = tny_simple_list_new ();
5328 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5329 iter = tny_list_create_iterator (parts);
5331 while (!tny_iterator_is_done (iter)) {
5333 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5334 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5335 if (tny_mime_part_is_purged (part))
5342 g_object_unref (part);
5344 tny_iterator_next (iter);
5346 g_object_unref (iter);
5349 if (pending_purges>0) {
5351 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5353 if (response == GTK_RESPONSE_OK) {
5356 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5357 iter = tny_list_create_iterator (parts);
5358 while (!tny_iterator_is_done (iter)) {
5361 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5362 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5363 tny_mime_part_set_purged (part);
5366 g_object_unref (part);
5368 tny_iterator_next (iter);
5370 g_object_unref (iter);
5372 tny_msg_rewrite_cache (msg);
5374 gtk_widget_destroy (info);
5378 modest_window_mgr_unregister_header (mgr, header);
5380 g_object_unref (parts);
5384 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5385 ModestMainWindow *win)
5387 GtkWidget *header_view;
5388 TnyList *header_list;
5390 TnyHeaderFlags flags;
5391 ModestWindow *msg_view_window = NULL;
5394 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5396 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5397 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5399 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5401 g_warning ("%s: no header selected", __FUNCTION__);
5405 if (tny_list_get_length (header_list) == 1) {
5406 TnyIterator *iter = tny_list_create_iterator (header_list);
5407 header = TNY_HEADER (tny_iterator_get_current (iter));
5408 g_object_unref (iter);
5412 if (!header || !TNY_IS_HEADER(header)) {
5413 g_warning ("%s: header is not valid", __FUNCTION__);
5417 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5418 header, &msg_view_window);
5419 flags = tny_header_get_flags (header);
5420 if (!(flags & TNY_HEADER_FLAG_CACHED))
5423 if (msg_view_window != NULL)
5424 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5426 /* do nothing; uid was registered before, so window is probably on it's way */
5427 g_warning ("debug: header %p has already been registered", header);
5430 ModestMailOperation *mail_op = NULL;
5431 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5432 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5433 modest_ui_actions_disk_operations_error_handler,
5435 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5436 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5438 g_object_unref (mail_op);
5441 g_object_unref (header);
5443 g_object_unref (header_list);
5447 * Checks if we need a connection to do the transfer and if the user
5448 * wants to connect to complete it
5451 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5452 TnyFolderStore *src_folder,
5454 TnyFolder *dst_folder,
5455 gboolean delete_originals,
5456 gboolean *need_connection,
5459 TnyAccount *src_account;
5460 gint uncached_msgs = 0;
5462 /* We don't need any further check if
5464 * 1- the source folder is local OR
5465 * 2- the device is already online
5467 if (!modest_tny_folder_store_is_remote (src_folder) ||
5468 tny_device_is_online (modest_runtime_get_device())) {
5469 *need_connection = FALSE;
5474 /* We must ask for a connection when
5476 * - the message(s) is not already cached OR
5477 * - the message(s) is cached but the leave_on_server setting
5478 * is FALSE (because we need to sync the source folder to
5479 * delete the message from the server (for IMAP we could do it
5480 * offline, it'll take place the next time we get a
5483 uncached_msgs = header_list_count_uncached_msgs (headers);
5484 src_account = get_account_from_folder_store (src_folder);
5485 if (uncached_msgs > 0) {
5489 *need_connection = TRUE;
5490 num_headers = tny_list_get_length (headers);
5491 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5493 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5494 GTK_RESPONSE_CANCEL) {
5500 /* The transfer is possible and the user wants to */
5503 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5504 const gchar *account_name;
5505 gboolean leave_on_server;
5507 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5508 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5511 if (leave_on_server == TRUE) {
5512 *need_connection = FALSE;
5514 *need_connection = TRUE;
5517 *need_connection = FALSE;
5522 g_object_unref (src_account);
5526 xfer_messages_error_handler (ModestMailOperation *mail_op,
5530 const GError *error;
5532 win = modest_mail_operation_get_source (mail_op);
5533 error = modest_mail_operation_get_error (mail_op);
5535 if (error && is_memory_full_error ((GError *) error, mail_op)) {
5536 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
5537 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
5540 modest_platform_run_information_dialog ((GtkWindow *) win,
5541 _("mail_in_ui_folder_move_target_error"),
5545 g_object_unref (win);
5549 TnyFolderStore *dst_folder;
5554 * Utility function that transfer messages from both the main window
5555 * and the msg view window when using the "Move to" dialog
5558 xfer_messages_performer (gboolean canceled,
5560 GtkWindow *parent_window,
5561 TnyAccount *account,
5564 ModestWindow *win = MODEST_WINDOW (parent_window);
5565 TnyAccount *dst_account = NULL;
5566 gboolean dst_forbids_message_add = FALSE;
5567 XferMsgsHelper *helper;
5568 MoveToHelper *movehelper;
5569 ModestMailOperation *mail_op;
5571 helper = (XferMsgsHelper *) user_data;
5573 if (canceled || err) {
5574 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5575 /* Show the proper error message */
5576 modest_ui_actions_on_account_connection_error (parent_window, account);
5581 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5583 /* tinymail will return NULL for local folders it seems */
5584 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5585 modest_tny_account_get_protocol_type (dst_account),
5586 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5587 g_object_unref (dst_account);
5589 if (dst_forbids_message_add) {
5590 modest_platform_information_banner (GTK_WIDGET (win),
5592 ngettext("mail_in_ui_folder_move_target_error",
5593 "mail_in_ui_folder_move_targets_error",
5594 tny_list_get_length (helper->headers)));
5598 movehelper = g_new0 (MoveToHelper, 1);
5600 #ifndef MODEST_TOOLKIT_HILDON2
5601 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5602 _CS("ckct_nw_pasting"));
5603 if (movehelper->banner != NULL) {
5604 g_object_ref (movehelper->banner);
5605 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5609 if (MODEST_IS_MAIN_WINDOW (win)) {
5610 GtkWidget *header_view =
5611 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5612 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5613 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5616 /* Perform the mail operation */
5617 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5618 xfer_messages_error_handler,
5620 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5623 modest_mail_operation_xfer_msgs (mail_op,
5625 TNY_FOLDER (helper->dst_folder),
5630 g_object_unref (G_OBJECT (mail_op));
5632 g_object_unref (helper->dst_folder);
5633 g_object_unref (helper->headers);
5634 g_slice_free (XferMsgsHelper, helper);
5638 TnyFolder *src_folder;
5639 TnyFolderStore *dst_folder;
5640 gboolean delete_original;
5641 GtkWidget *folder_view;
5645 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5646 TnyAccount *account, gpointer user_data)
5648 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5649 GtkTreeSelection *sel;
5650 ModestMailOperation *mail_op = NULL;
5652 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5653 g_object_unref (G_OBJECT (info->src_folder));
5654 g_object_unref (G_OBJECT (info->dst_folder));
5659 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5660 #ifndef MODEST_TOOLKIT_HILDON2
5661 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5662 _CS("ckct_nw_pasting"));
5663 if (helper->banner != NULL) {
5664 g_object_ref (helper->banner);
5665 gtk_widget_show (GTK_WIDGET(helper->banner));
5668 /* Clean folder on header view before moving it */
5669 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5670 gtk_tree_selection_unselect_all (sel);
5672 /* Let gtk events run. We need that the folder
5673 view frees its reference to the source
5674 folder *before* issuing the mail operation
5675 so we need the signal handler of selection
5676 changed to happen before the mail
5678 while (gtk_events_pending ())
5679 gtk_main_iteration (); */
5682 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5683 modest_ui_actions_move_folder_error_handler,
5684 info->src_folder, NULL);
5685 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5688 /* Select *after* the changes */
5689 /* TODO: this function hangs UI after transfer */
5690 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5691 /* TNY_FOLDER (src_folder), TRUE); */
5693 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5694 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5695 TNY_FOLDER (info->dst_folder), TRUE);
5697 modest_mail_operation_xfer_folder (mail_op,
5698 TNY_FOLDER (info->src_folder),
5700 info->delete_original,
5703 g_object_unref (G_OBJECT (info->src_folder));
5705 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5708 /* Unref mail operation */
5709 g_object_unref (G_OBJECT (mail_op));
5710 g_object_unref (G_OBJECT (info->dst_folder));
5715 get_account_from_folder_store (TnyFolderStore *folder_store)
5717 if (TNY_IS_ACCOUNT (folder_store))
5718 return g_object_ref (folder_store);
5720 return tny_folder_get_account (TNY_FOLDER (folder_store));
5724 * UI handler for the "Move to" action when invoked from the
5728 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5729 GtkWidget *folder_view,
5730 TnyFolderStore *dst_folder,
5731 ModestMainWindow *win)
5733 ModestHeaderView *header_view = NULL;
5734 TnyFolderStore *src_folder = NULL;
5736 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5738 /* Get the source folder */
5739 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5741 /* Get header view */
5742 header_view = (ModestHeaderView *)
5743 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5745 /* Get folder or messages to transfer */
5746 if (gtk_widget_is_focus (folder_view)) {
5747 gboolean do_xfer = TRUE;
5749 /* Allow only to transfer folders to the local root folder */
5750 if (TNY_IS_ACCOUNT (dst_folder) &&
5751 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5752 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5754 } else if (!TNY_IS_FOLDER (src_folder)) {
5755 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5760 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5761 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5763 info->src_folder = g_object_ref (src_folder);
5764 info->dst_folder = g_object_ref (dst_folder);
5765 info->delete_original = TRUE;
5766 info->folder_view = folder_view;
5768 connect_info->callback = on_move_folder_cb;
5769 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5770 connect_info->data = info;
5772 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5773 TNY_FOLDER_STORE (src_folder),
5776 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5779 headers = modest_header_view_get_selected_headers(header_view);
5781 /* Transfer the messages */
5782 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5783 headers, TNY_FOLDER (dst_folder));
5785 g_object_unref (headers);
5789 g_object_unref (src_folder);
5792 #ifdef MODEST_TOOLKIT_HILDON2
5794 * UI handler for the "Move to" action when invoked from the
5795 * ModestFolderWindow
5798 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5799 TnyFolderStore *dst_folder,
5803 TnyFolderStore *src_folder = NULL;
5804 TnyIterator *iterator;
5806 if (tny_list_get_length (selection) != 1)
5809 iterator = tny_list_create_iterator (selection);
5810 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5811 g_object_unref (iterator);
5814 gboolean do_xfer = TRUE;
5816 /* Allow only to transfer folders to the local root folder */
5817 if (TNY_IS_ACCOUNT (dst_folder) &&
5818 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5819 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5822 modest_platform_run_information_dialog (win,
5823 _("mail_in_ui_folder_move_target_error"),
5825 } else if (!TNY_IS_FOLDER (src_folder)) {
5826 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5831 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5832 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5834 info->src_folder = g_object_ref (src_folder);
5835 info->dst_folder = g_object_ref (dst_folder);
5836 info->delete_original = TRUE;
5837 info->folder_view = folder_view;
5839 connect_info->callback = on_move_folder_cb;
5840 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5841 connect_info->data = info;
5843 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5844 TNY_FOLDER_STORE (src_folder),
5849 g_object_unref (src_folder);
5855 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5856 TnyFolder *src_folder,
5858 TnyFolder *dst_folder)
5860 gboolean need_connection = TRUE;
5861 gboolean do_xfer = TRUE;
5862 XferMsgsHelper *helper;
5864 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5865 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5866 g_return_if_fail (TNY_IS_LIST (headers));
5868 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5869 headers, TNY_FOLDER (dst_folder),
5870 TRUE, &need_connection,
5873 /* If we don't want to transfer just return */
5877 /* Create the helper */
5878 helper = g_slice_new (XferMsgsHelper);
5879 helper->dst_folder = g_object_ref (dst_folder);
5880 helper->headers = g_object_ref (headers);
5882 if (need_connection) {
5883 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5884 connect_info->callback = xfer_messages_performer;
5885 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5886 connect_info->data = helper;
5888 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5889 TNY_FOLDER_STORE (src_folder),
5892 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5893 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5894 src_account, helper);
5895 g_object_unref (src_account);
5900 * UI handler for the "Move to" action when invoked from the
5901 * ModestMsgViewWindow
5904 modest_ui_actions_on_window_move_to (GtkAction *action,
5906 TnyFolderStore *dst_folder,
5909 TnyFolder *src_folder = NULL;
5911 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5914 TnyHeader *header = NULL;
5917 iter = tny_list_create_iterator (headers);
5918 header = (TnyHeader *) tny_iterator_get_current (iter);
5919 src_folder = tny_header_get_folder (header);
5921 /* Transfer the messages */
5922 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5924 TNY_FOLDER (dst_folder));
5927 g_object_unref (header);
5928 g_object_unref (iter);
5929 g_object_unref (src_folder);
5934 modest_ui_actions_on_move_to (GtkAction *action,
5937 modest_ui_actions_on_edit_mode_move_to (win);
5941 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5943 GtkWidget *dialog = NULL;
5944 MoveToInfo *helper = NULL;
5945 TnyList *list_to_move;
5947 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5949 #ifndef MODEST_TOOLKIT_HILDON2
5950 /* Get the main window if exists */
5951 ModestMainWindow *main_window;
5952 if (MODEST_IS_MAIN_WINDOW (win))
5953 main_window = MODEST_MAIN_WINDOW (win);
5956 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5957 FALSE)); /* don't create */
5960 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5965 if (tny_list_get_length (list_to_move) < 1) {
5966 g_object_unref (list_to_move);
5970 /* Create and run the dialog */
5971 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5972 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5973 GTK_WINDOW (dialog),
5977 helper = g_slice_new0 (MoveToInfo);
5978 helper->list = list_to_move;
5981 /* Listen to response signal */
5982 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5984 /* Show the dialog */
5985 gtk_widget_show (dialog);
5991 * Calls #HeadersFunc for each header already selected in the main
5992 * window or the message currently being shown in the msg view window
5995 do_headers_action (ModestWindow *win,
5999 TnyList *headers_list = NULL;
6000 TnyIterator *iter = NULL;
6001 TnyHeader *header = NULL;
6002 TnyFolder *folder = NULL;
6005 headers_list = get_selected_headers (win);
6009 /* Get the folder */
6010 iter = tny_list_create_iterator (headers_list);
6011 header = TNY_HEADER (tny_iterator_get_current (iter));
6013 folder = tny_header_get_folder (header);
6014 g_object_unref (header);
6017 /* Call the function for each header */
6018 while (!tny_iterator_is_done (iter)) {
6019 header = TNY_HEADER (tny_iterator_get_current (iter));
6020 func (header, win, user_data);
6021 g_object_unref (header);
6022 tny_iterator_next (iter);
6025 /* Trick: do a poke status in order to speed up the signaling
6028 tny_folder_poke_status (folder);
6029 g_object_unref (folder);
6033 g_object_unref (iter);
6034 g_object_unref (headers_list);
6038 modest_ui_actions_view_attachment (GtkAction *action,
6039 ModestWindow *window)
6041 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6042 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6044 /* not supported window for this action */
6045 g_return_if_reached ();
6050 modest_ui_actions_save_attachments (GtkAction *action,
6051 ModestWindow *window)
6053 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6055 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6058 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6060 /* not supported window for this action */
6061 g_return_if_reached ();
6066 modest_ui_actions_remove_attachments (GtkAction *action,
6067 ModestWindow *window)
6069 if (MODEST_IS_MAIN_WINDOW (window)) {
6070 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6071 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6072 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6074 /* not supported window for this action */
6075 g_return_if_reached ();
6080 modest_ui_actions_on_settings (GtkAction *action,
6085 dialog = modest_platform_get_global_settings_dialog ();
6086 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6087 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6088 gtk_widget_show_all (dialog);
6090 gtk_dialog_run (GTK_DIALOG (dialog));
6092 gtk_widget_destroy (dialog);
6096 modest_ui_actions_on_help (GtkAction *action,
6099 /* Help app is not available at all in fremantle */
6100 #ifndef MODEST_TOOLKIT_HILDON2
6101 const gchar *help_id;
6103 g_return_if_fail (win && GTK_IS_WINDOW(win));
6105 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6108 modest_platform_show_help (GTK_WINDOW (win), help_id);
6113 modest_ui_actions_on_csm_help (GtkAction *action,
6116 /* Help app is not available at all in fremantle */
6117 #ifndef MODEST_TOOLKIT_HILDON2
6119 const gchar* help_id = NULL;
6120 GtkWidget *folder_view;
6121 TnyFolderStore *folder_store;
6123 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6125 /* Get selected folder */
6126 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6127 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6128 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6130 /* Switch help_id */
6131 if (folder_store && TNY_IS_FOLDER (folder_store))
6132 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6135 g_object_unref (folder_store);
6138 modest_platform_show_help (GTK_WINDOW (win), help_id);
6140 modest_ui_actions_on_help (action, win);
6145 retrieve_contents_cb (ModestMailOperation *mail_op,
6152 /* We only need this callback to show an error in case of
6153 memory low condition */
6154 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6155 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6160 retrieve_msg_contents_performer (gboolean canceled,
6162 GtkWindow *parent_window,
6163 TnyAccount *account,
6166 ModestMailOperation *mail_op;
6167 TnyList *headers = TNY_LIST (user_data);
6169 if (err || canceled) {
6170 check_memory_full_error ((GtkWidget *) parent_window, err);
6174 /* Create mail operation */
6175 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6176 modest_ui_actions_disk_operations_error_handler,
6178 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6179 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6182 g_object_unref (mail_op);
6184 g_object_unref (headers);
6185 g_object_unref (account);
6189 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6190 ModestWindow *window)
6192 TnyList *headers = NULL;
6193 TnyAccount *account = NULL;
6194 TnyIterator *iter = NULL;
6195 TnyHeader *header = NULL;
6196 TnyFolder *folder = NULL;
6199 headers = get_selected_headers (window);
6203 /* Pick the account */
6204 iter = tny_list_create_iterator (headers);
6205 header = TNY_HEADER (tny_iterator_get_current (iter));
6206 folder = tny_header_get_folder (header);
6207 account = tny_folder_get_account (folder);
6208 g_object_unref (folder);
6209 g_object_unref (header);
6210 g_object_unref (iter);
6212 /* Connect and perform the message retrieval */
6213 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6214 g_object_ref (account),
6215 retrieve_msg_contents_performer,
6216 g_object_ref (headers));
6219 g_object_unref (account);
6220 g_object_unref (headers);
6224 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6226 g_return_if_fail (MODEST_IS_WINDOW (window));
6229 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6233 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6235 g_return_if_fail (MODEST_IS_WINDOW (window));
6238 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6242 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6243 ModestWindow *window)
6245 g_return_if_fail (MODEST_IS_WINDOW (window));
6248 modest_ui_actions_check_menu_dimming_rules (window);
6252 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6253 ModestWindow *window)
6255 g_return_if_fail (MODEST_IS_WINDOW (window));
6258 modest_ui_actions_check_menu_dimming_rules (window);
6262 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6263 ModestWindow *window)
6265 g_return_if_fail (MODEST_IS_WINDOW (window));
6268 modest_ui_actions_check_menu_dimming_rules (window);
6272 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6273 ModestWindow *window)
6275 g_return_if_fail (MODEST_IS_WINDOW (window));
6278 modest_ui_actions_check_menu_dimming_rules (window);
6282 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6283 ModestWindow *window)
6285 g_return_if_fail (MODEST_IS_WINDOW (window));
6288 modest_ui_actions_check_menu_dimming_rules (window);
6292 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6293 ModestWindow *window)
6295 g_return_if_fail (MODEST_IS_WINDOW (window));
6298 modest_ui_actions_check_menu_dimming_rules (window);
6302 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6303 ModestWindow *window)
6305 g_return_if_fail (MODEST_IS_WINDOW (window));
6308 modest_ui_actions_check_menu_dimming_rules (window);
6312 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6313 ModestWindow *window)
6315 g_return_if_fail (MODEST_IS_WINDOW (window));
6318 modest_ui_actions_check_menu_dimming_rules (window);
6322 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6323 ModestWindow *window)
6325 g_return_if_fail (MODEST_IS_WINDOW (window));
6328 modest_ui_actions_check_menu_dimming_rules (window);
6332 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6334 g_return_if_fail (MODEST_IS_WINDOW (window));
6336 /* we check for low-mem; in that case, show a warning, and don't allow
6339 if (modest_platform_check_memory_low (window, TRUE))
6342 modest_platform_show_search_messages (GTK_WINDOW (window));
6346 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6348 g_return_if_fail (MODEST_IS_WINDOW (win));
6351 /* we check for low-mem; in that case, show a warning, and don't allow
6352 * for the addressbook
6354 if (modest_platform_check_memory_low (win, TRUE))
6358 modest_platform_show_addressbook (GTK_WINDOW (win));
6363 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6364 ModestWindow *window)
6367 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6369 if (GTK_IS_TOGGLE_ACTION (action))
6370 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6374 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6379 on_send_receive_finished (ModestMailOperation *mail_op,
6382 GtkWidget *header_view, *folder_view;
6383 TnyFolderStore *folder_store;
6384 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6386 /* Set send/receive operation finished */
6387 modest_main_window_notify_send_receive_completed (main_win);
6389 /* Don't refresh the current folder if there were any errors */
6390 if (modest_mail_operation_get_status (mail_op) !=
6391 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6394 /* Refresh the current folder if we're viewing a window. We do
6395 this because the user won't be able to see the new mails in
6396 the selected folder after a Send&Receive because it only
6397 performs a poke_status, i.e, only the number of read/unread
6398 messages is updated, but the new headers are not
6400 folder_view = modest_main_window_get_child_widget (main_win,
6401 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6405 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6407 /* Do not need to refresh INBOX again because the
6408 update_account does it always automatically */
6409 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6410 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6411 ModestMailOperation *refresh_op;
6413 header_view = modest_main_window_get_child_widget (main_win,
6414 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6416 /* We do not need to set the contents style
6417 because it hasn't changed. We also do not
6418 need to save the widget status. Just force
6420 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6421 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6422 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6423 folder_refreshed_cb, main_win);
6424 g_object_unref (refresh_op);
6428 g_object_unref (folder_store);
6433 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6439 const gchar* server_name = NULL;
6440 TnyTransportAccount *transport;
6441 gchar *message = NULL;
6442 ModestProtocol *protocol;
6444 /* Don't show anything if the user cancelled something or the
6445 * send receive request is not interactive. Authentication
6446 * errors are managed by the account store so no need to show
6447 * a dialog here again */
6448 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6449 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6450 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6454 /* Get the server name. Note that we could be using a
6455 connection specific transport account */
6456 transport = (TnyTransportAccount *)
6457 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6459 ModestTnyAccountStore *acc_store;
6460 const gchar *acc_name;
6461 TnyTransportAccount *conn_specific;
6463 acc_store = modest_runtime_get_account_store();
6464 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6465 conn_specific = (TnyTransportAccount *)
6466 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6467 if (conn_specific) {
6468 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6469 g_object_unref (conn_specific);
6471 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6473 g_object_unref (transport);
6477 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6478 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6479 tny_account_get_proto (TNY_ACCOUNT (transport)));
6481 g_warning ("%s: Account with no proto", __FUNCTION__);
6485 /* Show the appropriate message text for the GError: */
6486 switch (err->code) {
6487 case TNY_SERVICE_ERROR_CONNECT:
6488 message = modest_protocol_get_translation (protocol,
6489 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6492 case TNY_SERVICE_ERROR_SEND:
6493 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6495 case TNY_SERVICE_ERROR_UNAVAILABLE:
6496 message = modest_protocol_get_translation (protocol,
6497 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6501 g_warning ("%s: unexpected ERROR %d",
6502 __FUNCTION__, err->code);
6503 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6507 modest_platform_run_information_dialog (NULL, message, FALSE);
6512 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6517 ModestWindow *top_window = NULL;
6518 ModestWindowMgr *mgr = NULL;
6519 GtkWidget *header_view = NULL;
6520 TnyFolder *selected_folder = NULL;
6521 TnyFolderType folder_type;
6523 mgr = modest_runtime_get_window_mgr ();
6524 top_window = modest_window_mgr_get_current_top (mgr);
6529 #ifndef MODEST_TOOLKIT_HILDON2
6530 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6531 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6532 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6535 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6536 header_view = (GtkWidget *)
6537 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6541 /* Get selected folder */
6543 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6544 if (!selected_folder)
6547 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6548 #if GTK_CHECK_VERSION(2, 8, 0)
6549 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6550 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6551 GtkTreeViewColumn *tree_column;
6553 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6554 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6556 gtk_tree_view_column_queue_resize (tree_column);
6558 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6559 gtk_widget_queue_draw (header_view);
6562 #ifndef MODEST_TOOLKIT_HILDON2
6563 /* Rerun dimming rules, because the message could become deletable for example */
6564 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6565 MODEST_DIMMING_RULES_TOOLBAR);
6566 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6567 MODEST_DIMMING_RULES_MENU);
6571 g_object_unref (selected_folder);
6575 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6576 TnyAccount *account)
6578 ModestProtocolType protocol_type;
6579 ModestProtocol *protocol;
6580 gchar *error_note = NULL;
6582 protocol_type = modest_tny_account_get_protocol_type (account);
6583 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6586 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6587 if (error_note == NULL) {
6588 g_warning ("%s: This should not be reached", __FUNCTION__);
6590 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6591 g_free (error_note);
6596 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6600 TnyFolderStore *folder = NULL;
6601 TnyAccount *account = NULL;
6602 ModestProtocolType proto;
6603 ModestProtocol *protocol;
6604 TnyHeader *header = NULL;
6606 if (MODEST_IS_MAIN_WINDOW (win)) {
6607 GtkWidget *header_view;
6608 TnyList* headers = NULL;
6610 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6611 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6612 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6613 if (!headers || tny_list_get_length (headers) == 0) {
6615 g_object_unref (headers);
6618 iter = tny_list_create_iterator (headers);
6619 header = TNY_HEADER (tny_iterator_get_current (iter));
6620 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6621 g_object_unref (iter);
6622 g_object_unref (headers);
6623 #ifdef MODEST_TOOLKIT_HILDON2
6624 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6625 GtkWidget *header_view;
6626 TnyList* headers = NULL;
6628 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6629 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6630 if (!headers || tny_list_get_length (headers) == 0) {
6632 g_object_unref (headers);
6635 iter = tny_list_create_iterator (headers);
6636 header = TNY_HEADER (tny_iterator_get_current (iter));
6638 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6640 g_warning ("List should contain headers");
6642 g_object_unref (iter);
6643 g_object_unref (headers);
6645 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6646 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6648 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6651 if (!header || !folder)
6654 /* Get the account type */
6655 account = tny_folder_get_account (TNY_FOLDER (folder));
6656 proto = modest_tny_account_get_protocol_type (account);
6657 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6660 subject = tny_header_dup_subject (header);
6661 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6665 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6671 g_object_unref (account);
6673 g_object_unref (folder);
6675 g_object_unref (header);
6681 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6682 const gchar *account_name,
6683 const gchar *account_title)
6685 ModestAccountMgr *account_mgr;
6688 ModestProtocol *protocol;
6689 gboolean removed = FALSE;
6691 g_return_val_if_fail (account_name, FALSE);
6692 g_return_val_if_fail (account_title, FALSE);
6694 account_mgr = modest_runtime_get_account_mgr();
6696 /* The warning text depends on the account type: */
6697 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6698 modest_account_mgr_get_store_protocol (account_mgr,
6700 txt = modest_protocol_get_translation (protocol,
6701 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6704 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6706 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6710 if (response == GTK_RESPONSE_OK) {
6711 /* Remove account. If it succeeds then it also removes
6712 the account from the ModestAccountView: */
6713 gboolean is_default = FALSE;
6714 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6715 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6717 g_free (default_account_name);
6719 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6721 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6727 modest_ui_actions_on_fetch_images (GtkAction *action,
6728 ModestWindow *window)
6730 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6732 modest_msg_view_window_fetch_images (MODEST_MSG_VIEW_WINDOW (window));
6737 modest_ui_actions_on_reload_message (const gchar *msg_id)
6739 ModestWindow *window = NULL;
6741 g_return_if_fail (msg_id && msg_id[0] != '\0');
6742 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6748 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6751 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));